|
|
|
@ -404,22 +404,10 @@ func (evm *EVM) StaticCall(caller common.Address, addr common.Address, input []b |
|
|
|
|
return ret, gas, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type codeAndHash struct { |
|
|
|
|
code []byte |
|
|
|
|
hash common.Hash |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (c *codeAndHash) Hash() common.Hash { |
|
|
|
|
if c.hash == (common.Hash{}) { |
|
|
|
|
c.hash = crypto.Keccak256Hash(c.code) |
|
|
|
|
} |
|
|
|
|
return c.hash |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// create creates a new contract using code as deployment code.
|
|
|
|
|
func (evm *EVM) create(caller common.Address, codeAndHash *codeAndHash, gas uint64, value *uint256.Int, address common.Address, typ OpCode) (ret []byte, createAddress common.Address, leftOverGas uint64, err error) { |
|
|
|
|
func (evm *EVM) create(caller common.Address, code []byte, gas uint64, value *uint256.Int, address common.Address, typ OpCode) (ret []byte, createAddress common.Address, leftOverGas uint64, err error) { |
|
|
|
|
if evm.Config.Tracer != nil { |
|
|
|
|
evm.captureBegin(evm.depth, typ, caller, address, codeAndHash.code, gas, value.ToBig()) |
|
|
|
|
evm.captureBegin(evm.depth, typ, caller, address, code, gas, value.ToBig()) |
|
|
|
|
defer func(startGas uint64) { |
|
|
|
|
evm.captureEnd(evm.depth, startGas, leftOverGas, ret, err) |
|
|
|
|
}(gas) |
|
|
|
@ -502,10 +490,13 @@ func (evm *EVM) create(caller common.Address, codeAndHash *codeAndHash, gas uint |
|
|
|
|
// Initialise a new contract and set the code that is to be used by the EVM.
|
|
|
|
|
// The contract is a scoped environment for this execution context only.
|
|
|
|
|
contract := NewContract(caller, address, value, gas, evm.jumpDests) |
|
|
|
|
contract.SetCodeOptionalHash(codeAndHash) |
|
|
|
|
|
|
|
|
|
// Explicitly set the code to a null hash to prevent caching of jump analysis
|
|
|
|
|
// for the initialization code.
|
|
|
|
|
contract.SetCallCode(common.Hash{}, code) |
|
|
|
|
contract.IsDeployment = true |
|
|
|
|
|
|
|
|
|
ret, err = evm.initNewContract(contract, address, value) |
|
|
|
|
ret, err = evm.initNewContract(contract, address) |
|
|
|
|
if err != nil && (evm.chainRules.IsHomestead || err != ErrCodeStoreOutOfGas) { |
|
|
|
|
evm.StateDB.RevertToSnapshot(snapshot) |
|
|
|
|
if err != ErrExecutionReverted { |
|
|
|
@ -517,7 +508,7 @@ func (evm *EVM) create(caller common.Address, codeAndHash *codeAndHash, gas uint |
|
|
|
|
|
|
|
|
|
// initNewContract runs a new contract's creation code, performs checks on the
|
|
|
|
|
// resulting code that is to be deployed, and consumes necessary gas.
|
|
|
|
|
func (evm *EVM) initNewContract(contract *Contract, address common.Address, value *uint256.Int) ([]byte, error) { |
|
|
|
|
func (evm *EVM) initNewContract(contract *Contract, address common.Address) ([]byte, error) { |
|
|
|
|
ret, err := evm.interpreter.Run(contract, nil, false) |
|
|
|
|
if err != nil { |
|
|
|
|
return ret, err |
|
|
|
@ -551,7 +542,7 @@ func (evm *EVM) initNewContract(contract *Contract, address common.Address, valu |
|
|
|
|
// Create creates a new contract using code as deployment code.
|
|
|
|
|
func (evm *EVM) Create(caller common.Address, code []byte, gas uint64, value *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { |
|
|
|
|
contractAddr = crypto.CreateAddress(caller, evm.StateDB.GetNonce(caller)) |
|
|
|
|
return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr, CREATE) |
|
|
|
|
return evm.create(caller, code, gas, value, contractAddr, CREATE) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Create2 creates a new contract using code as deployment code.
|
|
|
|
@ -559,9 +550,8 @@ func (evm *EVM) Create(caller common.Address, code []byte, gas uint64, value *ui |
|
|
|
|
// The different between Create2 with Create is Create2 uses keccak256(0xff ++ msg.sender ++ salt ++ keccak256(init_code))[12:]
|
|
|
|
|
// instead of the usual sender-and-nonce-hash as the address where the contract is initialized at.
|
|
|
|
|
func (evm *EVM) Create2(caller common.Address, code []byte, gas uint64, endowment *uint256.Int, salt *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { |
|
|
|
|
codeAndHash := &codeAndHash{code: code} |
|
|
|
|
contractAddr = crypto.CreateAddress2(caller, salt.Bytes32(), codeAndHash.Hash().Bytes()) |
|
|
|
|
return evm.create(caller, codeAndHash, gas, endowment, contractAddr, CREATE2) |
|
|
|
|
contractAddr = crypto.CreateAddress2(caller, salt.Bytes32(), crypto.Keccak256(code)) |
|
|
|
|
return evm.create(caller, code, gas, endowment, contractAddr, CREATE2) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// resolveCode returns the code associated with the provided account. After
|
|
|
|
|