Skip to content

Commit

Permalink
all: implement EIP-7002 & EIP-7251 (ethereum#30571)
Browse files Browse the repository at this point in the history
This is a redo of ethereum#29052 based on newer specs. Here we implement EIPs
scheduled for the Prague fork:

- EIP-7002: Execution layer triggerable withdrawals
- EIP-7251: Increase the MAX_EFFECTIVE_BALANCE

Co-authored-by: lightclient <[email protected]>
  • Loading branch information
fjl and lightclient authored Oct 11, 2024
1 parent 16bf471 commit 3a5313f
Show file tree
Hide file tree
Showing 24 changed files with 216 additions and 41 deletions.
21 changes: 17 additions & 4 deletions cmd/evm/internal/t8ntool/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ type ExecutionResult struct {
WithdrawalsRoot *common.Hash `json:"withdrawalsRoot,omitempty"`
CurrentExcessBlobGas *math.HexOrDecimal64 `json:"currentExcessBlobGas,omitempty"`
CurrentBlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed,omitempty"`
RequestsHash *common.Hash `json:"requestsRoot,omitempty"`
RequestsHash *common.Hash `json:"requestsHash,omitempty"`
Requests [][]byte `json:"requests,omitempty"`
}

Expand Down Expand Up @@ -379,8 +379,10 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
execRs.CurrentExcessBlobGas = (*math.HexOrDecimal64)(&excessBlobGas)
execRs.CurrentBlobGasUsed = (*math.HexOrDecimal64)(&blobGasUsed)
}

var requests [][]byte
if chainConfig.IsPrague(vmContext.BlockNumber, vmContext.Time) {
// Parse the requests from the logs
// EIP-6110 deposits
var allLogs []*types.Log
for _, receipt := range receipts {
allLogs = append(allLogs, receipt.Logs...)
Expand All @@ -389,12 +391,23 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
if err != nil {
return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not parse requests logs: %v", err))
}
requests := [][]byte{depositRequests}
// Calculate the requests root
requests = append(requests, depositRequests)
// create EVM for system calls
vmenv := vm.NewEVM(vmContext, vm.TxContext{}, statedb, chainConfig, vm.Config{})
// EIP-7002 withdrawals
withdrawalRequests := core.ProcessWithdrawalQueue(vmenv, statedb)
requests = append(requests, withdrawalRequests)
// EIP-7251 consolidations
consolidationRequests := core.ProcessConsolidationQueue(vmenv, statedb)
requests = append(requests, consolidationRequests)
}
if requests != nil {
// Set requestsHash on block.
h := types.CalcRequestsHash(requests)
execRs.RequestsHash = &h
execRs.Requests = requests
}

// Re-create statedb instance with new root upon the updated database
// for accessing latest states.
statedb, err = state.New(root, statedb.Database())
Expand Down
84 changes: 84 additions & 0 deletions core/blockchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4227,3 +4227,87 @@ func TestEIP3651(t *testing.T) {
t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)
}
}

// Simple deposit generator, source: https://gist.github.com/lightclient/54abb2af2465d6969fa6d1920b9ad9d7
var depositsGeneratorCode = common.FromHex("6080604052366103aa575f603067ffffffffffffffff811115610025576100246103ae565b5b6040519080825280601f01601f1916602001820160405280156100575781602001600182028036833780820191505090505b5090505f8054906101000a900460ff1660f81b815f8151811061007d5761007c6103db565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f602067ffffffffffffffff8111156100c7576100c66103ae565b5b6040519080825280601f01601f1916602001820160405280156100f95781602001600182028036833780820191505090505b5090505f8054906101000a900460ff1660f81b815f8151811061011f5761011e6103db565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f600867ffffffffffffffff811115610169576101686103ae565b5b6040519080825280601f01601f19166020018201604052801561019b5781602001600182028036833780820191505090505b5090505f8054906101000a900460ff1660f81b815f815181106101c1576101c06103db565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f606067ffffffffffffffff81111561020b5761020a6103ae565b5b6040519080825280601f01601f19166020018201604052801561023d5781602001600182028036833780820191505090505b5090505f8054906101000a900460ff1660f81b815f81518110610263576102626103db565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f600867ffffffffffffffff8111156102ad576102ac6103ae565b5b6040519080825280601f01601f1916602001820160405280156102df5781602001600182028036833780820191505090505b5090505f8054906101000a900460ff1660f81b815f81518110610305576103046103db565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f8081819054906101000a900460ff168092919061035090610441565b91906101000a81548160ff021916908360ff160217905550507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c585858585856040516103a09594939291906104d9565b60405180910390a1005b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f60ff82169050919050565b5f61044b82610435565b915060ff820361045e5761045d610408565b5b600182019050919050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6104ab82610469565b6104b58185610473565b93506104c5818560208601610483565b6104ce81610491565b840191505092915050565b5f60a0820190508181035f8301526104f181886104a1565b9050818103602083015261050581876104a1565b9050818103604083015261051981866104a1565b9050818103606083015261052d81856104a1565b9050818103608083015261054181846104a1565b9050969550505050505056fea26469706673582212208569967e58690162d7d6fe3513d07b393b4c15e70f41505cbbfd08f53eba739364736f6c63430008190033")

// This is a smoke test for EIP-7685 requests added in the Prague fork. The test first
// creates a block containing requests, and then inserts it into the chain to run
// validation.
func TestPragueRequests(t *testing.T) {
var (
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
addr1 = crypto.PubkeyToAddress(key1.PublicKey)
config = *params.MergedTestChainConfig
signer = types.LatestSigner(&config)
engine = beacon.NewFaker()
)
gspec := &Genesis{
Config: &config,
Alloc: types.GenesisAlloc{
addr1: {Balance: big.NewInt(9999900000000000)},
config.DepositContractAddress: {Code: depositsGeneratorCode},
params.WithdrawalQueueAddress: {Code: params.WithdrawalQueueCode},
params.ConsolidationQueueAddress: {Code: params.ConsolidationQueueCode},
},
}

_, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) {
// create deposit
depositTx := types.MustSignNewTx(key1, signer, &types.DynamicFeeTx{
ChainID: gspec.Config.ChainID,
Nonce: 0,
To: &config.DepositContractAddress,
Gas: 500_000,
GasFeeCap: newGwei(5),
GasTipCap: big.NewInt(2),
})
b.AddTx(depositTx)

// create withdrawal request
withdrawalTx := types.MustSignNewTx(key1, signer, &types.DynamicFeeTx{
ChainID: gspec.Config.ChainID,
Nonce: 1,
To: &params.WithdrawalQueueAddress,
Gas: 500_000,
GasFeeCap: newGwei(5),
GasTipCap: big.NewInt(2),
Value: newGwei(1),
Data: common.FromHex("b917cfdc0d25b72d55cf94db328e1629b7f4fde2c30cdacf873b664416f76a0c7f7cc50c9f72a3cb84be88144cde91250000000000000d80"),
})
b.AddTx(withdrawalTx)

// create consolidation request
consolidationTx := types.MustSignNewTx(key1, signer, &types.DynamicFeeTx{
ChainID: gspec.Config.ChainID,
Nonce: 2,
To: &params.ConsolidationQueueAddress,
Gas: 500_000,
GasFeeCap: newGwei(5),
GasTipCap: big.NewInt(2),
Value: newGwei(1),
Data: common.FromHex("b917cfdc0d25b72d55cf94db328e1629b7f4fde2c30cdacf873b664416f76a0c7f7cc50c9f72a3cb84be88144cde9125b9812f7d0b1f2f969b52bbb2d316b0c2fa7c9dba85c428c5e6c27766bcc4b0c6e874702ff1eb1c7024b08524a9771601"),
})
b.AddTx(consolidationTx)
})

// Check block has the correct requests hash.
rh := blocks[0].RequestsHash()
if rh == nil {
t.Fatal("block has nil requests hash")
}
expectedRequestsHash := common.HexToHash("0x06ffb72b9f0823510b128bca6cd4f96f59b745de6791e9fc350b596e7605101e")
if *rh != expectedRequestsHash {
t.Fatalf("block has wrong requestsHash %v, want %v", *rh, expectedRequestsHash)
}

// Insert block to check validation.
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{}, nil)
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
defer chain.Stop()
if n, err := chain.InsertChain(blocks); err != nil {
t.Fatalf("block %d: failed to insert into chain: %v", n, err)
}
}
10 changes: 10 additions & 0 deletions core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse

var requests [][]byte
if config.IsPrague(b.header.Number, b.header.Time) {
// EIP-6110 deposits
var blockLogs []*types.Log
for _, r := range b.receipts {
blockLogs = append(blockLogs, r.Logs...)
Expand All @@ -357,6 +358,15 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
panic(fmt.Sprintf("failed to parse deposit log: %v", err))
}
requests = append(requests, depositRequests)
// create EVM for system calls
blockContext := NewEVMBlockContext(b.header, cm, &b.header.Coinbase)
vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, cm.config, vm.Config{})
// EIP-7002 withdrawals
withdrawalRequests := ProcessWithdrawalQueue(vmenv, statedb)
requests = append(requests, withdrawalRequests)
// EIP-7251 consolidations
consolidationRequests := ProcessConsolidationQueue(vmenv, statedb)
requests = append(requests, consolidationRequests)
}
if requests != nil {
reqHash := types.CalcRequestsHash(requests)
Expand Down
11 changes: 6 additions & 5 deletions core/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ func (g *Genesis) toBlockWithRoot(root common.Hash) *types.Block {
}
}
if conf.IsPrague(num, g.Timestamp) {
emptyRequests := [][]byte{{0}}
emptyRequests := [][]byte{{0x00}, {0x01}, {0x02}}
rhash := types.CalcRequestsHash(emptyRequests)
head.RequestsHash = &rhash
}
Expand Down Expand Up @@ -588,10 +588,11 @@ func DeveloperGenesisBlock(gasLimit uint64, faucet *common.Address) *Genesis {
common.BytesToAddress([]byte{7}): {Balance: big.NewInt(1)}, // ECScalarMul
common.BytesToAddress([]byte{8}): {Balance: big.NewInt(1)}, // ECPairing
common.BytesToAddress([]byte{9}): {Balance: big.NewInt(1)}, // BLAKE2b
// Pre-deploy EIP-4788 system contract
params.BeaconRootsAddress: {Nonce: 1, Code: params.BeaconRootsCode, Balance: common.Big0},
// Pre-deploy EIP-2935 history contract.
params.HistoryStorageAddress: {Nonce: 1, Code: params.HistoryStorageCode, Balance: common.Big0},
// Pre-deploy system contracts
params.BeaconRootsAddress: {Nonce: 1, Code: params.BeaconRootsCode, Balance: common.Big0},
params.HistoryStorageAddress: {Nonce: 1, Code: params.HistoryStorageCode, Balance: common.Big0},
params.WithdrawalQueueAddress: {Nonce: 1, Code: params.WithdrawalQueueCode, Balance: common.Big0},
params.ConsolidationQueueAddress: {Nonce: 1, Code: params.ConsolidationQueueCode, Balance: common.Big0},
},
}
if faucet != nil {
Expand Down
53 changes: 49 additions & 4 deletions core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,18 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
// Read requests if Prague is enabled.
var requests [][]byte
if p.config.IsPrague(block.Number(), block.Time()) {
// EIP-6110 deposits
depositRequests, err := ParseDepositLogs(allLogs, p.config)
if err != nil {
return nil, err
}
requests = append(requests, depositRequests)
// EIP-7002 withdrawals
withdrawalRequests := ProcessWithdrawalQueue(vmenv, statedb)
requests = append(requests, withdrawalRequests)
// EIP-7251 consolidations
consolidationRequests := ProcessConsolidationQueue(vmenv, statedb)
requests = append(requests, consolidationRequests)
}

// Finalize the block, applying any consensus engine specific extras (e.g. block rewards)
Expand Down Expand Up @@ -219,9 +226,6 @@ func ProcessBeaconBlockRoot(beaconRoot common.Hash, vmenv *vm.EVM, statedb *stat
defer tracer.OnSystemCallEnd()
}
}

// If EIP-4788 is enabled, we need to invoke the beaconroot storage contract with
// the new root
msg := &Message{
From: params.SystemAddress,
GasLimit: 30_000_000,
Expand All @@ -248,7 +252,6 @@ func ProcessParentBlockHash(prevHash common.Hash, vmenv *vm.EVM, statedb *state.
defer tracer.OnSystemCallEnd()
}
}

msg := &Message{
From: params.SystemAddress,
GasLimit: 30_000_000,
Expand All @@ -264,6 +267,48 @@ func ProcessParentBlockHash(prevHash common.Hash, vmenv *vm.EVM, statedb *state.
statedb.Finalise(true)
}

// ProcessWithdrawalQueue calls the EIP-7002 withdrawal queue contract.
// It returns the opaque request data returned by the contract.
func ProcessWithdrawalQueue(vmenv *vm.EVM, statedb *state.StateDB) []byte {
return processRequestsSystemCall(vmenv, statedb, 0x01, params.WithdrawalQueueAddress)
}

// ProcessConsolidationQueue calls the EIP-7251 consolidation queue contract.
// It returns the opaque request data returned by the contract.
func ProcessConsolidationQueue(vmenv *vm.EVM, statedb *state.StateDB) []byte {
return processRequestsSystemCall(vmenv, statedb, 0x02, params.ConsolidationQueueAddress)
}

func processRequestsSystemCall(vmenv *vm.EVM, statedb *state.StateDB, requestType byte, addr common.Address) []byte {
if tracer := vmenv.Config.Tracer; tracer != nil {
if tracer.OnSystemCallStart != nil {
tracer.OnSystemCallStart()
}
if tracer.OnSystemCallEnd != nil {
defer tracer.OnSystemCallEnd()
}
}

msg := &Message{
From: params.SystemAddress,
GasLimit: 30_000_000,
GasPrice: common.Big0,
GasFeeCap: common.Big0,
GasTipCap: common.Big0,
To: &addr,
}
vmenv.Reset(NewEVMTxContext(msg), statedb)
statedb.AddAddressToAccessList(addr)
ret, _, _ := vmenv.Call(vm.AccountRef(msg.From), *msg.To, msg.Data, 30_000_000, common.U2560)
statedb.Finalise(true)

// Create withdrawals requestsData with prefix 0x01
requestsData := make([]byte, len(ret)+1)
requestsData[0] = requestType
copy(requestsData[1:], ret)
return requestsData
}

// ParseDepositLogs extracts the EIP-6110 deposit values from logs emitted by
// BeaconDepositContract.
func ParseDepositLogs(logs []*types.Log, config *params.ChainConfig) ([]byte, error) {
Expand Down
3 changes: 2 additions & 1 deletion core/types/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,8 @@ func (b *Block) BaseFee() *big.Int {
return new(big.Int).Set(b.header.BaseFee)
}

func (b *Block) BeaconRoot() *common.Hash { return b.header.ParentBeaconRoot }
func (b *Block) BeaconRoot() *common.Hash { return b.header.ParentBeaconRoot }
func (b *Block) RequestsHash() *common.Hash { return b.header.RequestsHash }

func (b *Block) ExcessBlobGas() *uint64 {
var excessBlobGas *uint64
Expand Down
2 changes: 1 addition & 1 deletion eth/catalyst/simulated_beacon.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal, timestamp u
}
}
// Mark the payload as canon
if _, err = c.engineAPI.NewPayloadV3(*payload, blobHashes, &common.Hash{}); err != nil {
if _, err = c.engineAPI.NewPayloadV4(*payload, blobHashes, &common.Hash{}, envelope.Requests); err != nil {
return err
}
c.setCurrentState(payload.BlockHash, finalizedHash)
Expand Down
2 changes: 1 addition & 1 deletion eth/catalyst/simulated_beacon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func startSimulatedBeaconEthService(t *testing.T, genesis *core.Genesis, period

n, err := node.New(&node.Config{
P2P: p2p.Config{
ListenAddr: "127.0.0.1:8545",
ListenAddr: "127.0.0.1:0",
NoDiscovery: true,
MaxPeers: 0,
},
Expand Down
2 changes: 1 addition & 1 deletion eth/tracers/internal/tracetest/supply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func TestSupplyOmittedFields(t *testing.T) {

expected := supplyInfo{
Number: 0,
Hash: common.HexToHash("0x52f276d96f0afaaf2c3cb358868bdc2779c4b0cb8de3e7e5302e247c0b66a703"),
Hash: common.HexToHash("0xc02ee8ee5b54a40e43f0fa827d431e1bd4f217e941790dda10b2521d1925a20b"),
ParentHash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"),
}
actual := out[expected.Number]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{
"blobGasPrice": "0x1",
"blobGasUsed": "0x20000",
"blockHash": "0xd1392771155ce83f6403c6af275efd22bed567030c21168fcc9dbad5004eb245",
"blockHash": "0x11e6318d77a45c01f89f76b56d36c6936c5250f4e2bd238cb7b09df73cf0cb7d",
"blockNumber": "0x6",
"contractAddress": null,
"cumulativeGasUsed": "0x5208",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[
{
"blockHash": "0x56ea26cf955d7f2e08e194ad212ca4d5f99ee8e0b19dec3c71d8faafa33b1d22",
"blockHash": "0x5526cd89bc188f20fd5e9bb50d8054dc5a51a81a74ed07eacf36a4a8b10de4b1",
"blockNumber": "0x2",
"contractAddress": "0xae9bea628c4ce503dcfd7e305cab4e29e7476592",
"cumulativeGasUsed": "0xcf50",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[
{
"blockHash": "0xf41e7a7a716382f20464cf76c6ae1fa701e9d32f5cc550ebfd2391b9642ae6bc",
"blockHash": "0x3e946aa9e252873af511b257d9d89a1bcafa54ce7c6a6442f8407ecdf81e288d",
"blockNumber": "0x4",
"contractAddress": null,
"cumulativeGasUsed": "0x538d",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[
{
"blockHash": "0xa1410af902e98b32e0bbe464f8637ff464f1d4344b585127d2ce71f9cb39cb8a",
"blockHash": "0xc281d4299fc4e8ce5bba7ecb8deb50f5403d604c806b36aa887dfe2ff84c064f",
"blockNumber": "0x3",
"contractAddress": null,
"cumulativeGasUsed": "0x5e28",
Expand All @@ -19,7 +19,7 @@
"blockNumber": "0x3",
"transactionHash": "0xeaf3921cbf03ba45bad4e6ab807b196ce3b2a0b5bacc355b6272fa96b11b4287",
"transactionIndex": "0x0",
"blockHash": "0xa1410af902e98b32e0bbe464f8637ff464f1d4344b585127d2ce71f9cb39cb8a",
"blockHash": "0xc281d4299fc4e8ce5bba7ecb8deb50f5403d604c806b36aa887dfe2ff84c064f",
"logIndex": "0x0",
"removed": false
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[
{
"blockHash": "0x797d0c5603eccb33cc8ebd1300e977746512ec49e6b89087c7aad28ff760a26f",
"blockHash": "0xda50d57d8802553b00bb8e4d777bd5c4114086941119ca04edb15429f4818ed9",
"blockNumber": "0x1",
"contractAddress": null,
"cumulativeGasUsed": "0x5208",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{
"blobGasPrice": "0x1",
"blobGasUsed": "0x20000",
"blockHash": "0xd1392771155ce83f6403c6af275efd22bed567030c21168fcc9dbad5004eb245",
"blockHash": "0x11e6318d77a45c01f89f76b56d36c6936c5250f4e2bd238cb7b09df73cf0cb7d",
"blockNumber": "0x6",
"contractAddress": null,
"cumulativeGasUsed": "0x5208",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"blobGasPrice": "0x1",
"blobGasUsed": "0x20000",
"blockHash": "0xd1392771155ce83f6403c6af275efd22bed567030c21168fcc9dbad5004eb245",
"blockHash": "0x11e6318d77a45c01f89f76b56d36c6936c5250f4e2bd238cb7b09df73cf0cb7d",
"blockNumber": "0x6",
"contractAddress": null,
"cumulativeGasUsed": "0x5208",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"blockHash": "0x56ea26cf955d7f2e08e194ad212ca4d5f99ee8e0b19dec3c71d8faafa33b1d22",
"blockHash": "0x5526cd89bc188f20fd5e9bb50d8054dc5a51a81a74ed07eacf36a4a8b10de4b1",
"blockNumber": "0x2",
"contractAddress": "0xae9bea628c4ce503dcfd7e305cab4e29e7476592",
"cumulativeGasUsed": "0xcf50",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"blockHash": "0x69bf6ba924d95b6c50b0357768e5c892bd1b00cdf2f97e2e81fc06a76dfa57e3",
"blockHash": "0xa04ad6be58c45fe483991b89416572bc50426b0de44b769757e95c704250f874",
"blockNumber": "0x5",
"contractAddress": "0xfdaa97661a584d977b4d3abb5370766ff5b86a18",
"cumulativeGasUsed": "0xe01c",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"blockHash": "0xf41e7a7a716382f20464cf76c6ae1fa701e9d32f5cc550ebfd2391b9642ae6bc",
"blockHash": "0x3e946aa9e252873af511b257d9d89a1bcafa54ce7c6a6442f8407ecdf81e288d",
"blockNumber": "0x4",
"contractAddress": null,
"cumulativeGasUsed": "0x538d",
Expand Down
Loading

0 comments on commit 3a5313f

Please sign in to comment.