aboutsummaryrefslogtreecommitdiffstats
path: root/core/vm/evm.go
diff options
context:
space:
mode:
Diffstat (limited to 'core/vm/evm.go')
-rw-r--r--core/vm/evm.go14
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)