mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 02:12:23 +00:00
implemented eip-7708
This commit is contained in:
parent
69ee9a4e2c
commit
efd8a42a74
4 changed files with 56 additions and 10 deletions
|
|
@ -205,7 +205,16 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
||||||
}
|
}
|
||||||
evm.StateDB.CreateAccount(addr)
|
evm.StateDB.CreateAccount(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
evm.Context.Transfer(evm.StateDB, caller.Address(), addr, value)
|
evm.Context.Transfer(evm.StateDB, caller.Address(), addr, value)
|
||||||
|
if shouldLogNonZeroNativeTransfers := value.Sign() > 0 && evm.chainRules.IsEIP7708; shouldLogNonZeroNativeTransfers {
|
||||||
|
evm.StateDB.AddLog(&types.Log{
|
||||||
|
Address: params.LogNativeTransferContractAddress,
|
||||||
|
Topics: []common.Hash{params.LogNativeTransferTopicMagic, common.BytesToHash(caller.Address().Bytes()), common.BytesToHash(addr.Bytes())},
|
||||||
|
Data: value.Bytes(),
|
||||||
|
BlockNumber: evm.Context.BlockNumber.Uint64(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if isPrecompile {
|
if isPrecompile {
|
||||||
ret, gas, err = RunPrecompiledContract(p, input, gas, evm.Config.Tracer)
|
ret, gas, err = RunPrecompiledContract(p, input, gas, evm.Config.Tracer)
|
||||||
|
|
@ -213,15 +222,16 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
||||||
// Initialise a new contract and set the code that is to be used by the EVM.
|
// 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.
|
// The contract is a scoped environment for this execution context only.
|
||||||
code := evm.StateDB.GetCode(addr)
|
code := evm.StateDB.GetCode(addr)
|
||||||
|
// Call is to contract if "there is contract code", if not it's just
|
||||||
|
// transfer to EOA (Externally owned account)
|
||||||
|
if isToEOA := len(code) == 0; isToEOA {
|
||||||
|
ret, err = nil, nil // gas is unchanged
|
||||||
|
} else {
|
||||||
if witness := evm.StateDB.Witness(); witness != nil {
|
if witness := evm.StateDB.Witness(); witness != nil {
|
||||||
witness.AddCode(code)
|
witness.AddCode(code)
|
||||||
}
|
}
|
||||||
if len(code) == 0 {
|
|
||||||
ret, err = nil, nil // gas is unchanged
|
|
||||||
} else {
|
|
||||||
addrCopy := addr
|
addrCopy := addr
|
||||||
// If the account has no code, we can abort here
|
|
||||||
// The depth-check is already done, and precompiles handled above
|
|
||||||
contract := NewContract(caller, AccountRef(addrCopy), value, gas)
|
contract := NewContract(caller, AccountRef(addrCopy), value, gas)
|
||||||
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), code)
|
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), code)
|
||||||
ret, err = evm.interpreter.Run(contract, input, false)
|
ret, err = evm.interpreter.Run(contract, input, false)
|
||||||
|
|
@ -273,7 +283,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
|
||||||
if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) {
|
if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) {
|
||||||
return nil, gas, ErrInsufficientBalance
|
return nil, gas, ErrInsufficientBalance
|
||||||
}
|
}
|
||||||
var snapshot = evm.StateDB.Snapshot()
|
snapshot := evm.StateDB.Snapshot()
|
||||||
|
|
||||||
// It is allowed to call precompiles, even via delegatecall
|
// It is allowed to call precompiles, even via delegatecall
|
||||||
if p, isPrecompile := evm.precompile(addr); isPrecompile {
|
if p, isPrecompile := evm.precompile(addr); isPrecompile {
|
||||||
|
|
@ -324,7 +334,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
|
||||||
if evm.depth > int(params.CallCreateDepth) {
|
if evm.depth > int(params.CallCreateDepth) {
|
||||||
return nil, gas, ErrDepth
|
return nil, gas, ErrDepth
|
||||||
}
|
}
|
||||||
var snapshot = evm.StateDB.Snapshot()
|
snapshot := evm.StateDB.Snapshot()
|
||||||
|
|
||||||
// It is allowed to call precompiles, even via delegatecall
|
// It is allowed to call precompiles, even via delegatecall
|
||||||
if p, isPrecompile := evm.precompile(addr); isPrecompile {
|
if p, isPrecompile := evm.precompile(addr); isPrecompile {
|
||||||
|
|
@ -373,7 +383,7 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
|
||||||
// after all empty accounts were deleted, so this is not required. However, if we omit this,
|
// after all empty accounts were deleted, so this is not required. However, if we omit this,
|
||||||
// then certain tests start failing; stRevertTest/RevertPrecompiledTouchExactOOG.json.
|
// then certain tests start failing; stRevertTest/RevertPrecompiledTouchExactOOG.json.
|
||||||
// We could change this, but for now it's left for legacy reasons
|
// We could change this, but for now it's left for legacy reasons
|
||||||
var snapshot = evm.StateDB.Snapshot()
|
snapshot := evm.StateDB.Snapshot()
|
||||||
|
|
||||||
// We do an AddBalance of zero here, just in order to trigger a touch.
|
// We do an AddBalance of zero here, just in order to trigger a touch.
|
||||||
// This doesn't matter on Mainnet, where all empties are gone at the time of Byzantium,
|
// This doesn't matter on Mainnet, where all empties are gone at the time of Byzantium,
|
||||||
|
|
|
||||||
|
|
@ -328,7 +328,7 @@ func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeConte
|
||||||
return nil, ErrReturnDataOutOfBounds
|
return nil, ErrReturnDataOutOfBounds
|
||||||
}
|
}
|
||||||
// we can reuse dataOffset now (aliasing it for clarity)
|
// we can reuse dataOffset now (aliasing it for clarity)
|
||||||
var end = dataOffset
|
end := dataOffset
|
||||||
end.Add(&dataOffset, &length)
|
end.Add(&dataOffset, &length)
|
||||||
end64, overflow := end.Uint64WithOverflow()
|
end64, overflow := end.Uint64WithOverflow()
|
||||||
if overflow || uint64(len(interpreter.returnData)) < end64 {
|
if overflow || uint64(len(interpreter.returnData)) < end64 {
|
||||||
|
|
@ -899,6 +899,16 @@ func opSelfdestruct(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext
|
||||||
beneficiary := scope.Stack.pop()
|
beneficiary := scope.Stack.pop()
|
||||||
balance := interpreter.evm.StateDB.GetBalance(scope.Contract.Address())
|
balance := interpreter.evm.StateDB.GetBalance(scope.Contract.Address())
|
||||||
interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance, tracing.BalanceIncreaseSelfdestruct)
|
interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance, tracing.BalanceIncreaseSelfdestruct)
|
||||||
|
|
||||||
|
if shouldLogNonZeroNativeTransfers := balance.Sign() > 0 && interpreter.evm.chainRules.IsEIP7708; shouldLogNonZeroNativeTransfers {
|
||||||
|
interpreter.evm.StateDB.AddLog(&types.Log{
|
||||||
|
Address: params.LogNativeTransferContractAddress,
|
||||||
|
Topics: []common.Hash{params.LogNativeTransferTopicMagic, common.BytesToHash(scope.Contract.Address().Bytes()), common.BytesToHash(scope.Caller().Bytes())},
|
||||||
|
Data: balance.Bytes(),
|
||||||
|
BlockNumber: interpreter.evm.Context.BlockNumber.Uint64(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
interpreter.evm.StateDB.SelfDestruct(scope.Contract.Address())
|
interpreter.evm.StateDB.SelfDestruct(scope.Contract.Address())
|
||||||
if tracer := interpreter.evm.Config.Tracer; tracer != nil {
|
if tracer := interpreter.evm.Config.Tracer; tracer != nil {
|
||||||
if tracer.OnEnter != nil {
|
if tracer.OnEnter != nil {
|
||||||
|
|
@ -919,6 +929,16 @@ func opSelfdestruct6780(pc *uint64, interpreter *EVMInterpreter, scope *ScopeCon
|
||||||
balance := interpreter.evm.StateDB.GetBalance(scope.Contract.Address())
|
balance := interpreter.evm.StateDB.GetBalance(scope.Contract.Address())
|
||||||
interpreter.evm.StateDB.SubBalance(scope.Contract.Address(), balance, tracing.BalanceDecreaseSelfdestruct)
|
interpreter.evm.StateDB.SubBalance(scope.Contract.Address(), balance, tracing.BalanceDecreaseSelfdestruct)
|
||||||
interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance, tracing.BalanceIncreaseSelfdestruct)
|
interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance, tracing.BalanceIncreaseSelfdestruct)
|
||||||
|
|
||||||
|
if shouldLogNonZeroNativeTransfers := balance.Sign() > 0 && interpreter.evm.chainRules.IsEIP7708; shouldLogNonZeroNativeTransfers {
|
||||||
|
interpreter.evm.StateDB.AddLog(&types.Log{
|
||||||
|
Address: params.LogNativeTransferContractAddress,
|
||||||
|
Topics: []common.Hash{params.LogNativeTransferTopicMagic, common.BytesToHash(scope.Contract.Address().Bytes()), common.BytesToHash(scope.Caller().Bytes())},
|
||||||
|
Data: balance.Bytes(),
|
||||||
|
BlockNumber: interpreter.evm.Context.BlockNumber.Uint64(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
interpreter.evm.StateDB.Selfdestruct6780(scope.Contract.Address())
|
interpreter.evm.StateDB.Selfdestruct6780(scope.Contract.Address())
|
||||||
if tracer := interpreter.evm.Config.Tracer; tracer != nil {
|
if tracer := interpreter.evm.Config.Tracer; tracer != nil {
|
||||||
if tracer.OnEnter != nil {
|
if tracer.OnEnter != nil {
|
||||||
|
|
|
||||||
|
|
@ -561,6 +561,12 @@ func (c *ChainConfig) IsEIP4762(num *big.Int, time uint64) bool {
|
||||||
return c.IsVerkle(num, time)
|
return c.IsVerkle(num, time)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsEIP7708 returns whether [EIP-7708](https://eips.ethereum.org/EIPS/eip-7708) has been activated at given block.
|
||||||
|
func (c *ChainConfig) IsEIP7708(num *big.Int, time uint64) bool {
|
||||||
|
// TODO:Decide how to activate this EIP
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// CheckCompatible checks whether scheduled fork transitions have been imported
|
// CheckCompatible checks whether scheduled fork transitions have been imported
|
||||||
// with a mismatching chain configuration.
|
// with a mismatching chain configuration.
|
||||||
func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64, time uint64) *ConfigCompatError {
|
func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64, time uint64) *ConfigCompatError {
|
||||||
|
|
@ -894,6 +900,7 @@ type Rules struct {
|
||||||
IsBerlin, IsLondon bool
|
IsBerlin, IsLondon bool
|
||||||
IsMerge, IsShanghai, IsCancun, IsPrague bool
|
IsMerge, IsShanghai, IsCancun, IsPrague bool
|
||||||
IsVerkle bool
|
IsVerkle bool
|
||||||
|
IsEIP7708 bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rules ensures c's ChainID is not nil.
|
// Rules ensures c's ChainID is not nil.
|
||||||
|
|
@ -924,5 +931,6 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules
|
||||||
IsPrague: isMerge && c.IsPrague(num, timestamp),
|
IsPrague: isMerge && c.IsPrague(num, timestamp),
|
||||||
IsVerkle: isVerkle,
|
IsVerkle: isVerkle,
|
||||||
IsEIP4762: isVerkle,
|
IsEIP4762: isVerkle,
|
||||||
|
IsEIP7708: c.IsEIP7708(num, timestamp),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -200,3 +201,10 @@ var (
|
||||||
// HistoryStorageCode is the code with getters for historical block hashes.
|
// HistoryStorageCode is the code with getters for historical block hashes.
|
||||||
HistoryStorageCode = common.FromHex("3373fffffffffffffffffffffffffffffffffffffffe1460575767ffffffffffffffff5f3511605357600143035f3511604b575f35612000014311604b57611fff5f3516545f5260205ff35b5f5f5260205ff35b5f5ffd5b5f35611fff60014303165500")
|
HistoryStorageCode = common.FromHex("3373fffffffffffffffffffffffffffffffffffffffe1460575767ffffffffffffffff5f3511605357600143035f3511604b575f35612000014311604b57611fff5f3516545f5260205ff35b5f5f5260205ff35b5f5ffd5b5f35611fff60014303165500")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// [EIP-7708](https://eips.ethereum.org/EIPS/eip-7708) specific params
|
||||||
|
var (
|
||||||
|
LogNativeTransferTopicMagic = common.BytesToHash(crypto.Keccak256([]byte("0000000000000000000000000000000000000000000000000000000000000000")))
|
||||||
|
// Proposed here: https://ethereum-magicians.org/t/eip-7708-eth-transfers-emit-a-log/20034/25
|
||||||
|
LogNativeTransferContractAddress = common.HexToAddress("0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE")
|
||||||
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue