From cdab129ee6115a5d1a4ca068b1bb39fc7d74d20a Mon Sep 17 00:00:00 2001 From: Edmond-Honglei-Cong Date: Thu, 13 Feb 2020 15:34:29 +0800 Subject: [PATCH 1/8] move native contract addrs to native/common --- cmd/utils/gas.go | 8 ++-- consensus/vbft/service.go | 4 +- consensus/vbft/utils.go | 10 ++-- core/genesis/genesis.go | 17 +++---- core/store/ledgerstore/state_store.go | 4 +- core/store/ledgerstore/tx_handler.go | 3 +- go.sum | 4 +- http/base/actor/utils.go | 22 ++++----- http/base/common/common.go | 6 +-- smartcontract/service/native/auth/auth.go | 5 +- smartcontract/service/native/common.go | 27 ----------- smartcontract/service/native/common/params.go | 46 +++++++++++++++++++ smartcontract/service/native/did/init.go | 4 +- smartcontract/service/native/did/utils.go | 5 +- smartcontract/service/native/gas/gas.go | 3 +- .../native/global_params/global_params.go | 3 +- .../service/native/governance/governance.go | 33 ++++++------- .../service/native/governance/method.go | 33 ++++++------- .../service/native/governance/utils.go | 15 +++--- smartcontract/service/native/init/init.go | 4 +- .../service/native/native_service.go | 5 +- smartcontract/service/native/utils/params.go | 20 -------- smartcontract/service/wasmvm/runtime.go | 6 +-- txnpool/proc/txnpool_server.go | 11 +++-- 24 files changed, 154 insertions(+), 144 deletions(-) delete mode 100644 smartcontract/service/native/common.go create mode 100644 smartcontract/service/native/common/params.go diff --git a/cmd/utils/gas.go b/cmd/utils/gas.go index ea1f123a..71579dc6 100644 --- a/cmd/utils/gas.go +++ b/cmd/utils/gas.go @@ -43,8 +43,8 @@ import ( cutils "github.com/DNAProject/DNA/core/utils" httpcom "github.com/DNAProject/DNA/http/base/common" rpccommon "github.com/DNAProject/DNA/http/base/common" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" "github.com/DNAProject/DNA/smartcontract/service/native/gas" - "github.com/DNAProject/DNA/smartcontract/service/native/utils" cstates "github.com/DNAProject/DNA/smartcontract/states" "github.com/ontio/ontology-crypto/keypair" sig "github.com/ontio/ontology-crypto/signature" @@ -194,7 +194,7 @@ func ApproveTx(gasPrice, gasLimit uint64, asset string, from, to string, amount switch strings.ToLower(asset) { case ASSET_GAS: version = VERSION_CONTRACT_GAS - contractAddr = utils.GasContractAddress + contractAddr = common2.GasContractAddress default: return nil, fmt.Errorf("Unsupport asset:%s", asset) } @@ -226,7 +226,7 @@ func TransferTx(gasPrice, gasLimit uint64, asset, from, to string, amount uint64 switch strings.ToLower(asset) { case ASSET_GAS: version = VERSION_CONTRACT_GAS - contractAddr = utils.GasContractAddress + contractAddr = common2.GasContractAddress default: return nil, fmt.Errorf("unsupport asset:%s", asset) } @@ -262,7 +262,7 @@ func TransferFromTx(gasPrice, gasLimit uint64, asset, sender, from, to string, a switch strings.ToLower(asset) { case ASSET_GAS: version = VERSION_CONTRACT_GAS - contractAddr = utils.GasContractAddress + contractAddr = common2.GasContractAddress default: return nil, fmt.Errorf("unsupport asset:%s", asset) } diff --git a/consensus/vbft/service.go b/consensus/vbft/service.go index bd03a851..7250b743 100644 --- a/consensus/vbft/service.go +++ b/consensus/vbft/service.go @@ -41,9 +41,9 @@ import ( "github.com/DNAProject/DNA/events" "github.com/DNAProject/DNA/events/message" p2pmsg "github.com/DNAProject/DNA/p2pserver/message/types" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" gover "github.com/DNAProject/DNA/smartcontract/service/native/governance" ninit "github.com/DNAProject/DNA/smartcontract/service/native/init" - nutils "github.com/DNAProject/DNA/smartcontract/service/native/utils" "github.com/DNAProject/DNA/validator/increment" "github.com/ontio/ontology-crypto/keypair" "github.com/ontio/ontology-crypto/vrf" @@ -2132,7 +2132,7 @@ func (self *Server) msgSendLoop() { //creategovernaceTransaction invoke governance native contract commit_pos func (self *Server) creategovernaceTransaction(blkNum uint32) (*types.Transaction, error) { - mutable := utils.BuildNativeTransaction(nutils.GovernanceContractAddress, gover.COMMIT_DPOS, []byte{}) + mutable := utils.BuildNativeTransaction(common2.GovernanceContractAddress, gover.COMMIT_DPOS, []byte{}) mutable.Nonce = blkNum tx, err := mutable.IntoImmutable() return tx, err diff --git a/consensus/vbft/utils.go b/consensus/vbft/utils.go index 8a837af1..7163caf2 100644 --- a/consensus/vbft/utils.go +++ b/consensus/vbft/utils.go @@ -37,8 +37,8 @@ import ( "github.com/DNAProject/DNA/core/states" scommon "github.com/DNAProject/DNA/core/store/common" "github.com/DNAProject/DNA/core/store/overlaydb" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" gov "github.com/DNAProject/DNA/smartcontract/service/native/governance" - nutils "github.com/DNAProject/DNA/smartcontract/service/native/utils" "github.com/ontio/ontology-crypto/keypair" "github.com/ontio/ontology-crypto/vrf" ) @@ -138,7 +138,7 @@ func GetVbftConfigInfo(memdb *overlaydb.MemDB) (*config.VBFTConfig, error) { //get preConfig preCfg := new(gov.PreConfig) - data, err := GetStorageValue(memdb, ledger.DefLedger, nutils.GovernanceContractAddress, []byte(gov.PRE_CONFIG)) + data, err := GetStorageValue(memdb, ledger.DefLedger, common2.GovernanceContractAddress, []byte(gov.PRE_CONFIG)) if err != nil && err != scommon.ErrNotFound { return nil, err } @@ -162,7 +162,7 @@ func GetVbftConfigInfo(memdb *overlaydb.MemDB) (*config.VBFTConfig, error) { MaxBlockChangeView: uint32(preCfg.Configuration.MaxBlockChangeView), } } else { - data, err := GetStorageValue(memdb, ledger.DefLedger, nutils.GovernanceContractAddress, []byte(gov.VBFT_CONFIG)) + data, err := GetStorageValue(memdb, ledger.DefLedger, common2.GovernanceContractAddress, []byte(gov.VBFT_CONFIG)) if err != nil { return nil, err } @@ -195,7 +195,7 @@ func GetPeersConfig(memdb *overlaydb.MemDB) ([]*config.VBFTPeerStakeInfo, error) return nil, err } key := append([]byte(gov.PEER_POOL), viewBytes...) - data, err := GetStorageValue(memdb, ledger.DefLedger, nutils.GovernanceContractAddress, key) + data, err := GetStorageValue(memdb, ledger.DefLedger, common2.GovernanceContractAddress, key) if err != nil { return nil, err } @@ -256,7 +256,7 @@ func GetStorageValue(memdb *overlaydb.MemDB, backend *ledger.Ledger, addr common } func GetGovernanceView(memdb *overlaydb.MemDB) (*gov.GovernanceView, error) { - value, err := GetStorageValue(memdb, ledger.DefLedger, nutils.GovernanceContractAddress, []byte(gov.GOVERNANCE_VIEW)) + value, err := GetStorageValue(memdb, ledger.DefLedger, common2.GovernanceContractAddress, []byte(gov.GOVERNANCE_VIEW)) if err != nil { return nil, err } diff --git a/core/genesis/genesis.go b/core/genesis/genesis.go index d93e0e78..629dae44 100644 --- a/core/genesis/genesis.go +++ b/core/genesis/genesis.go @@ -34,6 +34,7 @@ import ( "github.com/DNAProject/DNA/core/payload" "github.com/DNAProject/DNA/core/types" "github.com/DNAProject/DNA/core/utils" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" "github.com/DNAProject/DNA/smartcontract/service/native/gas" "github.com/DNAProject/DNA/smartcontract/service/native/global_params" "github.com/DNAProject/DNA/smartcontract/service/native/governance" @@ -120,7 +121,7 @@ func BuildGenesisBlock(defaultBookkeeper []keypair.PublicKey, genesisConfig *con } func newUtilityToken() *types.Transaction { - mutable, err := utils.NewDeployTransaction(nutils.GasContractAddress[:], "GAS", "1.0", + mutable, err := utils.NewDeployTransaction(common2.GasContractAddress[:], "GAS", "1.0", "DNA Dev Team", "contact@onchain.com", "Blockchain Network Gas", payload.NEOVM_TYPE) if err != nil { panic("[NewDeployTransaction] construct genesis utility token transaction error ") @@ -133,7 +134,7 @@ func newUtilityToken() *types.Transaction { } func newParamContract() *types.Transaction { - mutable, err := utils.NewDeployTransaction(nutils.ParamContractAddress[:], + mutable, err := utils.NewDeployTransaction(common2.ParamContractAddress[:], "ParamConfig", "1.0", "DNA Dev Team", "contact@onchain.com", "Chain Global Environment Variables Manager ", payload.NEOVM_TYPE) if err != nil { @@ -147,7 +148,7 @@ func newParamContract() *types.Transaction { } func newGovConfigTx() *types.Transaction { - mutable, err := utils.NewDeployTransaction(nutils.GovernanceContractAddress[:], "CONFIG", "1.0", + mutable, err := utils.NewDeployTransaction(common2.GovernanceContractAddress[:], "CONFIG", "1.0", "DNA Dev Team", "contact@ont.io", "Blockchain Network Consensus Config", payload.NEOVM_TYPE) if err != nil { panic("[NewDeployTransaction] construct genesis governing token transaction error ") @@ -160,7 +161,7 @@ func newGovConfigTx() *types.Transaction { } func deployAuthContract() *types.Transaction { - mutable, err := utils.NewDeployTransaction(nutils.AuthContractAddress[:], "AuthContract", "1.0", + mutable, err := utils.NewDeployTransaction(common2.AuthContractAddress[:], "AuthContract", "1.0", "DNA Dev Team", "contact@ont.io", "Blockchain Network Authorization Contract", payload.NEOVM_TYPE) if err != nil { panic("[NewDeployTransaction] construct genesis governing token transaction error ") @@ -173,7 +174,7 @@ func deployAuthContract() *types.Transaction { } func deployOntIDContract() *types.Transaction { - mutable, err := utils.NewDeployTransaction(nutils.DIDContractAddress[:], "OID", "1.0", + mutable, err := utils.NewDeployTransaction(common2.DIDContractAddress[:], "OID", "1.0", "DNA Dev Team", "contact@ont.io", "Blockchain Network ONT ID", payload.NEOVM_TYPE) if err != nil { panic("[NewDeployTransaction] construct genesis governing token transaction error ") @@ -212,7 +213,7 @@ func newUtilityInit() *types.Transaction { nutils.EncodeVarUint(args, part.value) } - mutable := utils.BuildNativeTransaction(nutils.GasContractAddress, gas.INIT_NAME, args.Bytes()) + mutable := utils.BuildNativeTransaction(common2.GasContractAddress, gas.INIT_NAME, args.Bytes()) tx, err := mutable.IntoImmutable() if err != nil { panic("construct genesis governing token transaction error ") @@ -253,7 +254,7 @@ func newParamInit() *types.Transaction { } nutils.EncodeAddress(sink, addr) - mutable := utils.BuildNativeTransaction(nutils.ParamContractAddress, global_params.INIT_NAME, sink.Bytes()) + mutable := utils.BuildNativeTransaction(common2.ParamContractAddress, global_params.INIT_NAME, sink.Bytes()) tx, err := mutable.IntoImmutable() if err != nil { panic("construct genesis governing token transaction error ") @@ -262,7 +263,7 @@ func newParamInit() *types.Transaction { } func newGoverConfigInit(config []byte) *types.Transaction { - mutable := utils.BuildNativeTransaction(nutils.GovernanceContractAddress, governance.INIT_CONFIG, config) + mutable := utils.BuildNativeTransaction(common2.GovernanceContractAddress, governance.INIT_CONFIG, config) tx, err := mutable.IntoImmutable() if err != nil { panic("construct genesis governing token transaction error ") diff --git a/core/store/ledgerstore/state_store.go b/core/store/ledgerstore/state_store.go index 3e83a1b8..aab3e7f5 100644 --- a/core/store/ledgerstore/state_store.go +++ b/core/store/ledgerstore/state_store.go @@ -37,8 +37,8 @@ import ( "github.com/DNAProject/DNA/core/store/leveldbstore" "github.com/DNAProject/DNA/core/store/overlaydb" "github.com/DNAProject/DNA/merkle" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" "github.com/DNAProject/DNA/smartcontract/service/native/did" - "github.com/DNAProject/DNA/smartcontract/service/native/utils" ) var ( @@ -419,7 +419,7 @@ func (self *StateStore) Close() error { func (self *StateStore) CheckStorage() error { db := self.store - prefix := append([]byte{byte(scom.ST_STORAGE)}, utils.DIDContractAddress[:]...) //prefix of new storage key + prefix := append([]byte{byte(scom.ST_STORAGE)}, common2.DIDContractAddress[:]...) //prefix of new storage key flag := append(prefix, did.FIELD_VERSION) val, err := db.Get(flag) if err == nil { diff --git a/core/store/ledgerstore/tx_handler.go b/core/store/ledgerstore/tx_handler.go index 783c5854..984de852 100644 --- a/core/store/ledgerstore/tx_handler.go +++ b/core/store/ledgerstore/tx_handler.go @@ -36,6 +36,7 @@ import ( "github.com/DNAProject/DNA/core/types" "github.com/DNAProject/DNA/smartcontract" "github.com/DNAProject/DNA/smartcontract/event" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" "github.com/DNAProject/DNA/smartcontract/service/native/global_params" "github.com/DNAProject/DNA/smartcontract/service/native/utils" "github.com/DNAProject/DNA/smartcontract/service/neovm" @@ -154,7 +155,7 @@ func refreshGlobalParam(config *smartcontract.Config, cache *storage.CacheDB, st } service, _ := sc.NewNativeService() - result, err := service.NativeCall(utils.ParamContractAddress, "getGlobalParam", sink.Bytes()) + result, err := service.NativeCall(common2.ParamContractAddress, "getGlobalParam", sink.Bytes()) if err != nil { return err } diff --git a/go.sum b/go.sum index 62bee4e2..61ffc698 100644 --- a/go.sum +++ b/go.sum @@ -51,8 +51,8 @@ github.com/ontio/ontology-crypto v1.0.6 h1:U4Yrcq9zH3af8m8hk9nrgwkOqoAYmRtiZnrEk github.com/ontio/ontology-crypto v1.0.6/go.mod h1:ebrQJ4/VS2F6pwHGktHDYtY/7Y2ca/ogfnlYABrQI2c= github.com/ontio/ontology-eventbus v0.9.1 h1:nt3AXWx3gOyqtLiU4EwI92Yc4ik/pWHu9xRK15uHSOs= github.com/ontio/ontology-eventbus v0.9.1/go.mod h1:hCQIlbdPckcfykMeVUdWrqHZ8d30TBdmLfXCVWGkYhM= -github.com/ontio/wagon v0.3.1-0.20191012103353-ef8d35ecd300 h1:E+8mJjO4xOPGlbSoJiElZ6yYks/KdPe4j9gXYUMpbdA= -github.com/ontio/wagon v0.3.1-0.20191012103353-ef8d35ecd300/go.mod h1:zHOMvbitcZek8oshsMO5VpyBjWjV9X8cn8WTZwdebpM= +github.com/ontio/wagon v0.3.1-0.20191223040208-db6073fb2776 h1:cfHznrh9WsSH7F253Lr6TkYa38p/3Cgk0PJS7238cRQ= +github.com/ontio/wagon v0.3.1-0.20191223040208-db6073fb2776/go.mod h1:zHOMvbitcZek8oshsMO5VpyBjWjV9X8cn8WTZwdebpM= github.com/orcaman/concurrent-map v0.0.0-20190826125027-8c72a8bb44f6 h1:lNCW6THrCKBiJBpz8kbVGjC7MgdCGKwuvBgc7LoD6sw= github.com/orcaman/concurrent-map v0.0.0-20190826125027-8c72a8bb44f6/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI= github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= diff --git a/http/base/actor/utils.go b/http/base/actor/utils.go index 13429996..08775ff3 100644 --- a/http/base/actor/utils.go +++ b/http/base/actor/utils.go @@ -24,20 +24,20 @@ package actor import ( "github.com/DNAProject/DNA/common" - "github.com/DNAProject/DNA/smartcontract/service/native/utils" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" ) func updateNativeSCAddr(hash common.Address) common.Address { - if hash == utils.GasContractAddress { - hash = common.AddressFromVmCode(utils.GasContractAddress[:]) - } else if hash == utils.DIDContractAddress { - hash = common.AddressFromVmCode(utils.DIDContractAddress[:]) - } else if hash == utils.ParamContractAddress { - hash = common.AddressFromVmCode(utils.ParamContractAddress[:]) - } else if hash == utils.AuthContractAddress { - hash = common.AddressFromVmCode(utils.AuthContractAddress[:]) - } else if hash == utils.GovernanceContractAddress { - hash = common.AddressFromVmCode(utils.GovernanceContractAddress[:]) + if hash == common2.GasContractAddress { + hash = common.AddressFromVmCode(common2.GasContractAddress[:]) + } else if hash == common2.DIDContractAddress { + hash = common.AddressFromVmCode(common2.DIDContractAddress[:]) + } else if hash == common2.ParamContractAddress { + hash = common.AddressFromVmCode(common2.ParamContractAddress[:]) + } else if hash == common2.AuthContractAddress { + hash = common.AddressFromVmCode(common2.AuthContractAddress[:]) + } else if hash == common2.GovernanceContractAddress { + hash = common.AddressFromVmCode(common2.GovernanceContractAddress[:]) } return hash } diff --git a/http/base/common/common.go b/http/base/common/common.go index 9e819509..2e318895 100644 --- a/http/base/common/common.go +++ b/http/base/common/common.go @@ -37,7 +37,7 @@ import ( ontErrors "github.com/DNAProject/DNA/errors" bactor "github.com/DNAProject/DNA/http/base/actor" "github.com/DNAProject/DNA/smartcontract/event" - "github.com/DNAProject/DNA/smartcontract/service/native/utils" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" cstate "github.com/DNAProject/DNA/smartcontract/states" "github.com/DNAProject/DNA/vm/neovm" "github.com/ontio/ontology-crypto/keypair" @@ -279,7 +279,7 @@ func GetBlockInfo(block *types.Block) BlockInfo { } func GetBalance(address common.Address) (*BalanceOfRsp, error) { - balances, height, err := GetContractBalance(0, []common.Address{utils.GasContractAddress}, address, true) + balances, height, err := GetContractBalance(0, []common.Address{common2.GasContractAddress}, address, true) if err != nil { return nil, fmt.Errorf("get balance error:%s", err) } @@ -293,7 +293,7 @@ func GetAllowance(asset string, from, to common.Address) (string, error) { var contractAddr common.Address switch strings.ToLower(asset) { case "gas": - contractAddr = utils.GasContractAddress + contractAddr = common2.GasContractAddress default: return "", fmt.Errorf("unsupport asset") } diff --git a/smartcontract/service/native/auth/auth.go b/smartcontract/service/native/auth/auth.go index 84931ca5..fe386932 100644 --- a/smartcontract/service/native/auth/auth.go +++ b/smartcontract/service/native/auth/auth.go @@ -31,6 +31,7 @@ import ( "github.com/DNAProject/DNA/common/log" "github.com/DNAProject/DNA/errors" "github.com/DNAProject/DNA/smartcontract/service/native" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" "github.com/DNAProject/DNA/smartcontract/service/native/utils" ) @@ -39,7 +40,7 @@ var ( ) func Init() { - native.Contracts[utils.AuthContractAddress] = RegisterAuthContract + native.Contracts[common2.AuthContractAddress] = RegisterAuthContract } /* @@ -645,7 +646,7 @@ func verifySig(native *native.NativeService, ontID []byte, keyNo uint64) (bool, sink.WriteVarBytes(ontID) utils.EncodeVarUint(sink, keyNo) args := sink.Bytes() - ret, err := native.NativeCall(utils.DIDContractAddress, "verifySignature", args) + ret, err := native.NativeCall(common2.DIDContractAddress, "verifySignature", args) if err != nil { return false, err } diff --git a/smartcontract/service/native/common.go b/smartcontract/service/native/common.go deleted file mode 100644 index 1e53d67d..00000000 --- a/smartcontract/service/native/common.go +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// Copyright 2019 DNA Dev team -// -/* - * Copyright (C) 2018 The ontology Authors - * This file is part of The ontology library. - * - * The ontology is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The ontology is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The ontology. If not, see . - */ - -package native - -var ( - BYTE_FALSE = []byte{0} - BYTE_TRUE = []byte{1} -) diff --git a/smartcontract/service/native/common/params.go b/smartcontract/service/native/common/params.go new file mode 100644 index 00000000..62dcbaca --- /dev/null +++ b/smartcontract/service/native/common/params.go @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright 2019 DNA Dev team +// +/* + * Copyright (C) 2018 The ontology Authors + * This file is part of The ontology library. + * + * The ontology is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ontology is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The ontology. If not, see . + */ +package common + +import ( + "bytes" + + "github.com/DNAProject/DNA/common" +) + +var ( + BYTE_FALSE = []byte{0} + BYTE_TRUE = []byte{1} + + GasContractAddress, _ = common.AddressParseFromBytes([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}) + DIDContractAddress, _ = common.AddressParseFromBytes([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}) + ParamContractAddress, _ = common.AddressParseFromBytes([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04}) + AuthContractAddress, _ = common.AddressParseFromBytes([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06}) + GovernanceContractAddress, _ = common.AddressParseFromBytes([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07}) +) + +func IsNativeContract(addr common.Address) bool { + return bytes.Compare(addr[:], GasContractAddress[:]) == 0 || + bytes.Compare(addr[:], DIDContractAddress[:]) == 0 || + bytes.Compare(addr[:], ParamContractAddress[:]) == 0 || + bytes.Compare(addr[:], AuthContractAddress[:]) == 0 || + bytes.Compare(addr[:], GovernanceContractAddress[:]) == 0 +} diff --git a/smartcontract/service/native/did/init.go b/smartcontract/service/native/did/init.go index 5a56f0cc..52106b4d 100644 --- a/smartcontract/service/native/did/init.go +++ b/smartcontract/service/native/did/init.go @@ -22,11 +22,11 @@ package did import ( "github.com/DNAProject/DNA/smartcontract/service/native" - "github.com/DNAProject/DNA/smartcontract/service/native/utils" + "github.com/DNAProject/DNA/smartcontract/service/native/common" ) func Init() { - native.Contracts[utils.DIDContractAddress] = RegisterIDContract + native.Contracts[common.DIDContractAddress] = RegisterIDContract } func RegisterIDContract(srvc *native.NativeService) { diff --git a/smartcontract/service/native/did/utils.go b/smartcontract/service/native/did/utils.go index 41cb7c04..a434461a 100644 --- a/smartcontract/service/native/did/utils.go +++ b/smartcontract/service/native/did/utils.go @@ -27,6 +27,7 @@ import ( "github.com/DNAProject/DNA/core/states" "github.com/DNAProject/DNA/core/types" "github.com/DNAProject/DNA/smartcontract/service/native" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" "github.com/DNAProject/DNA/smartcontract/service/native/utils" "github.com/ontio/ontology-crypto/keypair" ) @@ -68,13 +69,13 @@ func encodeID(id []byte) ([]byte, error) { return nil, errors.New("encode ONT ID error: invalid ID length") } //enc := []byte{byte(length)} - enc := append(utils.DIDContractAddress[:], byte(length)) + enc := append(common2.DIDContractAddress[:], byte(length)) enc = append(enc, id...) return enc, nil } func decodeID(data []byte) ([]byte, error) { - prefix := len(utils.DIDContractAddress) + prefix := len(common2.DIDContractAddress) size := len(data) if size < prefix || size != int(data[prefix])+1+prefix { return nil, errors.New("decode ONT ID error: invalid data length") diff --git a/smartcontract/service/native/gas/gas.go b/smartcontract/service/native/gas/gas.go index f6971736..1faa1137 100644 --- a/smartcontract/service/native/gas/gas.go +++ b/smartcontract/service/native/gas/gas.go @@ -29,6 +29,7 @@ import ( "github.com/DNAProject/DNA/common/constants" "github.com/DNAProject/DNA/errors" "github.com/DNAProject/DNA/smartcontract/service/native" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" "github.com/DNAProject/DNA/smartcontract/service/native/utils" ) @@ -38,7 +39,7 @@ const ( ) func InitGas() { - native.Contracts[utils.GasContractAddress] = RegisterGasContract + native.Contracts[common2.GasContractAddress] = RegisterGasContract } func RegisterGasContract(native *native.NativeService) { diff --git a/smartcontract/service/native/global_params/global_params.go b/smartcontract/service/native/global_params/global_params.go index f5bb84a6..a6051101 100644 --- a/smartcontract/service/native/global_params/global_params.go +++ b/smartcontract/service/native/global_params/global_params.go @@ -27,6 +27,7 @@ import ( "github.com/DNAProject/DNA/common" "github.com/DNAProject/DNA/errors" "github.com/DNAProject/DNA/smartcontract/service/native" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" "github.com/DNAProject/DNA/smartcontract/service/native/utils" ) @@ -46,7 +47,7 @@ const ( ) func InitGlobalParams() { - native.Contracts[utils.ParamContractAddress] = RegisterParamContract + native.Contracts[common2.ParamContractAddress] = RegisterParamContract } func RegisterParamContract(native *native.NativeService) { diff --git a/smartcontract/service/native/governance/governance.go b/smartcontract/service/native/governance/governance.go index 72c07165..ff441cea 100644 --- a/smartcontract/service/native/governance/governance.go +++ b/smartcontract/service/native/governance/governance.go @@ -34,6 +34,7 @@ import ( "github.com/DNAProject/DNA/common/constants" cstates "github.com/DNAProject/DNA/core/states" "github.com/DNAProject/DNA/smartcontract/service/native" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" "github.com/DNAProject/DNA/smartcontract/service/native/global_params" "github.com/DNAProject/DNA/smartcontract/service/native/utils" ) @@ -119,7 +120,7 @@ var Xi = []uint32{ //Init governance contract address func InitGovernance() { - native.Contracts[utils.GovernanceContractAddress] = RegisterGovernanceContract + native.Contracts[common2.GovernanceContractAddress] = RegisterGovernanceContract } //Register methods of governance contract @@ -402,7 +403,7 @@ func ApproveCandidate(native *native.NativeService) ([]byte, error) { // get admin from database adminAddress, err := global_params.GetStorageRole(native, - global_params.GenerateOperatorKey(utils.ParamContractAddress)) + global_params.GenerateOperatorKey(common2.ParamContractAddress)) if err != nil { return utils.BYTE_FALSE, fmt.Errorf("getAdmin, get admin error: %v", err) } @@ -532,7 +533,7 @@ func RejectCandidate(native *native.NativeService) ([]byte, error) { // get admin from database adminAddress, err := global_params.GetStorageRole(native, - global_params.GenerateOperatorKey(utils.ParamContractAddress)) + global_params.GenerateOperatorKey(common2.ParamContractAddress)) if err != nil { return utils.BYTE_FALSE, fmt.Errorf("getAdmin, get admin error: %v", err) } @@ -596,7 +597,7 @@ func BlackNode(native *native.NativeService) ([]byte, error) { // get admin from database adminAddress, err := global_params.GetStorageRole(native, - global_params.GenerateOperatorKey(utils.ParamContractAddress)) + global_params.GenerateOperatorKey(common2.ParamContractAddress)) if err != nil { return utils.BYTE_FALSE, fmt.Errorf("getAdmin, get admin error: %v", err) } @@ -667,7 +668,7 @@ func WhiteNode(native *native.NativeService) ([]byte, error) { // get admin from database adminAddress, err := global_params.GetStorageRole(native, - global_params.GenerateOperatorKey(utils.ParamContractAddress)) + global_params.GenerateOperatorKey(common2.ParamContractAddress)) if err != nil { return utils.BYTE_FALSE, fmt.Errorf("getAdmin, get admin error: %v", err) } @@ -954,7 +955,7 @@ func Withdraw(native *native.NativeService) ([]byte, error) { } //ont transfer - err = appCallTransferOnt(native, utils.GovernanceContractAddress, address, total) + err = appCallTransferOnt(native, common2.GovernanceContractAddress, address, total) if err != nil { return utils.BYTE_FALSE, fmt.Errorf("appCallTransferOnt, ont transfer error: %v", err) } @@ -986,7 +987,7 @@ func CommitDpos(native *native.NativeService) ([]byte, error) { // get admin from database adminAddress, err := global_params.GetStorageRole(native, - global_params.GenerateOperatorKey(utils.ParamContractAddress)) + global_params.GenerateOperatorKey(common2.ParamContractAddress)) if err != nil { return utils.BYTE_FALSE, fmt.Errorf("getAdmin, get admin error: %v", err) } @@ -1012,7 +1013,7 @@ func CommitDpos(native *native.NativeService) ([]byte, error) { func UpdateConfig(native *native.NativeService) ([]byte, error) { // get admin from database adminAddress, err := global_params.GetStorageRole(native, - global_params.GenerateOperatorKey(utils.ParamContractAddress)) + global_params.GenerateOperatorKey(common2.ParamContractAddress)) if err != nil { return utils.BYTE_FALSE, fmt.Errorf("getAdmin, get admin error: %v", err) } @@ -1100,7 +1101,7 @@ func UpdateConfig(native *native.NativeService) ([]byte, error) { func UpdateGlobalParam(native *native.NativeService) ([]byte, error) { // get admin from database adminAddress, err := global_params.GetStorageRole(native, - global_params.GenerateOperatorKey(utils.ParamContractAddress)) + global_params.GenerateOperatorKey(common2.ParamContractAddress)) if err != nil { return utils.BYTE_FALSE, fmt.Errorf("getAdmin, get admin error: %v", err) } @@ -1160,7 +1161,7 @@ func UpdateGlobalParam2(native *native.NativeService) ([]byte, error) { } // get admin from database adminAddress, err := global_params.GetStorageRole(native, - global_params.GenerateOperatorKey(utils.ParamContractAddress)) + global_params.GenerateOperatorKey(common2.ParamContractAddress)) if err != nil { return utils.BYTE_FALSE, fmt.Errorf("getAdmin, get admin error: %v", err) } @@ -1198,7 +1199,7 @@ func UpdateGlobalParam2(native *native.NativeService) ([]byte, error) { func UpdateSplitCurve(native *native.NativeService) ([]byte, error) { // get admin from database adminAddress, err := global_params.GetStorageRole(native, - global_params.GenerateOperatorKey(utils.ParamContractAddress)) + global_params.GenerateOperatorKey(common2.ParamContractAddress)) if err != nil { return utils.BYTE_FALSE, fmt.Errorf("getAdmin, get admin error: %v", err) } @@ -1227,7 +1228,7 @@ func UpdateSplitCurve(native *native.NativeService) ([]byte, error) { func TransferPenalty(native *native.NativeService) ([]byte, error) { // get admin from database adminAddress, err := global_params.GetStorageRole(native, - global_params.GenerateOperatorKey(utils.ParamContractAddress)) + global_params.GenerateOperatorKey(common2.ParamContractAddress)) if err != nil { return utils.BYTE_FALSE, fmt.Errorf("getAdmin, get admin error: %v", err) } @@ -1391,7 +1392,7 @@ func WithdrawFee(native *native.NativeService) ([]byte, error) { fee := splitFeeAddress.Amount //ong transfer - err = appCallTransferOng(native, utils.GovernanceContractAddress, params.Address, fee) + err = appCallTransferOng(native, common2.GovernanceContractAddress, params.Address, fee) if err != nil { return utils.BYTE_FALSE, fmt.Errorf("appCallTransferOng, ong transfer error: %v", err) } @@ -1468,7 +1469,7 @@ func AddInitPos(native *native.NativeService) ([]byte, error) { } //ont transfer - err = appCallTransferOnt(native, params.Address, utils.GovernanceContractAddress, uint64(params.Pos)) + err = appCallTransferOnt(native, params.Address, common2.GovernanceContractAddress, uint64(params.Pos)) if err != nil { return utils.BYTE_FALSE, fmt.Errorf("appCallTransferOnt, ont transfer error: %v", err) } @@ -1580,7 +1581,7 @@ func SetPromisePos(native *native.NativeService) ([]byte, error) { } // get admin from database adminAddress, err := global_params.GetStorageRole(native, - global_params.GenerateOperatorKey(utils.ParamContractAddress)) + global_params.GenerateOperatorKey(common2.ParamContractAddress)) if err != nil { return utils.BYTE_FALSE, fmt.Errorf("getAdmin, get admin error: %v", err) } @@ -1609,7 +1610,7 @@ func SetPromisePos(native *native.NativeService) ([]byte, error) { func SetGasAddress(native *native.NativeService) ([]byte, error) { // get operator from database operatorAddress, err := global_params.GetStorageRole(native, - global_params.GenerateOperatorKey(utils.ParamContractAddress)) + global_params.GenerateOperatorKey(common2.ParamContractAddress)) if err != nil { return utils.BYTE_FALSE, fmt.Errorf("SetGasAddress, get operator error: %v", err) } diff --git a/smartcontract/service/native/governance/method.go b/smartcontract/service/native/governance/method.go index 44be8c0b..7b6e504c 100644 --- a/smartcontract/service/native/governance/method.go +++ b/smartcontract/service/native/governance/method.go @@ -31,6 +31,7 @@ import ( "github.com/DNAProject/DNA/common/constants" cstates "github.com/DNAProject/DNA/core/states" "github.com/DNAProject/DNA/smartcontract/service/native" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" "github.com/DNAProject/DNA/smartcontract/service/native/utils" ) @@ -115,25 +116,25 @@ func registerCandidate(native *native.NativeService, flag string) error { switch flag { case "transfer": //ont transfer - err = appCallTransferOnt(native, params.Address, utils.GovernanceContractAddress, uint64(params.InitPos)) + err = appCallTransferOnt(native, params.Address, common2.GovernanceContractAddress, uint64(params.InitPos)) if err != nil { return fmt.Errorf("appCallTransferOnt, ont transfer error: %v", err) } //ong transfer - err = appCallTransferOng(native, params.Address, utils.GovernanceContractAddress, globalParam.CandidateFee) + err = appCallTransferOng(native, params.Address, common2.GovernanceContractAddress, globalParam.CandidateFee) if err != nil { return fmt.Errorf("appCallTransferOng, ong transfer error: %v", err) } case "transferFrom": //ont transfer from - err = appCallTransferFromOnt(native, utils.GovernanceContractAddress, params.Address, utils.GovernanceContractAddress, uint64(params.InitPos)) + err = appCallTransferFromOnt(native, common2.GovernanceContractAddress, params.Address, common2.GovernanceContractAddress, uint64(params.InitPos)) if err != nil { return fmt.Errorf("appCallTransferFromOnt, ont transfer error: %v", err) } //ong transfer from - err = appCallTransferFromOng(native, utils.GovernanceContractAddress, params.Address, utils.GovernanceContractAddress, globalParam.CandidateFee) + err = appCallTransferFromOng(native, common2.GovernanceContractAddress, params.Address, common2.GovernanceContractAddress, globalParam.CandidateFee) if err != nil { return fmt.Errorf("appCallTransferFromOng, ong transfer error: %v", err) } @@ -248,13 +249,13 @@ func authorizeForPeer(native *native.NativeService, flag string) error { switch flag { case "transfer": //ont transfer - err = appCallTransferOnt(native, params.Address, utils.GovernanceContractAddress, total) + err = appCallTransferOnt(native, params.Address, common2.GovernanceContractAddress, total) if err != nil { return fmt.Errorf("appCallTransferOnt, ont transfer error: %v", err) } case "transferFrom": //ont transfer from - err = appCallTransferFromOnt(native, utils.GovernanceContractAddress, params.Address, utils.GovernanceContractAddress, total) + err = appCallTransferFromOnt(native, common2.GovernanceContractAddress, params.Address, common2.GovernanceContractAddress, total) if err != nil { return fmt.Errorf("appCallTransferFromOnt, ont transfer error: %v", err) } @@ -323,7 +324,7 @@ func normalQuit(native *native.NativeService, contract common.Address, peerPoolI func blackQuit(native *native.NativeService, contract common.Address, peerPoolItem *PeerPoolItem) error { // ont transfer to trigger unboundong - err := appCallTransferOnt(native, utils.GovernanceContractAddress, utils.GovernanceContractAddress, peerPoolItem.InitPos) + err := appCallTransferOnt(native, common2.GovernanceContractAddress, common2.GovernanceContractAddress, peerPoolItem.InitPos) if err != nil { return fmt.Errorf("appCallTransferOnt, ont transfer error: %v", err) } @@ -577,7 +578,7 @@ func depositTotalStake(native *native.NativeService, contract common.Address, ad timeOffset := native.Time - constants.GENESIS_BLOCK_TIMESTAMP amount := utils.CalcUnbindOng(preStake, preTimeOffset, timeOffset) - err = appCallTransferFromOng(native, utils.GovernanceContractAddress, utils.GasContractAddress, totalStake.Address, amount) + err = appCallTransferFromOng(native, common2.GovernanceContractAddress, common2.GasContractAddress, totalStake.Address, amount) if err != nil { return fmt.Errorf("appCallTransferFromOng, transfer from ong error: %v", err) } @@ -606,7 +607,7 @@ func withdrawTotalStake(native *native.NativeService, contract common.Address, a timeOffset := native.Time - constants.GENESIS_BLOCK_TIMESTAMP amount := utils.CalcUnbindOng(preStake, preTimeOffset, timeOffset) - err = appCallTransferFromOng(native, utils.GovernanceContractAddress, utils.GasContractAddress, totalStake.Address, amount) + err = appCallTransferFromOng(native, common2.GovernanceContractAddress, common2.GasContractAddress, totalStake.Address, amount) if err != nil { return fmt.Errorf("appCallTransferFromOng, transfer from ong error: %v", err) } @@ -662,12 +663,12 @@ func withdrawPenaltyStake(native *native.NativeService, contract common.Address, amount := utils.CalcUnbindOng(preStake, preTimeOffset, timeOffset) //ont transfer - err = appCallTransferOnt(native, utils.GovernanceContractAddress, address, preStake) + err = appCallTransferOnt(native, common2.GovernanceContractAddress, address, preStake) if err != nil { return fmt.Errorf("appCallTransferOnt, ont transfer error: %v", err) } //ong approve - err = appCallTransferFromOng(native, utils.GovernanceContractAddress, utils.GasContractAddress, address, amount+preAmount) + err = appCallTransferFromOng(native, common2.GovernanceContractAddress, common2.GasContractAddress, address, amount+preAmount) if err != nil { return fmt.Errorf("appCallTransferFromOng, transfer from ong error: %v", err) } @@ -730,7 +731,7 @@ func executeSplit(native *native.NativeService, contract common.Address, view ui return fmt.Errorf("executeSplit, get peerPoolMap error: %v", err) } - balance, err := getOngBalance(native, utils.GovernanceContractAddress) + balance, err := getOngBalance(native, common2.GovernanceContractAddress) if err != nil { return fmt.Errorf("executeSplit, getOngBalance error: %v", err) } @@ -790,7 +791,7 @@ func executeSplit(native *native.NativeService, contract common.Address, view ui for i := 0; i < int(config.K); i++ { nodeAmount := balance * uint64(globalParam.A) / 100 * peersCandidate[i].S / sumS address := peersCandidate[i].Address - err = appCallTransferOng(native, utils.GovernanceContractAddress, address, nodeAmount) + err = appCallTransferOng(native, common2.GovernanceContractAddress, address, nodeAmount) if err != nil { return fmt.Errorf("executeSplit, ong transfer error: %v", err) } @@ -808,7 +809,7 @@ func executeSplit(native *native.NativeService, contract common.Address, view ui for i := int(config.K); i < len(peersCandidate); i++ { nodeAmount := balance * uint64(globalParam.B) / 100 * peersCandidate[i].Stake / sum address := peersCandidate[i].Address - err = appCallTransferOng(native, utils.GovernanceContractAddress, address, nodeAmount) + err = appCallTransferOng(native, common2.GovernanceContractAddress, address, nodeAmount) if err != nil { return fmt.Errorf("executeSplit, ong transfer error: %v", err) } @@ -843,7 +844,7 @@ func executeSplit2(native *native.NativeService, contract common.Address, view u return splitSum, fmt.Errorf("executeSplit, get currentPeerPoolMap error: %v", err) } - balance, err := getOngBalance(native, utils.GovernanceContractAddress) + balance, err := getOngBalance(native, common2.GovernanceContractAddress) if err != nil { return splitSum, fmt.Errorf("executeSplit, getOngBalance error: %v", err) } @@ -866,7 +867,7 @@ func executeSplit2(native *native.NativeService, contract common.Address, view u if gasAddress.Address == common.ADDRESS_EMPTY { dappIncome = new(big.Int).SetUint64(0) } else { - err := appCallTransferOng(native, utils.GovernanceContractAddress, gasAddress.Address, dappIncome.Uint64()) + err := appCallTransferOng(native, common2.GovernanceContractAddress, gasAddress.Address, dappIncome.Uint64()) if err != nil { return splitSum, fmt.Errorf("appCallTransferOng, appCallTransferOng error: %v", err) } diff --git a/smartcontract/service/native/governance/utils.go b/smartcontract/service/native/governance/utils.go index 222634c4..fafecc4b 100644 --- a/smartcontract/service/native/governance/utils.go +++ b/smartcontract/service/native/governance/utils.go @@ -33,6 +33,7 @@ import ( cstates "github.com/DNAProject/DNA/core/states" "github.com/DNAProject/DNA/smartcontract/service/native" "github.com/DNAProject/DNA/smartcontract/service/native/auth" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" "github.com/DNAProject/DNA/smartcontract/service/native/gas" "github.com/DNAProject/DNA/smartcontract/service/native/utils" "github.com/ontio/ontology-crypto/vrf" @@ -116,7 +117,7 @@ func GetView(native *native.NativeService, contract common.Address) (uint32, err } func appCallTransferOnt(native *native.NativeService, from common.Address, to common.Address, amount uint64) error { - err := appCallTransfer(native, utils.GasContractAddress, from, to, amount) + err := appCallTransfer(native, common2.GasContractAddress, from, to, amount) if err != nil { return fmt.Errorf("appCallTransferOnt, appCallTransfer error: %v", err) } @@ -124,7 +125,7 @@ func appCallTransferOnt(native *native.NativeService, from common.Address, to co } func appCallTransferOng(native *native.NativeService, from common.Address, to common.Address, amount uint64) error { - err := appCallTransfer(native, utils.GasContractAddress, from, to, amount) + err := appCallTransfer(native, common2.GasContractAddress, from, to, amount) if err != nil { return fmt.Errorf("appCallTransferOng, appCallTransfer error: %v", err) } @@ -149,7 +150,7 @@ func appCallTransfer(native *native.NativeService, contract common.Address, from } func appCallTransferFromOnt(native *native.NativeService, sender common.Address, from common.Address, to common.Address, amount uint64) error { - err := appCallTransferFrom(native, utils.GasContractAddress, sender, from, to, amount) + err := appCallTransferFrom(native, common2.GasContractAddress, sender, from, to, amount) if err != nil { return fmt.Errorf("appCallTransferFromOnt, appCallTransferFrom error: %v", err) } @@ -157,7 +158,7 @@ func appCallTransferFromOnt(native *native.NativeService, sender common.Address, } func appCallTransferFromOng(native *native.NativeService, sender common.Address, from common.Address, to common.Address, amount uint64) error { - err := appCallTransferFrom(native, utils.GasContractAddress, sender, from, to, amount) + err := appCallTransferFrom(native, common2.GasContractAddress, sender, from, to, amount) if err != nil { return fmt.Errorf("appCallTransferFromOng, appCallTransferFrom error: %v", err) } @@ -182,7 +183,7 @@ func getOngBalance(native *native.NativeService, address common.Address) (uint64 sink := common.ZeroCopySink{} utils.EncodeAddress(&sink, address) - value, err := native.NativeCall(utils.GasContractAddress, "balanceOf", sink.Bytes()) + value, err := native.NativeCall(common2.GasContractAddress, "balanceOf", sink.Bytes()) if err != nil { return 0, fmt.Errorf("getOngBalance, appCall error: %v", err) } @@ -636,7 +637,7 @@ func appCallInitContractAdmin(native *native.NativeService, adminOntID []byte) e params := &auth.InitContractAdminParam{ AdminOntID: adminOntID, } - if _, err := native.NativeCall(utils.AuthContractAddress, "initContractAdmin", common.SerializeToBytes(params)); err != nil { + if _, err := native.NativeCall(common2.AuthContractAddress, "initContractAdmin", common.SerializeToBytes(params)); err != nil { return fmt.Errorf("appCallInitContractAdmin, appCall error: %v", err) } return nil @@ -649,7 +650,7 @@ func appCallVerifyToken(native *native.NativeService, contract common.Address, c Fn: fn, KeyNo: keyNo, } - ok, err := native.NativeCall(utils.AuthContractAddress, "verifyToken", common.SerializeToBytes(params)) + ok, err := native.NativeCall(common2.AuthContractAddress, "verifyToken", common.SerializeToBytes(params)) if err != nil { return fmt.Errorf("appCallVerifyToken, appCall error: %v", err) } diff --git a/smartcontract/service/native/init/init.go b/smartcontract/service/native/init/init.go index dfa4b4df..ee1b5c3c 100644 --- a/smartcontract/service/native/init/init.go +++ b/smartcontract/service/native/init/init.go @@ -27,17 +27,17 @@ import ( "github.com/DNAProject/DNA/common" "github.com/DNAProject/DNA/smartcontract/service/native/auth" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" "github.com/DNAProject/DNA/smartcontract/service/native/did" "github.com/DNAProject/DNA/smartcontract/service/native/gas" params "github.com/DNAProject/DNA/smartcontract/service/native/global_params" "github.com/DNAProject/DNA/smartcontract/service/native/governance" - "github.com/DNAProject/DNA/smartcontract/service/native/utils" "github.com/DNAProject/DNA/smartcontract/service/neovm" vm "github.com/DNAProject/DNA/vm/neovm" ) var ( - COMMIT_DPOS_BYTES = InitBytes(utils.GovernanceContractAddress, governance.COMMIT_DPOS) + COMMIT_DPOS_BYTES = InitBytes(common2.GovernanceContractAddress, governance.COMMIT_DPOS) ) func init() { diff --git a/smartcontract/service/native/native_service.go b/smartcontract/service/native/native_service.go index c04fbceb..380eb14a 100644 --- a/smartcontract/service/native/native_service.go +++ b/smartcontract/service/native/native_service.go @@ -28,6 +28,7 @@ import ( "github.com/DNAProject/DNA/errors" "github.com/DNAProject/DNA/smartcontract/context" "github.com/DNAProject/DNA/smartcontract/event" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" "github.com/DNAProject/DNA/smartcontract/states" sstates "github.com/DNAProject/DNA/smartcontract/states" "github.com/DNAProject/DNA/smartcontract/storage" @@ -65,12 +66,12 @@ func (this *NativeService) Invoke() ([]byte, error) { contract := this.InvokeParam services, ok := Contracts[contract.Address] if !ok { - return BYTE_FALSE, fmt.Errorf("Native contract address %x haven't been registered.", contract.Address) + return common2.BYTE_FALSE, fmt.Errorf("Native contract address %x haven't been registered.", contract.Address) } services(this) service, ok := this.ServiceMap[contract.Method] if !ok { - return BYTE_FALSE, fmt.Errorf("Native contract %x doesn't support this function %s.", + return common2.BYTE_FALSE, fmt.Errorf("Native contract %x doesn't support this function %s.", contract.Address, contract.Method) } args := this.Input diff --git a/smartcontract/service/native/utils/params.go b/smartcontract/service/native/utils/params.go index 256f5bf0..bb178c7a 100644 --- a/smartcontract/service/native/utils/params.go +++ b/smartcontract/service/native/utils/params.go @@ -20,27 +20,7 @@ */ package utils -import ( - "bytes" - - "github.com/DNAProject/DNA/common" -) - var ( BYTE_FALSE = []byte{0} BYTE_TRUE = []byte{1} - - GasContractAddress, _ = common.AddressParseFromBytes([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}) - DIDContractAddress, _ = common.AddressParseFromBytes([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}) - ParamContractAddress, _ = common.AddressParseFromBytes([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04}) - AuthContractAddress, _ = common.AddressParseFromBytes([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06}) - GovernanceContractAddress, _ = common.AddressParseFromBytes([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07}) ) - -func IsNativeContract(addr common.Address) bool { - return bytes.Compare(addr[:], GasContractAddress[:]) == 0 || - bytes.Compare(addr[:], DIDContractAddress[:]) == 0 || - bytes.Compare(addr[:], ParamContractAddress[:]) == 0 || - bytes.Compare(addr[:], AuthContractAddress[:]) == 0 || - bytes.Compare(addr[:], GovernanceContractAddress[:]) == 0 -} diff --git a/smartcontract/service/wasmvm/runtime.go b/smartcontract/service/wasmvm/runtime.go index c81f088d..4b53f120 100644 --- a/smartcontract/service/wasmvm/runtime.go +++ b/smartcontract/service/wasmvm/runtime.go @@ -24,6 +24,7 @@ import ( "bytes" "crypto/sha256" "fmt" + "io" "reflect" "github.com/DNAProject/DNA/common" @@ -33,14 +34,13 @@ import ( "github.com/DNAProject/DNA/errors" "github.com/DNAProject/DNA/smartcontract/event" native2 "github.com/DNAProject/DNA/smartcontract/service/native" - "github.com/DNAProject/DNA/smartcontract/service/native/utils" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" "github.com/DNAProject/DNA/smartcontract/service/util" "github.com/DNAProject/DNA/smartcontract/states" "github.com/DNAProject/DNA/vm/crossvm_codec" neotypes "github.com/DNAProject/DNA/vm/neovm/types" "github.com/go-interpreter/wagon/exec" "github.com/go-interpreter/wagon/wasm" - "io" ) type ContractType byte @@ -691,7 +691,7 @@ func NewHostModule() *wasm.Module { } func (self *Runtime) getContractType(addr common.Address) (ContractType, error) { - if utils.IsNativeContract(addr) { + if common2.IsNativeContract(addr) { return NATIVE_CONTRACT, nil } diff --git a/txnpool/proc/txnpool_server.go b/txnpool/proc/txnpool_server.go index 6c4610f8..e273ee88 100644 --- a/txnpool/proc/txnpool_server.go +++ b/txnpool/proc/txnpool_server.go @@ -26,6 +26,10 @@ package proc import ( "encoding/hex" "fmt" + "sort" + "strconv" + "sync" + "github.com/DNAProject/DNA/common" "github.com/DNAProject/DNA/common/config" "github.com/DNAProject/DNA/common/log" @@ -33,14 +37,11 @@ import ( tx "github.com/DNAProject/DNA/core/types" "github.com/DNAProject/DNA/errors" httpcom "github.com/DNAProject/DNA/http/base/common" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" params "github.com/DNAProject/DNA/smartcontract/service/native/global_params" - nutils "github.com/DNAProject/DNA/smartcontract/service/native/utils" tc "github.com/DNAProject/DNA/txnpool/common" "github.com/DNAProject/DNA/validator/types" "github.com/ontio/ontology-eventbus/actor" - "sort" - "strconv" - "sync" ) type txStats struct { @@ -100,7 +101,7 @@ func NewTxPoolServer(num uint8, disablePreExec, disableBroadcastNetTx bool) *TXP // getGlobalGasPrice returns a global gas price func getGlobalGasPrice() (uint64, error) { - mutable, err := httpcom.NewNativeInvokeTransaction(0, 0, nutils.ParamContractAddress, 0, "getGlobalParam", []interface{}{[]interface{}{"gasPrice"}}) + mutable, err := httpcom.NewNativeInvokeTransaction(0, 0, common2.ParamContractAddress, 0, "getGlobalParam", []interface{}{[]interface{}{"gasPrice"}}) if err != nil { return 0, fmt.Errorf("NewNativeInvokeTransaction error:%s", err) } From 64134f626a0fc254a52a48d0c5c2797a69f394ee Mon Sep 17 00:00:00 2001 From: Edmond-Honglei-Cong Date: Thu, 13 Feb 2020 16:29:34 +0800 Subject: [PATCH 2/8] support deployable native --- cmd/utils/params.go | 6 +- core/genesis/genesis.go | 10 ++-- core/payload/deploy_code.go | 56 ++++++++++++++++++- smartcontract/service/native/common/params.go | 11 ++++ .../service/native/native_service.go | 31 +++++++++- smartcontract/service/wasmvm/runtime.go | 2 + 6 files changed, 104 insertions(+), 12 deletions(-) diff --git a/cmd/utils/params.go b/cmd/utils/params.go index cc23dc60..568d3fae 100644 --- a/cmd/utils/params.go +++ b/cmd/utils/params.go @@ -222,10 +222,10 @@ func ParseReturnValue(rawValue interface{}, rawReturnTypeStr string, vmtype payl if !ok { rawValues = append(rawValues, rawValue) } - if vmtype == payload.NEOVM_TYPE { - return parseReturnNeoValueArray(rawValues, returnTypes) - } else { + if vmtype == payload.WASMVM_TYPE { return parasReturnValueWasmArray(rawValues, returnTypes) + } else { + return parseReturnNeoValueArray(rawValues, returnTypes) } } diff --git a/core/genesis/genesis.go b/core/genesis/genesis.go index 629dae44..e4f2bf35 100644 --- a/core/genesis/genesis.go +++ b/core/genesis/genesis.go @@ -149,7 +149,7 @@ func newParamContract() *types.Transaction { func newGovConfigTx() *types.Transaction { mutable, err := utils.NewDeployTransaction(common2.GovernanceContractAddress[:], "CONFIG", "1.0", - "DNA Dev Team", "contact@ont.io", "Blockchain Network Consensus Config", payload.NEOVM_TYPE) + "DNA Dev Team", "contact@onchain.com", "Blockchain Network Consensus Config", payload.NEOVM_TYPE) if err != nil { panic("[NewDeployTransaction] construct genesis governing token transaction error ") } @@ -162,7 +162,7 @@ func newGovConfigTx() *types.Transaction { func deployAuthContract() *types.Transaction { mutable, err := utils.NewDeployTransaction(common2.AuthContractAddress[:], "AuthContract", "1.0", - "DNA Dev Team", "contact@ont.io", "Blockchain Network Authorization Contract", payload.NEOVM_TYPE) + "DNA Dev Team", "contact@onchain.com", "Blockchain Network Authorization Contract", payload.NEOVM_TYPE) if err != nil { panic("[NewDeployTransaction] construct genesis governing token transaction error ") } @@ -174,14 +174,14 @@ func deployAuthContract() *types.Transaction { } func deployOntIDContract() *types.Transaction { - mutable, err := utils.NewDeployTransaction(common2.DIDContractAddress[:], "OID", "1.0", - "DNA Dev Team", "contact@ont.io", "Blockchain Network ONT ID", payload.NEOVM_TYPE) + mutable, err := utils.NewDeployTransaction(common2.DIDContractAddress[:], "DID", "1.0", + "DNA Dev Team", "contact@onchain.com", "Blockchain Network DID", payload.NEOVM_TYPE) if err != nil { panic("[NewDeployTransaction] construct genesis governing token transaction error ") } tx, err := mutable.IntoImmutable() if err != nil { - panic("construct genesis ontid transaction error ") + panic("construct genesis DID transaction error ") } return tx } diff --git a/core/payload/deploy_code.go b/core/payload/deploy_code.go index 887b18a1..2052cf41 100644 --- a/core/payload/deploy_code.go +++ b/core/payload/deploy_code.go @@ -27,6 +27,7 @@ import ( "github.com/DNAProject/DNA/common" "github.com/DNAProject/DNA/errors" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" ) type VmType byte @@ -34,11 +35,12 @@ type VmType byte const ( NEOVM_TYPE VmType = 1 WASMVM_TYPE VmType = 3 + NATIVE_TYPE VmType = 4 ) func VmTypeFromByte(ty byte) (VmType, error) { switch ty { - case 1, 3: + case 1, 3, 4: return VmType(ty), nil default: return VmType(0), fmt.Errorf("can not convert byte:%d to vm type", ty) @@ -48,7 +50,7 @@ func VmTypeFromByte(ty byte) (VmType, error) { // DeployCode is an implementation of transaction payload for deploy smartcontract type DeployCode struct { code []byte - //0, 1 means NEOVM_TYPE, 3 means WASMVM_TYPE + //0, 1 means NEOVM_TYPE, 3 means WASMVM_TYPE, 4 means NATIVE_TYPE vmFlags byte Name string Version string @@ -105,7 +107,7 @@ func (dc *DeployCode) GetNeoCode() ([]byte, error) { func checkVmFlags(vmFlags byte) error { switch vmFlags { - case 0, 1, 3: + case 0, 1, 3, 4: return nil default: return fmt.Errorf("invalid vm flags: %d", vmFlags) @@ -118,6 +120,8 @@ func (dc *DeployCode) VmType() VmType { return NEOVM_TYPE case 3: return WASMVM_TYPE + case 4: + return NATIVE_TYPE default: panic("unreachable") } @@ -197,6 +201,10 @@ func validateDeployCode(dep *DeployCode) error { if len(dep.code) > maxWasmCodeSize { return errors.NewErr("[contract] Code too long!") } + } else if dep.VmType() == NATIVE_TYPE { + if _, err := NewNativeDeployCode(dep.code); err != nil { + return err + } } else { if len(dep.code) > 1024*1024 { return errors.NewErr("[contract] Code too long!") @@ -253,3 +261,45 @@ func CreateDeployCode(code []byte, } return contract, nil } + +type NativeDeployCode struct { + BaseContractAddress common.Address + InitParam []byte // optional +} + +func (ndc *NativeDeployCode) Serialization(sink *common.ZeroCopySink) { + sink.WriteAddress(ndc.BaseContractAddress) + if len(ndc.InitParam) > 0 { + sink.WriteVarBytes(ndc.InitParam) + } +} + +func (ndc *NativeDeployCode) Deserialization(source *common.ZeroCopySource) error { + var eof, irregular bool + + ndc.BaseContractAddress, eof = source.NextAddress() + if eof { + return io.ErrUnexpectedEOF + } + + // skip eof check of initParam, + ndc.InitParam, _, irregular, _ = source.NextVarBytes() + if irregular { + return common.ErrIrregularData + } + return nil +} + +func NewNativeDeployCode(code []byte) (*NativeDeployCode, error) { + ndc := &NativeDeployCode{} + // 1. validate data format + if err := ndc.Deserialization(common.NewZeroCopySource(code)); err != nil { + return nil, fmt.Errorf("[contract] invalid code format: %s", err) + } + // 2. validate base-contract is native deployable + if !common2.IsNativeDeployable(ndc.BaseContractAddress) { + return nil, errors.NewErr("[contract] invalid base contract address") + } + + return ndc, nil +} diff --git a/smartcontract/service/native/common/params.go b/smartcontract/service/native/common/params.go index 62dcbaca..18e46e97 100644 --- a/smartcontract/service/native/common/params.go +++ b/smartcontract/service/native/common/params.go @@ -35,6 +35,8 @@ var ( ParamContractAddress, _ = common.AddressParseFromBytes([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04}) AuthContractAddress, _ = common.AddressParseFromBytes([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06}) GovernanceContractAddress, _ = common.AddressParseFromBytes([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07}) + + deployableNative = []common.Address{GasContractAddress, DIDContractAddress, ParamContractAddress, AuthContractAddress} ) func IsNativeContract(addr common.Address) bool { @@ -44,3 +46,12 @@ func IsNativeContract(addr common.Address) bool { bytes.Compare(addr[:], AuthContractAddress[:]) == 0 || bytes.Compare(addr[:], GovernanceContractAddress[:]) == 0 } + +func IsNativeDeployable(addr common.Address) bool { + for _, nativeAddr := range deployableNative { + if nativeAddr == addr { + return true + } + } + return false +} diff --git a/smartcontract/service/native/native_service.go b/smartcontract/service/native/native_service.go index 380eb14a..e8398011 100644 --- a/smartcontract/service/native/native_service.go +++ b/smartcontract/service/native/native_service.go @@ -24,6 +24,7 @@ package native import ( "fmt" "github.com/DNAProject/DNA/common" + "github.com/DNAProject/DNA/core/payload" "github.com/DNAProject/DNA/core/types" "github.com/DNAProject/DNA/errors" "github.com/DNAProject/DNA/smartcontract/context" @@ -62,9 +63,37 @@ func (this *NativeService) Register(methodName string, handler Handler) { this.ServiceMap[methodName] = handler } +func (this *NativeService) getBaseContractAddress(addr common.Address) (common.Address, error) { + if common2.IsNativeContract(addr) { + return addr, nil + } + + dep, err := this.CacheDB.GetContract(addr) + if err != nil { + return common.ADDRESS_EMPTY, fmt.Errorf("[getNativeContract] get contract context error: %s", err) + } + if dep == nil { + return common.ADDRESS_EMPTY, errors.NewErr("[NativeVmService] deploy code type error!") + } + + ndc, err := payload.NewNativeDeployCode(dep.GetRawCode()) + if err != nil { + return common.ADDRESS_EMPTY, fmt.Errorf("[NativeVmService] native deploy code type error: %s", err) + } + + return ndc.BaseContractAddress, nil +} + func (this *NativeService) Invoke() ([]byte, error) { contract := this.InvokeParam - services, ok := Contracts[contract.Address] + + // update baseContractAddr from deploy code + baseContractAddr, err := this.getBaseContractAddress(contract.Address) + if err != nil { + return common2.BYTE_FALSE, fmt.Errorf("get native contract base address: %s", err) + } + + services, ok := Contracts[baseContractAddr] if !ok { return common2.BYTE_FALSE, fmt.Errorf("Native contract address %x haven't been registered.", contract.Address) } diff --git a/smartcontract/service/wasmvm/runtime.go b/smartcontract/service/wasmvm/runtime.go index 4b53f120..04dccabe 100644 --- a/smartcontract/service/wasmvm/runtime.go +++ b/smartcontract/service/wasmvm/runtime.go @@ -704,6 +704,8 @@ func (self *Runtime) getContractType(addr common.Address) (ContractType, error) } if dep.VmType() == payload.WASMVM_TYPE { return WASMVM_CONTRACT, nil + } else if dep.VmType() == payload.NATIVE_TYPE { + return NATIVE_CONTRACT, nil } return NEOVM_CONTRACT, nil From 51614dcfb4d8f53bcf2332827dae39ee91593597 Mon Sep 17 00:00:00 2001 From: Edmond-Honglei-Cong Date: Sat, 15 Feb 2020 11:04:40 +0800 Subject: [PATCH 3/8] did/auth support native deployable --- account/identity.go | 6 +- account/identity_test.go | 4 +- .../handlers/sig_native_invoke_tx_test.go | 7 ++- core/store/ledgerstore/block_store_test.go | 4 +- core/store/ledgerstore/state_store.go | 45 +------------- smartcontract/service/native/auth/auth.go | 57 ++++++++++++++--- .../service/native/auth/param_test.go | 4 +- smartcontract/service/native/auth/utils.go | 42 +++++++++++-- .../service/native/did/attribute_test.go | 7 +++ .../service/native/did/controller.go | 46 +++++++++----- .../service/native/did/controller_test.go | 17 ++++- smartcontract/service/native/did/group.go | 20 +++--- .../service/native/did/group_test.go | 26 ++++++-- smartcontract/service/native/did/init.go | 36 +++++++++++ smartcontract/service/native/did/method.go | 62 ++++++++++++------- .../service/native/did/ontid_test.go | 58 ++++++++++++++++- smartcontract/service/native/did/query.go | 43 +++---------- smartcontract/service/native/did/recovery.go | 32 +++++++--- .../service/native/did/recovery_test.go | 7 +++ smartcontract/service/native/did/utils.go | 10 +-- .../native/testsuite/gas_suite_test.go | 5 +- 21 files changed, 370 insertions(+), 168 deletions(-) diff --git a/account/identity.go b/account/identity.go index 2f9707b3..e4f55b66 100644 --- a/account/identity.go +++ b/account/identity.go @@ -68,11 +68,11 @@ func CreateID(nonce []byte) (string, error) { return SCHEME + ":" + METHOD + ":" + string(idstring), nil } -func VerifyID(id string) bool { - if len(id) < 9 { +func VerifyID(method, id string) bool { + if len(id) < 9 || len(method) != 3 { return false } - if id[0:8] != "did:dna:" { + if id[0:8] != "did:"+method+":" { return false } buf, err := base58.BitcoinEncoding.Decode([]byte(id[8:])) diff --git a/account/identity_test.go b/account/identity_test.go index c8c8dda6..60d17a74 100644 --- a/account/identity_test.go +++ b/account/identity_test.go @@ -42,7 +42,7 @@ func TestCreate(t *testing.T) { func TestVerify(t *testing.T) { t.Log("verify", id) - if !VerifyID(id) { + if !VerifyID("dna", id) { t.Error("error: failed") } @@ -56,7 +56,7 @@ func TestVerify(t *testing.T) { for _, v := range invalid { t.Log("verify", v) - if VerifyID(v) { + if VerifyID("dna", v) { t.Error("error: passed") } } diff --git a/cmd/sigsvr/handlers/sig_native_invoke_tx_test.go b/cmd/sigsvr/handlers/sig_native_invoke_tx_test.go index 08039370..9d0a4356 100644 --- a/cmd/sigsvr/handlers/sig_native_invoke_tx_test.go +++ b/cmd/sigsvr/handlers/sig_native_invoke_tx_test.go @@ -23,12 +23,13 @@ package handlers import ( "encoding/json" + "testing" + "github.com/DNAProject/DNA/cmd/abi" clisvrcom "github.com/DNAProject/DNA/cmd/sigsvr/common" - nutils "github.com/DNAProject/DNA/smartcontract/service/native/utils" + "github.com/DNAProject/DNA/smartcontract/service/native/common" "github.com/ontio/ontology-crypto/keypair" "github.com/ontio/ontology-crypto/signature" - "testing" ) func TestSigNativeInvokeTx(t *testing.T) { @@ -46,7 +47,7 @@ func TestSigNativeInvokeTx(t *testing.T) { invokeReq := &SigNativeInvokeTxReq{ GasPrice: 0, GasLimit: 40000, - Address: nutils.GasContractAddress.ToHexString(), + Address: common.GasContractAddress.ToHexString(), Method: "transfer", Version: 0, Params: []interface{}{ diff --git a/core/store/ledgerstore/block_store_test.go b/core/store/ledgerstore/block_store_test.go index bfb2caaa..96f2ee51 100644 --- a/core/store/ledgerstore/block_store_test.go +++ b/core/store/ledgerstore/block_store_test.go @@ -32,8 +32,8 @@ import ( "github.com/DNAProject/DNA/core/payload" "github.com/DNAProject/DNA/core/types" "github.com/DNAProject/DNA/core/utils" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" "github.com/DNAProject/DNA/smartcontract/service/native/gas" - nutils "github.com/DNAProject/DNA/smartcontract/service/native/utils" "github.com/ontio/ontology-crypto/keypair" "github.com/stretchr/testify/assert" ) @@ -376,7 +376,7 @@ func transferTx(from, to common.Address, amount uint64) (*types.Transaction, err Value: amount, }) var cversion byte - return invokeSmartContractTx(0, 30000, cversion, nutils.GasContractAddress, "transfer", []interface{}{sts}) + return invokeSmartContractTx(0, 30000, cversion, common2.GasContractAddress, "transfer", []interface{}{sts}) } func invokeSmartContractTx(gasPrice, diff --git a/core/store/ledgerstore/state_store.go b/core/store/ledgerstore/state_store.go index aab3e7f5..62b07052 100644 --- a/core/store/ledgerstore/state_store.go +++ b/core/store/ledgerstore/state_store.go @@ -24,7 +24,6 @@ package ledgerstore import ( "bytes" "encoding/binary" - "errors" "fmt" "io" @@ -37,8 +36,6 @@ import ( "github.com/DNAProject/DNA/core/store/leveldbstore" "github.com/DNAProject/DNA/core/store/overlaydb" "github.com/DNAProject/DNA/merkle" - common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" - "github.com/DNAProject/DNA/smartcontract/service/native/did" ) var ( @@ -417,45 +414,5 @@ func (self *StateStore) Close() error { } func (self *StateStore) CheckStorage() error { - db := self.store - - prefix := append([]byte{byte(scom.ST_STORAGE)}, common2.DIDContractAddress[:]...) //prefix of new storage key - flag := append(prefix, did.FIELD_VERSION) - val, err := db.Get(flag) - if err == nil { - item := &states.StorageItem{} - source := common.NewZeroCopySource(val) - err := item.Deserialization(source) - if err == nil && item.Value[0] == did.FLAG_VERSION { - return nil - } else if err == nil { - return errors.New("check ontid storage: invalid version flag") - } else { - return err - } - } - - prefix1 := []byte{byte(scom.ST_STORAGE), 0x2a, 0x64, 0x69, 0x64} //prefix of old storage key - - iter := db.NewIterator(prefix1) - db.NewBatch() - for ok := iter.First(); ok; ok = iter.Next() { - key := append(prefix, iter.Key()[1:]...) - db.BatchPut(key, iter.Value()) - db.BatchDelete(iter.Key()) - } - iter.Release() - err = iter.Error() - if err != nil { - return err - } - - tag := states.StorageItem{} - tag.Value = []byte{did.FLAG_VERSION} - buf := common.NewZeroCopySink(nil) - tag.Serialization(buf) - db.BatchPut(flag, buf.Bytes()) - err = db.BatchCommit() - - return err + return nil } diff --git a/smartcontract/service/native/auth/auth.go b/smartcontract/service/native/auth/auth.go index fe386932..bfadaf13 100644 --- a/smartcontract/service/native/auth/auth.go +++ b/smartcontract/service/native/auth/auth.go @@ -29,6 +29,7 @@ import ( "github.com/DNAProject/DNA/account" "github.com/DNAProject/DNA/common" "github.com/DNAProject/DNA/common/log" + "github.com/DNAProject/DNA/core/states" "github.com/DNAProject/DNA/errors" "github.com/DNAProject/DNA/smartcontract/service/native" common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" @@ -75,7 +76,11 @@ func InitContractAdmin(native *native.NativeService) ([]byte, error) { } invokeAddr := cxt.ContractAddress - if !account.VerifyID(string(param.AdminOntID)) { + didMethod, err := getDIDMethod(native) + if err != nil || didMethod == nil { + return nil, fmt.Errorf("[initContractAdmin] get did method: %s", err) + } + if !account.VerifyID(string(didMethod), string(param.AdminOntID)) { return nil, fmt.Errorf("[initContractAdmin] invalid param: adminOntID is %x", param.AdminOntID) } ret, err := initContractAdmin(native, invokeAddr, param.AdminOntID) @@ -123,7 +128,11 @@ func Transfer(native *native.NativeService) ([]byte, error) { return nil, fmt.Errorf("[transfer] deserialize param failed: %v", err) } - if !account.VerifyID(string(param.NewAdminOntID)) { + didMethod, err := getDIDMethod(native) + if err != nil || didMethod == nil { + return nil, fmt.Errorf("[transfer] get did method: %s", err) + } + if !account.VerifyID(string(didMethod), string(param.NewAdminOntID)) { return nil, fmt.Errorf("[transfer] invalid param: newAdminOntID is %x", param.NewAdminOntID) } //prepare event msg @@ -269,7 +278,7 @@ func assignToRole(native *native.NativeService, param *DIDsToRoleParam) (bool, e return true, nil } -func AssignOntIDsToRole(native *native.NativeService) ([]byte, error) { +func AssignDIDsToRole(native *native.NativeService) ([]byte, error) { //deserialize param param := new(DIDsToRoleParam) source := common.NewZeroCopySource(native.Input) @@ -280,8 +289,12 @@ func AssignOntIDsToRole(native *native.NativeService) ([]byte, error) { if param.Role == nil { return nil, fmt.Errorf("[assignOntIDsToRole] invalid param: role is nil") } + didMethod, err := getDIDMethod(native) + if err != nil || didMethod == nil { + return nil, fmt.Errorf("[assignOntIDsToRole] get did method: %s", err) + } for i, ontID := range param.Persons { - if !account.VerifyID(string(ontID)) { + if !account.VerifyID(string(didMethod), string(ontID)) { return nil, fmt.Errorf("[assignOntIDsToRole] invalid param: param.Persons[%d]=%s", i, string(ontID)) } @@ -384,7 +397,11 @@ func delegate(native *native.NativeService, contractAddr common.Address, from [] return false, nil } - if !account.VerifyID(string(to)) { + didMethod, err := getDIDMethod(native) + if err != nil || didMethod == nil { + return false, fmt.Errorf("[get did method: %s", err) + } + if !account.VerifyID(string(didMethod), string(to)) { return false, fmt.Errorf("can not pass OntID validity test: to=%s", string(to)) } @@ -642,11 +659,16 @@ func VerifyToken(native *native.NativeService) ([]byte, error) { } func verifySig(native *native.NativeService, ontID []byte, keyNo uint64) (bool, error) { + didContractAddr, err := getDIDContractAddr(native) + if err != nil { + return false, fmt.Errorf("verify sig: %s", err) + } + sink := common.NewZeroCopySink(nil) sink.WriteVarBytes(ontID) utils.EncodeVarUint(sink, keyNo) args := sink.Bytes() - ret, err := native.NativeCall(common2.DIDContractAddress, "verifySignature", args) + ret, err := native.NativeCall(didContractAddr, "verifySignature", args) if err != nil { return false, err } @@ -661,12 +683,33 @@ func verifySig(native *native.NativeService, ontID []byte, keyNo uint64) (bool, } } +func authInit(srvc *native.NativeService) ([]byte, error) { + didContractAddr, err := utils.DecodeVarBytes(common.NewZeroCopySource(srvc.Input)) + if err != nil { + return utils.BYTE_FALSE, fmt.Errorf("init auth, contract param deserialize err: %s", err) + } + if len(didContractAddr) != common.ADDR_LEN { + return utils.BYTE_FALSE, fmt.Errorf("init auth, invalid length of DID contract addr: %v", didContractAddr) + } + + // check if has initialized + if _, err := getDIDContractAddr(srvc); err == nil { + return utils.BYTE_FALSE, fmt.Errorf("init auth, already inited") + } + + // save did contract addr + contract := srvc.ContextRef.CurrentContext().ContractAddress + srvc.CacheDB.Put(utils.ConcatKey(contract, PreDIDContractAddr), states.GenRawStorageItem(didContractAddr)) + return utils.BYTE_TRUE, nil +} + func RegisterAuthContract(native *native.NativeService) { + native.Register("initAuth", authInit) native.Register("initContractAdmin", InitContractAdmin) native.Register("assignFuncsToRole", AssignFuncsToRole) native.Register("delegate", Delegate) native.Register("withdraw", Withdraw) - native.Register("assignOntIDsToRole", AssignOntIDsToRole) + native.Register("assignDIDsToRole", AssignDIDsToRole) native.Register("verifyToken", VerifyToken) native.Register("transfer", Transfer) } diff --git a/smartcontract/service/native/auth/param_test.go b/smartcontract/service/native/auth/param_test.go index 4f6caf05..1f3f5d4a 100644 --- a/smartcontract/service/native/auth/param_test.go +++ b/smartcontract/service/native/auth/param_test.go @@ -26,7 +26,7 @@ import ( "testing" "github.com/DNAProject/DNA/common" - "github.com/DNAProject/DNA/smartcontract/service/native/utils" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" "github.com/stretchr/testify/assert" ) @@ -39,7 +39,7 @@ var ( var ( funcs = []string{"foo1", "foo2"} role = "role" - GasContractAddr = utils.GasContractAddress + GasContractAddr = common2.GasContractAddress ) func init() { diff --git a/smartcontract/service/native/auth/utils.go b/smartcontract/service/native/auth/utils.go index bcf1c15a..db284534 100644 --- a/smartcontract/service/native/auth/utils.go +++ b/smartcontract/service/native/auth/utils.go @@ -26,16 +26,18 @@ import ( "sort" "github.com/DNAProject/DNA/common" + "github.com/DNAProject/DNA/core/states" "github.com/DNAProject/DNA/smartcontract/event" "github.com/DNAProject/DNA/smartcontract/service/native" "github.com/DNAProject/DNA/smartcontract/service/native/utils" ) var ( - PreAdmin = []byte{0x01} - PreRoleFunc = []byte{0x02} - PreRoleToken = []byte{0x03} - PreDelegateStatus = []byte{0x04} + PreAdmin = []byte{0x01} + PreRoleFunc = []byte{0x02} + PreRoleToken = []byte{0x03} + PreDelegateStatus = []byte{0x04} + PreDIDContractAddr = []byte{0x05} ) //type(this.contractAddr.Admin) = []byte @@ -196,3 +198,35 @@ func pushEvent(native *native.NativeService, s interface{}) { func serializeAddress(sink *common.ZeroCopySink, addr common.Address) { sink.WriteVarBytes(addr[:]) } + +func getDIDContractAddr(native *native.NativeService) (common.Address, error) { + contract := native.ContextRef.CurrentContext().ContractAddress + didContractAddrBytes, err := native.CacheDB.Get(utils.ConcatKey(contract, PreDIDContractAddr)) + if err != nil { + return common.ADDRESS_EMPTY, fmt.Errorf("get did contract: %s", err) + } + value, err := states.GetValueFromRawStorageItem(didContractAddrBytes) + if err != nil { + return common.ADDRESS_EMPTY, fmt.Errorf("parse did contract: %s", err) + } + didContractAddr, err := common.AddressParseFromBytes(value) + if err != nil { + return common.ADDRESS_EMPTY, fmt.Errorf("invalid did contract addr: %s", err) + } + return didContractAddr, nil +} + +func getDIDMethod(native *native.NativeService) ([]byte, error) { + didContractAddr, err := getDIDContractAddr(native) + if err != nil { + return nil, fmt.Errorf("invalid did contract addr: %s", err) + } + didMethod, err := native.NativeCall(didContractAddr, "getDIDMethod", []byte{}) + if err != nil { + return nil, fmt.Errorf("get did method from contract: %s", err) + } + if result, ok := didMethod.([]byte); ok { + return result, nil + } + return nil, fmt.Errorf("get did method from contract failed") +} diff --git a/smartcontract/service/native/did/attribute_test.go b/smartcontract/service/native/did/attribute_test.go index fa828c39..568e39eb 100644 --- a/smartcontract/service/native/did/attribute_test.go +++ b/smartcontract/service/native/did/attribute_test.go @@ -37,6 +37,13 @@ func TestAttribute(t *testing.T) { } func CaseAttribute(t *testing.T, n *native.NativeService) { + initSink := common.NewZeroCopySink(nil) + initSink.WriteVarBytes([]byte("dna")) + n.Input = initSink.Bytes() + if _, err := didInit(n); err != nil { + t.Errorf("failed to init did: %s", err) + } + // 1. register id a := account.NewAccount("") id, err := account.GenerateID() diff --git a/smartcontract/service/native/did/controller.go b/smartcontract/service/native/did/controller.go index 22706661..94557636 100644 --- a/smartcontract/service/native/did/controller.go +++ b/smartcontract/service/native/did/controller.go @@ -32,6 +32,11 @@ import ( ) func regIdWithController(srvc *native.NativeService) ([]byte, error) { + contract := srvc.ContextRef.CurrentContext().ContractAddress + didMethod, err := getDIDMethod(srvc) + if err != nil || didMethod == nil { + return utils.BYTE_FALSE, fmt.Errorf("regIDWithController, get did method: %s", err) + } source := common.NewZeroCopySource(srvc.Input) // arg0: ID arg0, err := utils.DecodeVarBytes(source) @@ -39,11 +44,11 @@ func regIdWithController(srvc *native.NativeService) ([]byte, error) { return utils.BYTE_FALSE, fmt.Errorf("argument 0 error") } - if !account.VerifyID(string(arg0)) { + if !account.VerifyID(string(didMethod), string(arg0)) { return utils.BYTE_FALSE, fmt.Errorf("invalid ID") } - encId, err := encodeID(arg0) + encId, err := encodeID(contract, arg0) if err != nil { return utils.BYTE_FALSE, err } @@ -58,13 +63,13 @@ func regIdWithController(srvc *native.NativeService) ([]byte, error) { return utils.BYTE_FALSE, fmt.Errorf("argument 1 error") } - if account.VerifyID(string(arg1)) { + if account.VerifyID(string(didMethod), string(arg1)) { err = verifySingleController(srvc, arg1, source) if err != nil { return utils.BYTE_FALSE, err } } else { - controller, err := deserializeGroup(arg1) + controller, err := deserializeGroup(didMethod, arg1) if err != nil { return utils.BYTE_FALSE, errors.New("deserialize controller error") } @@ -83,6 +88,7 @@ func regIdWithController(srvc *native.NativeService) ([]byte, error) { } func revokeIDByController(srvc *native.NativeService) ([]byte, error) { + contract := srvc.ContextRef.CurrentContext().ContractAddress source := common.NewZeroCopySource(srvc.Input) // arg0: id arg0, err := utils.DecodeVarBytes(source) @@ -90,7 +96,7 @@ func revokeIDByController(srvc *native.NativeService) ([]byte, error) { return utils.BYTE_FALSE, fmt.Errorf("argument 0 error") } - encID, err := encodeID(arg0) + encID, err := encodeID(contract, arg0) if err != nil { return utils.BYTE_FALSE, err } @@ -114,6 +120,7 @@ func revokeIDByController(srvc *native.NativeService) ([]byte, error) { } func verifyController(srvc *native.NativeService) ([]byte, error) { + contract := srvc.ContextRef.CurrentContext().ContractAddress source := common.NewZeroCopySource(srvc.Input) // arg0: ID arg0, err := utils.DecodeVarBytes(source) @@ -121,7 +128,7 @@ func verifyController(srvc *native.NativeService) ([]byte, error) { return utils.BYTE_FALSE, fmt.Errorf("argument 0 error, %s", err) } - key, err := encodeID(arg0) + key, err := encodeID(contract, arg0) if err != nil { return utils.BYTE_FALSE, err } @@ -135,6 +142,7 @@ func verifyController(srvc *native.NativeService) ([]byte, error) { } func removeController(srvc *native.NativeService) ([]byte, error) { + contract := srvc.ContextRef.CurrentContext().ContractAddress source := common.NewZeroCopySource(srvc.Input) // arg0: id arg0, err := utils.DecodeVarBytes(source) @@ -146,7 +154,7 @@ func removeController(srvc *native.NativeService) ([]byte, error) { if err != nil { return utils.BYTE_FALSE, fmt.Errorf("argument 1 error") } - encId, err := encodeID(arg0) + encId, err := encodeID(contract, arg0) if err != nil { return utils.BYTE_FALSE, err } @@ -161,6 +169,7 @@ func removeController(srvc *native.NativeService) ([]byte, error) { } func addKeyByController(srvc *native.NativeService) ([]byte, error) { + contract := srvc.ContextRef.CurrentContext().ContractAddress source := common.NewZeroCopySource(srvc.Input) // arg0: id arg0, err := utils.DecodeVarBytes(source) @@ -178,7 +187,7 @@ func addKeyByController(srvc *native.NativeService) ([]byte, error) { return utils.BYTE_FALSE, fmt.Errorf("invalid key") } - encId, err := encodeID(arg0) + encId, err := encodeID(contract, arg0) if err != nil { return utils.BYTE_FALSE, err } @@ -198,6 +207,7 @@ func addKeyByController(srvc *native.NativeService) ([]byte, error) { } func removeKeyByController(srvc *native.NativeService) ([]byte, error) { + contract := srvc.ContextRef.CurrentContext().ContractAddress source := common.NewZeroCopySource(srvc.Input) // arg0: id arg0, err := utils.DecodeVarBytes(source) @@ -211,7 +221,7 @@ func removeKeyByController(srvc *native.NativeService) ([]byte, error) { return utils.BYTE_FALSE, errors.New("argument 1") } - encId, err := encodeID(arg0) + encId, err := encodeID(contract, arg0) if err != nil { return utils.BYTE_FALSE, errors.New(err.Error()) } @@ -231,6 +241,7 @@ func removeKeyByController(srvc *native.NativeService) ([]byte, error) { } func addAttributesByController(srvc *native.NativeService) ([]byte, error) { + contract := srvc.ContextRef.CurrentContext().ContractAddress source := common.NewZeroCopySource(srvc.Input) // arg0: id arg0, err := utils.DecodeVarBytes(source) @@ -253,7 +264,7 @@ func addAttributesByController(srvc *native.NativeService) ([]byte, error) { arg1 = append(arg1, v) } - encId, err := encodeID(arg0) + encId, err := encodeID(contract, arg0) if err != nil { return utils.BYTE_FALSE, err } @@ -274,6 +285,7 @@ func addAttributesByController(srvc *native.NativeService) ([]byte, error) { } func removeAttributeByController(srvc *native.NativeService) ([]byte, error) { + contract := srvc.ContextRef.CurrentContext().ContractAddress source := common.NewZeroCopySource(srvc.Input) // arg0: id arg0, err := utils.DecodeVarBytes(source) @@ -287,7 +299,7 @@ func removeAttributeByController(srvc *native.NativeService) ([]byte, error) { return utils.BYTE_FALSE, errors.New("argument 1 error") } - encId, err := encodeID(arg0) + encId, err := encodeID(contract, arg0) if err != nil { return utils.BYTE_FALSE, err } @@ -307,6 +319,11 @@ func removeAttributeByController(srvc *native.NativeService) ([]byte, error) { } func getController(srvc *native.NativeService, encId []byte) (interface{}, error) { + didMethod, err := getDIDMethod(srvc) + if err != nil || didMethod == nil { + return nil, fmt.Errorf("getController, get did method: %s", err) + } + key := append(encId, FIELD_CONTROLLER) item, err := utils.GetStorageItem(srvc, key) if err != nil { @@ -315,20 +332,21 @@ func getController(srvc *native.NativeService, encId []byte) (interface{}, error return nil, errors.New("empty controller storage") } - if account.VerifyID(string(item.Value)) { + if account.VerifyID(string(didMethod), string(item.Value)) { return item.Value, nil } else { - return deserializeGroup(item.Value) + return deserializeGroup(didMethod, item.Value) } } func verifySingleController(srvc *native.NativeService, id []byte, args *common.ZeroCopySource) error { + contract := srvc.ContextRef.CurrentContext().ContractAddress // public key index index, err := utils.DecodeVarUint(args) if err != nil { return fmt.Errorf("index error, %s", err) } - encId, err := encodeID(id) + encId, err := encodeID(contract, id) if err != nil { return err } diff --git a/smartcontract/service/native/did/controller_test.go b/smartcontract/service/native/did/controller_test.go index 54c4d424..0c07ac91 100644 --- a/smartcontract/service/native/did/controller_test.go +++ b/smartcontract/service/native/did/controller_test.go @@ -27,6 +27,7 @@ import ( "github.com/DNAProject/DNA/account" "github.com/DNAProject/DNA/common" "github.com/DNAProject/DNA/smartcontract/service/native" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" "github.com/DNAProject/DNA/smartcontract/service/native/utils" "github.com/ontio/ontology-crypto/keypair" ) @@ -41,6 +42,13 @@ func TestGroupController(t *testing.T) { // Test case: register an ID controlled by another ID func CaseController(t *testing.T, n *native.NativeService) { + initSink := common.NewZeroCopySink(nil) + initSink.WriteVarBytes([]byte("dna")) + n.Input = initSink.Bytes() + if _, err := didInit(n); err != nil { + t.Errorf("failed to init did: %s", err) + } + a0 := account.NewAccount("") id0, _ := account.GenerateID() id1, _ := account.GenerateID() @@ -204,6 +212,13 @@ func CaseController(t *testing.T, n *native.NativeService) { } func CaseGroupController(t *testing.T, n *native.NativeService) { + initSink := common.NewZeroCopySink(nil) + initSink.WriteVarBytes([]byte("dna")) + n.Input = initSink.Bytes() + if _, err := didInit(n); err != nil { + t.Errorf("failed to init did: %s", err) + } + id, _ := account.GenerateID() id0, _ := account.GenerateID() id1, _ := account.GenerateID() @@ -301,7 +316,7 @@ func CaseGroupController(t *testing.T, n *native.NativeService) { } // 10. check id state - enc, _ := encodeID([]byte(id)) + enc, _ := encodeID(common2.DIDContractAddress, []byte(id)) if checkIDState(n, enc) != flag_revoke { t.Fatal("id state is not revoked") } diff --git a/smartcontract/service/native/did/group.go b/smartcontract/service/native/did/group.go index f13561ad..5c2f560d 100644 --- a/smartcontract/service/native/did/group.go +++ b/smartcontract/service/native/did/group.go @@ -53,14 +53,14 @@ func (g *Group) Serialize() []byte { case *Group: sink.WriteVarBytes(t.Serialize()) default: - panic("invlid member type") + panic("invalid member type") } } utils.EncodeVarUint(sink, uint64(g.Threshold)) return sink.Bytes() } -func rDeserialize(data []byte, depth uint) (*Group, error) { +func rDeserialize(didPrefix, data []byte, depth uint) (*Group, error) { if depth == MAX_DEPTH { return nil, fmt.Errorf("recursion is too deep") } @@ -79,11 +79,11 @@ func rDeserialize(data []byte, depth uint) (*Group, error) { if err != nil { return nil, fmt.Errorf("error parsing group members: %s", err) } - if len(m) > 8 && bytes.Equal(m[:8], []byte("did:dna:")) { + if len(m) > 8 && bytes.Equal(m[:8], didPrefix) { g.Members = append(g.Members, m) } else { // parse recursively - g1, err := rDeserialize(m, depth+1) + g1, err := rDeserialize(didPrefix, m, depth+1) if err != nil { return nil, fmt.Errorf("error parsing subgroup: %s", err) } @@ -105,15 +105,18 @@ func rDeserialize(data []byte, depth uint) (*Group, error) { return &g, nil } -func deserializeGroup(data []byte) (*Group, error) { - return rDeserialize(data, 0) +func deserializeGroup(didMethod, data []byte) (*Group, error) { + didPrefix := []byte("did:" + string(didMethod) + ":") + return rDeserialize(didPrefix, data, 0) } func validateMembers(srvc *native.NativeService, g *Group) error { + contract := srvc.ContextRef.CurrentContext().ContractAddress + for _, m := range g.Members { switch t := m.(type) { case []byte: - key, err := encodeID(t) + key, err := encodeID(contract, t) if err != nil { return fmt.Errorf("invalid id: %s", string(t)) } @@ -210,8 +213,9 @@ func verifyGroupSignature(srvc *native.NativeService, g *Group, signers []Signer return false } + contract := srvc.ContextRef.CurrentContext().ContractAddress for _, signer := range signers { - key, err := encodeID(signer.id) + key, err := encodeID(contract, signer.id) if err != nil { return false } diff --git a/smartcontract/service/native/did/group_test.go b/smartcontract/service/native/did/group_test.go index d4184e31..4439a0aa 100644 --- a/smartcontract/service/native/did/group_test.go +++ b/smartcontract/service/native/did/group_test.go @@ -31,9 +31,13 @@ import ( "github.com/DNAProject/DNA/core/store/overlaydb" "github.com/DNAProject/DNA/smartcontract/service/native" "github.com/DNAProject/DNA/smartcontract/storage" + "github.com/DNAProject/DNA/smartcontract/service/native/common" + "github.com/DNAProject/DNA/smartcontract" + "github.com/DNAProject/DNA/smartcontract/context" ) func TestDeserializeGroup(t *testing.T) { + didMethod := []byte("dna") id0 := []byte("did:dna:ARY2ekof1eCSetcimGdjqyzUYaVDDPVWmw") id1 := []byte("did:dna:ASbxtSqrpmydpjqCUGDiQp2mzsfd4zFArs") id2 := []byte("did:dna:AGxc3cdeB6QFvmZXzWhGwzuvohNtqaaaDw") @@ -51,7 +55,7 @@ func TestDeserializeGroup(t *testing.T) { }, } - g, err := deserializeGroup(g_.Serialize()) + g, err := deserializeGroup(didMethod, g_.Serialize()) if err != nil { t.Fatal(err) } @@ -65,16 +69,24 @@ func TestDeserializeGroup(t *testing.T) { overlay := overlaydb.NewOverlayDB(memback) cache := storage.NewCacheDB(overlay) + ctx := &context.Context{ + ContractAddress: common.DIDContractAddress, + } + sc := &smartcontract.SmartContract{ + CacheDB: cache, + } + sc.PushContext(ctx) srvc := new(native.NativeService) srvc.CacheDB = cache + srvc.ContextRef = sc - key, _ := encodeID(id0) + key, _ := encodeID(common.DIDContractAddress, id0) insertPk(srvc, key, []byte("test pk")) cache.Put(key, states.GenRawStorageItem([]byte{flag_valid})) - key, _ = encodeID(id1) + key, _ = encodeID(common.DIDContractAddress, id1) insertPk(srvc, key, []byte("test pk")) cache.Put(key, states.GenRawStorageItem([]byte{flag_valid})) - key, _ = encodeID(id2) + key, _ = encodeID(common.DIDContractAddress, id2) insertPk(srvc, key, []byte("test pk")) cache.Put(key, states.GenRawStorageItem([]byte{flag_valid})) @@ -118,16 +130,18 @@ func groupCmp(a, b *Group) error { } func TestDeserializeGroup1(t *testing.T) { + didMethod := []byte("ont") data, _ := hex.DecodeString("01022a6469643a6f6e743a4153627874537172706d7964706a7143554744695170326d7a736664347a464172732a6469643a6f6e743a414778633363646542365146766d5a587a576847777a75766f684e747161616144770103") - _, err := deserializeGroup(data) + _, err := deserializeGroup(didMethod, data) if err == nil { t.Fatal("deserializeGroup should fail due to the invalid threshold") } } func TestDeserializeGroup2(t *testing.T) { + didMethod := []byte("ont") data, _ := hex.DecodeString("010203646964086469643a6f6e740101") - _, err := deserializeGroup(data) + _, err := deserializeGroup(didMethod, data) if err == nil { t.Fatal("deserializeGroup should fail due to invalid member data") } diff --git a/smartcontract/service/native/did/init.go b/smartcontract/service/native/did/init.go index 52106b4d..07c8e8db 100644 --- a/smartcontract/service/native/did/init.go +++ b/smartcontract/service/native/did/init.go @@ -21,8 +21,13 @@ package did import ( + "fmt" + + common2 "github.com/DNAProject/DNA/common" + "github.com/DNAProject/DNA/core/states" "github.com/DNAProject/DNA/smartcontract/service/native" "github.com/DNAProject/DNA/smartcontract/service/native/common" + "github.com/DNAProject/DNA/smartcontract/service/native/utils" ) func Init() { @@ -30,6 +35,8 @@ func Init() { } func RegisterIDContract(srvc *native.NativeService) { + srvc.Register("initDID", didInit) + srvc.Register("getDIDMethod", getDIDMethod) srvc.Register("regIDWithPublicKey", regIdWithPublicKey) srvc.Register("regIDWithController", regIdWithController) srvc.Register("revokeID", revokeID) @@ -58,3 +65,32 @@ func RegisterIDContract(srvc *native.NativeService) { srvc.Register("getDDO", GetDDO) return } + +func didInit(srvc *native.NativeService) ([]byte, error) { + didMethod, err := utils.DecodeVarBytes(common2.NewZeroCopySource(srvc.Input)) + if err != nil { + return utils.BYTE_FALSE, fmt.Errorf("init did, contract param deserialize err: %s", err) + } + if len(didMethod) != 3 { + return utils.BYTE_FALSE, fmt.Errorf("init did, invalid length of did-method: %s", string(didMethod)) + } + + // check if has initialized + if _, err := getDIDMethod(srvc); err == nil { + return utils.BYTE_FALSE, fmt.Errorf("init did, already inited") + } + + // save did-method + contract := srvc.ContextRef.CurrentContext().ContractAddress + srvc.CacheDB.Put(utils.ConcatKey(contract, []byte{FIELD_DID_METHOD}), states.GenRawStorageItem(didMethod)) + return utils.BYTE_TRUE, nil +} + +func getDIDMethod(srvc *native.NativeService) ([]byte, error) { + contract := srvc.ContextRef.CurrentContext().ContractAddress + didMethodBytes, err := srvc.CacheDB.Get(utils.ConcatKey(contract, []byte{FIELD_DID_METHOD})) + if err != nil { + return nil, err + } + return states.GetValueFromRawStorageItem(didMethodBytes) +} diff --git a/smartcontract/service/native/did/method.go b/smartcontract/service/native/did/method.go index e9dad5f0..5b59f35c 100644 --- a/smartcontract/service/native/did/method.go +++ b/smartcontract/service/native/did/method.go @@ -43,49 +43,55 @@ func regIdWithPublicKey(srvc *native.NativeService) ([]byte, error) { // arg0: ID arg0, err := utils.DecodeVarBytes(source) if err != nil { - return utils.BYTE_FALSE, errors.New("register ONT ID error: parsing argument 0 failed") + return utils.BYTE_FALSE, errors.New("register DID error: parsing argument 0 failed") } else if len(arg0) == 0 { - return utils.BYTE_FALSE, errors.New("register ONT ID error: invalid length of argument 0") + return utils.BYTE_FALSE, errors.New("register DID error: invalid length of argument 0") } log.Debug("arg 0:", hex.EncodeToString(arg0), string(arg0)) // arg1: public key arg1, err := utils.DecodeVarBytes(source) if err != nil { - return utils.BYTE_FALSE, errors.New("register ONT ID error: parsing argument 1 failed") + return utils.BYTE_FALSE, errors.New("register DID error: parsing argument 1 failed") } log.Debug("arg 1:", hex.EncodeToString(arg1)) if len(arg0) == 0 || len(arg1) == 0 { - return utils.BYTE_FALSE, errors.New("register ONT ID error: invalid argument") + return utils.BYTE_FALSE, errors.New("register DID error: invalid argument") } - if !account.VerifyID(string(arg0)) { - return utils.BYTE_FALSE, errors.New("register ONT ID error: invalid ID") + didMethod, err := getDIDMethod(srvc) + if err != nil || didMethod == nil { + return nil, fmt.Errorf("regIdWithPublicKey, get did method: %s", err) } - key, err := encodeID(arg0) + if !account.VerifyID(string(didMethod), string(arg0)) { + return utils.BYTE_FALSE, errors.New("register DID error: invalid ID") + } + + contract := srvc.ContextRef.CurrentContext().ContractAddress + key, err := encodeID(contract, arg0) if err != nil { - return utils.BYTE_FALSE, errors.New("register ONT ID error: " + err.Error()) + return utils.BYTE_FALSE, errors.New("register DID error: " + err.Error()) } if checkIDState(srvc, key) != flag_not_exist { - return utils.BYTE_FALSE, errors.New("register ONT ID error: already registered") + return utils.BYTE_FALSE, errors.New("register DID error: already registered") } public, err := keypair.DeserializePublicKey(arg1) if err != nil { - return utils.BYTE_FALSE, errors.New("register ONT ID error: invalid public key") + return utils.BYTE_FALSE, errors.New("register DID error: invalid public key") } addr := types.AddressFromPubKey(public) if !srvc.ContextRef.CheckWitness(addr) { - return utils.BYTE_FALSE, errors.New("register ONT ID error: checking witness failed") + return utils.BYTE_FALSE, errors.New("register DID error: checking witness failed") } // insert public key _, err = insertPk(srvc, key, arg1) if err != nil { - return utils.BYTE_FALSE, errors.New("register ONT ID error: store public key error, " + err.Error()) + return utils.BYTE_FALSE, errors.New("register DID error: store public key error, " + err.Error()) } // set flags utils.PutBytes(srvc, key, []byte{flag_valid}) @@ -106,8 +112,14 @@ func regIdWithAttributes(srvc *native.NativeService) ([]byte, error) { } else if len(arg0) == 0 { return utils.BYTE_FALSE, errors.New("register ID with attributes error: argument 0 error, invalid length") } - if !account.VerifyID(string(arg0)) { - return utils.BYTE_FALSE, errors.New("register ONT ID error: invalid ID") + + didMethod, err := getDIDMethod(srvc) + if err != nil || didMethod == nil { + return nil, fmt.Errorf("regIdWithAttributes, get did method: %s", err) + } + + if !account.VerifyID(string(didMethod), string(arg0)) { + return utils.BYTE_FALSE, errors.New("register DID error: invalid ID") } // arg1: public key @@ -133,7 +145,8 @@ func regIdWithAttributes(srvc *native.NativeService) ([]byte, error) { arg2 = append(arg2, v) } - key, err := encodeID(arg0) + contract := srvc.ContextRef.CurrentContext().ContractAddress + key, err := encodeID(contract, arg0) if err != nil { return utils.BYTE_FALSE, errors.New("register ID with attributes error: " + err.Error()) } @@ -197,7 +210,8 @@ func addKey(srvc *native.NativeService) ([]byte, error) { return utils.BYTE_FALSE, errors.New("add key failed: check witness failed, " + err.Error()) } - key, err := encodeID(arg0) + contract := srvc.ContextRef.CurrentContext().ContractAddress + key, err := encodeID(contract, arg0) if err != nil { return utils.BYTE_FALSE, errors.New("add key failed: " + err.Error()) } @@ -248,7 +262,8 @@ func removeKey(srvc *native.NativeService) ([]byte, error) { return utils.BYTE_FALSE, fmt.Errorf("remove key failed: check witness failed, %s", err) } - key, err := encodeID(arg0) + contract := srvc.ContextRef.CurrentContext().ContractAddress + key, err := encodeID(contract, arg0) if err != nil { return utils.BYTE_FALSE, fmt.Errorf("remove key failed: %s", err) } @@ -305,7 +320,8 @@ func addAttributes(srvc *native.NativeService) ([]byte, error) { return utils.BYTE_FALSE, fmt.Errorf("add attributes failed, argument 2, error: %s", err) } - key, err := encodeID(arg0) + contract := srvc.ContextRef.CurrentContext().ContractAddress + key, err := encodeID(contract, arg0) if err != nil { return utils.BYTE_FALSE, fmt.Errorf("add attributes failed: %s", err) } @@ -352,7 +368,9 @@ func removeAttribute(srvc *native.NativeService) ([]byte, error) { if err != nil { return utils.BYTE_FALSE, errors.New("remove attribute failed: " + err.Error()) } - key, err := encodeID(arg0) + + contract := srvc.ContextRef.CurrentContext().ContractAddress + key, err := encodeID(contract, arg0) if err != nil { return utils.BYTE_FALSE, errors.New("remove attribute failed: " + err.Error()) } @@ -385,7 +403,8 @@ func verifySignature(srvc *native.NativeService) ([]byte, error) { return utils.BYTE_FALSE, errors.New("verify signature error: argument 1 error, " + err.Error()) } - key, err := encodeID(arg0) + contract := srvc.ContextRef.CurrentContext().ContractAddress + key, err := encodeID(contract, arg0) if err != nil { return utils.BYTE_FALSE, errors.New("verify signature error: " + err.Error()) } @@ -409,7 +428,8 @@ func revokeID(srvc *native.NativeService) ([]byte, error) { return utils.BYTE_FALSE, fmt.Errorf("argument 1 error") } - encID, err := encodeID(arg0) + contract := srvc.ContextRef.CurrentContext().ContractAddress + encID, err := encodeID(contract, arg0) if err != nil { return utils.BYTE_FALSE, err } diff --git a/smartcontract/service/native/did/ontid_test.go b/smartcontract/service/native/did/ontid_test.go index c9fca252..2e8d7ca7 100644 --- a/smartcontract/service/native/did/ontid_test.go +++ b/smartcontract/service/native/did/ontid_test.go @@ -22,18 +22,21 @@ package did import ( "bytes" + "errors" + "fmt" "testing" "github.com/DNAProject/DNA/account" "github.com/DNAProject/DNA/common" "github.com/DNAProject/DNA/smartcontract/service/native" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" "github.com/DNAProject/DNA/smartcontract/service/native/testsuite" "github.com/DNAProject/DNA/smartcontract/service/native/utils" "github.com/ontio/ontology-crypto/keypair" ) func testcase(t *testing.T, f func(t *testing.T, n *native.NativeService)) { - testsuite.InvokeNativeContract(t, utils.DIDContractAddress, + testsuite.InvokeNativeContract(t, common2.DIDContractAddress, func(n *native.NativeService) ([]byte, error) { f(t, n) return nil, nil @@ -69,6 +72,13 @@ func regID(n *native.NativeService, id string, a *account.Account) error { } func CaseRegID(t *testing.T, n *native.NativeService) { + initSink := common.NewZeroCopySink(nil) + initSink.WriteVarBytes([]byte("dna")) + n.Input = initSink.Bytes() + if _, err := didInit(n); err != nil { + t.Errorf("failed to init did: %s", err) + } + id, err := account.GenerateID() if err != nil { t.Fatal(err) @@ -165,6 +175,13 @@ func CaseRegID(t *testing.T, n *native.NativeService) { } func CaseOwner(t *testing.T, n *native.NativeService) { + initSink := common.NewZeroCopySink(nil) + initSink.WriteVarBytes([]byte("dna")) + n.Input = initSink.Bytes() + if _, err := didInit(n); err != nil { + t.Errorf("failed to init did: %s", err) + } + // 1. register ID id, err := account.GenerateID() if err != nil { @@ -320,6 +337,13 @@ func CaseOwner(t *testing.T, n *native.NativeService) { } func CaseOwnerSize(t *testing.T, n *native.NativeService) { + sink := common.NewZeroCopySink(nil) + sink.WriteVarBytes([]byte("dna")) + n.Input = sink.Bytes() + if _, err := didInit(n); err != nil { + t.Errorf("failed to init did: %s", err) + } + id, _ := account.GenerateID() a := account.NewAccount("") err := regID(n, id, a) @@ -327,7 +351,7 @@ func CaseOwnerSize(t *testing.T, n *native.NativeService) { t.Fatal(err) } - enc, err := encodeID([]byte(id)) + enc, err := encodeID(common2.DIDContractAddress, []byte(id)) if err != nil { t.Fatal(err) } @@ -338,3 +362,33 @@ func CaseOwnerSize(t *testing.T, n *native.NativeService) { t.Fatal("total size of the owner's key should be limited") } } + +func GetPublicKeyByID(srvc *native.NativeService) ([]byte, error) { + args := common.NewZeroCopySource(srvc.Input) + // arg0: ID + arg0, err := utils.DecodeVarBytes(args) + if err != nil { + return nil, errors.New("get public key failed: argument 0 error") + } + // arg1: key ID + arg1, err := utils.DecodeUint32(args) + if err != nil { + return nil, errors.New("get public key failed: argument 1 error") + } + + key, err := encodeID(common2.DIDContractAddress, arg0) + if err != nil { + return nil, fmt.Errorf("get public key failed: %s", err) + } + + pk, err := getPk(srvc, key, arg1) + if err != nil { + return nil, fmt.Errorf("get public key failed: %s", err) + } else if pk == nil { + return nil, errors.New("get public key failed: not found") + } else if pk.revoked { + return nil, errors.New("get public key failed: revoked") + } + + return pk.key, nil +} diff --git a/smartcontract/service/native/did/query.go b/smartcontract/service/native/did/query.go index 06eddf86..368424b3 100644 --- a/smartcontract/service/native/did/query.go +++ b/smartcontract/service/native/did/query.go @@ -31,36 +31,6 @@ import ( "github.com/DNAProject/DNA/smartcontract/service/native/utils" ) -func GetPublicKeyByID(srvc *native.NativeService) ([]byte, error) { - args := common.NewZeroCopySource(srvc.Input) - // arg0: ID - arg0, err := utils.DecodeVarBytes(args) - if err != nil { - return nil, errors.New("get public key failed: argument 0 error") - } - // arg1: key ID - arg1, err := utils.DecodeUint32(args) - if err != nil { - return nil, errors.New("get public key failed: argument 1 error") - } - - key, err := encodeID(arg0) - if err != nil { - return nil, fmt.Errorf("get public key failed: %s", err) - } - - pk, err := getPk(srvc, key, arg1) - if err != nil { - return nil, fmt.Errorf("get public key failed: %s", err) - } else if pk == nil { - return nil, errors.New("get public key failed: not found") - } else if pk.revoked { - return nil, errors.New("get public key failed: revoked") - } - - return pk.key, nil -} - func GetDDO(srvc *native.NativeService) ([]byte, error) { log.Debug("GetDDO") source := common.NewZeroCopySource(srvc.Input) @@ -69,7 +39,8 @@ func GetDDO(srvc *native.NativeService) ([]byte, error) { return nil, fmt.Errorf("get id error, %s", err) } - key, err := encodeID(did) + contract := srvc.ContextRef.CurrentContext().ContractAddress + key, err := encodeID(contract, did) if err != nil { return nil, err } @@ -137,7 +108,9 @@ func GetPublicKeys(srvc *native.NativeService) ([]byte, error) { if len(did) == 0 { return nil, errors.New("get public keys error: invalid ID") } - key, err := encodeID(did) + + contract := srvc.ContextRef.CurrentContext().ContractAddress + key, err := encodeID(contract, did) if err != nil { return nil, fmt.Errorf("get public keys error: %s", err) } @@ -171,7 +144,8 @@ func GetAttributes(srvc *native.NativeService) ([]byte, error) { if len(did) == 0 { return nil, errors.New("get attributes error: invalid ID") } - key, err := encodeID(did) + contract := srvc.ContextRef.CurrentContext().ContractAddress + key, err := encodeID(contract, did) if err != nil { return nil, fmt.Errorf("get public keys error: %s", err) } @@ -197,7 +171,8 @@ func GetKeyState(srvc *native.NativeService) ([]byte, error) { return nil, fmt.Errorf("get key state failed: argument 1 error, %s", err) } - key, err := encodeID(arg0) + contract := srvc.ContextRef.CurrentContext().ContractAddress + key, err := encodeID(contract, arg0) if err != nil { return nil, fmt.Errorf("get key state failed: %s", err) } diff --git a/smartcontract/service/native/did/recovery.go b/smartcontract/service/native/did/recovery.go index 3f038c85..db473fb5 100644 --- a/smartcontract/service/native/did/recovery.go +++ b/smartcontract/service/native/did/recovery.go @@ -54,7 +54,8 @@ func setRecovery(srvc *native.NativeService) ([]byte, error) { return utils.BYTE_FALSE, errors.New("setRecovery: argument 2 error") } - encId, err := encodeID(arg0) + contract := srvc.ContextRef.CurrentContext().ContractAddress + encId, err := encodeID(contract, arg0) if err != nil { return utils.BYTE_FALSE, errors.New("setRecovery: " + err.Error()) } @@ -94,7 +95,8 @@ func updateRecovery(srvc *native.NativeService) ([]byte, error) { return utils.BYTE_FALSE, errors.New("updateRecovery: argument 2 error") } - key, err := encodeID(arg0) + contract := srvc.ContextRef.CurrentContext().ContractAddress + key, err := encodeID(contract, arg0) if err != nil { return utils.BYTE_FALSE, errors.New("update recovery: " + err.Error()) } @@ -137,7 +139,8 @@ func addKeyByRecovery(srvc *native.NativeService) ([]byte, error) { return utils.BYTE_FALSE, errors.New("argument 2 error") } - encId, err := encodeID(arg0) + contract := srvc.ContextRef.CurrentContext().ContractAddress + encId, err := encodeID(contract, arg0) if err != nil { return utils.BYTE_FALSE, err } @@ -183,7 +186,8 @@ func removeKeyByRecovery(srvc *native.NativeService) ([]byte, error) { return utils.BYTE_FALSE, errors.New("argument 2 error") } - encId, err := encodeID(arg0) + contract := srvc.ContextRef.CurrentContext().ContractAddress + encId, err := encodeID(contract, arg0) if err != nil { return utils.BYTE_FALSE, err } @@ -212,7 +216,12 @@ func removeKeyByRecovery(srvc *native.NativeService) ([]byte, error) { } func putRecovery(srvc *native.NativeService, encID, data []byte) (*Group, error) { - rec, err := deserializeGroup(data) + didMethod, err := getDIDMethod(srvc) + if err != nil || didMethod == nil { + return nil, fmt.Errorf("putRecovery, get did method: %s", err) + } + + rec, err := deserializeGroup(didMethod, data) if err != nil { return nil, err } @@ -229,6 +238,11 @@ func putRecovery(srvc *native.NativeService, encID, data []byte) (*Group, error) } func getRecovery(srvc *native.NativeService, encID []byte) (*Group, error) { + didMethod, err := getDIDMethod(srvc) + if err != nil || didMethod == nil { + return nil, fmt.Errorf("getRecovery, get did method: %s", err) + } + key := append(encID, FIELD_RECOVERY) item, err := utils.GetStorageItem(srvc, key) if err != nil { @@ -239,7 +253,7 @@ func getRecovery(srvc *native.NativeService, encID []byte) (*Group, error) { if item.StateVersion != _VERSION_1 { return nil, errors.New("unexpected storage version") } - return deserializeGroup(item.Value) + return deserializeGroup(didMethod, item.Value) } // deprecated @@ -267,7 +281,8 @@ func addRecovery(srvc *native.NativeService) ([]byte, error) { return utils.BYTE_FALSE, errors.New("add recovery failed: " + err.Error()) } - key, err := encodeID(arg0) + contract := srvc.ContextRef.CurrentContext().ContractAddress + key, err := encodeID(contract, arg0) if err != nil { return utils.BYTE_FALSE, errors.New("add recovery failed: " + err.Error()) } @@ -313,7 +328,8 @@ func changeRecovery(srvc *native.NativeService) ([]byte, error) { return utils.BYTE_FALSE, errors.New("change recovery failed: argument 2 error") } - key, err := encodeID(arg0) + contract := srvc.ContextRef.CurrentContext().ContractAddress + key, err := encodeID(contract, arg0) if err != nil { return utils.BYTE_FALSE, errors.New("change recovery failed: " + err.Error()) } diff --git a/smartcontract/service/native/did/recovery_test.go b/smartcontract/service/native/did/recovery_test.go index 9a5a71ac..e6f6ff2f 100644 --- a/smartcontract/service/native/did/recovery_test.go +++ b/smartcontract/service/native/did/recovery_test.go @@ -36,6 +36,13 @@ func TestRecovery(t *testing.T) { } func CaseRecovery(t *testing.T, n *native.NativeService) { + initSink := common.NewZeroCopySink(nil) + initSink.WriteVarBytes([]byte("dna")) + n.Input = initSink.Bytes() + if _, err := didInit(n); err != nil { + t.Errorf("failed to init did: %s", err) + } + id0, _ := account.GenerateID() a0 := account.NewAccount("") id1, _ := account.GenerateID() diff --git a/smartcontract/service/native/did/utils.go b/smartcontract/service/native/did/utils.go index a434461a..1e5f6c0c 100644 --- a/smartcontract/service/native/did/utils.go +++ b/smartcontract/service/native/did/utils.go @@ -27,7 +27,6 @@ import ( "github.com/DNAProject/DNA/core/states" "github.com/DNAProject/DNA/core/types" "github.com/DNAProject/DNA/smartcontract/service/native" - common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" "github.com/DNAProject/DNA/smartcontract/service/native/utils" "github.com/ontio/ontology-crypto/keypair" ) @@ -61,21 +60,22 @@ const ( FIELD_ATTR byte = 2 FIELD_RECOVERY byte = 3 FIELD_CONTROLLER byte = 4 + FIELD_DID_METHOD byte = 5 ) -func encodeID(id []byte) ([]byte, error) { +func encodeID(contract common.Address, id []byte) ([]byte, error) { length := len(id) if length == 0 || length > 255 { return nil, errors.New("encode ONT ID error: invalid ID length") } //enc := []byte{byte(length)} - enc := append(common2.DIDContractAddress[:], byte(length)) + enc := append(contract[:], byte(length)) enc = append(enc, id...) return enc, nil } -func decodeID(data []byte) ([]byte, error) { - prefix := len(common2.DIDContractAddress) +func decodeID(contract common.Address, data []byte) ([]byte, error) { + prefix := len(contract) size := len(data) if size < prefix || size != int(data[prefix])+1+prefix { return nil, errors.New("decode ONT ID error: invalid data length") diff --git a/smartcontract/service/native/testsuite/gas_suite_test.go b/smartcontract/service/native/testsuite/gas_suite_test.go index 4f633b34..b3560aeb 100644 --- a/smartcontract/service/native/testsuite/gas_suite_test.go +++ b/smartcontract/service/native/testsuite/gas_suite_test.go @@ -25,6 +25,7 @@ import ( "github.com/DNAProject/DNA/common" "github.com/DNAProject/DNA/smartcontract/service/native" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" "github.com/DNAProject/DNA/smartcontract/service/native/gas" _ "github.com/DNAProject/DNA/smartcontract/service/native/init" "github.com/DNAProject/DNA/smartcontract/service/native/utils" @@ -33,7 +34,7 @@ import ( ) func setBalance(db *storage.CacheDB, addr common.Address, value uint64) { - balanceKey := gas.GenBalanceKey(utils.GasContractAddress, addr) + balanceKey := gas.GenBalanceKey(common2.GasContractAddress, addr) item := utils.GenUInt64StorageItem(value) db.Put(balanceKey, item.ToArray()) } @@ -58,7 +59,7 @@ func makeTransfer(native *native.NativeService, from, to common.Address, value u } func TestTransfer(t *testing.T) { - InvokeNativeContract(t, utils.GasContractAddress, func(native *native.NativeService) ([]byte, error) { + InvokeNativeContract(t, common2.GasContractAddress, func(native *native.NativeService) ([]byte, error) { a := RandomAddress() b := RandomAddress() c := RandomAddress() From 183996e6ed4dedb63b1e2d538bd3d1a6df3387ab Mon Sep 17 00:00:00 2001 From: Edmond-Honglei-Cong Date: Sun, 16 Feb 2020 12:07:04 +0800 Subject: [PATCH 4/8] remove some unused vars --- core/store/ledgerstore/tx_handler.go | 29 +++++++--------------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/core/store/ledgerstore/tx_handler.go b/core/store/ledgerstore/tx_handler.go index 984de852..975ae8bf 100644 --- a/core/store/ledgerstore/tx_handler.go +++ b/core/store/ledgerstore/tx_handler.go @@ -48,14 +48,9 @@ import ( func (self *StateStore) HandleDeployTransaction(store store.LedgerStore, overlay *overlaydb.OverlayDB, gasTable map[string]uint64, cache *storage.CacheDB, tx *types.Transaction, block *types.Block, notify *event.ExecuteNotify) error { deploy := tx.Payload.(*payload.DeployCode) - var ( - notifies []*event.NotifyEventInfo - gasConsumed uint64 - err error - ) if deploy.VmType() == payload.WASMVM_TYPE { - _, err = wasmvm.ReadWasmModule(deploy.GetRawCode(), true) + _, err := wasmvm.ReadWasmModule(deploy.GetRawCode(), true) if err != nil { return err } @@ -73,8 +68,9 @@ func (self *StateStore) HandleDeployTransaction(store store.LedgerStore, overlay } cache.Commit() - notify.Notify = append(notify.Notify, notifies...) - notify.GasConsumed = gasConsumed + notify.Notify = append(notify.Notify, &event.NotifyEventInfo{ + ContractAddress: address, + }) notify.State = event.CONTRACT_STATE_SUCCESS return nil } @@ -92,21 +88,13 @@ func (self *StateStore) HandleInvokeTransaction(store store.LedgerStore, overlay BlockHash: block.Hash(), } - var ( - costGasLimit uint64 - availableGasLimit uint64 - err error - ) - - availableGasLimit = tx.GasLimit - //init smart contract info sc := smartcontract.SmartContract{ Config: config, CacheDB: cache, Store: store, GasTable: gasTable, - Gas: availableGasLimit, + Gas: tx.GasLimit, WasmExecStep: sysconfig.DEFAULT_WASM_MAX_STEPCOUNT, PreExec: false, } @@ -114,16 +102,13 @@ func (self *StateStore) HandleInvokeTransaction(store store.LedgerStore, overlay //start the smart contract executive function engine, _ := sc.NewExecuteEngine(invoke.Code, tx.TxType) - _, err = engine.Invoke() + _, err := engine.Invoke() if err != nil { return err } - costGasLimit = availableGasLimit - sc.Gas - var notifies []*event.NotifyEventInfo notify.Notify = append(notify.Notify, sc.Notifications...) - notify.Notify = append(notify.Notify, notifies...) - notify.GasConsumed = costGasLimit + notify.GasConsumed = tx.GasLimit - sc.Gas notify.State = event.CONTRACT_STATE_SUCCESS sc.CacheDB.Commit() return nil From 3559b2234feda2c4aa21b918694c0159c3ccdac0 Mon Sep 17 00:00:00 2001 From: Edmond-Honglei-Cong Date: Mon, 17 Feb 2020 11:19:33 +0800 Subject: [PATCH 5/8] add did/auth init to genesis block --- core/genesis/genesis.go | 38 ++++++++++--- smartcontract/service/native/auth/auth.go | 7 ++- .../service/native/auth/auth_test.go | 55 +++++++++++++++++++ smartcontract/service/native/auth/utils.go | 5 ++ smartcontract/service/native/did/init.go | 10 +++- .../service/native/did/ontid_test.go | 20 +++++++ 6 files changed, 122 insertions(+), 13 deletions(-) create mode 100644 smartcontract/service/native/auth/auth_test.go diff --git a/core/genesis/genesis.go b/core/genesis/genesis.go index e4f2bf35..12f2f34d 100644 --- a/core/genesis/genesis.go +++ b/core/genesis/genesis.go @@ -99,21 +99,25 @@ func BuildGenesisBlock(defaultBookkeeper []keypair.PublicKey, genesisConfig *con //block gas := newUtilityToken() param := newParamContract() - oid := deployOntIDContract() - auth := deployAuthContract() - govConfigTx := newGovConfigTx() + did := deployBaseDIDContract() + auth := deployBaseAuthContract() + gov := deploygGovContract() + didInit := newDidInit("dna") + authInit := newAuthInit(common2.DIDContractAddress[:]) genesisBlock := &types.Block{ Header: genesisHeader, Transactions: []*types.Transaction{ gas, param, - oid, + did, auth, - govConfigTx, + gov, newUtilityInit(), newParamInit(), govConfig, + didInit, + authInit, }, } genesisBlock.RebuildMerkleRoot() @@ -147,7 +151,7 @@ func newParamContract() *types.Transaction { return tx } -func newGovConfigTx() *types.Transaction { +func deploygGovContract() *types.Transaction { mutable, err := utils.NewDeployTransaction(common2.GovernanceContractAddress[:], "CONFIG", "1.0", "DNA Dev Team", "contact@onchain.com", "Blockchain Network Consensus Config", payload.NEOVM_TYPE) if err != nil { @@ -160,7 +164,7 @@ func newGovConfigTx() *types.Transaction { return tx } -func deployAuthContract() *types.Transaction { +func deployBaseAuthContract() *types.Transaction { mutable, err := utils.NewDeployTransaction(common2.AuthContractAddress[:], "AuthContract", "1.0", "DNA Dev Team", "contact@onchain.com", "Blockchain Network Authorization Contract", payload.NEOVM_TYPE) if err != nil { @@ -173,7 +177,7 @@ func deployAuthContract() *types.Transaction { return tx } -func deployOntIDContract() *types.Transaction { +func deployBaseDIDContract() *types.Transaction { mutable, err := utils.NewDeployTransaction(common2.DIDContractAddress[:], "DID", "1.0", "DNA Dev Team", "contact@onchain.com", "Blockchain Network DID", payload.NEOVM_TYPE) if err != nil { @@ -270,3 +274,21 @@ func newGoverConfigInit(config []byte) *types.Transaction { } return tx } + +func newDidInit(didMethod string) *types.Transaction { + mutable := utils.BuildNativeTransaction(common2.DIDContractAddress, "initDID", []byte(didMethod)) + tx, err := mutable.IntoImmutable() + if err != nil { + panic(fmt.Sprintf("construct did init transaction error: %s", err)) + } + return tx +} + +func newAuthInit(didBaseContract []byte) *types.Transaction { + mutable := utils.BuildNativeTransaction(common2.AuthContractAddress, "initAuth", didBaseContract) + tx, err := mutable.IntoImmutable() + if err != nil { + panic(fmt.Sprintf("construct auth init transaction error: %s", err)) + } + return tx +} diff --git a/smartcontract/service/native/auth/auth.go b/smartcontract/service/native/auth/auth.go index bfadaf13..178f74af 100644 --- a/smartcontract/service/native/auth/auth.go +++ b/smartcontract/service/native/auth/auth.go @@ -693,12 +693,13 @@ func authInit(srvc *native.NativeService) ([]byte, error) { } // check if has initialized - if _, err := getDIDContractAddr(srvc); err == nil { - return utils.BYTE_FALSE, fmt.Errorf("init auth, already inited") + contract := srvc.ContextRef.CurrentContext().ContractAddress + didContractAddrBytes, err := srvc.CacheDB.Get(utils.ConcatKey(contract, PreDIDContractAddr)) + if didContractAddrBytes != nil || err != nil { + return utils.BYTE_FALSE, fmt.Errorf("get did contract: %s", err) } // save did contract addr - contract := srvc.ContextRef.CurrentContext().ContractAddress srvc.CacheDB.Put(utils.ConcatKey(contract, PreDIDContractAddr), states.GenRawStorageItem(didContractAddr)) return utils.BYTE_TRUE, nil } diff --git a/smartcontract/service/native/auth/auth_test.go b/smartcontract/service/native/auth/auth_test.go new file mode 100644 index 00000000..bd47b60c --- /dev/null +++ b/smartcontract/service/native/auth/auth_test.go @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright 2020 DNA Dev team +// +package auth + +import ( + "testing" + + "github.com/DNAProject/DNA/common" + "github.com/DNAProject/DNA/smartcontract/service/native" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" + "github.com/DNAProject/DNA/smartcontract/service/native/testsuite" +) + +func testcase(t *testing.T, f func(t *testing.T, n *native.NativeService)) { + testsuite.InvokeNativeContract(t, common2.AuthContractAddress, + func(n *native.NativeService) ([]byte, error) { + f(t, n) + return nil, nil + }, + ) +} + +func TestAuthInit(t *testing.T) { + testcase(t, CaseAuthInit) +} + +func TestAuthDoubleInitFail(t *testing.T) { + testcase(t, CaseAuthDoubleInitFail) +} + +func CaseAuthInit(t *testing.T, n *native.NativeService) { + initSink := common.NewZeroCopySink(nil) + initSink.WriteVarBytes(common2.DIDContractAddress[:]) + n.Input = initSink.Bytes() + if _, err := authInit(n); err != nil { + t.Errorf("failed to init auth: %s", err) + } +} + +func CaseAuthDoubleInitFail(t *testing.T, n *native.NativeService) { + initSink := common.NewZeroCopySink(nil) + initSink.WriteVarBytes(common2.DIDContractAddress[:]) + n.Input = initSink.Bytes() + if _, err := authInit(n); err != nil { + t.Errorf("failed to init auth: %s", err) + } + + initSink = common.NewZeroCopySink(nil) + initSink.WriteVarBytes(common2.DIDContractAddress[:]) + n.Input = initSink.Bytes() + if _, err := authInit(n); err == nil { + t.Error("failed to double init auth") + } +} diff --git a/smartcontract/service/native/auth/utils.go b/smartcontract/service/native/auth/utils.go index db284534..e46883ef 100644 --- a/smartcontract/service/native/auth/utils.go +++ b/smartcontract/service/native/auth/utils.go @@ -29,6 +29,7 @@ import ( "github.com/DNAProject/DNA/core/states" "github.com/DNAProject/DNA/smartcontract/event" "github.com/DNAProject/DNA/smartcontract/service/native" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" "github.com/DNAProject/DNA/smartcontract/service/native/utils" ) @@ -201,6 +202,10 @@ func serializeAddress(sink *common.ZeroCopySink, addr common.Address) { func getDIDContractAddr(native *native.NativeService) (common.Address, error) { contract := native.ContextRef.CurrentContext().ContractAddress + if contract == common2.AuthContractAddress { + // default auth contract + return common2.DIDContractAddress, nil + } didContractAddrBytes, err := native.CacheDB.Get(utils.ConcatKey(contract, PreDIDContractAddr)) if err != nil { return common.ADDRESS_EMPTY, fmt.Errorf("get did contract: %s", err) diff --git a/smartcontract/service/native/did/init.go b/smartcontract/service/native/did/init.go index 07c8e8db..c5d30541 100644 --- a/smartcontract/service/native/did/init.go +++ b/smartcontract/service/native/did/init.go @@ -76,18 +76,24 @@ func didInit(srvc *native.NativeService) ([]byte, error) { } // check if has initialized - if _, err := getDIDMethod(srvc); err == nil { + contract := srvc.ContextRef.CurrentContext().ContractAddress + didMethodBytes, err := srvc.CacheDB.Get(utils.ConcatKey(contract, []byte{FIELD_DID_METHOD})) + if didMethodBytes != nil || err != nil { return utils.BYTE_FALSE, fmt.Errorf("init did, already inited") } // save did-method - contract := srvc.ContextRef.CurrentContext().ContractAddress srvc.CacheDB.Put(utils.ConcatKey(contract, []byte{FIELD_DID_METHOD}), states.GenRawStorageItem(didMethod)) return utils.BYTE_TRUE, nil } func getDIDMethod(srvc *native.NativeService) ([]byte, error) { contract := srvc.ContextRef.CurrentContext().ContractAddress + if contract == common.DIDContractAddress { + // default did contract + return []byte("dna"), nil + } + didMethodBytes, err := srvc.CacheDB.Get(utils.ConcatKey(contract, []byte{FIELD_DID_METHOD})) if err != nil { return nil, err diff --git a/smartcontract/service/native/did/ontid_test.go b/smartcontract/service/native/did/ontid_test.go index 2e8d7ca7..1bb29821 100644 --- a/smartcontract/service/native/did/ontid_test.go +++ b/smartcontract/service/native/did/ontid_test.go @@ -56,6 +56,10 @@ func TestOwnerSize(t *testing.T) { testcase(t, CaseOwnerSize) } +func TestDoubleInitFail(t *testing.T) { + testcase(t, CaseDoubleInit) +} + // Register id with account acc func regID(n *native.NativeService, id string, a *account.Account) error { // make arguments @@ -363,6 +367,22 @@ func CaseOwnerSize(t *testing.T, n *native.NativeService) { } } +func CaseDoubleInit(t *testing.T, n *native.NativeService) { + initSink := common.NewZeroCopySink(nil) + initSink.WriteVarBytes([]byte("dna")) + n.Input = initSink.Bytes() + if _, err := didInit(n); err != nil { + t.Errorf("failed to init did: %s", err) + } + + initSink = common.NewZeroCopySink(nil) + initSink.WriteVarBytes([]byte("abc")) + n.Input = initSink.Bytes() + if _, err := didInit(n); err == nil { + t.Error("failed to double init did") + } +} + func GetPublicKeyByID(srvc *native.NativeService) ([]byte, error) { args := common.NewZeroCopySource(srvc.Input) // arg0: ID From 309b11ab85e7f149bef239b65f4506b782d26a45 Mon Sep 17 00:00:00 2001 From: Edmond-Honglei-Cong Date: Mon, 17 Feb 2020 13:22:24 +0800 Subject: [PATCH 6/8] update auth init err log --- smartcontract/service/native/auth/auth.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/smartcontract/service/native/auth/auth.go b/smartcontract/service/native/auth/auth.go index 178f74af..689e767d 100644 --- a/smartcontract/service/native/auth/auth.go +++ b/smartcontract/service/native/auth/auth.go @@ -81,7 +81,8 @@ func InitContractAdmin(native *native.NativeService) ([]byte, error) { return nil, fmt.Errorf("[initContractAdmin] get did method: %s", err) } if !account.VerifyID(string(didMethod), string(param.AdminOntID)) { - return nil, fmt.Errorf("[initContractAdmin] invalid param: adminOntID is %x", param.AdminOntID) + return nil, fmt.Errorf("[initContractAdmin] invalid param: didMethod %s, adminOntID is %s", + string(didMethod), string(param.AdminOntID)) } ret, err := initContractAdmin(native, invokeAddr, param.AdminOntID) if err != nil { From ad93cbdefe22aafb3514652b2ea4ce6bf03ffc98 Mon Sep 17 00:00:00 2001 From: Edmond-Honglei-Cong Date: Mon, 17 Feb 2020 13:41:20 +0800 Subject: [PATCH 7/8] gofmt --- smartcontract/service/native/did/group_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/smartcontract/service/native/did/group_test.go b/smartcontract/service/native/did/group_test.go index 4439a0aa..b28e5f4f 100644 --- a/smartcontract/service/native/did/group_test.go +++ b/smartcontract/service/native/did/group_test.go @@ -29,11 +29,11 @@ import ( "github.com/DNAProject/DNA/core/states" "github.com/DNAProject/DNA/core/store/leveldbstore" "github.com/DNAProject/DNA/core/store/overlaydb" - "github.com/DNAProject/DNA/smartcontract/service/native" - "github.com/DNAProject/DNA/smartcontract/storage" - "github.com/DNAProject/DNA/smartcontract/service/native/common" "github.com/DNAProject/DNA/smartcontract" "github.com/DNAProject/DNA/smartcontract/context" + "github.com/DNAProject/DNA/smartcontract/service/native" + "github.com/DNAProject/DNA/smartcontract/service/native/common" + "github.com/DNAProject/DNA/smartcontract/storage" ) func TestDeserializeGroup(t *testing.T) { From 4e533dd2583daa8ffc7339e6e337d3417f561204 Mon Sep 17 00:00:00 2001 From: Edmond-Honglei-Cong Date: Mon, 17 Feb 2020 18:04:33 +0800 Subject: [PATCH 8/8] fix NativeDeployCode Serialization --- core/payload/deploy_code.go | 4 +--- core/payload/deploy_code_test.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/core/payload/deploy_code.go b/core/payload/deploy_code.go index 2052cf41..9673dc9e 100644 --- a/core/payload/deploy_code.go +++ b/core/payload/deploy_code.go @@ -269,9 +269,7 @@ type NativeDeployCode struct { func (ndc *NativeDeployCode) Serialization(sink *common.ZeroCopySink) { sink.WriteAddress(ndc.BaseContractAddress) - if len(ndc.InitParam) > 0 { - sink.WriteVarBytes(ndc.InitParam) - } + sink.WriteVarBytes(ndc.InitParam) } func (ndc *NativeDeployCode) Deserialization(source *common.ZeroCopySource) error { diff --git a/core/payload/deploy_code_test.go b/core/payload/deploy_code_test.go index 40559e9a..ad003f91 100644 --- a/core/payload/deploy_code_test.go +++ b/core/payload/deploy_code_test.go @@ -21,9 +21,11 @@ package payload import ( + "bytes" "testing" "github.com/DNAProject/DNA/common" + common2 "github.com/DNAProject/DNA/smartcontract/service/native/common" "github.com/stretchr/testify/assert" ) @@ -44,3 +46,30 @@ func TestDeployCode_Serialize(t *testing.T) { err = deploy2.Deserialization(source) assert.NotNil(t, err) } + +func TestNativeDeployCode_Serialization(t *testing.T) { + ndc := &NativeDeployCode{ + BaseContractAddress: common2.GasContractAddress, + InitParam: []byte("abcd"), + } + + sink := common.NewZeroCopySink(nil) + ndc.Serialization(sink) + + ndc2 := &NativeDeployCode{} + if err := ndc2.Deserialization(common.NewZeroCopySource(sink.Bytes())); err != nil { + t.Fatalf("deserialize NativeDeployCode failed: %s", err) + } + if ndc.BaseContractAddress != ndc2.BaseContractAddress || + bytes.Compare(ndc.InitParam, ndc2.InitParam) != 0 { + t.Fatalf("deserialize NativeDeployCode unmatched") + } + + ndc3 := &NativeDeployCode{} + if err := ndc3.Deserialization(common.NewZeroCopySource(common2.GasContractAddress[:])); err != nil { + t.Fatalf("deserialize NativeDeployCode from contract addr failed: %s", err) + } + if ndc3.BaseContractAddress != common2.GasContractAddress || ndc3.InitParam != nil { + t.Fatalf("deserialize NativeDeployCode from contract addr not matched") + } +}