Add state mananger create function

This commit is contained in:
Mason Fischer 2020-05-13 16:12:09 -04:00
parent 6f11ce9a49
commit 073b488c74
4 changed files with 50 additions and 186 deletions

View file

@ -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()))

View file

@ -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
}

View file

@ -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"

View file

@ -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)