@ -319,9 +319,8 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
return ret , contract . Gas , err
}
// 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 ) {
// create creates a new contract using code as deployment code.
func ( evm * EVM ) create ( caller ContractRef , code [ ] byte , gas uint64 , value * big . Int , address common . Address ) ( [ ] byte , common . Address , uint64 , error ) {
// Depth check execution. Fail if we're trying to execute above the
// limit.
if evm . depth > int ( params . CallCreateDepth ) {
@ -330,39 +329,38 @@ func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.I
if ! evm . CanTransfer ( evm . StateDB , caller . Address ( ) , value ) {
return nil , common . Address { } , gas , ErrInsufficientBalance
}
// Ensure there's no existing contract already at the designated address
nonce := evm . StateDB . GetNonce ( caller . Address ( ) )
evm . StateDB . SetNonce ( caller . Address ( ) , nonce + 1 )
contractAddr = crypto . CreateAddress ( caller . Address ( ) , nonce )
contractHash := evm . StateDB . GetCodeHash ( contr actA ddr)
if evm . StateDB . GetNonce ( contr actA ddr) != 0 || ( contractHash != ( common . Hash { } ) && contractHash != emptyCodeHash ) {
// Ensure there's no existing contract already at the designated address
contractHash := evm . StateDB . GetCodeHash ( address )
if evm . StateDB . GetNonce ( address ) != 0 || ( contractHash != ( common . Hash { } ) && contractHash != emptyCodeHash ) {
return nil , common . Address { } , 0 , ErrContractAddressCollision
}
// Create a new account on the state
snapshot := evm . StateDB . Snapshot ( )
evm . StateDB . CreateAccount ( contr actA ddr)
evm . StateDB . CreateAccount ( address )
if evm . ChainConfig ( ) . IsEIP158 ( evm . BlockNumber ) {
evm . StateDB . SetNonce ( contr actA ddr, 1 )
evm . StateDB . SetNonce ( address , 1 )
}
evm . Transfer ( evm . StateDB , caller . Address ( ) , contr actA ddr, value )
evm . Transfer ( evm . StateDB , caller . Address ( ) , address , value )
// 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 , AccountRef ( contr actA ddr) , value , gas )
contract . SetCallCode ( & contr actA ddr, crypto . Keccak256Hash ( code ) , code )
contract := NewContract ( caller , AccountRef ( address ) , value , gas )
contract . SetCallCode ( & address , crypto . Keccak256Hash ( code ) , code )
if evm . vmConfig . NoRecursion && evm . depth > 0 {
return nil , contr actA ddr, gas , nil
return nil , address , gas , nil
}
if evm . vmConfig . Debug && evm . depth == 0 {
evm . vmConfig . Tracer . CaptureStart ( caller . Address ( ) , contr actA ddr, true , code , gas , value )
evm . vmConfig . Tracer . CaptureStart ( caller . Address ( ) , address , true , code , gas , value )
}
start := time . Now ( )
ret , err = run ( evm , contract , nil )
ret , err : = run ( evm , contract , nil )
// check whether the max code size has been exceeded
maxCodeSizeExceeded := evm . ChainConfig ( ) . IsEIP158 ( evm . BlockNumber ) && len ( ret ) > params . MaxCodeSize
@ -373,7 +371,7 @@ func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.I
if err == nil && ! maxCodeSizeExceeded {
createDataGas := uint64 ( len ( ret ) ) * params . CreateDataGas
if contract . UseGas ( createDataGas ) {
evm . StateDB . SetCode ( contr actA ddr, ret )
evm . StateDB . SetCode ( address , ret )
} else {
err = ErrCodeStoreOutOfGas
}
@ -395,7 +393,23 @@ func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.I
if evm . vmConfig . Debug && evm . depth == 0 {
evm . vmConfig . Tracer . CaptureEnd ( ret , gas - contract . Gas , time . Since ( start ) , err )
}
return ret , contractAddr , contract . Gas , err
return ret , address , contract . Gas , err
}
// 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 ( ) ) )
return evm . create ( caller , code , gas , value , contractAddr )
}
// Create2 creates a new contract using code as deployment code.
//
// The different between Create2 with Create is Create2 uses sha3(msg.sender ++ salt ++ 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 ContractRef , code [ ] byte , gas uint64 , endowment * big . Int , salt * big . Int ) ( ret [ ] byte , contractAddr common . Address , leftOverGas uint64 , err error ) {
contractAddr = crypto . CreateAddress2 ( caller . Address ( ) , common . BigToHash ( salt ) , code )
return evm . create ( caller , code , gas , endowment , contractAddr )
}
// ChainConfig returns the environment's chain configuration