Skip to content

Commit

Permalink
Bring EIP-7610
Browse files Browse the repository at this point in the history
  • Loading branch information
hyeonLewis committed Jan 2, 2025
1 parent 59b9689 commit 0d57b76
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 2 deletions.
7 changes: 7 additions & 0 deletions blockchain/state/state_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,13 @@ func (s *stateObject) Nonce() uint64 {
return s.account.GetNonce()
}

func (s *stateObject) Root() common.Hash {
if acc := account.GetProgramAccount(s.account); acc != nil {
return acc.GetStorageRoot().Unextend()
}
return common.Hash{}
}

// Never called, but must be present to allow stateObject to be used
// as a vm.Account interface that also satisfies the vm.ContractRef
// interface. Interfaces are awesome.
Expand Down
8 changes: 8 additions & 0 deletions blockchain/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,14 @@ func (s *StateDB) GetCode(addr common.Address) []byte {
return nil
}

func (s *StateDB) GetStorageRoot(addr common.Address) common.Hash {
stateObject := s.getStateObject(addr)
if stateObject != nil {
return stateObject.Root()
}
return common.Hash{}
}

func (s *StateDB) GetAccount(addr common.Address) account.Account {
stateObject := s.getStateObject(addr)
if stateObject != nil {
Expand Down
11 changes: 9 additions & 2 deletions blockchain/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -511,16 +511,23 @@ func (evm *EVM) create(caller types.ContractRef, codeAndHash *codeAndHash, gas u
evm.StateDB.AddAddressToAccessList(address)
}

// Ensure there's no existing contract already at the designated address
// Ensure there's no existing contract already at the designated address.
// Account is regarded as existent if any of these three conditions is met:
// - the nonce is nonzero
// - the code is non-empty
// - the storage is non-empty
contractHash := evm.StateDB.ResolveCodeHash(address)
storageRoot := evm.StateDB.GetStorageRoot(address)

// The early Kaia design tried to support the account creation with a user selected address,
// so the account overwriting was restricted.
// Because the feature was postponed for a long time and the restriction can be abused to prevent SCA creation,
// Kaia enables SCA overwriting over EOA like Ethereum after Shanghai compatible hardfork.
// NOTE: The following code should be re-considered when Kaia enables TxTypeAccountCreation
if evm.chainRules.IsShanghai {
if evm.StateDB.GetNonce(address) != 0 || (contractHash != (common.Hash{}) && contractHash != emptyCodeHash) {
if evm.StateDB.GetNonce(address) != 0 ||
(contractHash != (common.Hash{}) && contractHash != types.EmptyCodeHash) || // non-empty code
(storageRoot != (common.Hash{}) && storageRoot != types.EmptyRootHash) { // non-empty storage
return nil, common.Address{}, 0, ErrContractAddressCollision
}
} else if evm.StateDB.Exist(address) {
Expand Down
1 change: 1 addition & 0 deletions blockchain/vm/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ type StateDB interface {
SetCodeToEOA(common.Address, []byte, params.Rules) error
GetCodeSize(common.Address) int
GetVmVersion(common.Address) (params.VmVersion, bool)
GetStorageRoot(common.Address) common.Hash

ResolveCodeHash(common.Address) common.Hash
ResolveCode(common.Address) []byte
Expand Down
14 changes: 14 additions & 0 deletions blockchain/vm/mocks/statedb_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 0d57b76

Please sign in to comment.