diff options
Diffstat (limited to 'core/vm/evm.go')
-rw-r--r-- | core/vm/evm.go | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/core/vm/evm.go b/core/vm/evm.go index 34933a1dc..caf8b4507 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -25,6 +25,10 @@ import ( "github.com/ethereum/go-ethereum/params" ) +// emptyCodeHash is used by create to ensure deployment is disallowed to already +// deployed contract addresses (relevant after the account abstraction). +var emptyCodeHash = crypto.Keccak256Hash(nil) + type ( CanTransferFunc func(StateDB, common.Address, *big.Int) bool TransferFunc func(StateDB, common.Address, common.Address, *big.Int) @@ -307,13 +311,17 @@ 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 } - - // Create a new account on the state + // Ensure there's no existing contract already at the designated address nonce := evm.StateDB.GetNonce(caller.Address()) evm.StateDB.SetNonce(caller.Address(), nonce+1) - snapshot := evm.StateDB.Snapshot() contractAddr = crypto.CreateAddress(caller.Address(), nonce) + contractHash := evm.StateDB.GetCodeHash(contractAddr) + if evm.StateDB.GetNonce(contractAddr) != 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(contractAddr) if evm.ChainConfig().IsEIP158(evm.BlockNumber) { evm.StateDB.SetNonce(contractAddr, 1) |