From 073b488c74d43b6034ed998a40baed5335f45798 Mon Sep 17 00:00:00 2001 From: Mason Fischer Date: Wed, 13 May 2020 16:12:09 -0400 Subject: [PATCH] Add state mananger create function --- core/vm/evm.go | 5 + core/vm/state_manager.go | 16 ++- tests/StateManagerABI.json | 198 +++---------------------------------- tests/ovm_test.go | 17 ++++ 4 files changed, 50 insertions(+), 186 deletions(-) diff --git a/core/vm/evm.go b/core/vm/evm.go index f541b9ebe3..39352a8f0b 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -457,6 +457,11 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, } +// TODO Pass in actual contract ref +func (evm *EVM) OvmCreate(caller ContractRef, contractAddr common.Address, code []byte, gas uint64, value *big.Int) (ret []byte, retContractAddr common.Address, leftOverGas uint64, err error) { + return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr) +} + // Create creates a new contract using code as deployment code. func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { contractAddr = crypto.CreateAddress(caller.Address(), evm.StateDB.GetNonce(caller.Address())) diff --git a/core/vm/state_manager.go b/core/vm/state_manager.go index 86854ff3ad..c81fceb0ff 100644 --- a/core/vm/state_manager.go +++ b/core/vm/state_manager.go @@ -1,6 +1,7 @@ package vm import ( + "encoding/binary" "os" "github.com/ethereum/go-ethereum/common" @@ -15,8 +16,9 @@ type stateManagerFunction func(*EVM, *Contract, []byte) ([]byte, error) type methodId [4]byte var funcs = map[string]stateManagerFunction{ - "getStorage(address,bytes32)": getStorage, - "setStorage(address,bytes32,bytes32)": setStorage, + "getStorage(address,bytes32)": getStorage, + "setStorage(address,bytes32,bytes32)": setStorage, + "deployContract(address,bytes,bool,address)": deployContract, } var methodIds map[[4]byte]stateManagerFunction var executionMangerBytecode []byte @@ -55,3 +57,13 @@ func getStorage(evm *EVM, contract *Contract, input []byte) (ret []byte, err err val := evm.StateDB.GetState(address, key) return val.Bytes(), nil } + +func deployContract(evm *EVM, contract *Contract, input []byte) (ret []byte, err error) { + address := common.BytesToAddress(input[4:36]) + callerAddress := common.BytesToAddress(input[100:132]) + initCodeLength := binary.BigEndian.Uint32(input[160:164]) + initCode := input[164 : 164+initCodeLength] + callerContractRef := &Contract{self: AccountRef(callerAddress)} + returnVal, _, _, _ := evm.OvmCreate(callerContractRef, address, initCode, 0, bigZero) + return returnVal, nil +} diff --git a/tests/StateManagerABI.json b/tests/StateManagerABI.json index 02d159f9db..841c19beca 100644 --- a/tests/StateManagerABI.json +++ b/tests/StateManagerABI.json @@ -20,207 +20,37 @@ "type": "function" }, { - "constant": true, + "constant": false, "inputs": [ { "internalType": "address", - "name": "_ovmContractAddress", + "name": "_newOvmContractAddress", "type": "address" - } - ], - "name": "getCodeContractAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "internalType": "address", - "name": "_codeContractAddress", - "type": "address" - } - ], - "name": "getCodeContractBytecode", - "outputs": [ + }, { "internalType": "bytes", - "name": "codeContractBytecode", + "name": "_ovmContractInitcode", "type": "bytes" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ + }, { - "internalType": "address", - "name": "_codeContractAddress", + "internalType": "bool", + "name": "overridePurityChecker", + "type": "bool" + }, + { + "internalType": "contract PurityChecker", + "name": "purityChecker", "type": "address" } ], - "name": "getCodeContractHash", + "name": "deployContract", "outputs": [ - { - "internalType": "bytes32", - "name": "_codeContractHash", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ { "internalType": "address", - "name": "_ovmContractAddress", + "name": "codeContractAddress", "type": "address" } ], - "name": "getOvmContractNonce", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "internalType": "address", - "name": "_ovmContractAddress", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "_slot", - "type": "bytes32" - } - ], - "name": "getStorage", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "address", - "name": "_ovmContractAddress", - "type": "address" - } - ], - "name": "incrementOvmContractNonce", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "address", - "name": "_ovmContractAddress", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_value", - "type": "uint256" - } - ], - "name": "setOvmContractNonce", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "address", - "name": "_ovmContractAddress", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "_slot", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "_value", - "type": "bytes32" - } - ], - "name": "setStorage", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - } -], -"evm": { - "bytecode": { - "linkReferences": {}, - "object": "", - "opcodes": "", - "sourceMap": "" - }, - "deployedBytecode": { - "linkReferences": {}, - "object": "", - "opcodes": "", - "sourceMap": "" - } -}, -"interface": [ - { - "constant": false, - "inputs": [ - { - "internalType": "address", - "name": "_ovmContractAddress", - "type": "address" - }, - { - "internalType": "address", - "name": "_codeContractAddress", - "type": "address" - } - ], - "name": "associateCodeContract", - "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" diff --git a/tests/ovm_test.go b/tests/ovm_test.go index 19ff866b9c..d38f3ddbb4 100644 --- a/tests/ovm_test.go +++ b/tests/ovm_test.go @@ -2,6 +2,7 @@ package tests import ( "bytes" + "encoding/hex" "io/ioutil" "math/big" "strings" @@ -54,6 +55,22 @@ func TestSloadAndStore(t *testing.T) { } } +func TestCreate(t *testing.T) { + initCode, _ := hex.DecodeString("6080604052348015600f57600080fd5b5060b28061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c80639b0b0fda14602d575b600080fd5b606060048036036040811015604157600080fd5b8101908080359060200190929190803590602001909291905050506062565b005b8060008084815260200190815260200160002081905550505056fea265627a7a7231582053ac32a8b70d1cf87fb4ebf5a538ea9d9e773351e6c8afbc4bf6a6c273187f4a64736f6c63430005110032") + rawStateManagerAbi, _ := ioutil.ReadFile("./StateManagerABI.json") + stateManagerAbi, _ := abi.JSON(strings.NewReader(string(rawStateManagerAbi))) + state := newState() + + address := common.HexToAddress("9999999999999999999999999999999999999999") + callerAddress := common.HexToAddress("42") + + deployContractCalldata, _ := stateManagerAbi.Pack("deployContract", address, initCode, true, callerAddress) + createdContractAddr, _ := call(t, state, vm.StateManagerAddress, deployContractCalldata) + if !bytes.Equal(createdContractAddr, []byte{}) { + t.Errorf("Expected %020x; got %020x", createdContractAddr, []byte{}) + } +} + func newState() *state.StateDB { db := state.NewDatabase(rawdb.NewMemoryDatabase()) state, _ := state.New(common.Hash{}, db, nil)