From 9c555054882355e283e8231d16af718d45f42d3b Mon Sep 17 00:00:00 2001 From: Ayaz Abbas Date: Fri, 1 Sep 2023 18:23:13 +0100 Subject: [PATCH 01/40] use makefile to build --- .github/workflows/release.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5604e00c6e56..aeac28f23cbf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ jobs: - uses: actions/checkout@v2 - name: Build geth run: | - cd cmd/geth && /opt/go/1.19.5/bin/go build + make && cd ./build/bin tar -czvf geth-$(basename ${GITHUB_REF})-linux-arm64.tar.gz geth echo $(md5sum geth | awk '{print $1}') > geth-$(basename ${GITHUB_REF})-linux-arm64.tar.gz.md5 - name: Upload geth to release page @@ -31,10 +31,4 @@ jobs: goarch: amd64 project_path: ./cmd/geth binary_name: geth - - uses: wangyoucao577/go-release-action@v1.39 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - goos: linux - goarch: amd64 - project_path: ./cmd/bootnode - binary_name: bootnode + build_command: make && mv ./build/bin/geth ./geth From 4ca65f4e87519fef9df27a09bb25ce7439efac08 Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Fri, 15 Sep 2023 19:30:10 -0400 Subject: [PATCH 02/40] tests,fix: Use new MakePreState signature. --- eth/tracers/internal/tracetest/txnOpCodeTracer_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eth/tracers/internal/tracetest/txnOpCodeTracer_test.go b/eth/tracers/internal/tracetest/txnOpCodeTracer_test.go index 1387d65d42cb..0b8849f604cd 100644 --- a/eth/tracers/internal/tracetest/txnOpCodeTracer_test.go +++ b/eth/tracers/internal/tracetest/txnOpCodeTracer_test.go @@ -88,7 +88,7 @@ func testTxnOpCodeTracer(tracerName string, dirPath string, t *testing.T) { BaseFee: baseFee, Random: test.Context.Random, } - _, statedb = tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false) + _, _, statedb = tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme) ) tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), test.TracerConfig) if err != nil { From b436d98ae3737811e04042fd34948b9a7b32b189 Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Thu, 14 Sep 2023 22:35:29 -0400 Subject: [PATCH 03/40] tweak: Add missing data to sim tx stream and skip empty txs. --- eth/filters/trace_api.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/eth/filters/trace_api.go b/eth/filters/trace_api.go index 349c8cf5fa05..878bc7ced1d7 100644 --- a/eth/filters/trace_api.go +++ b/eth/filters/trace_api.go @@ -77,34 +77,43 @@ func (api *FilterAPI) NewPendingTransactionsWithTrace(ctx context.Context, trace tracedTxs = make([]*RPCTransaction, 0, len(txs)) blockNumber = hexutil.Big(*header.Number) blockHash = header.Hash() + txIndex = hexutil.Uint64(0) ) statedb, err := api.sys.chain.State() if err != nil { - log.Error("NewPendingTransactionsWithTrace failed to get state", "err", err) + log.Error("failed to get state", "err", err) return } for _, tx := range txs { msg, _ = core.TransactionToMessage(tx, signer, header.BaseFee) if err != nil { - log.Error("NewPendingTransactionsWithTrace failed to create tx message", "err", err, "tx", tx.Hash()) + log.Error("failed to create tx message", "err", err, "tx", tx.Hash()) continue } traceCtx.TxHash = tx.Hash() trace, err := traceTx(msg, traceCtx, blockCtx, chainConfig, statedb, tracerOpts) if err != nil { - log.Error("NewPendingTransactionsWithTrace failed to trace tx", "err", err, "tx", tx.Hash()) + log.Error("failed to trace tx", "err", err, "tx", tx.Hash()) continue } + gasPrice := hexutil.Big(*tx.GasPrice()) rpcTx := newRPCPendingTransaction(tx) rpcTx.BlockHash = &blockHash rpcTx.BlockNumber = &blockNumber + rpcTx.TransactionIndex = &txIndex rpcTx.Trace = trace + rpcTx.GasPrice = &gasPrice tracedTxs = append(tracedTxs, rpcTx) } + + if len(tracedTxs) == 0 { + continue + } + notifier.Notify(rpcSub.ID, tracedTxs) case <-rpcSub.Err(): return From 4ce5dd0d6459f101e9cc95e7564cbd6d5b4160ba Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Thu, 14 Sep 2023 22:36:37 -0400 Subject: [PATCH 04/40] fix: Finalize single-depth callframes. --- eth/tracers/blocknative/txnOpCodeTracer.go | 81 ++++++++++------------ 1 file changed, 37 insertions(+), 44 deletions(-) diff --git a/eth/tracers/blocknative/txnOpCodeTracer.go b/eth/tracers/blocknative/txnOpCodeTracer.go index 5901015f9f79..9b6075a28363 100644 --- a/eth/tracers/blocknative/txnOpCodeTracer.go +++ b/eth/tracers/blocknative/txnOpCodeTracer.go @@ -139,13 +139,7 @@ func (t *txnOpCodeTracer) CaptureStart(env *vm.EVM, from common.Address, to comm // CaptureEnd is called after the call finishes to finalize the tracing. func (t *txnOpCodeTracer) CaptureEnd(output []byte, gasUsed uint64, err error) { - elapsedTime := time.Now().Sub(t.startTime) - - // Collect final gasUsed - t.callStack[0].GasUsed = uintToHex(gasUsed) - - // Add total time duration for this trace request - t.trace.Time = fmt.Sprintf("%v", elapsedTime) + finalizeCallFrame(&t.callStack[0], output, gasUsed, err) // If the user wants the logs, grab them from the state if t.opts.Logs { @@ -158,28 +152,14 @@ func (t *txnOpCodeTracer) CaptureEnd(output []byte, gasUsed uint64, err error) { } } - // This is the final output of a call - if err != nil { - t.callStack[0].Error = err.Error() - if err.Error() == "execution reverted" && len(output) > 0 { - t.callStack[0].Output = bytesToHex(output) - - // This revert reason is found via the standard introduced in v0.8.4 - // It uses a ABI with the method Error(string) - // This is the top level call, internal txs may fail while top level succeeds still - revertReason, _ := abi.UnpackRevert(output) - t.callStack[0].ErrorReason = revertReason - } - } else { - // TODO: This output is for the originally called contract, we can use the ABI to decode this for useful information - // ie: there are custom error types in ABIs since 0.8.4 which will turn up here - t.callStack[0].Output = bytesToHex(output) - } - // Add gas payments to balance changes if t.opts.BalanceChanges { t.balanceTracker.captureGas(t.env.TxContext.Origin, t.env.Context.Coinbase, gasUsed, t.env.TxContext.GasPrice, t.env.Context.BaseFee) } + + // Add total time duration for this trace request + elapsedTime := time.Now().Sub(t.startTime) + t.trace.Time = fmt.Sprintf("%v", elapsedTime) } // CaptureState implements the EVMLogger interface to trace a single step of VM execution. @@ -223,31 +203,26 @@ func (t *txnOpCodeTracer) CaptureEnter(typ vm.OpCode, from common.Address, to co // CaptureExit is called when EVM exits a scope, even if the scope didn't execute any code. func (t *txnOpCodeTracer) CaptureExit(output []byte, gasUsed uint64, err error) { + // Skip if we have no call frames. size := len(t.callStack) - if size <= 1 { + if size == 0 { return } - // pop call - call := t.callStack[size-1] - t.callStack = t.callStack[:size-1] - size -= 1 - call.GasUsed = uintToHex(gasUsed) - if err == nil { - call.Output = bytesToHex(output) - } else { - call.Error = err.Error() - if err.Error() == "execution reverted" && len(output) > 0 { - call.Output = bytesToHex(output) - revertReason, _ := abi.UnpackRevert(output) - call.ErrorReason = revertReason - } + // We have a call frame, so finalize it. + finalizeCallFrame(&t.callStack[size-1], output, gasUsed, err) - if call.Type == "CREATE" || call.Type == "CREATE2" { - call.To = "" - } + // We have a parent call frame, so nest this one into it. + if size <= 1 { + return } - t.callStack[size-1].Calls = append(t.callStack[size-1].Calls, call) + + // Pop call and append to parent. + end := size - 1 + call := t.callStack[end] + t.callStack = t.callStack[:end] + end -= 1 + t.callStack[end].Calls = append(t.callStack[end].Calls, call) } // CaptureTxStart fulfils the standard Tracer interface, but we don't use it. @@ -268,3 +243,21 @@ func (t *txnOpCodeTracer) SetStateRoot(root common.Hash) { t.trace.BlockContext.StateRoot = bytesToHex(root.Bytes()) } } + +func finalizeCallFrame(call *CallFrame, output []byte, gasUsed uint64, err error) { + call.GasUsed = uintToHex(gasUsed) + if err == nil { + call.Output = bytesToHex(output) + } else { + call.Error = err.Error() + if err.Error() == "execution reverted" && len(output) > 0 { + call.Output = bytesToHex(output) + revertReason, _ := abi.UnpackRevert(output) + call.ErrorReason = revertReason + } + + if call.Type == "CREATE" || call.Type == "CREATE2" { + call.To = "" + } + } +} From be1675f371d6122a09100a2ca50a7b513ba1ef89 Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Fri, 15 Sep 2023 20:29:37 -0400 Subject: [PATCH 05/40] fix: Add a RWMutex to metadata cache. --- eth/tracers/blocknative/decoder/metadata.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/eth/tracers/blocknative/decoder/metadata.go b/eth/tracers/blocknative/decoder/metadata.go index 4ea11bee15cf..bf3b92fb4edf 100644 --- a/eth/tracers/blocknative/decoder/metadata.go +++ b/eth/tracers/blocknative/decoder/metadata.go @@ -3,6 +3,7 @@ package decoder import ( "fmt" "math/big" + "sync" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" @@ -49,7 +50,8 @@ type AssetID struct { } type AssetDecoder struct { - cache lru.BasicLRU[AssetID, *Asset] + cacheMu sync.RWMutex + cache lru.BasicLRU[AssetID, *Asset] } func NewAssetDecoder() *AssetDecoder { @@ -64,7 +66,10 @@ func (d *AssetDecoder) Decode(evm *vm.EVM, assetID AssetID) (*Asset, error) { } // Check the cache for an existing entry. - if asset, ok := d.cache.Get(assetID); ok { + d.cacheMu.RLock() + asset, ok := d.cache.Get(assetID) + d.cacheMu.RUnlock() + if ok { return asset, nil } @@ -73,7 +78,10 @@ func (d *AssetDecoder) Decode(evm *vm.EVM, assetID AssetID) (*Asset, error) { if err != nil { return nil, err } + + d.cacheMu.Lock() d.cache.Add(assetID, asset) + d.cacheMu.Unlock() return asset, nil } From ea3988e9e2c22cf10acbbeed28a520dc184060b4 Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Sat, 16 Sep 2023 01:39:16 -0400 Subject: [PATCH 06/40] fix tests --- .../balance_changes_erc20_transfer.json | 67 +++-- .../delegatecall.json | 256 +++++++----------- 2 files changed, 140 insertions(+), 183 deletions(-) diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/balance_changes_erc20_transfer.json b/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/balance_changes_erc20_transfer.json index 88848d8b53a6..a003d61bdd35 100644 --- a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/balance_changes_erc20_transfer.json +++ b/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/balance_changes_erc20_transfer.json @@ -56,12 +56,12 @@ "input": "0x02f8b301038505b3524e108505b3524e108405f5e10094c3761eb917cd790b30dad99f6cc5b4ff93c4f9ea80b844a9059cbb000000000000000000000000fba9f22d040e53e5fac36698080cee3dd3792262000000000000000000000000000000000000000000000207b733832c88c007cac080a07371e0060c5a04e594e52bc949f0155ef29c9205cfce0dffebe6cef23a68c8eba00ff5c780cf75d1e6eeb9d08719e2988bb09e1f4bd18af3ee357dd47186265160", "result": { "type": "CALL", - "from": "0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea", + "from": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", "to": "0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea", "value": "0x0", - "gas": "0xffffffffffffffff", + "gas": "0x5f58c50", "gasUsed": "0x60b4", - "input": "0x06fdde03", + "input": "0xa9059cbb000000000000000000000000fba9f22d040e53e5fac36698080cee3dd3792262000000000000000000000000000000000000000000000207b733832c88c007ca", "output": "0x6060604052600436106100b95763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde0381146100be578063095ea7b31461014857806318160ddd1461017e57806323b872dd146101a3578063313ce567146101cb57806342966c68146101f457806370a082311461020a57806379cc67901461022957806395d89b411461024b578063a9059cbb1461025e578063cae9ca5114610282578063dd62ed3e146102e7575b600080fd5b34156100c957600080fd5b6100d161030c565b60405160208082528190810183818151815260200191508051906020019080838360005b8381101561010d5780820151838201526020016100f5565b50505050905090810190601f16801561013a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015357600080fd5b61016a600160a060020a03600435166024356103aa565b604051901515815260200160405180910390f35b341561018957600080fd5b6101916103da565b60405190815260200160405180910390f35b34156101ae57600080fd5b61016a600160a060020a03600435811690602435166044356103e0565b34156101d657600080fd5b6101de610457565b60405160ff909116815260200160405180910390f35b34156101ff57600080fd5b61016a600435610460565b341561021557600080fd5b610191600160a060020a03600435166104eb565b341561023457600080fd5b61016a600160a060020a03600435166024356104fd565b341561025657600080fd5b6100d16105d9565b341561026957600080fd5b610280600160a060020a0360043516602435610644565b005b341561028d57600080fd5b61016a60048035600160a060020a03169060248035919060649060443590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965061065395505050505050565b34156102f257600080fd5b610191600160a060020a0360043581169060243516610785565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103a25780601f10610377576101008083540402835291602001916103a2565b820191906000526020600020905b81548152906001019060200180831161038557829003601f168201915b505050505081565b600160a060020a033381166000908152600560209081526040808320938616835292905220819055600192915050565b60035481565b600160a060020a0380841660009081526005602090815260408083203390941683529290529081205482111561041557600080fd5b600160a060020a038085166000908152600560209081526040808320339094168352929052208054839003905561044d8484846107a2565b5060019392505050565b60025460ff1681565b600160a060020a0333166000908152600460205260408120548290101561048657600080fd5b600160a060020a03331660008181526004602052604090819020805485900390556003805485900390557fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca59084905190815260200160405180910390a2506001919050565b60046020526000908152604090205481565b600160a060020a0382166000908152600460205260408120548290101561052357600080fd5b600160a060020a038084166000908152600560209081526040808320339094168352929052205482111561055657600080fd5b600160a060020a038084166000818152600460209081526040808320805488900390556005825280832033909516835293905282902080548590039055600380548590039055907fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca59084905190815260200160405180910390a250600192915050565b60018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103a25780601f10610377576101008083540402835291602001916103a2565b61064f3383836107a2565b5050565b60008361066081856103aa565b1561077d5780600160a060020a0316638f4ffcb1338630876040518563ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018085600160a060020a0316600160a060020a0316815260200184815260200183600160a060020a0316600160a060020a0316815260200180602001828103825283818151815260200191508051906020019080838360005b838110156107165780820151838201526020016106fe565b50505050905090810190601f1680156107435780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b151561076457600080fd5b6102c65a03f1151561077557600080fd5b505050600191505b509392505050565b600560209081526000928352604080842090915290825290205481565b6000600160a060020a03831615156107b957600080fd5b600160a060020a038416600090815260046020526040902054829010156107df57600080fd5b600160a060020a0383166000908152600460205260409020548281011161080557600080fd5b50600160a060020a0380831660008181526004602052604080822080549488168084528284208054888103909155938590528154870190915591909301927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a3600160a060020a038084166000908152600460205260408082205492871682529020540181146108a257fe5b505050505600a165627a7a72305820604ef788ac8abdaedc46b8f7086ffceec1d1e365e29400b7d236b16d049806500029", "blockContext": { "number": 16967879, @@ -72,27 +72,56 @@ "gasLimit": 30000000 }, "balanceChanges": [ + { + "address": "0xfba9f22d040e53e5fac36698080cee3dd3792262", + "balanceChanges": [ + { + "delta": "9587061213415306430410", + "asset": { + "address": "0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea", + "name": "", + "symbol": "", + "decimals": 41, + "type": "erc20" + }, + "breakdown": [ + { + "counterparty": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", + "amount": "9587061213415306430410" + } + ] + } + ] + }, { "address": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", "balanceChanges": [ { - "delta": "-776416061160960", + "delta": "-9587061213415306430410", + "asset": { + "address": "0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea", + "name": "", + "symbol": "", + "decimals": 41, + "type": "erc20" + }, + "breakdown": [ + { + "counterparty": "0xfba9f22d040e53e5fac36698080cee3dd3792262", + "amount": "-9587061213415306430410" + } + ] + }, + { + "delta": "-606109864092480", "asset": { "address": "0x0000000000000000000000000000000000000000", - "type": "eth", "name": "Ether", "symbol": "ETH", - "decimals": 18 + "decimals": 18, + "type": "eth" }, "breakdown": [ - { - "counterparty": "0x0000000000000000000000000000000000000000", - "amount": "-116246446080" - }, - { - "counterparty": "0x4675c7e5baafbffbca748158becba61ef3b0a263", - "amount": "-170189950622400" - }, { "counterparty": "0x0000000000000000000000000000000000000000", "amount": "-413714350080" @@ -109,19 +138,15 @@ "address": "0x4675c7e5baafbffbca748158becba61ef3b0a263", "balanceChanges": [ { - "delta": "775886100364800", + "delta": "605696149742400", "asset": { "address": "0x0000000000000000000000000000000000000000", - "type": "eth", "name": "Ether", "symbol": "ETH", - "decimals": 18 + "decimals": 18, + "type": "eth" }, "breakdown": [ - { - "counterparty": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", - "amount": "170189950622400" - }, { "counterparty": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", "amount": "605696149742400" diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/delegatecall.json b/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/delegatecall.json index f7327d3ff575..f464d39b3b82 100644 --- a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/delegatecall.json +++ b/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/delegatecall.json @@ -257,56 +257,22 @@ { "type": "CALL", "from": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "to": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "value": "0x0", - "gas": "0xffffffffffffffff", - "gasUsed": "0x640a", - "input": "0x06fdde03", - "output": "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000", - "calls": [ - { - "type": "CALL", - "from": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0", - "gas": "0xf", - "gasUsed": "0xf", - "input": "0x", - "output": "0x" - } - ] - }, - { - "type": "CALL", - "from": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "to": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", + "to": "0x0000000000000000000000000000000000000004", "value": "0x0", - "gas": "0xffffffffffffffff", - "gasUsed": "0x2fc", - "input": "0x95d89b41", - "output": "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000", - "calls": [ - { - "type": "CALL", - "from": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0", - "gas": "0xf", - "gasUsed": "0xf", - "input": "0x", - "output": "0x" - } - ] + "gas": "0xf", + "gasUsed": "0xf", + "input": "0x", + "output": "0x" }, { "type": "CALL", "from": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "to": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", + "to": "0x0000000000000000000000000000000000000004", "value": "0x0", - "gas": "0xffffffffffffffff", - "gasUsed": "0x138", - "input": "0x313ce567", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" + "gas": "0xf", + "gasUsed": "0xf", + "input": "0x", + "output": "0x" } ] }, @@ -395,56 +361,22 @@ { "type": "CALL", "from": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", - "to": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", - "value": "0x0", - "gas": "0xffffffffffffffff", - "gasUsed": "0x1a2", - "input": "0x06fdde03", - "output": "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000", - "calls": [ - { - "type": "CALL", - "from": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0", - "gas": "0xf", - "gasUsed": "0xf", - "input": "0x", - "output": "0x" - } - ] - }, - { - "type": "CALL", - "from": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", - "to": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", + "to": "0x0000000000000000000000000000000000000004", "value": "0x0", - "gas": "0xffffffffffffffff", - "gasUsed": "0x252", - "input": "0x95d89b41", - "output": "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000", - "calls": [ - { - "type": "CALL", - "from": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0", - "gas": "0xf", - "gasUsed": "0xf", - "input": "0x", - "output": "0x" - } - ] + "gas": "0xf", + "gasUsed": "0xf", + "input": "0x", + "output": "0x" }, { "type": "CALL", "from": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", - "to": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", + "to": "0x0000000000000000000000000000000000000004", "value": "0x0", - "gas": "0xffffffffffffffff", - "gasUsed": "0xe8", - "input": "0x313ce567", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" + "gas": "0xf", + "gasUsed": "0xf", + "input": "0x", + "output": "0x" }, { "type": "DELEGATECALL", @@ -469,159 +401,159 @@ }, "balanceChanges": [ { - "address": "0x950ca4a06c78934a148b7a3ff3ea8fc366f77a06", + "address": "0x3de712784baf97260455ae25fb74f574ec9c1add", "balanceChanges": [ { - "delta": "18565314632837192", + "delta": "-3074620000000000", + "asset": { + "address": "0x0000000000000000000000000000000000000000", + "name": "Ether", + "symbol": "ETH", + "decimals": 18, + "type": "eth" + }, + "breakdown": [ + { + "counterparty": "0x0000000000000000000000000000000000000000", + "amount": "-2569103278080" + }, + { + "counterparty": "0x61c808d82a3ac53231750dadc13c777b59310bd9", + "amount": "-3072050896721920" + } + ] + }, + { + "delta": "-9282657316418596268", "asset": { "address": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "type": "erc20", "name": "", - "symbol": "" + "symbol": "", + "type": "erc20" }, "breakdown": [ { - "counterparty": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", - "amount": "18565314632837192" + "counterparty": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", + "amount": "-9282657316418596268" } ] - } - ] - }, - { - "address": "0x61c808d82a3ac53231750dadc13c777b59310bd9", - "balanceChanges": [ + }, { - "delta": "3072050896721920", + "delta": "16000000000000000000", "asset": { - "address": "0x0000000000000000000000000000000000000000", - "type": "eth", - "name": "Ether", - "symbol": "ETH", - "decimals": 18 + "address": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", + "name": "", + "symbol": "", + "type": "erc20" }, "breakdown": [ { - "counterparty": "0x3de712784baf97260455ae25fb74f574ec9c1add", - "amount": "3072050896721920" + "counterparty": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", + "amount": "16000000000000000000" } ] } ] }, { - "address": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", + "address": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", "balanceChanges": [ { - "delta": "0", + "delta": "9264092001785759076", "asset": { "address": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "type": "erc20", "name": "", - "symbol": "" + "symbol": "", + "type": "erc20" }, "breakdown": [ { - "counterparty": "0x3de712784baf97260455ae25fb74f574ec9c1add", + "counterparty": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", "amount": "9282657316418596268" }, { - "counterparty": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", - "amount": "-9282657316418596268" + "counterparty": "0x950ca4a06c78934a148b7a3ff3ea8fc366f77a06", + "amount": "-18565314632837192" } ] - }, + } + ] + }, + { + "address": "0x61c808d82a3ac53231750dadc13c777b59310bd9", + "balanceChanges": [ { - "delta": "-16000000000000000000", + "delta": "3072050896721920", "asset": { - "address": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", - "type": "erc20", - "name": "", - "symbol": "" + "address": "0x0000000000000000000000000000000000000000", + "name": "Ether", + "symbol": "ETH", + "decimals": 18, + "type": "eth" }, "breakdown": [ { "counterparty": "0x3de712784baf97260455ae25fb74f574ec9c1add", - "amount": "-16000000000000000000" + "amount": "3072050896721920" } ] } ] }, { - "address": "0x3de712784baf97260455ae25fb74f574ec9c1add", + "address": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", "balanceChanges": [ { - "delta": "-9282657316418596268", + "delta": "0", "asset": { "address": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "type": "erc20", "name": "", - "symbol": "" + "symbol": "", + "type": "erc20" }, "breakdown": [ { - "counterparty": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", + "counterparty": "0x3de712784baf97260455ae25fb74f574ec9c1add", + "amount": "9282657316418596268" + }, + { + "counterparty": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", "amount": "-9282657316418596268" } ] }, { - "delta": "16000000000000000000", + "delta": "-16000000000000000000", "asset": { "address": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", - "type": "erc20", "name": "", - "symbol": "" - }, - "breakdown": [ - { - "counterparty": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", - "amount": "16000000000000000000" - } - ] - }, - { - "delta": "-3074620000000000", - "asset": { - "address": "0x0000000000000000000000000000000000000000", - "type": "eth", - "name": "Ether", - "symbol": "ETH", - "decimals": 18 + "symbol": "", + "type": "erc20" }, "breakdown": [ { - "counterparty": "0x0000000000000000000000000000000000000000", - "amount": "-2569103278080" - }, - { - "counterparty": "0x61c808d82a3ac53231750dadc13c777b59310bd9", - "amount": "-3072050896721920" + "counterparty": "0x3de712784baf97260455ae25fb74f574ec9c1add", + "amount": "-16000000000000000000" } ] } ] }, { - "address": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", + "address": "0x950ca4a06c78934a148b7a3ff3ea8fc366f77a06", "balanceChanges": [ { - "delta": "9264092001785759076", + "delta": "18565314632837192", "asset": { "address": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "type": "erc20", "name": "", - "symbol": "" + "symbol": "", + "type": "erc20" }, "breakdown": [ { - "counterparty": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", - "amount": "9282657316418596268" - }, - { - "counterparty": "0x950ca4a06c78934a148b7a3ff3ea8fc366f77a06", - "amount": "-18565314632837192" + "counterparty": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", + "amount": "18565314632837192" } ] } From 56bca315a31fbebcb1227f42a2763e42e9aaebfa Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Sat, 16 Sep 2023 01:41:31 -0400 Subject: [PATCH 07/40] smaller type size for interfacetypes --- eth/tracers/blocknative/decoder/interfaces_types.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/eth/tracers/blocknative/decoder/interfaces_types.go b/eth/tracers/blocknative/decoder/interfaces_types.go index 22372fff6b1f..95dac3d93bb3 100644 --- a/eth/tracers/blocknative/decoder/interfaces_types.go +++ b/eth/tracers/blocknative/decoder/interfaces_types.go @@ -6,15 +6,15 @@ import ( ) const ( - interfaceTypeUnknown InterfaceType = iota + interfaceTypeUnknown interfaceType = iota interfaceTypeERC20 interfaceTypeERC721 interfaceTypeERC1155 ) -type InterfaceType int +type interfaceType uint8 -func (t InterfaceType) String() string { +func (t interfaceType) String() string { switch t { case interfaceTypeERC20: return "erc20" @@ -27,11 +27,11 @@ func (t InterfaceType) String() string { } } -func (t InterfaceType) MarshalJSON() ([]byte, error) { +func (t interfaceType) MarshalJSON() ([]byte, error) { return json.Marshal(t.String()) } -func (t *InterfaceType) UnmarshalJSON(data []byte) error { +func (t *interfaceType) UnmarshalJSON(data []byte) error { var s string if err := json.Unmarshal(data, &s); err != nil { return err From 14295297f4db1b1f890e0dfea7334f9860cd5490 Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Sat, 16 Sep 2023 01:42:30 -0400 Subject: [PATCH 08/40] make calldata decoding contract-aware --- eth/tracers/blocknative/decoder/calldata.go | 12 +++- .../blocknative/decoder/calldata_test.go | 64 +++++++++++++++++-- 2 files changed, 67 insertions(+), 9 deletions(-) diff --git a/eth/tracers/blocknative/decoder/calldata.go b/eth/tracers/blocknative/decoder/calldata.go index 7691012fd349..d235ae5c6f11 100644 --- a/eth/tracers/blocknative/decoder/calldata.go +++ b/eth/tracers/blocknative/decoder/calldata.go @@ -18,11 +18,10 @@ type DecodedCall struct { From common.Address To common.Address Value *big.Int - - TokenID *big.Int + TokenID *big.Int } -func DecodeCalldata(sender common.Address, input []byte) *DecodedCall { +func DecodeCalldata(sender common.Address, input []byte, contract *Contract) *DecodedCall { // Check if the input is capable of being a function call selector. // If not then we're done. If so then check if it's a transfer call. if len(input) < 4 { @@ -76,6 +75,13 @@ func DecodeCalldata(sender common.Address, input []byte) *DecodedCall { to = common.BytesToAddress(scanWord()) amount.SetBytes(scanWord()) + // If the contract is an ERC-721, but not an ERC-20, then move the + // scanned amount to the tokenID and set the amount to 1. + if contract.IsERC721() && !contract.IsERC20() { + tokenID = amount + amount = big.NewInt(1) + } + // ERC1155 style transfers // // safeTransferFrom(address,address,uint256,uint256,bytes) diff --git a/eth/tracers/blocknative/decoder/calldata_test.go b/eth/tracers/blocknative/decoder/calldata_test.go index aa410ad8849d..1e0b5679b54c 100644 --- a/eth/tracers/blocknative/decoder/calldata_test.go +++ b/eth/tracers/blocknative/decoder/calldata_test.go @@ -1,7 +1,9 @@ package decoder import ( + "encoding/hex" "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" "math/big" "reflect" "testing" @@ -9,8 +11,9 @@ import ( func TestDecodeCalldata(t *testing.T) { type args struct { - sender common.Address - input []byte + sender common.Address + input string + contract *Contract } tests := []struct { name string @@ -18,10 +21,11 @@ func TestDecodeCalldata(t *testing.T) { want *DecodedCall }{ { - "erc721", + "erc20 transferFrom", args{ common.Address{}, - []byte{35, 184, 114, 221, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 112, 197, 166, 252, 231, 68, 122, 253, 44, 155, 227, 160, 242, 94, 54, 44, 9, 54, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 158, 224, 54, 58, 122, 194, 239, 52, 203, 167, 238, 130, 210, 194, 224, 101, 45, 70, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 197}, + "23b872dd0000000000000000000000005470c5a6fce7447afd2c9be3a0f25e362c093661000000000000000000000000479ee0363a7ac2ef34cba7ee82d2c2e0652d466900000000000000000000000000000000000000000000000000000000000018c5", + &Contract{Interfaces: []interfaceType{interfaceTypeERC20}}, }, &DecodedCall{ CallType: AssetTransfer, @@ -29,11 +33,59 @@ func TestDecodeCalldata(t *testing.T) { To: common.HexToAddress("0x479ee0363a7Ac2ef34cba7ee82D2C2E0652D4669"), Value: big.NewInt(6341), TokenID: nil, - }}, + }, + }, + { + "erc721 transferFrom", + args{ + common.Address{}, + "23b872dd0000000000000000000000005470c5a6fce7447afd2c9be3a0f25e362c093661000000000000000000000000479ee0363a7ac2ef34cba7ee82d2c2e0652d466900000000000000000000000000000000000000000000000000000000000018c5", + &Contract{Interfaces: []interfaceType{interfaceTypeERC721}}, + }, + &DecodedCall{ + CallType: AssetTransfer, + From: common.HexToAddress("0x5470c5a6Fce7447aFd2C9BE3A0F25e362C093661"), + To: common.HexToAddress("0x479ee0363a7Ac2ef34cba7ee82D2C2E0652D4669"), + Value: big.NewInt(1), + TokenID: big.NewInt(6341), + }, + }, + { + "erc20 erc721 transferFrom", + args{ + common.Address{}, + "23b872dd0000000000000000000000005470c5a6fce7447afd2c9be3a0f25e362c093661000000000000000000000000479ee0363a7ac2ef34cba7ee82d2c2e0652d466900000000000000000000000000000000000000000000000000000000000018c5", + &Contract{Interfaces: []interfaceType{interfaceTypeERC20, interfaceTypeERC721}}, + }, + &DecodedCall{ + CallType: AssetTransfer, + From: common.HexToAddress("0x5470c5a6Fce7447aFd2C9BE3A0F25e362C093661"), + To: common.HexToAddress("0x479ee0363a7Ac2ef34cba7ee82D2C2E0652D4669"), + Value: big.NewInt(6341), + TokenID: nil, + }, + }, + { + "erc1155 safeTransferFrom", + args{ + common.Address{}, + "f242432a000000000000000000000000cb89354a1c6e7abd1972a68466db238e48a3b0c800000000000000000000000020964f741d2dffd2ccec658ca086e21af1d7df8e000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000360c6ebe", + &Contract{Interfaces: []interfaceType{interfaceTypeERC20, interfaceTypeERC721}}, + }, + &DecodedCall{ + CallType: AssetTransfer, + From: common.HexToAddress("0xcb89354a1c6e7ABd1972a68466Db238e48a3B0C8"), + To: common.HexToAddress("0x20964f741d2dffd2ccec658ca086e21af1d7df8e"), + Value: big.NewInt(1), + TokenID: big.NewInt(29), + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := DecodeCalldata(tt.args.sender, tt.args.input); !reflect.DeepEqual(got, tt.want) { + input, err := hex.DecodeString(tt.args.input) + require.NoError(t, err) + if got := DecodeCalldata(tt.args.sender, input, tt.args.contract); !reflect.DeepEqual(got, tt.want) { t.Errorf("DecodeCalldata() = %v, want %v", got, tt.want) } }) From 3f09ca188e671285e5205099f426af4c78139f27 Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Sat, 16 Sep 2023 02:00:55 -0400 Subject: [PATCH 09/40] feature: ERC1155 decoding, and decoding in CallFrames --- eth/tracers/blocknative/blocknative.go | 97 +- eth/tracers/blocknative/decoder/abi.go | 61 + eth/tracers/blocknative/decoder/asset.go | 203 +++ .../blocknative/decoder/asset_types.go | 25 +- .../balances.go} | 98 +- eth/tracers/blocknative/decoder/bytecode.go | 65 - eth/tracers/blocknative/decoder/cache.go | 27 + eth/tracers/blocknative/decoder/calldata.go | 134 +- .../blocknative/decoder/calldata_test.go | 117 +- eth/tracers/blocknative/decoder/contract.go | 90 ++ eth/tracers/blocknative/decoder/decoder.go | 143 ++ .../blocknative/decoder/interfaces_types.go | 10 +- eth/tracers/blocknative/decoder/metadata.go | 196 --- eth/tracers/blocknative/decoder/method_ids.go | 46 - eth/tracers/blocknative/decoder/methods.go | 113 ++ .../{method_ids_test.go => methods_test.go} | 23 +- eth/tracers/blocknative/decoder/types.go | 149 +++ eth/tracers/blocknative/decoding.go | 26 + eth/tracers/blocknative/txnOpCodeTracer.go | 95 +- .../delegatecall.json | 302 +++-- ...rc20_transfer.json => erc20_transfer.json} | 76 +- ...changes_txns.json => erc20_transfer2.json} | 63 +- .../inner_create.json | 313 +++-- ...ns.json => multi_contracts_transfers.json} | 1157 ++++++++++++----- .../tracetest/txnOpCodeTracer_test.go | 33 +- 25 files changed, 2472 insertions(+), 1190 deletions(-) create mode 100644 eth/tracers/blocknative/decoder/abi.go create mode 100644 eth/tracers/blocknative/decoder/asset.go rename eth/tracers/blocknative/{balance_changes.go => decoder/balances.go} (51%) delete mode 100644 eth/tracers/blocknative/decoder/bytecode.go create mode 100644 eth/tracers/blocknative/decoder/cache.go create mode 100644 eth/tracers/blocknative/decoder/contract.go create mode 100644 eth/tracers/blocknative/decoder/decoder.go delete mode 100644 eth/tracers/blocknative/decoder/metadata.go delete mode 100644 eth/tracers/blocknative/decoder/method_ids.go create mode 100644 eth/tracers/blocknative/decoder/methods.go rename eth/tracers/blocknative/decoder/{method_ids_test.go => methods_test.go} (99%) create mode 100644 eth/tracers/blocknative/decoder/types.go create mode 100644 eth/tracers/blocknative/decoding.go rename eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/{balance_changes_erc20_transfer.json => erc20_transfer.json} (96%) rename eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/{erc20_transfer_netbalchanges_txns.json => erc20_transfer2.json} (97%) rename eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/{multi_contracts_netbalchanges_txns.json => multi_contracts_transfers.json} (86%) diff --git a/eth/tracers/blocknative/blocknative.go b/eth/tracers/blocknative/blocknative.go index 959006b5f72e..cdfaf685fcc2 100644 --- a/eth/tracers/blocknative/blocknative.go +++ b/eth/tracers/blocknative/blocknative.go @@ -2,9 +2,6 @@ package blocknative import ( "encoding/json" - "fmt" - "math/big" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/tracers/blocknative/decoder" @@ -20,6 +17,7 @@ type Tracer interface { // TracerOpts configure the tracer to save or ignore various aspects of a transaction execution. type TracerOpts struct { Logs bool `json:"logs"` + Decode bool `json:"decode"` BalanceChanges bool `json:"balanceChanges"` // DisableBlockContext disables the block context in the trace. @@ -30,10 +28,10 @@ type TracerOpts struct { // Trace contains all the accumulated details of a transaction execution. type Trace struct { CallFrame - BlockContext *BlockContext `json:"blockContext,omitempty"` - Logs []CallLog `json:"logs,omitempty"` - Time string `json:"time,omitempty"` - BalanceChanges NetBalanceChanges `json:"balanceChanges"` + BlockContext *BlockContext `json:"blockContext,omitempty"` + Logs []CallLog `json:"logs,omitempty"` + Time string `json:"time,omitempty"` + BalanceChanges decoder.NetBalanceChanges `json:"balanceChanges"` } // BlockContext contains information about the block we simulate transactions in. @@ -48,17 +46,18 @@ type BlockContext struct { } type CallFrame struct { - Type string `json:"type"` - From string `json:"from"` - To string `json:"to,omitempty"` - Value string `json:"value,omitempty"` - Gas string `json:"gas"` - GasUsed string `json:"gasUsed"` - Input string `json:"input"` - Output string `json:"output,omitempty"` - Error string `json:"error,omitempty"` - ErrorReason string `json:"errorReason,omitempty"` - Calls []CallFrame `json:"calls,omitempty"` + Type string `json:"type"` + From string `json:"from"` + To string `json:"to,omitempty"` + Value string `json:"value,omitempty"` + Gas string `json:"gas"` + GasUsed string `json:"gasUsed"` + Input string `json:"input"` + Output string `json:"output,omitempty"` + Error string `json:"error,omitempty"` + ErrorReason string `json:"errorReason,omitempty"` + Calls []CallFrame `json:"calls,omitempty"` + Decoded *decoder.CallFrame `json:"decoded,omitempty"` } // CallLog represents a single log entry from the receipt of a transaction. @@ -72,65 +71,3 @@ type CallLog struct { // Topics is a slice of up to 4 32byte words provided with the log. Topics []common.Hash `json:"topics"` } - -// NetBalanceChanges is a list of account balance changes. -type NetBalanceChanges []AccountBalanceChanges - -// AccountBalanceChanges is a list of balance changes for a single account. -type AccountBalanceChanges struct { - Address common.Address `json:"address"` - BalanceChanges []BalanceChange `json:"balanceChanges"` -} - -// BalanceChange is a change in an account's balance for a single asset. -type BalanceChange struct { - Delta *Amount `json:"delta"` - Asset *decoder.Asset `json:"asset"` - Breakdown []AssetTransferEvent `json:"breakdown"` -} - -// AssetTransferEvent is a single transfer of an asset. -type AssetTransferEvent struct { - Counterparty common.Address `json:"counterparty"` - Amount *Amount `json:"amount"` -} - -type Amount big.Int - -func NewAmount(i *big.Int) *Amount { - return (*Amount)(i) -} - -func (a *Amount) Add(x *Amount, y *big.Int) { - a.ToInt().Add(x.ToInt(), y) -} - -func (a *Amount) ToInt() *big.Int { - return (*big.Int)(a) -} - -func (a *Amount) String() string { - return a.ToInt().String() -} - -func (a *Amount) MarshalJSON() ([]byte, error) { - return json.Marshal(a.ToInt().String()) -} - -func (a *Amount) UnmarshalJSON(data []byte) error { - if data == nil || len(data) == 0 { - *a = *NewAmount(big.NewInt(0)) - return nil - } - - var s string - if err := json.Unmarshal(data, &s); err != nil { - return err - } - aInt, ok := new(big.Int).SetString(s, 10) - if !ok { - return fmt.Errorf("failed to convert string to Amount") - } - *a = *(*Amount)(aInt) - return nil -} diff --git a/eth/tracers/blocknative/decoder/abi.go b/eth/tracers/blocknative/decoder/abi.go new file mode 100644 index 000000000000..e79c9458d275 --- /dev/null +++ b/eth/tracers/blocknative/decoder/abi.go @@ -0,0 +1,61 @@ +package decoder + +import ( + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/log" +) + +var ( + abiTypes = struct { + _string abi.Type + _address abi.Type + _uint256 abi.Type + _uint256Array abi.Type + _bytes abi.Type + }{} + + abiArgs = struct { + singleString abi.Arguments + batchTransfer abi.Arguments + }{} +) + +func init() { + if err := initABITypes(); err != nil { + log.Error("failed to initialize abi types", "err", err) + } + initABIArgs() +} + +// initABITypes initializes all the abiTypes. +func initABITypes() error { + var err error + if abiTypes._string, err = abi.NewType("string", "", nil); err != nil { + return err + } + if abiTypes._address, err = abi.NewType("address", "", nil); err != nil { + return err + } + if abiTypes._uint256, err = abi.NewType("uint256", "", nil); err != nil { + return err + } + if abiTypes._uint256Array, err = abi.NewType("uint256[]", "", nil); err != nil { + return err + } + if abiTypes._bytes, err = abi.NewType("bytes", "", nil); err != nil { + return err + } + return nil +} + +// initABIArgs initializes all the abiArgs. +func initABIArgs() { + abiArgs.singleString = abi.Arguments{abi.Argument{Type: abiTypes._string, Name: "name"}} + abiArgs.batchTransfer = abi.Arguments{ + abi.Argument{Type: abiTypes._address, Name: "from"}, + abi.Argument{Type: abiTypes._address, Name: "to"}, + abi.Argument{Type: abiTypes._uint256Array, Name: "tokenIDs"}, + abi.Argument{Type: abiTypes._uint256Array, Name: "values"}, + abi.Argument{Type: abiTypes._bytes, Name: "data"}, + } +} diff --git a/eth/tracers/blocknative/decoder/asset.go b/eth/tracers/blocknative/decoder/asset.go new file mode 100644 index 000000000000..03a0bbf11e0e --- /dev/null +++ b/eth/tracers/blocknative/decoder/asset.go @@ -0,0 +1,203 @@ +package decoder + +import ( + "fmt" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "math/big" +) + +var ( + ethAddress = common.Address{} + EthAssetID = AssetID{ethAddress, nil} + EthAsset = &Asset{ + AssetID: EthAssetID, + AssetMetadata: &AssetMetadata{ + Type: AssetTypeNative, + Name: "Ether", + Symbol: "ETH", + Decimals: 18, + }, + } +) + +func DecodeAsset(evmCall EVMCallFn, contract *Contract, assetID AssetID) (*AssetMetadata, error) { + var metadata AssetMetadata + switch { + case contract.IsERC20(): + metadata = decodeERC20Metadata(evmCall, assetID.Address) + case contract.IsERC721(): + metadata = decodeERC721Metadata(evmCall, assetID.Address, assetID.TokenID) + case contract.IsERC1155(): + metadata = decodeERC1155Metadata(evmCall, assetID.Address, assetID.TokenID) + } + return &metadata, nil +} + +// decodeERC20Metadata decodes the metadata for an ERC20 token from the EVM. +func decodeERC20Metadata(evmCall EVMCallFn, addr common.Address) AssetMetadata { + var err error + metadata := AssetMetadata{Type: AssetTypeERC20} + + if metadata.Name, err = decodeMetadataName(evmCall, addr); err != nil { + log.Trace("failed to decode ERC20 name", "err", err) + } + if metadata.Symbol, err = decodeMetadataSymbol(evmCall, addr); err != nil { + log.Trace("failed to decode ERC20 symbol", "err", err) + } + if metadata.Decimals, err = decodeMetadataDecimals(evmCall, addr); err != nil { + log.Trace("failed to decode ERC20 decimals", "err", err) + } + + return metadata +} + +// decodeERC721Metadata decodes the metadata for an ERC721 token from the EVM. +func decodeERC721Metadata(evmCall EVMCallFn, addr common.Address, tokenID *big.Int) AssetMetadata { + var err error + metadata := AssetMetadata{Type: AssetTypeERC721} + + if metadata.Name, err = decodeMetadataName(evmCall, addr); err != nil { + log.Trace("failed to decode ERC721 name", "err", err) + } + if metadata.Symbol, err = decodeMetadataSymbol(evmCall, addr); err != nil { + log.Trace("failed to decode ERC721 symbol", "err", err) + } + if metadata.URI, err = decodeMetadataTokenURI(evmCall, addr, tokenID); err != nil { + log.Trace("failed to decode ERC721 tokenURI", "err", err) + } + + return metadata +} + +// decodeERC1155Metadata decodes the metadata for an ERC1155 token from the EVM. +func decodeERC1155Metadata(evmCall EVMCallFn, addr common.Address, tokenID *big.Int) AssetMetadata { + var err error + metadata := AssetMetadata{Type: AssetTypeERC1155} + + if metadata.URI, err = decodeMetadataURI(evmCall, addr, tokenID); err != nil { + log.Trace("failed to decode ERC1155 URI", "err", err) + } + + return metadata +} + +// decodeMetadataName decodes the name of an asset from the EVM. +func decodeMetadataName(evmCall EVMCallFn, addr common.Address) (string, error) { + return callAndDecodeString(evmCall, addr, methodIDName) +} + +// decodeMetadataSymbol decodes the symbol of an asset from the EVM. +func decodeMetadataSymbol(evmCall EVMCallFn, addr common.Address) (string, error) { + return callAndDecodeString(evmCall, addr, methodIDSymbol) +} + +// decodeMetadataDecimals decodes the decimals of an asset from the EVM. +func decodeMetadataDecimals(evmCall EVMCallFn, addr common.Address) (uint8, error) { + return callAndDecodeUint8(evmCall, addr, methodIDDecimals) +} + +// decodeMetadataTokenURI decodes the tokenURI of an asset from the EVM. +func decodeMetadataTokenURI(evmCall EVMCallFn, addr common.Address, tokenID *big.Int) (string, error) { + tokenIDBytes := tokenID.Bytes() + if len(tokenIDBytes) > 32 { + return "", fmt.Errorf("tokenID is too large") + } + common.LeftPadBytes(tokenIDBytes, 32) + input := append(methodIDTokenURI, tokenIDBytes...) + return callAndDecodeString(evmCall, addr, input) +} + +// decodeMetadataURI decodes the URI of an asset from the EVM. +func decodeMetadataURI(evmCall EVMCallFn, addr common.Address, tokenID *big.Int) (string, error) { + tokenIDBytes := tokenID.Bytes() + if len(tokenIDBytes) > 32 { + return "", fmt.Errorf("tokenID is too large") + } + common.LeftPadBytes(tokenIDBytes, 32) + input := append(methodIDURI, tokenIDBytes...) + return callAndDecodeString(evmCall, addr, input) +} + +// callAndDecodeString calls a method and decodes the result as a string. +func callAndDecodeString(evmCall EVMCallFn, addr common.Address, method []byte) (string, error) { + // Load bytes from the EVM. + stringBytes, err := evmCall(addr, method) + if err != nil { + return "", err + } + + // Parse into a string. + stringInterface, err := abiArgs.singleString.Unpack(stringBytes) + if err != nil { + return "", err + } + if len(stringInterface) < len(abiArgs.singleString) { + return "", fmt.Errorf("unexpected decoded size") + } + str, ok := stringInterface[0].(string) + if !ok { + return "", fmt.Errorf("unexpected type for decoded string") + } + + return str, nil +} + +// callAndDecodeUint8 calls a method and decodes the result as a uint8. +func callAndDecodeUint8(evmCall EVMCallFn, addr common.Address, method []byte) (uint8, error) { + // Load bytes from the EVM. + uint8Bytes, err := evmCall(addr, method) + if err != nil { + return 0, err + } + + // Parse into a uint8. + if len(uint8Bytes) < 1 { + return 0, fmt.Errorf("unexpected decoded size") + } + return uint8Bytes[len(uint8Bytes)-1], nil +} + +// decodeArgsSafeBatchTransferFrom calls a method and decodes the result as a uint256[]. +func decodeArgsSafeBatchTransferFrom(bytes []byte) ([]*Transfer, error) { + args, err := abiArgs.batchTransfer.UnpackValues(bytes) + if err != nil { + return nil, err + } + if len(args) < len(abiArgs.batchTransfer) { + return nil, fmt.Errorf("unexpected decoded size") + } + + from, ok := args[0].(common.Address) + if !ok { + return nil, fmt.Errorf("unexpected type for decoded address") + } + to, ok := args[1].(common.Address) + if !ok { + return nil, fmt.Errorf("unexpected type for decoded address") + } + tokenIDs, ok := args[2].([]*big.Int) + if !ok { + return nil, fmt.Errorf("unexpected type for decoded uint265[]") + } + values, ok := args[3].([]*big.Int) + if !ok { + return nil, fmt.Errorf("unexpected type for decoded uint265[]") + } + + if len(tokenIDs) != len(values) { + return nil, fmt.Errorf("expected matching array lengths") + } + + transfers := make([]*Transfer, len(tokenIDs)) + for i := 0; i < len(tokenIDs); i++ { + transfers[i] = &Transfer{ + From: from, + To: to, + Value: NewAmount(values[i]), + TokenID: tokenIDs[i], + } + } + + return transfers, nil +} diff --git a/eth/tracers/blocknative/decoder/asset_types.go b/eth/tracers/blocknative/decoder/asset_types.go index ab1626d5e308..489154c09d8c 100644 --- a/eth/tracers/blocknative/decoder/asset_types.go +++ b/eth/tracers/blocknative/decoder/asset_types.go @@ -2,24 +2,9 @@ package decoder import ( "encoding/json" - "github.com/ethereum/go-ethereum/common" - "math/big" "strings" ) -type Asset struct { - Address common.Address `json:"address,omitempty"` - Type AssetType `json:"type"` - TokenID *big.Int `json:"TokenID,omitempty"` - TokenMetadata -} - -type TokenMetadata struct { - Name string `json:"name"` - Symbol string `json:"symbol"` - Decimals uint8 `json:"decimals,omitempty"` -} - const ( AssetTypeUnknown AssetType = iota AssetTypeNative @@ -28,7 +13,7 @@ const ( AssetTypeERC1155 ) -type AssetType int +type AssetType uint8 func (t AssetType) String() string { switch t { @@ -38,6 +23,8 @@ func (t AssetType) String() string { return "erc20" case AssetTypeERC721: return "erc721" + case AssetTypeERC1155: + return "erc1155" case AssetTypeUnknown: return "unknown" default: @@ -61,6 +48,8 @@ func (t *AssetType) UnmarshalJSON(data []byte) error { *t = AssetTypeERC20 case "erc721": *t = AssetTypeERC721 + case "erc1155": + *t = AssetTypeERC1155 default: *t = AssetTypeUnknown } @@ -68,7 +57,9 @@ func (t *AssetType) UnmarshalJSON(data []byte) error { } // AssetTypeForInterfaces returns the asset type for the given interfaces. -func AssetTypeForInterfaces(interfaces []InterfaceType) AssetType { +// A contract can implement multiple interfaces, so we check them in the order +// of precedence and take the first. +func AssetTypeForInterfaces(interfaces []Interface) AssetType { for _, i := range interfaces { switch i { case interfaceTypeERC1155: diff --git a/eth/tracers/blocknative/balance_changes.go b/eth/tracers/blocknative/decoder/balances.go similarity index 51% rename from eth/tracers/blocknative/balance_changes.go rename to eth/tracers/blocknative/decoder/balances.go index 94d41dc64584..09e9907d9447 100644 --- a/eth/tracers/blocknative/balance_changes.go +++ b/eth/tracers/blocknative/decoder/balances.go @@ -1,45 +1,43 @@ -package blocknative +package decoder import ( "math/big" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/eth/tracers/blocknative/decoder" - "github.com/ethereum/go-ethereum/log" ) // balanceTracker represents the difference of value (ETH, erc20, erc721) after the transaction for all addresses. -type balanceTracker struct { - stateDB stateDB - assetGetter assetGetter +type balances struct { balanceChanges balanceChangeByOwnerByAsset } // newBalanceChangeTracker creates a new balanceTracker. -func newBalanceChangeTracker(stateDB stateDB, assetGetter assetGetter) *balanceTracker { - return &balanceTracker{ - stateDB: stateDB, - assetGetter: assetGetter, +func newBalances() *balances { + return &balances{ balanceChanges: make(balanceChangeByOwnerByAsset, 4), } } // captureCall decodes potential balance change data out of calldata. -func (bt *balanceTracker) captureCall(sender common.Address, contract common.Address, value *big.Int, input []byte) { +func (bt *balances) captureCall(sender common.Address, receiver common.Address, value *Amount, decoded *CallFrame) { // Add the native transfer. - bt.balanceChanges.addAssetTransfer(bt, sender, contract, decoder.EthAssetID, value) + if value.ToInt().Sign() > 0 { + bt.balanceChanges.addAssetTransfer(EthAsset, sender, receiver, value) + } - // Decode the call data and if it's a transfer then add it. - decodedCall := decoder.DecodeCalldata(sender, input) - if decodedCall == nil || decodedCall.CallType != decoder.AssetTransfer { + if decoded == nil { return } - asset := decoder.AssetID{Address: contract, TokenID: decodedCall.TokenID} - bt.balanceChanges.addAssetTransfer(bt, decodedCall.From, decodedCall.To, asset, decodedCall.Value) + + // Add any decoded transfers. + for _, transfer := range decoded.Transfers { + // Add the decoded transfer now. + bt.balanceChanges.addAssetTransfer(transfer.Asset, transfer.From, transfer.To, transfer.Value) + } } // captureGas adds the gas payments to the balance changes. -func (bt *balanceTracker) captureGas(origin common.Address, coinbase common.Address, gasUsed uint64, gasFee *big.Int, gasBaseFee *big.Int) { +func (bt *balances) captureGas(origin common.Address, coinbase common.Address, gasUsed uint64, gasFee *big.Int, gasBaseFee *big.Int) { gasUsedBig := new(big.Int).SetUint64(gasUsed) // Calculate the gas cost for the base fee. @@ -51,14 +49,14 @@ func (bt *balanceTracker) captureGas(origin common.Address, coinbase common.Addr gasCostTip.Mul(gasCostTip, gasUsedBig) // Add the gas tip as a two-way transfer between origin and coinbase. - bt.balanceChanges.accountAssetChange(bt, origin, common.Address{}, decoder.EthAssetID, gasCostBase) + bt.balanceChanges.accountAssetChange(origin, common.Address{}, EthAsset, NewAmount(gasCostBase)) // Add the base fee as a one-way transfer from origin to empty address. - bt.balanceChanges.addAssetTransfer(bt, origin, coinbase, decoder.EthAssetID, gasCostTip) + bt.balanceChanges.addAssetTransfer(EthAsset, origin, coinbase, NewAmount(gasCostTip)) } // formatNetBalanceChanges aggregates the balanceChanges into a NetBalanceChanges. -func (bt *balanceTracker) formatNetBalanceChanges() NetBalanceChanges { +func (bt *balances) formatNetBalanceChanges() NetBalanceChanges { // Turn the balanceChanges map into a list of [{addr, [{token, change}]}] netBalanceChanges := make(NetBalanceChanges, 0, len(bt.balanceChanges)) for addr, changes := range bt.balanceChanges { @@ -71,22 +69,20 @@ func (bt *balanceTracker) formatNetBalanceChanges() NetBalanceChanges { return netBalanceChanges } -// stateDB is an interface that provides access to account balances. -type stateDB interface { - GetBalance(common.Address) *big.Int -} - -// assetGetter is a function that returns the metadata for a given asset address. -type assetGetter func(decoder.AssetID) (*decoder.Asset, error) - // balanceChangeByAsset is a map of asset address to BalanceChange. -type balanceChangeByAsset map[decoder.AssetID]BalanceChange +type balanceChangeByAsset map[AssetID]BalanceChange // balanceChangeByOwnerByAsset is a map of owner address to balanceChangeByAsset. type balanceChangeByOwnerByAsset map[common.Address]balanceChangeByAsset +// addAssetTransfer adds a double-sided asset transfer to the balanceChangeByOwnerByAsset map. +func (changeMap balanceChangeByOwnerByAsset) addAssetTransfer(asset *Asset, from, to common.Address, value *Amount) { + changeMap.accountAssetChange(to, from, asset, value) + changeMap.accountAssetChange(from, to, asset, value.Neg()) +} + // accountAssetChange adds a single side change of an asset transfer to the balanceChangeByOwnerByAsset map. -func (changeMap balanceChangeByOwnerByAsset) accountAssetChange(bt *balanceTracker, owner common.Address, counterparty common.Address, assetID decoder.AssetID, delta *big.Int) { +func (changeMap balanceChangeByOwnerByAsset) accountAssetChange(owner common.Address, counterparty common.Address, asset *Asset, delta *Amount) { // If this is the first time we've seen this owner then create a new // balanceByAsset map. if _, ok := changeMap[owner]; !ok { @@ -95,35 +91,41 @@ func (changeMap balanceChangeByOwnerByAsset) accountAssetChange(bt *balanceTrack // If this is the first time we've seen this asset for this owner then // create a new BalanceChange, including loading the asset metadata. - if _, ok := changeMap[owner][assetID]; !ok { - asset, err := bt.assetGetter(assetID) - if err != nil { - log.Trace("failed to read token metadata", "err", err) - } - changeMap[owner][assetID] = BalanceChange{ + if _, ok := changeMap[owner][asset.AssetID]; !ok { + changeMap[owner][asset.AssetID] = BalanceChange{ Delta: NewAmount(big.NewInt(0)), Asset: asset, } } // Update the delta and add a breakdown event. - ownerBalanceChange := changeMap[owner][assetID] + ownerBalanceChange := changeMap[owner][asset.AssetID] ownerBalanceChange.Delta.Add(ownerBalanceChange.Delta, delta) ownerBalanceChange.Breakdown = append(ownerBalanceChange.Breakdown, AssetTransferEvent{ Counterparty: counterparty, - Amount: NewAmount(delta), + Amount: delta, }) - changeMap[owner][assetID] = ownerBalanceChange + changeMap[owner][asset.AssetID] = ownerBalanceChange +} + +// NetBalanceChanges is a list of account balance changes. +type NetBalanceChanges []AccountBalanceChanges +// AccountBalanceChanges is a list of balance changes for a single account. +type AccountBalanceChanges struct { + Address common.Address `json:"address"` + BalanceChanges []BalanceChange `json:"balanceChanges"` } -// addAssetTransfer adds a double-sided asset transfer to the balanceChangeByOwnerByAsset map. -func (changeMap balanceChangeByOwnerByAsset) addAssetTransfer(bt *balanceTracker, from common.Address, to common.Address, assetID decoder.AssetID, value *big.Int) { - if value == nil || value.Sign() == 0 { - return - } +// BalanceChange is a change in an account's balance for a single asset. +type BalanceChange struct { + Delta *Amount `json:"delta"` + Asset *Asset `json:"asset"` + Breakdown []AssetTransferEvent `json:"breakdown"` +} - changeMap.accountAssetChange(bt, to, from, assetID, value) - negValue := new(big.Int).Neg(value) - changeMap.accountAssetChange(bt, from, to, assetID, negValue) +// AssetTransferEvent is a single transfer of an asset. +type AssetTransferEvent struct { + Counterparty common.Address `json:"counterparty"` + Amount *Amount `json:"amount"` } diff --git a/eth/tracers/blocknative/decoder/bytecode.go b/eth/tracers/blocknative/decoder/bytecode.go deleted file mode 100644 index ef5d1d61b4ac..000000000000 --- a/eth/tracers/blocknative/decoder/bytecode.go +++ /dev/null @@ -1,65 +0,0 @@ -package decoder - -import "bytes" - -type Bytecode []byte - -// ContainsMethods returns true if all given methodIDs are found in the code. -func (b Bytecode) ContainsMethods(methodIDs ...[]byte) bool { - for _, methodID := range methodIDs { - firstNonZeroIndex := 0 - for firstNonZeroIndex < len(methodID) && methodID[firstNonZeroIndex] == 0 { - firstNonZeroIndex++ - } - - if !bytes.Contains(b, methodID[firstNonZeroIndex:]) { - return false - } - } - return true -} - -// IsMetadataBasic returns true iff the bytecode implements basic metadata. -func (b Bytecode) IsBasicMetadata() bool { - return b.ContainsMethods(methodIDsBasicMetadata...) -} - -// IsERC20 returns true iff the bytecode implements ERC20. -func (b Bytecode) IsERC20() bool { - return b.ContainsMethods(methodIDsERC20All...) -} - -// IsERC721 returns true iff the bytecode implements ERC721. -func (b Bytecode) IsERC721() bool { - return b.ContainsMethods(methodIDsERC721All...) -} - -// IsERC1155 returns true iff the bytecode implements ERC1155. -func (b Bytecode) IsERC1155() bool { - return b.ContainsMethods(methodIDsERC1155All...) -} - -// DecodeInterface determines the first interface implemented by a contract. -func (b Bytecode) DecodeInterface() InterfaceType { - interfaces := b.DecodeInterfaces() - if len(interfaces) == 0 { - return interfaceTypeUnknown - } - return interfaces[0] -} - -// DecodeInterfaces determines all interfaces implemented by a contract. -func (b Bytecode) DecodeInterfaces() []InterfaceType { - var interfaces []InterfaceType - - if b.IsERC20() { - interfaces = append(interfaces, interfaceTypeERC20) - } - if b.IsERC721() { - interfaces = append(interfaces, interfaceTypeERC721) - } - if b.IsERC1155() { - interfaces = append(interfaces, interfaceTypeERC1155) - } - return interfaces -} diff --git a/eth/tracers/blocknative/decoder/cache.go b/eth/tracers/blocknative/decoder/cache.go new file mode 100644 index 000000000000..f392b7875cf3 --- /dev/null +++ b/eth/tracers/blocknative/decoder/cache.go @@ -0,0 +1,27 @@ +package decoder + +import ( + "sync" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/lru" +) + +const ( + cacheSizeContracts = 10_0000 + cacheSizeAssets = 10_0000 +) + +type Caches struct { + contractsMu sync.RWMutex + contracts lru.BasicLRU[common.Address, *Contract] + assetsMu sync.RWMutex + assets lru.BasicLRU[AssetID, *AssetMetadata] +} + +func NewCaches() *Caches { + return &Caches{ + contracts: lru.NewBasicLRU[common.Address, *Contract](cacheSizeContracts), + assets: lru.NewBasicLRU[AssetID, *AssetMetadata](cacheSizeAssets), + } +} diff --git a/eth/tracers/blocknative/decoder/calldata.go b/eth/tracers/blocknative/decoder/calldata.go index d235ae5c6f11..016b4048a587 100644 --- a/eth/tracers/blocknative/decoder/calldata.go +++ b/eth/tracers/blocknative/decoder/calldata.go @@ -1,40 +1,34 @@ package decoder import ( - "bytes" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "math/big" ) -const ( - CallTypeUnknown CallType = iota - AssetTransfer -) +func decodeCallData(sender common.Address, contract *Contract, input []byte) (*CallData, error) { + // Check if the input is capable of being a function call. + // If not then we're done. If so then check if it's a transfer. + inputLen := len(input) + switch { + case inputLen < 4: + return nil, ErrCallDataTooShort + } -type CallType int + methodBytes := make([]byte, 4) + copy(methodBytes, input[:4]) -type DecodedCall struct { - CallType CallType - From common.Address - To common.Address - Value *big.Int - TokenID *big.Int -} + var ( + idx = 4 + method = MethodID(methodBytes) + args = make([]string, 0, 4) -func DecodeCalldata(sender common.Address, input []byte, contract *Contract) *DecodedCall { - // Check if the input is capable of being a function call selector. - // If not then we're done. If so then check if it's a transfer call. - if len(input) < 4 { - return nil - } + from common.Address + to common.Address + amount = new(Amount) + tokenID *big.Int - var ( - idx = 4 - methodID = input[:idx] - from common.Address - to common.Address - amount = new(big.Int) - tokenID *big.Int + transfers []*Transfer ) // scanWord gets the next 32 bytes and advances the index @@ -46,67 +40,91 @@ func DecodeCalldata(sender common.Address, input []byte, contract *Contract) *De switch { - // transfer(address,uint256) call. - // payload is [to, amount] - case bytes.Compare(methodID, methodIDTransfer) == 0: + // transfer(address,uint256). + case method.Is(methodIDTransfer): if len(input) < 68 { - return nil + return nil, ErrCallDataTooShort } - from = sender to = common.BytesToAddress(scanWord()) amount.SetBytes(scanWord()) - // transferFrom(address,address,uint256) call. - // safeTransferFrom(address,address,uint256) call. - // safeTransferFrom(address,address,uint256,bytes) call. - // - // payload is [from, to, amount] - case bytes.Compare(methodID, methodIDTransferFrom) == 0: + args = append(args, to.String(), amount.String()) + transfers = append(transfers, &Transfer{ + From: from, + To: to, + Value: amount, + }) + + // transferFrom(address,address,uint256). + case method.Is(methodIDTransferFrom): fallthrough - case bytes.Compare(methodID, methodIDSafeTransferFrom) == 0: + // safeTransferFrom(address,address,uint256). + case method.Is(methodIDSafeTransferFrom): fallthrough - case bytes.Compare(methodID, methodIDSafeTransferFrom2) == 0: + // safeTransferFrom(address,address,uint256,bytes). + case method.Is(methodIDSafeTransferFrom2): if len(input) < 100 { - return nil + return nil, ErrCallDataTooShort } from = common.BytesToAddress(scanWord()) to = common.BytesToAddress(scanWord()) amount.SetBytes(scanWord()) + args = append(args, from.String(), to.String(), amount.String()) + // If the contract is an ERC-721, but not an ERC-20, then move the // scanned amount to the tokenID and set the amount to 1. if contract.IsERC721() && !contract.IsERC20() { - tokenID = amount - amount = big.NewInt(1) + tokenID = (*big.Int)(amount) + amount = NewAmount(common.Big1) } - // ERC1155 style transfers - // + transfers = append(transfers, &Transfer{ + From: from, + To: to, + Value: amount, + TokenID: tokenID, + }) + // safeTransferFrom(address,address,uint256,uint256,bytes) - // - // payload is [from, to, tokenID, amount] - case bytes.Compare(methodID, methodIDSafeTransferFrom3) == 0: + case method.Is(methodIDSafeTransferFrom3): if len(input) < 100 { - return nil + return nil, ErrCallDataTooShort } - from = common.BytesToAddress(scanWord()) to = common.BytesToAddress(scanWord()) tokenID = new(big.Int).SetBytes(scanWord()) amount.SetBytes(scanWord()) - // Not a matching event; ignore + args = append(args, from.String(), to.String(), tokenID.String(), amount.String()) + + transfers = append(transfers, &Transfer{ + From: from, + To: to, + Value: amount, + TokenID: tokenID, + }) + + // safeBatchTransferFrom(address,address,uint256[],uint256[],bytes) + case method.Is(methodIDSafeBatchTransferFrom): + var err error + transfers, err = decodeArgsSafeBatchTransferFrom(input[idx:]) + if err != nil { + return nil, err + } default: - return nil + // We don't have a known method so we can't parse the args. + // Just add them as hex-encoded words. + for idx < len(input) { + args = append(args, hexutil.Encode(scanWord())) + } } - return &DecodedCall{ - CallType: AssetTransfer, - From: from, - To: to, - Value: amount, - TokenID: tokenID, - } + return &CallData{ + MethodID: method, + Args: args, + Transfers: transfers, + }, nil } diff --git a/eth/tracers/blocknative/decoder/calldata_test.go b/eth/tracers/blocknative/decoder/calldata_test.go index 1e0b5679b54c..10cbc3dcc1cb 100644 --- a/eth/tracers/blocknative/decoder/calldata_test.go +++ b/eth/tracers/blocknative/decoder/calldata_test.go @@ -2,11 +2,12 @@ package decoder import ( "encoding/hex" - "github.com/ethereum/go-ethereum/common" - "github.com/stretchr/testify/require" + "encoding/json" "math/big" - "reflect" "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" ) func TestDecodeCalldata(t *testing.T) { @@ -18,66 +19,95 @@ func TestDecodeCalldata(t *testing.T) { tests := []struct { name string args args - want *DecodedCall + want *CallData }{ { - "erc20 transferFrom", + "erc20 transferFrom(address,address,uint256)", args{ common.Address{}, "23b872dd0000000000000000000000005470c5a6fce7447afd2c9be3a0f25e362c093661000000000000000000000000479ee0363a7ac2ef34cba7ee82d2c2e0652d466900000000000000000000000000000000000000000000000000000000000018c5", - &Contract{Interfaces: []interfaceType{interfaceTypeERC20}}, + &Contract{interfaces: []Interface{interfaceTypeERC20}}, }, - &DecodedCall{ - CallType: AssetTransfer, - From: common.HexToAddress("0x5470c5a6Fce7447aFd2C9BE3A0F25e362C093661"), - To: common.HexToAddress("0x479ee0363a7Ac2ef34cba7ee82D2C2E0652D4669"), - Value: big.NewInt(6341), - TokenID: nil, + &CallData{ + MethodID: methodIDTransferFrom, + Args: []string{"0x5470c5a6Fce7447aFd2C9BE3A0F25e362C093661", "0x479ee0363a7Ac2ef34cba7ee82D2C2E0652D4669", "6341"}, + Transfers: []*Transfer{{ + From: common.HexToAddress("0x5470c5a6Fce7447aFd2C9BE3A0F25e362C093661"), + To: common.HexToAddress("0x479ee0363a7Ac2ef34cba7ee82D2C2E0652D4669"), + Value: NewAmount(big.NewInt(6341)), + TokenID: nil, + }}, }, }, { - "erc721 transferFrom", + "erc721 transferFrom(address,address,uint256)", args{ common.Address{}, "23b872dd0000000000000000000000005470c5a6fce7447afd2c9be3a0f25e362c093661000000000000000000000000479ee0363a7ac2ef34cba7ee82d2c2e0652d466900000000000000000000000000000000000000000000000000000000000018c5", - &Contract{Interfaces: []interfaceType{interfaceTypeERC721}}, + &Contract{interfaces: []Interface{interfaceTypeERC721}}, }, - &DecodedCall{ - CallType: AssetTransfer, - From: common.HexToAddress("0x5470c5a6Fce7447aFd2C9BE3A0F25e362C093661"), - To: common.HexToAddress("0x479ee0363a7Ac2ef34cba7ee82D2C2E0652D4669"), - Value: big.NewInt(1), - TokenID: big.NewInt(6341), + &CallData{ + MethodID: methodIDTransferFrom, + Args: []string{"0x5470c5a6Fce7447aFd2C9BE3A0F25e362C093661", "0x479ee0363a7Ac2ef34cba7ee82D2C2E0652D4669", "6341"}, + Transfers: []*Transfer{{ + From: common.HexToAddress("0x5470c5a6Fce7447aFd2C9BE3A0F25e362C093661"), + To: common.HexToAddress("0x479ee0363a7Ac2ef34cba7ee82D2C2E0652D4669"), + Value: NewAmount(big.NewInt(1)), + TokenID: big.NewInt(6341), + }}, }, }, { - "erc20 erc721 transferFrom", + "erc20+erc721 transferFrom(address,address,uint256)", args{ common.Address{}, "23b872dd0000000000000000000000005470c5a6fce7447afd2c9be3a0f25e362c093661000000000000000000000000479ee0363a7ac2ef34cba7ee82d2c2e0652d466900000000000000000000000000000000000000000000000000000000000018c5", - &Contract{Interfaces: []interfaceType{interfaceTypeERC20, interfaceTypeERC721}}, + &Contract{interfaces: []Interface{interfaceTypeERC20, interfaceTypeERC721}}, }, - &DecodedCall{ - CallType: AssetTransfer, - From: common.HexToAddress("0x5470c5a6Fce7447aFd2C9BE3A0F25e362C093661"), - To: common.HexToAddress("0x479ee0363a7Ac2ef34cba7ee82D2C2E0652D4669"), - Value: big.NewInt(6341), - TokenID: nil, + &CallData{ + MethodID: methodIDTransferFrom, + Args: []string{"0x5470c5a6Fce7447aFd2C9BE3A0F25e362C093661", "0x479ee0363a7Ac2ef34cba7ee82D2C2E0652D4669", "6341"}, + Transfers: []*Transfer{{ + From: common.HexToAddress("0x5470c5a6fce7447afd2c9be3a0f25e362c093661"), + To: common.HexToAddress("0x479ee0363a7Ac2ef34cba7ee82D2C2E0652D4669"), + Value: NewAmount(big.NewInt(6341)), + TokenID: nil, + }}, }, }, { - "erc1155 safeTransferFrom", + "erc1155 safeTransferFrom(address,address,uint256,uint256,bytes)", args{ common.Address{}, "f242432a000000000000000000000000cb89354a1c6e7abd1972a68466db238e48a3b0c800000000000000000000000020964f741d2dffd2ccec658ca086e21af1d7df8e000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000360c6ebe", - &Contract{Interfaces: []interfaceType{interfaceTypeERC20, interfaceTypeERC721}}, + &Contract{interfaces: []Interface{interfaceTypeERC20, interfaceTypeERC721}}, + }, + &CallData{ + MethodID: methodIDSafeTransferFrom3, + Args: []string{"0xcb89354a1c6e7ABd1972a68466Db238e48a3B0C8", "0x20964f741d2dfFD2cCec658CA086e21aF1D7dF8E", "29", "1"}, + Transfers: []*Transfer{{ + From: common.HexToAddress("0xcb89354a1c6e7ABd1972a68466Db238e48a3B0C8"), + To: common.HexToAddress("0x20964f741d2dffd2ccec658ca086e21af1d7df8e"), + Value: NewAmount(big.NewInt(1)), + TokenID: big.NewInt(29), + }}, + }, + }, + { + "erc1155 safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)", + args{ + common.Address{}, + "2eb2c2d6000000000000000000000000381e840f4ebe33d0153e9a312105554594a98c42000000000000000000000000a2b876dbb382d40cecee2acc670f55ad95c4767e00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000006ed00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000", + &Contract{interfaces: []Interface{interfaceTypeERC20, interfaceTypeERC721}}, }, - &DecodedCall{ - CallType: AssetTransfer, - From: common.HexToAddress("0xcb89354a1c6e7ABd1972a68466Db238e48a3B0C8"), - To: common.HexToAddress("0x20964f741d2dffd2ccec658ca086e21af1d7df8e"), - Value: big.NewInt(1), - TokenID: big.NewInt(29), + &CallData{ + MethodID: methodIDSafeBatchTransferFrom, + Transfers: []*Transfer{{ + From: common.HexToAddress("0x381E840F4eBe33d0153e9A312105554594A98C42"), + To: common.HexToAddress("0xA2b876dbb382d40cECeE2ACC670f55AD95c4767e"), + TokenID: parseBigInt("603320636550823895720563178976525038911488"), + Value: NewAmount(common.Big1), + }}, }, }, } @@ -85,9 +115,18 @@ func TestDecodeCalldata(t *testing.T) { t.Run(tt.name, func(t *testing.T) { input, err := hex.DecodeString(tt.args.input) require.NoError(t, err) - if got := DecodeCalldata(tt.args.sender, input, tt.args.contract); !reflect.DeepEqual(got, tt.want) { - t.Errorf("DecodeCalldata() = %v, want %v", got, tt.want) - } + + got, err := decodeCallData(tt.args.sender, tt.args.contract, input) + require.NoError(t, err) + + gotJSON, _ := json.Marshal(got) + wantJSON, _ := json.Marshal(tt.want) + require.Equal(t, string(gotJSON), string(wantJSON)) }) } } + +func parseBigInt(s string) *big.Int { + b, _ := new(big.Int).SetString(s, 10) + return b +} diff --git a/eth/tracers/blocknative/decoder/contract.go b/eth/tracers/blocknative/decoder/contract.go new file mode 100644 index 000000000000..cd967c5a45df --- /dev/null +++ b/eth/tracers/blocknative/decoder/contract.go @@ -0,0 +1,90 @@ +package decoder + +import ( + "bytes" + "golang.org/x/exp/slices" +) + +// decodeContract decodes the contract bytecode and determines all interfaces +func decodeContract(bytecode ByteCode) (*Contract, error) { + + interfaces := bytecode.DecodeInterfaces() + + return &Contract{ + interfaces: interfaces, + Type: contractTypeForInterfaces(interfaces), + }, nil +} + +// IsERC20 returns true iff the contract interfaces contains ERC-20. +func (c *Contract) IsERC20() bool { + return slices.Contains(c.interfaces, interfaceTypeERC20) +} + +// IsERC721 returns true iff the contract interfaces contains ERC-721. +func (c *Contract) IsERC721() bool { + return slices.Contains(c.interfaces, interfaceTypeERC721) +} + +// IsERC1155 returns true iff the contract interfaces contains ERC-1155. +func (c *Contract) IsERC1155() bool { + return slices.Contains(c.interfaces, interfaceTypeERC1155) +} + +type ByteCode []byte + +func containsMethod(b ByteCode, id MethodID) bool { + if id[0] == 0 { + id = id[1:] + } + if id[0] == 0 { + id = id[1:] + } + + if !bytes.Contains(b, id) { + return false + } + + return true +} + +// containsAllMethods returns true iff all ids are found in the ByteCode. +func containsAllMethods(b ByteCode, ids ...MethodID) bool { + for _, id := range ids { + if !containsMethod(b, id) { + return false + } + } + return true +} + +// DecodeInterfaces determines all interfaces implemented by a contract. +func (b ByteCode) DecodeInterfaces() []Interface { + var interfaces []Interface + + if containsAllMethods(b, interfaceMethodsERC20...) { + interfaces = append(interfaces, interfaceTypeERC20) + } + if containsAllMethods(b, interfaceMethodsERC721...) { + interfaces = append(interfaces, interfaceTypeERC721) + } + if containsAllMethods(b, interfaceMethodsERC1155...) { + interfaces = append(interfaces, interfaceTypeERC1155) + } + return interfaces +} + +func contractTypeForInterfaces(interfaces []Interface) ContractType { + for _, i := range interfaces { + + switch i { + case interfaceTypeERC1155: + return ContractTypeERC1155 + case interfaceTypeERC721: + return ContractTypeERC721 + case interfaceTypeERC20: + return ContractTypeERC20 + } + } + return ContractTypeUnknown +} diff --git a/eth/tracers/blocknative/decoder/decoder.go b/eth/tracers/blocknative/decoder/decoder.go new file mode 100644 index 000000000000..1b547204e49d --- /dev/null +++ b/eth/tracers/blocknative/decoder/decoder.go @@ -0,0 +1,143 @@ +package decoder + +import ( + "errors" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "math/big" +) + +var ( + ErrAccountNotAContract = errors.New("account is not a contract") + ErrCallDataTooShort = errors.New("call data too short") + ErrCallDataNotFullWords = errors.New("call data not full words") +) + +type Decoder struct { + caches *Caches + evm evm + balances *balances +} + +func New(caches *Caches, evm evm) *Decoder { + return &Decoder{ + caches: caches, + evm: evm, + balances: newBalances(), + } +} + +func (d *Decoder) DecodeCallFrame(sender common.Address, receiver common.Address, value *big.Int, input []byte) (*CallFrame, error) { + contract, err := d.DecodeContract(receiver) + if err != nil { + return nil, err + } + + callData, err := decodeCallData(sender, contract, input) + if err != nil { + return nil, err + } + + // Add decoded Assets to any transfers. + for _, transfer := range callData.Transfers { + // Always add the assetID. + assetID := AssetID{Address: receiver, TokenID: transfer.TokenID} + transfer.Asset = &Asset{AssetID: assetID} + + // Add metadata if we can decode it but don't fail if we can't. + assetMetadata, err := d.decodeAsset(contract, assetID) + if err != nil { + log.Trace("failed to decode asset", "err", err) + continue + } + transfer.Asset.AssetMetadata = assetMetadata + } + + cf := &CallFrame{Contract: contract, CallData: callData} + + d.balances.captureCall(sender, receiver, NewAmount(value), cf) + + return cf, nil +} + +// DecodeContract decodes the contract at the given address. +func (d *Decoder) DecodeContract(addr common.Address) (*Contract, error) { + // Check the cache for an existing entry. + d.caches.contractsMu.RLock() + contract, ok := d.caches.contracts.Get(addr) + d.caches.contractsMu.RUnlock() + if ok { + if contract == nil { + return nil, ErrAccountNotAContract + } + return contract, nil + } + + // Cache miss; First check if the account has code. If it doesn't we cache + // a nil to avoid hitting the stateDB repeatedly for accounts that don't + // have code. + bytecode := ByteCode(d.evm.GetCode(addr)) + if len(bytecode) == 0 { + d.caches.contractsMu.Lock() + d.caches.contracts.Add(addr, nil) + d.caches.contractsMu.Unlock() + return nil, ErrAccountNotAContract + } + + // We have an unknown contract; decode itm, add it to the cache, and return it. + contract, err := decodeContract(bytecode) + if err != nil { + return nil, err + } + d.caches.contractsMu.Lock() + d.caches.contracts.Add(addr, contract) + d.caches.contractsMu.Unlock() + return contract, nil +} + +func (d *Decoder) GetBalanceChanges() NetBalanceChanges { + return d.balances.formatNetBalanceChanges() +} + +// CaptureGas is a hack to expose the captureGas method to the tracer. +// Ideally this would happen internally but requires the tracer to cal +// DecodeCallFrame in CaptureEnd/CaptureExit instead of Start/Enter. +func (d *Decoder) CaptureGas(origin common.Address, coinbase common.Address, gasUsed uint64, gasFee *big.Int, gasBaseFee *big.Int) { + d.balances.captureGas(origin, coinbase, gasUsed, gasFee, gasBaseFee) +} + +func (d *Decoder) decodeAsset(contract *Contract, assetID AssetID) (*AssetMetadata, error) { + // Check for native ETH and skip the cache check entire. + if assetID.Address == ethAddress { + return EthAsset.AssetMetadata, nil + } + + // Check the cache for an existing entry. + d.caches.assetsMu.RLock() + asset, ok := d.caches.assets.Get(assetID) + d.caches.assetsMu.RUnlock() + if ok { + return asset, nil + } + + // Cache miss; decode and add to the cache. + + asset, err := DecodeAsset(d.evm.CallCode, contract, assetID) + if err != nil { + return nil, err + } + + d.caches.assetsMu.Lock() + d.caches.assets.Add(assetID, asset) + d.caches.assetsMu.Unlock() + + return asset, nil +} + +type evm interface { + GetCode(common.Address) []byte + CallCode(common.Address, []byte) ([]byte, error) +} + +type EVMCallFn func(addr common.Address, method []byte) ([]byte, error) +type GetCodeFn func(addr common.Address) []byte diff --git a/eth/tracers/blocknative/decoder/interfaces_types.go b/eth/tracers/blocknative/decoder/interfaces_types.go index 95dac3d93bb3..deed7779b902 100644 --- a/eth/tracers/blocknative/decoder/interfaces_types.go +++ b/eth/tracers/blocknative/decoder/interfaces_types.go @@ -6,15 +6,15 @@ import ( ) const ( - interfaceTypeUnknown interfaceType = iota + interfaceTypeUnknown Interface = iota interfaceTypeERC20 interfaceTypeERC721 interfaceTypeERC1155 ) -type interfaceType uint8 +type Interface uint8 -func (t interfaceType) String() string { +func (t Interface) String() string { switch t { case interfaceTypeERC20: return "erc20" @@ -27,11 +27,11 @@ func (t interfaceType) String() string { } } -func (t interfaceType) MarshalJSON() ([]byte, error) { +func (t Interface) MarshalJSON() ([]byte, error) { return json.Marshal(t.String()) } -func (t *interfaceType) UnmarshalJSON(data []byte) error { +func (t *Interface) UnmarshalJSON(data []byte) error { var s string if err := json.Unmarshal(data, &s); err != nil { return err diff --git a/eth/tracers/blocknative/decoder/metadata.go b/eth/tracers/blocknative/decoder/metadata.go deleted file mode 100644 index bf3b92fb4edf..000000000000 --- a/eth/tracers/blocknative/decoder/metadata.go +++ /dev/null @@ -1,196 +0,0 @@ -package decoder - -import ( - "fmt" - "math/big" - "sync" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/lru" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/log" -) - -const ( - cacheSize = 10_0000 -) - -var ( - abiStringType abi.Type - abiSingleStringArgs abi.Arguments - - ethAddress = common.Address{} - EthAssetID = AssetID{ethAddress, nil} - ethAsset = &Asset{ - Address: ethAddress, - Type: AssetTypeNative, - TokenMetadata: TokenMetadata{ - Name: "Ether", - Symbol: "ETH", - Decimals: 18, - }, - } -) - -func init() { - var err error - abiStringType, err = abi.NewType("string", "", nil) - if err != nil { - log.Error("failed to create abi string type", "err", err) - } - - abiSingleStringArgs = abi.Arguments{abi.Argument{Type: abiStringType, Name: "name"}} -} - -type AssetID struct { - Address common.Address - TokenID *big.Int -} - -type AssetDecoder struct { - cacheMu sync.RWMutex - cache lru.BasicLRU[AssetID, *Asset] -} - -func NewAssetDecoder() *AssetDecoder { - return &AssetDecoder{ - cache: lru.NewBasicLRU[AssetID, *Asset](cacheSize), - } -} - -func (d *AssetDecoder) Decode(evm *vm.EVM, assetID AssetID) (*Asset, error) { - if assetID.Address == ethAddress { - return ethAsset, nil - } - - // Check the cache for an existing entry. - d.cacheMu.RLock() - asset, ok := d.cache.Get(assetID) - d.cacheMu.RUnlock() - if ok { - return asset, nil - } - - // Cache miss; decode from EVM and add to the cache. - asset, err := d.decode(evm, assetID) - if err != nil { - return nil, err - } - - d.cacheMu.Lock() - d.cache.Add(assetID, asset) - d.cacheMu.Unlock() - - return asset, nil -} - -func (d *AssetDecoder) decode(evm *vm.EVM, assetID AssetID) (*Asset, error) { - bytecode := Bytecode(evm.StateDB.GetCode(assetID.Address)) - - asset := &Asset{ - Address: assetID.Address, - Type: AssetTypeForInterfaces(bytecode.DecodeInterfaces()), - TokenID: assetID.TokenID, - } - - var err error - - switch asset.Type { - case AssetTypeERC20: - asset.TokenMetadata, err = d.decodeERC20Metadata(evm, assetID.Address) - if err != nil { - return asset, err - } - case AssetTypeERC721: - fallthrough - case AssetTypeERC1155: - if bytecode.IsBasicMetadata() { - asset.TokenMetadata, err = d.decodeBasicMetadata(evm, assetID.Address) - if err != nil { - return asset, err - } - } - } - - return asset, nil -} - -// decodeERC20Metadata decodes the metadata for an ERC20 token from the EVM. -func (d *AssetDecoder) decodeERC20Metadata(evm *vm.EVM, contract common.Address) (TokenMetadata, error) { - metadata, err := d.decodeBasicMetadata(evm, contract) - if err != nil { - return TokenMetadata{}, err - } - - decimals, err := d.decodeMetadataUint8(evm, contract, methodIDDecimals) - if err != nil { - return TokenMetadata{}, err - } - - metadata.Decimals = decimals - return metadata, nil -} - -func (d *AssetDecoder) decodeBasicMetadata(evm *vm.EVM, contract common.Address) (TokenMetadata, error) { - name, err := d.decodeMetadataString(evm, contract, methodIDName) - if err != nil { - return TokenMetadata{}, err - } - - symbol, err := d.decodeMetadataString(evm, contract, methodIDSymbol) - if err != nil { - return TokenMetadata{}, err - } - - return TokenMetadata{ - Name: name, - Symbol: symbol, - }, nil -} - -func (d *AssetDecoder) decodeMetadataString(evm *vm.EVM, contract common.Address, method []byte) (string, error) { - // Load bytes from the EVM. - stringBytes, err := callEVMMethod(evm, contract, method) - if err != nil { - return "", err - } - - // Parse into a string. - stringInterface, err := abiSingleStringArgs.Unpack(stringBytes) - if err != nil { - return "", err - } - if len(stringInterface) < 1 { - return "", fmt.Errorf("unexpected decoded size") - } - name, ok := stringInterface[0].(string) - if !ok { - return "", fmt.Errorf("unexpected type for decoded string") - } - - return name, nil -} - -func (d *AssetDecoder) decodeMetadataUint8(evm *vm.EVM, contract common.Address, method []byte) (uint8, error) { - // Load bytes from the EVM. - uint8Bytes, err := callEVMMethod(evm, contract, method) - if err != nil { - return 0, err - } - - // Parse into a uint8. - if len(uint8Bytes) < 1 { - return 0, fmt.Errorf("unexpected decoded size") - } - return uint8Bytes[len(uint8Bytes)-1], nil -} - -func callEVMMethod(evm *vm.EVM, contract common.Address, method []byte) ([]byte, error) { - ret, _, err := evm.Call(vm.AccountRef(contract), contract, method, math.MaxUint64, common.Big0) - if err != nil { - return nil, err - } - return ret, nil -} diff --git a/eth/tracers/blocknative/decoder/method_ids.go b/eth/tracers/blocknative/decoder/method_ids.go deleted file mode 100644 index 935998240d9c..000000000000 --- a/eth/tracers/blocknative/decoder/method_ids.go +++ /dev/null @@ -1,46 +0,0 @@ -package decoder - -var ( - // ERC20 - methodIDName = methodIDToBytes(0x06fdde03) // name() - methodIDSymbol = methodIDToBytes(0x95d89b41) // symbol() - methodIDDecimals = methodIDToBytes(0x313ce567) // decimals() - - methodIDTransfer = methodIDToBytes(0xa9059cbb) // transfer(address,uint256) - methodIDTransferFrom = methodIDToBytes(0x23b872dd) // transferFrom(address,address,uint256) - methodIDTotalSupply = methodIDToBytes(0x18160ddd) // totalSupply() - methodIDBalanceOf = methodIDToBytes(0x70a08231) // balanceOf(address) - methodIDApprove = methodIDToBytes(0x095ea7b3) // approve(address,uint256) - methodIDAllowance = methodIDToBytes(0xdd62ed3e) // allowance(address,address) - - // ERC721 - methodIDSafeTransferFrom = methodIDToBytes(0x42842e0e) // safeTransferFrom(address,address,uint256) - methodIDSafeTransferFrom2 = methodIDToBytes(0xb88d4fde) // safeTransferFrom(address,address,uint256,bytes) - methodIDOwnerOf = methodIDToBytes(0x6352211e) // ownerOf(uint256) - methodIDSetApprovalForAll = methodIDToBytes(0xa22cb465) // setApprovalForAll(address,bool) - methodIDGetApproved = methodIDToBytes(0x081812fc) // getApproved(uint256) - methodIDIsApprovedForAll = methodIDToBytes(0xe985e9c5) // isApprovedForAll(address,address) - - // ERC1155 - methodIDBalanceOf2 = methodIDToBytes(0x00fdd58e) // balanceOf(address,uint256) - methodIDBalanceOfBatch = methodIDToBytes(0x4e1273f4) // balanceOfBatch(address[],uint256[]) - methodIDSafeTransferFrom3 = methodIDToBytes(0xf242432a) // safeTransferFrom(address,address,uint256,uint256,bytes) - methodIDSafeBatchTransferFrom = methodIDToBytes(0x2eb2c2d6) // safeBatchTransferFrom(address,address,uint256[],uint256[],bytes) - - // Interfaces by list of methodIDs - methodIDsERC20All = [][]byte{methodIDName, methodIDSymbol, methodIDDecimals, methodIDTransfer, methodIDTransferFrom, methodIDTotalSupply, methodIDBalanceOf, methodIDApprove, methodIDAllowance} - methodIDsERC721All = [][]byte{methodIDBalanceOf, methodIDOwnerOf, methodIDSafeTransferFrom, methodIDSafeTransferFrom2, methodIDTransferFrom, methodIDApprove, methodIDSetApprovalForAll, methodIDGetApproved, methodIDIsApprovedForAll} - methodIDsERC1155All = [][]byte{methodIDSafeTransferFrom3, methodIDSafeBatchTransferFrom, methodIDBalanceOf2, methodIDBalanceOfBatch, methodIDSetApprovalForAll, methodIDIsApprovedForAll} - methodIDsBasicMetadata = [][]byte{methodIDName, methodIDSymbol} -) - -// methodIDToBytes converts a uint32 methodID to slice of up 4 bytes. -// Leading zero bytes are omitted because contracts can/do safely omit them. -func methodIDToBytes(i uint32) []byte { - return []byte{ - byte(i >> 24), - byte(i >> 16), - byte(i >> 8), - byte(i), - } -} diff --git a/eth/tracers/blocknative/decoder/methods.go b/eth/tracers/blocknative/decoder/methods.go new file mode 100644 index 000000000000..5d0c8bd7d1e1 --- /dev/null +++ b/eth/tracers/blocknative/decoder/methods.go @@ -0,0 +1,113 @@ +package decoder + +import ( + "bytes" + "encoding/hex" + "encoding/json" + "fmt" + "github.com/ethereum/go-ethereum/common" +) + +const ( + methodIDLen = 4 + methodIDEncodedLen = methodIDLen * 2 +) + +var ( + ErrMethodIDTooLong = fmt.Errorf("methodID is too long") + + // ERC20 + methodIDTransfer = methodIDToBytes(0xa9059cbb) // transfer(address,uint256) + methodIDTransferFrom = methodIDToBytes(0x23b872dd) // transferFrom(address,address,uint256) + methodIDTotalSupply = methodIDToBytes(0x18160ddd) // totalSupply() + methodIDBalanceOf = methodIDToBytes(0x70a08231) // balanceOf(address) + methodIDApprove = methodIDToBytes(0x095ea7b3) // approve(address,uint256) + methodIDAllowance = methodIDToBytes(0xdd62ed3e) // allowance(address,address) + + // ERC721 + methodIDSafeTransferFrom = methodIDToBytes(0x42842e0e) // safeTransferFrom(address,address,uint256) + methodIDSafeTransferFrom2 = methodIDToBytes(0xb88d4fde) // safeTransferFrom(address,address,uint256,bytes) + methodIDOwnerOf = methodIDToBytes(0x6352211e) // ownerOf(uint256) + methodIDSetApprovalForAll = methodIDToBytes(0xa22cb465) // setApprovalForAll(address,bool) + methodIDGetApproved = methodIDToBytes(0x081812fc) // getApproved(uint256) + methodIDIsApprovedForAll = methodIDToBytes(0xe985e9c5) // isApprovedForAll(address,address) + + // ERC1155 + methodIDBalanceOf2 = methodIDToBytes(0x00fdd58e) // balanceOf(address,uint256) + methodIDBalanceOfBatch = methodIDToBytes(0x4e1273f4) // balanceOfBatch(address[],uint256[]) + methodIDSafeTransferFrom3 = methodIDToBytes(0xf242432a) // safeTransferFrom(address,address,uint256,uint256,bytes) + methodIDSafeBatchTransferFrom = methodIDToBytes(0x2eb2c2d6) // safeBatchTransferFrom(address,address,uint256[],uint256[],bytes) + + // Metadata + methodIDName = methodIDToBytes(0x06fdde03) // name() + methodIDSymbol = methodIDToBytes(0x95d89b41) // symbol() + methodIDDecimals = methodIDToBytes(0x313ce567) // decimals() + methodIDTokenURI = methodIDToBytes(0xc87b56dd) // tokenURI(uint256) + methodIDURI = methodIDToBytes(0x0e89341c) // uri(uint256) + + // Interfaces by list of methodIDs + interfaceMethodsERC20 = []MethodID{methodIDName, methodIDSymbol, methodIDDecimals, methodIDTransfer, methodIDTransferFrom, methodIDTotalSupply, methodIDBalanceOf, methodIDApprove, methodIDAllowance} + interfaceMethodsERC721 = []MethodID{methodIDBalanceOf, methodIDOwnerOf, methodIDSafeTransferFrom, methodIDSafeTransferFrom2, methodIDTransferFrom, methodIDApprove, methodIDSetApprovalForAll, methodIDGetApproved, methodIDIsApprovedForAll} + interfaceMethodsERC1155 = []MethodID{methodIDSafeTransferFrom3, methodIDSafeBatchTransferFrom, methodIDBalanceOf2, methodIDBalanceOfBatch, methodIDSetApprovalForAll, methodIDIsApprovedForAll} +) + +type MethodID []byte + +func (m MethodID) Is(other MethodID) bool { + return bytes.Compare(m, other) == 0 +} + +func (m MethodID) String() string { + return "0x" + hex.EncodeToString(m) +} + +func (m MethodID) MarshalJSON() ([]byte, error) { + return json.Marshal(m.String()) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +// The bytes come as ASCII-encoded hex, quoted and with a 0x prefix. +func (m *MethodID) UnmarshalJSON(b []byte) error { + // Remove quotes and 0x prefix, and ensure the remainder isn't too long. + if len(b) > 2 { + if b[0] == '"' && b[len(b)-1] == '"' { + b = b[1 : len(b)-1] + } + } + if len(b) > 2 { + if b[0] == '0' && (b[1] == 'x' || b[1] == 'X') { + b = b[2:] + } + } + + if len(b) > methodIDEncodedLen { + fmt.Println("sdfasdfasdf:", len(b), string(b), b) + return ErrMethodIDTooLong + } + + // Decode hex into m. + methodIDBytes := make([]byte, 4) + if _, err := hex.Decode(methodIDBytes, b); err != nil { + panic(err) + return err + } + + // Method IDs with leading zero bytes are sometimes expressed externally + // with fewer than 4 bytes. We pad them here to ensure they are always the + // right length internally. + common.LeftPadBytes(methodIDBytes, 0) + + *m = methodIDBytes + return nil +} + +// methodIDToBytes converts a uint32 methodID to slice of up 4 bytes. +// Leading zero bytes are omitted because contracts can/do safely omit them. +func methodIDToBytes(i uint32) MethodID { + return MethodID{ + byte(i >> 24), + byte(i >> 16), + byte(i >> 8), + byte(i), + } +} diff --git a/eth/tracers/blocknative/decoder/method_ids_test.go b/eth/tracers/blocknative/decoder/methods_test.go similarity index 99% rename from eth/tracers/blocknative/decoder/method_ids_test.go rename to eth/tracers/blocknative/decoder/methods_test.go index e94a5906a422..a8be3e5e342f 100644 --- a/eth/tracers/blocknative/decoder/method_ids_test.go +++ b/eth/tracers/blocknative/decoder/methods_test.go @@ -8,28 +8,25 @@ import ( func TestBytecodeDecodeInterfaces(t *testing.T) { tests := []struct { - bytecode Bytecode - expected []InterfaceType + bytecode ByteCode + expected []Interface }{ - {testERC20ContractBytecode, []InterfaceType{interfaceTypeERC20}}, - {testERC721ContractBytecode, []InterfaceType{interfaceTypeERC721}}, - {testERC1155ContractBytecode, []InterfaceType{interfaceTypeERC1155}}, - {testERC1155RealWorldBytecode, []InterfaceType{interfaceTypeERC1155}}, + {testERC20ContractBytecode, []Interface{interfaceTypeERC20}}, + {testERC721ContractBytecode, []Interface{interfaceTypeERC721}}, + {testERC1155ContractBytecode, []Interface{interfaceTypeERC1155}}, + {testERC1155RealWorldBytecode, []Interface{interfaceTypeERC1155}}, } for _, test := range tests { interfaces := test.bytecode.DecodeInterfaces() require.Equal(t, test.expected, interfaces) - - singleInterface := test.bytecode.DecodeInterface() - require.Equal(t, test.expected[0], singleInterface) } } var ( - testERC20ContractBytecode = Bytecode([]byte{96, 128, 96, 64, 82, 52, 128, 21, 97, 0, 15, 87, 95, 128, 253, 91, 80, 96, 4, 54, 16, 97, 0, 145, 87, 95, 53, 96, 224, 28, 128, 99, 49, 60, 229, 103, 17, 97, 0, 100, 87, 128, 99, 49, 60, 229, 103, 20, 97, 1, 49, 87, 128, 99, 112, 160, 130, 49, 20, 97, 1, 79, 87, 128, 99, 149, 216, 155, 65, 20, 97, 1, 127, 87, 128, 99, 169, 5, 156, 187, 20, 97, 1, 157, 87, 128, 99, 221, 98, 237, 62, 20, 97, 1, 205, 87, 97, 0, 145, 86, 91, 128, 99, 6, 253, 222, 3, 20, 97, 0, 149, 87, 128, 99, 9, 94, 167, 179, 20, 97, 0, 179, 87, 128, 99, 24, 22, 13, 221, 20, 97, 0, 227, 87, 128, 99, 35, 184, 114, 221, 20, 97, 1, 1, 87, 91, 95, 128, 253, 91, 97, 0, 157, 97, 1, 253, 86, 91, 96, 64, 81, 97, 0, 170, 145, 144, 97, 3, 48, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 0, 205, 96, 4, 128, 54, 3, 129, 1, 144, 97, 0, 200, 145, 144, 97, 3, 225, 86, 91, 97, 2, 58, 86, 91, 96, 64, 81, 97, 0, 218, 145, 144, 97, 4, 57, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 0, 235, 97, 2, 65, 86, 91, 96, 64, 81, 97, 0, 248, 145, 144, 97, 4, 97, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 1, 27, 96, 4, 128, 54, 3, 129, 1, 144, 97, 1, 22, 145, 144, 97, 4, 122, 86, 91, 97, 2, 69, 86, 91, 96, 64, 81, 97, 1, 40, 145, 144, 97, 4, 57, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 1, 57, 97, 2, 77, 86, 91, 96, 64, 81, 97, 1, 70, 145, 144, 97, 4, 229, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 1, 105, 96, 4, 128, 54, 3, 129, 1, 144, 97, 1, 100, 145, 144, 97, 4, 254, 86, 91, 97, 2, 85, 86, 91, 96, 64, 81, 97, 1, 118, 145, 144, 97, 4, 97, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 1, 135, 97, 2, 91, 86, 91, 96, 64, 81, 97, 1, 148, 145, 144, 97, 3, 48, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 1, 183, 96, 4, 128, 54, 3, 129, 1, 144, 97, 1, 178, 145, 144, 97, 3, 225, 86, 91, 97, 2, 152, 86, 91, 96, 64, 81, 97, 1, 196, 145, 144, 97, 4, 57, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 1, 231, 96, 4, 128, 54, 3, 129, 1, 144, 97, 1, 226, 145, 144, 97, 5, 41, 86, 91, 97, 2, 159, 86, 91, 96, 64, 81, 97, 1, 244, 145, 144, 97, 4, 97, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 96, 96, 96, 64, 81, 128, 96, 64, 1, 96, 64, 82, 128, 96, 16, 129, 82, 96, 32, 1, 127, 84, 101, 115, 116, 32, 69, 82, 67, 50, 48, 32, 84, 111, 107, 101, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 80, 144, 80, 144, 86, 91, 95, 146, 145, 80, 80, 86, 91, 95, 144, 86, 91, 95, 147, 146, 80, 80, 80, 86, 91, 95, 96, 18, 144, 80, 144, 86, 91, 95, 145, 144, 80, 86, 91, 96, 96, 96, 64, 81, 128, 96, 64, 1, 96, 64, 82, 128, 96, 3, 129, 82, 96, 32, 1, 127, 84, 69, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 80, 144, 80, 144, 86, 91, 95, 146, 145, 80, 80, 86, 91, 95, 146, 145, 80, 80, 86, 91, 95, 129, 81, 144, 80, 145, 144, 80, 86, 91, 95, 130, 130, 82, 96, 32, 130, 1, 144, 80, 146, 145, 80, 80, 86, 91, 95, 91, 131, 129, 16, 21, 97, 2, 221, 87, 128, 130, 1, 81, 129, 132, 1, 82, 96, 32, 129, 1, 144, 80, 97, 2, 194, 86, 91, 95, 132, 132, 1, 82, 80, 80, 80, 80, 86, 91, 95, 96, 31, 25, 96, 31, 131, 1, 22, 144, 80, 145, 144, 80, 86, 91, 95, 97, 3, 2, 130, 97, 2, 166, 86, 91, 97, 3, 12, 129, 133, 97, 2, 176, 86, 91, 147, 80, 97, 3, 28, 129, 133, 96, 32, 134, 1, 97, 2, 192, 86, 91, 97, 3, 37, 129, 97, 2, 232, 86, 91, 132, 1, 145, 80, 80, 146, 145, 80, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 129, 129, 3, 95, 131, 1, 82, 97, 3, 72, 129, 132, 97, 2, 248, 86, 91, 144, 80, 146, 145, 80, 80, 86, 91, 95, 128, 253, 91, 95, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 130, 22, 144, 80, 145, 144, 80, 86, 91, 95, 97, 3, 125, 130, 97, 3, 84, 86, 91, 144, 80, 145, 144, 80, 86, 91, 97, 3, 141, 129, 97, 3, 115, 86, 91, 129, 20, 97, 3, 151, 87, 95, 128, 253, 91, 80, 86, 91, 95, 129, 53, 144, 80, 97, 3, 168, 129, 97, 3, 132, 86, 91, 146, 145, 80, 80, 86, 91, 95, 129, 144, 80, 145, 144, 80, 86, 91, 97, 3, 192, 129, 97, 3, 174, 86, 91, 129, 20, 97, 3, 202, 87, 95, 128, 253, 91, 80, 86, 91, 95, 129, 53, 144, 80, 97, 3, 219, 129, 97, 3, 183, 86, 91, 146, 145, 80, 80, 86, 91, 95, 128, 96, 64, 131, 133, 3, 18, 21, 97, 3, 247, 87, 97, 3, 246, 97, 3, 80, 86, 91, 91, 95, 97, 4, 4, 133, 130, 134, 1, 97, 3, 154, 86, 91, 146, 80, 80, 96, 32, 97, 4, 21, 133, 130, 134, 1, 97, 3, 205, 86, 91, 145, 80, 80, 146, 80, 146, 144, 80, 86, 91, 95, 129, 21, 21, 144, 80, 145, 144, 80, 86, 91, 97, 4, 51, 129, 97, 4, 31, 86, 91, 130, 82, 80, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 97, 4, 76, 95, 131, 1, 132, 97, 4, 42, 86, 91, 146, 145, 80, 80, 86, 91, 97, 4, 91, 129, 97, 3, 174, 86, 91, 130, 82, 80, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 97, 4, 116, 95, 131, 1, 132, 97, 4, 82, 86, 91, 146, 145, 80, 80, 86, 91, 95, 128, 95, 96, 96, 132, 134, 3, 18, 21, 97, 4, 145, 87, 97, 4, 144, 97, 3, 80, 86, 91, 91, 95, 97, 4, 158, 134, 130, 135, 1, 97, 3, 154, 86, 91, 147, 80, 80, 96, 32, 97, 4, 175, 134, 130, 135, 1, 97, 3, 154, 86, 91, 146, 80, 80, 96, 64, 97, 4, 192, 134, 130, 135, 1, 97, 3, 205, 86, 91, 145, 80, 80, 146, 80, 146, 80, 146, 86, 91, 95, 96, 255, 130, 22, 144, 80, 145, 144, 80, 86, 91, 97, 4, 223, 129, 97, 4, 202, 86, 91, 130, 82, 80, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 97, 4, 248, 95, 131, 1, 132, 97, 4, 214, 86, 91, 146, 145, 80, 80, 86, 91, 95, 96, 32, 130, 132, 3, 18, 21, 97, 5, 19, 87, 97, 5, 18, 97, 3, 80, 86, 91, 91, 95, 97, 5, 32, 132, 130, 133, 1, 97, 3, 154, 86, 91, 145, 80, 80, 146, 145, 80, 80, 86, 91, 95, 128, 96, 64, 131, 133, 3, 18, 21, 97, 5, 63, 87, 97, 5, 62, 97, 3, 80, 86, 91, 91, 95, 97, 5, 76, 133, 130, 134, 1, 97, 3, 154, 86, 91, 146, 80, 80, 96, 32, 97, 5, 93, 133, 130, 134, 1, 97, 3, 154, 86, 91, 145, 80, 80, 146, 80, 146, 144, 80, 86, 254, 162, 100, 105, 112, 102, 115, 88, 34, 18, 32, 72, 111, 79, 210, 211, 6, 225, 165, 48, 231, 52, 251, 88, 109, 115, 207, 52, 76, 165, 40, 78, 234, 53, 186, 174, 133, 170, 150, 196, 225, 9, 80, 100, 115, 111, 108, 99, 67, 0, 8, 21, 0, 51}) - testERC721ContractBytecode = Bytecode([]byte{96, 128, 96, 64, 82, 52, 128, 21, 97, 0, 15, 87, 95, 128, 253, 91, 80, 96, 4, 54, 16, 97, 0, 205, 87, 95, 53, 96, 224, 28, 128, 99, 99, 82, 33, 30, 17, 97, 0, 138, 87, 128, 99, 162, 44, 180, 101, 17, 97, 0, 100, 87, 128, 99, 162, 44, 180, 101, 20, 97, 2, 33, 87, 128, 99, 184, 141, 79, 222, 20, 97, 2, 61, 87, 128, 99, 200, 123, 86, 221, 20, 97, 2, 89, 87, 128, 99, 233, 133, 233, 197, 20, 97, 2, 137, 87, 97, 0, 205, 86, 91, 128, 99, 99, 82, 33, 30, 20, 97, 1, 163, 87, 128, 99, 112, 160, 130, 49, 20, 97, 1, 211, 87, 128, 99, 149, 216, 155, 65, 20, 97, 2, 3, 87, 97, 0, 205, 86, 91, 128, 99, 1, 255, 201, 167, 20, 97, 0, 209, 87, 128, 99, 6, 253, 222, 3, 20, 97, 1, 1, 87, 128, 99, 8, 24, 18, 252, 20, 97, 1, 31, 87, 128, 99, 9, 94, 167, 179, 20, 97, 1, 79, 87, 128, 99, 35, 184, 114, 221, 20, 97, 1, 107, 87, 128, 99, 66, 132, 46, 14, 20, 97, 1, 135, 87, 91, 95, 128, 253, 91, 97, 0, 235, 96, 4, 128, 54, 3, 129, 1, 144, 97, 0, 230, 145, 144, 97, 17, 177, 86, 91, 97, 2, 185, 86, 91, 96, 64, 81, 97, 0, 248, 145, 144, 97, 17, 246, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 1, 9, 97, 3, 138, 86, 91, 96, 64, 81, 97, 1, 22, 145, 144, 97, 18, 153, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 1, 57, 96, 4, 128, 54, 3, 129, 1, 144, 97, 1, 52, 145, 144, 97, 18, 236, 86, 91, 97, 3, 199, 86, 91, 96, 64, 81, 97, 1, 70, 145, 144, 97, 19, 86, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 1, 105, 96, 4, 128, 54, 3, 129, 1, 144, 97, 1, 100, 145, 144, 97, 19, 153, 86, 91, 97, 4, 157, 86, 91, 0, 91, 97, 1, 133, 96, 4, 128, 54, 3, 129, 1, 144, 97, 1, 128, 145, 144, 97, 19, 215, 86, 91, 97, 6, 121, 86, 91, 0, 91, 97, 1, 161, 96, 4, 128, 54, 3, 129, 1, 144, 97, 1, 156, 145, 144, 97, 19, 215, 86, 91, 97, 9, 83, 86, 91, 0, 91, 97, 1, 189, 96, 4, 128, 54, 3, 129, 1, 144, 97, 1, 184, 145, 144, 97, 18, 236, 86, 91, 97, 10, 135, 86, 91, 96, 64, 81, 97, 1, 202, 145, 144, 97, 19, 86, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 1, 237, 96, 4, 128, 54, 3, 129, 1, 144, 97, 1, 232, 145, 144, 97, 20, 39, 86, 91, 97, 11, 45, 86, 91, 96, 64, 81, 97, 1, 250, 145, 144, 97, 20, 97, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 2, 11, 97, 11, 225, 86, 91, 96, 64, 81, 97, 2, 24, 145, 144, 97, 18, 153, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 2, 59, 96, 4, 128, 54, 3, 129, 1, 144, 97, 2, 54, 145, 144, 97, 20, 164, 86, 91, 97, 12, 30, 86, 91, 0, 91, 97, 2, 87, 96, 4, 128, 54, 3, 129, 1, 144, 97, 2, 82, 145, 144, 97, 21, 67, 86, 91, 97, 13, 22, 86, 91, 0, 91, 97, 2, 115, 96, 4, 128, 54, 3, 129, 1, 144, 97, 2, 110, 145, 144, 97, 18, 236, 86, 91, 97, 14, 80, 86, 91, 96, 64, 81, 97, 2, 128, 145, 144, 97, 18, 153, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 2, 163, 96, 4, 128, 54, 3, 129, 1, 144, 97, 2, 158, 145, 144, 97, 21, 199, 86, 91, 97, 14, 129, 86, 91, 96, 64, 81, 97, 2, 176, 145, 144, 97, 17, 246, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 95, 127, 128, 172, 88, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 25, 22, 130, 123, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 25, 22, 20, 128, 97, 3, 131, 87, 80, 127, 1, 255, 201, 167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 25, 22, 130, 123, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 25, 22, 20, 91, 144, 80, 145, 144, 80, 86, 91, 96, 96, 96, 64, 81, 128, 96, 64, 1, 96, 64, 82, 128, 96, 11, 129, 82, 96, 32, 1, 127, 84, 101, 115, 116, 32, 69, 82, 67, 55, 50, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 80, 144, 80, 144, 86, 91, 95, 128, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 95, 128, 132, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 144, 84, 144, 97, 1, 0, 10, 144, 4, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 3, 97, 4, 101, 87, 96, 64, 81, 127, 8, 195, 121, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 96, 4, 1, 97, 4, 92, 144, 97, 22, 79, 86, 91, 96, 64, 81, 128, 145, 3, 144, 253, 91, 96, 2, 95, 131, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 144, 84, 144, 97, 1, 0, 10, 144, 4, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 144, 80, 145, 144, 80, 86, 91, 95, 128, 95, 131, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 144, 84, 144, 97, 1, 0, 10, 144, 4, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 144, 80, 128, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 51, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 20, 128, 97, 5, 139, 87, 80, 96, 3, 95, 130, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 51, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 144, 84, 144, 97, 1, 0, 10, 144, 4, 96, 255, 22, 91, 97, 5, 202, 87, 96, 64, 81, 127, 8, 195, 121, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 96, 4, 1, 97, 5, 193, 144, 97, 22, 183, 86, 91, 96, 64, 81, 128, 145, 3, 144, 253, 91, 130, 96, 2, 95, 132, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 97, 1, 0, 10, 129, 84, 129, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 2, 25, 22, 144, 131, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 2, 23, 144, 85, 80, 129, 131, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 130, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 127, 140, 91, 225, 229, 235, 236, 125, 91, 209, 79, 113, 66, 125, 30, 132, 243, 221, 3, 20, 192, 247, 178, 41, 30, 91, 32, 10, 200, 199, 195, 185, 37, 96, 64, 81, 96, 64, 81, 128, 145, 3, 144, 164, 80, 80, 80, 86, 91, 95, 128, 130, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 144, 84, 144, 97, 1, 0, 10, 144, 4, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 131, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 20, 97, 7, 22, 87, 96, 64, 81, 127, 8, 195, 121, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 96, 4, 1, 97, 7, 13, 144, 97, 23, 31, 86, 91, 96, 64, 81, 128, 145, 3, 144, 253, 91, 95, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 130, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 3, 97, 7, 132, 87, 96, 64, 81, 127, 8, 195, 121, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 96, 4, 1, 97, 7, 123, 144, 97, 23, 135, 86, 91, 96, 64, 81, 128, 145, 3, 144, 253, 91, 97, 7, 143, 131, 51, 131, 97, 14, 171, 86, 91, 97, 7, 206, 87, 96, 64, 81, 127, 8, 195, 121, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 96, 4, 1, 97, 7, 197, 144, 97, 22, 183, 86, 91, 96, 64, 81, 128, 145, 3, 144, 253, 91, 96, 1, 95, 132, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 129, 84, 128, 146, 145, 144, 97, 8, 27, 144, 97, 23, 210, 86, 91, 145, 144, 80, 85, 80, 96, 1, 95, 131, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 129, 84, 128, 146, 145, 144, 97, 8, 109, 144, 97, 23, 249, 86, 91, 145, 144, 80, 85, 80, 129, 95, 128, 131, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 97, 1, 0, 10, 129, 84, 129, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 2, 25, 22, 144, 131, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 2, 23, 144, 85, 80, 96, 2, 95, 130, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 97, 1, 0, 10, 129, 84, 144, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 2, 25, 22, 144, 85, 128, 130, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 132, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 127, 221, 242, 82, 173, 27, 226, 200, 155, 105, 194, 176, 104, 252, 55, 141, 170, 149, 43, 167, 241, 99, 196, 161, 22, 40, 245, 90, 77, 245, 35, 179, 239, 96, 64, 81, 96, 64, 81, 128, 145, 3, 144, 164, 80, 80, 80, 86, 91, 97, 9, 94, 131, 131, 131, 97, 6, 121, 86, 91, 95, 130, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 59, 20, 128, 97, 10, 67, 87, 80, 99, 21, 11, 122, 2, 96, 224, 27, 123, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 25, 22, 130, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 99, 21, 11, 122, 2, 51, 134, 133, 96, 64, 81, 132, 99, 255, 255, 255, 255, 22, 96, 224, 27, 129, 82, 96, 4, 1, 97, 9, 226, 147, 146, 145, 144, 97, 24, 115, 86, 91, 96, 32, 96, 64, 81, 128, 131, 3, 129, 95, 135, 90, 241, 21, 128, 21, 97, 9, 254, 87, 61, 95, 128, 62, 61, 95, 253, 91, 80, 80, 80, 80, 96, 64, 81, 61, 96, 31, 25, 96, 31, 130, 1, 22, 130, 1, 128, 96, 64, 82, 80, 129, 1, 144, 97, 10, 34, 145, 144, 97, 24, 207, 86, 91, 123, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 25, 22, 20, 91, 97, 10, 130, 87, 96, 64, 81, 127, 8, 195, 121, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 96, 4, 1, 97, 10, 121, 144, 97, 25, 68, 86, 91, 96, 64, 81, 128, 145, 3, 144, 253, 91, 80, 80, 80, 86, 91, 95, 128, 95, 131, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 144, 84, 144, 97, 1, 0, 10, 144, 4, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 144, 80, 95, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 129, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 3, 97, 11, 40, 87, 96, 64, 81, 127, 8, 195, 121, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 96, 4, 1, 97, 11, 31, 144, 97, 22, 79, 86, 91, 96, 64, 81, 128, 145, 3, 144, 253, 91, 145, 144, 80, 86, 91, 95, 128, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 130, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 3, 97, 11, 156, 87, 96, 64, 81, 127, 8, 195, 121, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 96, 4, 1, 97, 11, 147, 144, 97, 25, 172, 86, 91, 96, 64, 81, 128, 145, 3, 144, 253, 91, 96, 1, 95, 131, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 84, 144, 80, 145, 144, 80, 86, 91, 96, 96, 96, 64, 81, 128, 96, 64, 1, 96, 64, 82, 128, 96, 3, 129, 82, 96, 32, 1, 127, 84, 69, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 80, 144, 80, 144, 86, 91, 128, 96, 3, 95, 51, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 132, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 97, 1, 0, 10, 129, 84, 129, 96, 255, 2, 25, 22, 144, 131, 21, 21, 2, 23, 144, 85, 80, 129, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 51, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 127, 23, 48, 126, 171, 57, 171, 97, 7, 232, 137, 152, 69, 173, 61, 89, 189, 150, 83, 242, 0, 242, 32, 146, 4, 137, 202, 43, 89, 55, 105, 108, 49, 131, 96, 64, 81, 97, 13, 10, 145, 144, 97, 17, 246, 86, 91, 96, 64, 81, 128, 145, 3, 144, 163, 80, 80, 86, 91, 97, 13, 33, 133, 133, 133, 97, 6, 121, 86, 91, 95, 132, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 59, 20, 128, 97, 14, 10, 87, 80, 99, 21, 11, 122, 2, 96, 224, 27, 123, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 25, 22, 132, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 99, 21, 11, 122, 2, 51, 136, 135, 135, 135, 96, 64, 81, 134, 99, 255, 255, 255, 255, 22, 96, 224, 27, 129, 82, 96, 4, 1, 97, 13, 169, 149, 148, 147, 146, 145, 144, 97, 26, 4, 86, 91, 96, 32, 96, 64, 81, 128, 131, 3, 129, 95, 135, 90, 241, 21, 128, 21, 97, 13, 197, 87, 61, 95, 128, 62, 61, 95, 253, 91, 80, 80, 80, 80, 96, 64, 81, 61, 96, 31, 25, 96, 31, 130, 1, 22, 130, 1, 128, 96, 64, 82, 80, 129, 1, 144, 97, 13, 233, 145, 144, 97, 24, 207, 86, 91, 123, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 25, 22, 20, 91, 97, 14, 73, 87, 96, 64, 81, 127, 8, 195, 121, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 96, 4, 1, 97, 14, 64, 144, 97, 25, 68, 86, 91, 96, 64, 81, 128, 145, 3, 144, 253, 91, 80, 80, 80, 80, 80, 86, 91, 96, 96, 97, 14, 91, 130, 97, 15, 214, 86, 91, 96, 64, 81, 96, 32, 1, 97, 14, 107, 145, 144, 97, 26, 176, 86, 91, 96, 64, 81, 96, 32, 129, 131, 3, 3, 129, 82, 144, 96, 64, 82, 144, 80, 145, 144, 80, 86, 91, 96, 3, 96, 32, 82, 129, 95, 82, 96, 64, 95, 32, 96, 32, 82, 128, 95, 82, 96, 64, 95, 32, 95, 145, 80, 145, 80, 144, 84, 144, 97, 1, 0, 10, 144, 4, 96, 255, 22, 129, 86, 91, 95, 131, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 131, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 20, 128, 97, 15, 103, 87, 80, 96, 3, 95, 133, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 132, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 144, 84, 144, 97, 1, 0, 10, 144, 4, 96, 255, 22, 91, 128, 97, 15, 205, 87, 80, 96, 2, 95, 131, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 144, 84, 144, 97, 1, 0, 10, 144, 4, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 131, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 20, 91, 144, 80, 147, 146, 80, 80, 80, 86, 91, 96, 96, 95, 130, 3, 97, 16, 28, 87, 96, 64, 81, 128, 96, 64, 1, 96, 64, 82, 128, 96, 1, 129, 82, 96, 32, 1, 127, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 80, 144, 80, 97, 17, 79, 86, 91, 95, 130, 144, 80, 95, 91, 95, 130, 20, 97, 16, 75, 87, 128, 128, 97, 16, 52, 144, 97, 23, 249, 86, 91, 145, 80, 80, 96, 10, 130, 97, 16, 68, 145, 144, 97, 27, 2, 86, 91, 145, 80, 97, 16, 34, 86, 91, 95, 129, 103, 255, 255, 255, 255, 255, 255, 255, 255, 129, 17, 21, 97, 16, 102, 87, 97, 16, 101, 97, 27, 50, 86, 91, 91, 96, 64, 81, 144, 128, 130, 82, 128, 96, 31, 1, 96, 31, 25, 22, 96, 32, 1, 130, 1, 96, 64, 82, 128, 21, 97, 16, 152, 87, 129, 96, 32, 1, 96, 1, 130, 2, 128, 54, 131, 55, 128, 130, 1, 145, 80, 80, 144, 80, 91, 80, 144, 80, 95, 130, 144, 80, 91, 95, 134, 20, 97, 17, 71, 87, 96, 1, 129, 97, 16, 180, 145, 144, 97, 27, 95, 86, 91, 144, 80, 95, 96, 10, 128, 136, 97, 16, 197, 145, 144, 97, 27, 2, 86, 91, 97, 16, 207, 145, 144, 97, 27, 146, 86, 91, 135, 97, 16, 218, 145, 144, 97, 27, 95, 86, 91, 96, 48, 97, 16, 230, 145, 144, 97, 27, 223, 86, 91, 144, 80, 95, 129, 96, 248, 27, 144, 80, 128, 132, 132, 129, 81, 129, 16, 97, 17, 3, 87, 97, 17, 2, 97, 28, 19, 86, 91, 91, 96, 32, 1, 1, 144, 126, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 25, 22, 144, 129, 95, 26, 144, 83, 80, 96, 10, 136, 97, 17, 62, 145, 144, 97, 27, 2, 86, 91, 151, 80, 80, 80, 97, 16, 160, 86, 91, 129, 148, 80, 80, 80, 80, 80, 91, 145, 144, 80, 86, 91, 95, 128, 253, 91, 95, 128, 253, 91, 95, 127, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 130, 22, 144, 80, 145, 144, 80, 86, 91, 97, 17, 144, 129, 97, 17, 92, 86, 91, 129, 20, 97, 17, 154, 87, 95, 128, 253, 91, 80, 86, 91, 95, 129, 53, 144, 80, 97, 17, 171, 129, 97, 17, 135, 86, 91, 146, 145, 80, 80, 86, 91, 95, 96, 32, 130, 132, 3, 18, 21, 97, 17, 198, 87, 97, 17, 197, 97, 17, 84, 86, 91, 91, 95, 97, 17, 211, 132, 130, 133, 1, 97, 17, 157, 86, 91, 145, 80, 80, 146, 145, 80, 80, 86, 91, 95, 129, 21, 21, 144, 80, 145, 144, 80, 86, 91, 97, 17, 240, 129, 97, 17, 220, 86, 91, 130, 82, 80, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 97, 18, 9, 95, 131, 1, 132, 97, 17, 231, 86, 91, 146, 145, 80, 80, 86, 91, 95, 129, 81, 144, 80, 145, 144, 80, 86, 91, 95, 130, 130, 82, 96, 32, 130, 1, 144, 80, 146, 145, 80, 80, 86, 91, 95, 91, 131, 129, 16, 21, 97, 18, 70, 87, 128, 130, 1, 81, 129, 132, 1, 82, 96, 32, 129, 1, 144, 80, 97, 18, 43, 86, 91, 95, 132, 132, 1, 82, 80, 80, 80, 80, 86, 91, 95, 96, 31, 25, 96, 31, 131, 1, 22, 144, 80, 145, 144, 80, 86, 91, 95, 97, 18, 107, 130, 97, 18, 15, 86, 91, 97, 18, 117, 129, 133, 97, 18, 25, 86, 91, 147, 80, 97, 18, 133, 129, 133, 96, 32, 134, 1, 97, 18, 41, 86, 91, 97, 18, 142, 129, 97, 18, 81, 86, 91, 132, 1, 145, 80, 80, 146, 145, 80, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 129, 129, 3, 95, 131, 1, 82, 97, 18, 177, 129, 132, 97, 18, 97, 86, 91, 144, 80, 146, 145, 80, 80, 86, 91, 95, 129, 144, 80, 145, 144, 80, 86, 91, 97, 18, 203, 129, 97, 18, 185, 86, 91, 129, 20, 97, 18, 213, 87, 95, 128, 253, 91, 80, 86, 91, 95, 129, 53, 144, 80, 97, 18, 230, 129, 97, 18, 194, 86, 91, 146, 145, 80, 80, 86, 91, 95, 96, 32, 130, 132, 3, 18, 21, 97, 19, 1, 87, 97, 19, 0, 97, 17, 84, 86, 91, 91, 95, 97, 19, 14, 132, 130, 133, 1, 97, 18, 216, 86, 91, 145, 80, 80, 146, 145, 80, 80, 86, 91, 95, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 130, 22, 144, 80, 145, 144, 80, 86, 91, 95, 97, 19, 64, 130, 97, 19, 23, 86, 91, 144, 80, 145, 144, 80, 86, 91, 97, 19, 80, 129, 97, 19, 54, 86, 91, 130, 82, 80, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 97, 19, 105, 95, 131, 1, 132, 97, 19, 71, 86, 91, 146, 145, 80, 80, 86, 91, 97, 19, 120, 129, 97, 19, 54, 86, 91, 129, 20, 97, 19, 130, 87, 95, 128, 253, 91, 80, 86, 91, 95, 129, 53, 144, 80, 97, 19, 147, 129, 97, 19, 111, 86, 91, 146, 145, 80, 80, 86, 91, 95, 128, 96, 64, 131, 133, 3, 18, 21, 97, 19, 175, 87, 97, 19, 174, 97, 17, 84, 86, 91, 91, 95, 97, 19, 188, 133, 130, 134, 1, 97, 19, 133, 86, 91, 146, 80, 80, 96, 32, 97, 19, 205, 133, 130, 134, 1, 97, 18, 216, 86, 91, 145, 80, 80, 146, 80, 146, 144, 80, 86, 91, 95, 128, 95, 96, 96, 132, 134, 3, 18, 21, 97, 19, 238, 87, 97, 19, 237, 97, 17, 84, 86, 91, 91, 95, 97, 19, 251, 134, 130, 135, 1, 97, 19, 133, 86, 91, 147, 80, 80, 96, 32, 97, 20, 12, 134, 130, 135, 1, 97, 19, 133, 86, 91, 146, 80, 80, 96, 64, 97, 20, 29, 134, 130, 135, 1, 97, 18, 216, 86, 91, 145, 80, 80, 146, 80, 146, 80, 146, 86, 91, 95, 96, 32, 130, 132, 3, 18, 21, 97, 20, 60, 87, 97, 20, 59, 97, 17, 84, 86, 91, 91, 95, 97, 20, 73, 132, 130, 133, 1, 97, 19, 133, 86, 91, 145, 80, 80, 146, 145, 80, 80, 86, 91, 97, 20, 91, 129, 97, 18, 185, 86, 91, 130, 82, 80, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 97, 20, 116, 95, 131, 1, 132, 97, 20, 82, 86, 91, 146, 145, 80, 80, 86, 91, 97, 20, 131, 129, 97, 17, 220, 86, 91, 129, 20, 97, 20, 141, 87, 95, 128, 253, 91, 80, 86, 91, 95, 129, 53, 144, 80, 97, 20, 158, 129, 97, 20, 122, 86, 91, 146, 145, 80, 80, 86, 91, 95, 128, 96, 64, 131, 133, 3, 18, 21, 97, 20, 186, 87, 97, 20, 185, 97, 17, 84, 86, 91, 91, 95, 97, 20, 199, 133, 130, 134, 1, 97, 19, 133, 86, 91, 146, 80, 80, 96, 32, 97, 20, 216, 133, 130, 134, 1, 97, 20, 144, 86, 91, 145, 80, 80, 146, 80, 146, 144, 80, 86, 91, 95, 128, 253, 91, 95, 128, 253, 91, 95, 128, 253, 91, 95, 128, 131, 96, 31, 132, 1, 18, 97, 21, 3, 87, 97, 21, 2, 97, 20, 226, 86, 91, 91, 130, 53, 144, 80, 103, 255, 255, 255, 255, 255, 255, 255, 255, 129, 17, 21, 97, 21, 32, 87, 97, 21, 31, 97, 20, 230, 86, 91, 91, 96, 32, 131, 1, 145, 80, 131, 96, 1, 130, 2, 131, 1, 17, 21, 97, 21, 60, 87, 97, 21, 59, 97, 20, 234, 86, 91, 91, 146, 80, 146, 144, 80, 86, 91, 95, 128, 95, 128, 95, 96, 128, 134, 136, 3, 18, 21, 97, 21, 92, 87, 97, 21, 91, 97, 17, 84, 86, 91, 91, 95, 97, 21, 105, 136, 130, 137, 1, 97, 19, 133, 86, 91, 149, 80, 80, 96, 32, 97, 21, 122, 136, 130, 137, 1, 97, 19, 133, 86, 91, 148, 80, 80, 96, 64, 97, 21, 139, 136, 130, 137, 1, 97, 18, 216, 86, 91, 147, 80, 80, 96, 96, 134, 1, 53, 103, 255, 255, 255, 255, 255, 255, 255, 255, 129, 17, 21, 97, 21, 172, 87, 97, 21, 171, 97, 17, 88, 86, 91, 91, 97, 21, 184, 136, 130, 137, 1, 97, 20, 238, 86, 91, 146, 80, 146, 80, 80, 146, 149, 80, 146, 149, 144, 147, 80, 86, 91, 95, 128, 96, 64, 131, 133, 3, 18, 21, 97, 21, 221, 87, 97, 21, 220, 97, 17, 84, 86, 91, 91, 95, 97, 21, 234, 133, 130, 134, 1, 97, 19, 133, 86, 91, 146, 80, 80, 96, 32, 97, 21, 251, 133, 130, 134, 1, 97, 19, 133, 86, 91, 145, 80, 80, 146, 80, 146, 144, 80, 86, 91, 127, 116, 111, 107, 101, 110, 32, 100, 111, 101, 115, 110, 39, 116, 32, 101, 120, 105, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 130, 1, 82, 80, 86, 91, 95, 97, 22, 57, 96, 19, 131, 97, 18, 25, 86, 91, 145, 80, 97, 22, 68, 130, 97, 22, 5, 86, 91, 96, 32, 130, 1, 144, 80, 145, 144, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 129, 129, 3, 95, 131, 1, 82, 97, 22, 102, 129, 97, 22, 45, 86, 91, 144, 80, 145, 144, 80, 86, 91, 127, 110, 111, 116, 32, 97, 117, 116, 104, 111, 114, 105, 122, 101, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 130, 1, 82, 80, 86, 91, 95, 97, 22, 161, 96, 14, 131, 97, 18, 25, 86, 91, 145, 80, 97, 22, 172, 130, 97, 22, 109, 86, 91, 96, 32, 130, 1, 144, 80, 145, 144, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 129, 129, 3, 95, 131, 1, 82, 97, 22, 206, 129, 97, 22, 149, 86, 91, 144, 80, 145, 144, 80, 86, 91, 127, 102, 114, 111, 109, 32, 33, 61, 32, 111, 119, 110, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 130, 1, 82, 80, 86, 91, 95, 97, 23, 9, 96, 13, 131, 97, 18, 25, 86, 91, 145, 80, 97, 23, 20, 130, 97, 22, 213, 86, 91, 96, 32, 130, 1, 144, 80, 145, 144, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 129, 129, 3, 95, 131, 1, 82, 97, 23, 54, 129, 97, 22, 253, 86, 91, 144, 80, 145, 144, 80, 86, 91, 127, 116, 114, 97, 110, 115, 102, 101, 114, 32, 116, 111, 32, 122, 101, 114, 111, 32, 97, 100, 100, 114, 101, 115, 115, 0, 0, 0, 0, 0, 0, 0, 0, 95, 130, 1, 82, 80, 86, 91, 95, 97, 23, 113, 96, 24, 131, 97, 18, 25, 86, 91, 145, 80, 97, 23, 124, 130, 97, 23, 61, 86, 91, 96, 32, 130, 1, 144, 80, 145, 144, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 129, 129, 3, 95, 131, 1, 82, 97, 23, 158, 129, 97, 23, 101, 86, 91, 144, 80, 145, 144, 80, 86, 91, 127, 78, 72, 123, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 82, 96, 17, 96, 4, 82, 96, 36, 95, 253, 91, 95, 97, 23, 220, 130, 97, 18, 185, 86, 91, 145, 80, 95, 130, 3, 97, 23, 238, 87, 97, 23, 237, 97, 23, 165, 86, 91, 91, 96, 1, 130, 3, 144, 80, 145, 144, 80, 86, 91, 95, 97, 24, 3, 130, 97, 18, 185, 86, 91, 145, 80, 127, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 130, 3, 97, 24, 53, 87, 97, 24, 52, 97, 23, 165, 86, 91, 91, 96, 1, 130, 1, 144, 80, 145, 144, 80, 86, 91, 95, 130, 130, 82, 96, 32, 130, 1, 144, 80, 146, 145, 80, 80, 86, 91, 80, 86, 91, 95, 97, 24, 94, 95, 131, 97, 24, 64, 86, 91, 145, 80, 97, 24, 105, 130, 97, 24, 80, 86, 91, 95, 130, 1, 144, 80, 145, 144, 80, 86, 91, 95, 96, 128, 130, 1, 144, 80, 97, 24, 134, 95, 131, 1, 134, 97, 19, 71, 86, 91, 97, 24, 147, 96, 32, 131, 1, 133, 97, 19, 71, 86, 91, 97, 24, 160, 96, 64, 131, 1, 132, 97, 20, 82, 86, 91, 129, 129, 3, 96, 96, 131, 1, 82, 97, 24, 177, 129, 97, 24, 83, 86, 91, 144, 80, 148, 147, 80, 80, 80, 80, 86, 91, 95, 129, 81, 144, 80, 97, 24, 201, 129, 97, 17, 135, 86, 91, 146, 145, 80, 80, 86, 91, 95, 96, 32, 130, 132, 3, 18, 21, 97, 24, 228, 87, 97, 24, 227, 97, 17, 84, 86, 91, 91, 95, 97, 24, 241, 132, 130, 133, 1, 97, 24, 187, 86, 91, 145, 80, 80, 146, 145, 80, 80, 86, 91, 127, 117, 110, 115, 97, 102, 101, 32, 114, 101, 99, 105, 112, 105, 101, 110, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 130, 1, 82, 80, 86, 91, 95, 97, 25, 46, 96, 16, 131, 97, 18, 25, 86, 91, 145, 80, 97, 25, 57, 130, 97, 24, 250, 86, 91, 96, 32, 130, 1, 144, 80, 145, 144, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 129, 129, 3, 95, 131, 1, 82, 97, 25, 91, 129, 97, 25, 34, 86, 91, 144, 80, 145, 144, 80, 86, 91, 127, 111, 119, 110, 101, 114, 32, 61, 32, 122, 101, 114, 111, 32, 97, 100, 100, 114, 101, 115, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 130, 1, 82, 80, 86, 91, 95, 97, 25, 150, 96, 20, 131, 97, 18, 25, 86, 91, 145, 80, 97, 25, 161, 130, 97, 25, 98, 86, 91, 96, 32, 130, 1, 144, 80, 145, 144, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 129, 129, 3, 95, 131, 1, 82, 97, 25, 195, 129, 97, 25, 138, 86, 91, 144, 80, 145, 144, 80, 86, 91, 130, 129, 131, 55, 95, 131, 131, 1, 82, 80, 80, 80, 86, 91, 95, 97, 25, 227, 131, 133, 97, 24, 64, 86, 91, 147, 80, 97, 25, 240, 131, 133, 132, 97, 25, 202, 86, 91, 97, 25, 249, 131, 97, 18, 81, 86, 91, 132, 1, 144, 80, 147, 146, 80, 80, 80, 86, 91, 95, 96, 128, 130, 1, 144, 80, 97, 26, 23, 95, 131, 1, 136, 97, 19, 71, 86, 91, 97, 26, 36, 96, 32, 131, 1, 135, 97, 19, 71, 86, 91, 97, 26, 49, 96, 64, 131, 1, 134, 97, 20, 82, 86, 91, 129, 129, 3, 96, 96, 131, 1, 82, 97, 26, 68, 129, 132, 134, 97, 25, 216, 86, 91, 144, 80, 150, 149, 80, 80, 80, 80, 80, 80, 86, 91, 127, 104, 116, 116, 112, 115, 58, 47, 47, 101, 120, 97, 109, 112, 108, 101, 46, 99, 111, 109, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 80, 86, 91, 95, 129, 144, 80, 146, 145, 80, 80, 86, 91, 95, 97, 26, 138, 130, 97, 18, 15, 86, 91, 97, 26, 148, 129, 133, 97, 26, 118, 86, 91, 147, 80, 97, 26, 164, 129, 133, 96, 32, 134, 1, 97, 18, 41, 86, 91, 128, 132, 1, 145, 80, 80, 146, 145, 80, 80, 86, 91, 95, 97, 26, 186, 130, 97, 26, 80, 86, 91, 96, 20, 130, 1, 145, 80, 97, 26, 202, 130, 132, 97, 26, 128, 86, 91, 145, 80, 129, 144, 80, 146, 145, 80, 80, 86, 91, 127, 78, 72, 123, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 82, 96, 18, 96, 4, 82, 96, 36, 95, 253, 91, 95, 97, 27, 12, 130, 97, 18, 185, 86, 91, 145, 80, 97, 27, 23, 131, 97, 18, 185, 86, 91, 146, 80, 130, 97, 27, 39, 87, 97, 27, 38, 97, 26, 213, 86, 91, 91, 130, 130, 4, 144, 80, 146, 145, 80, 80, 86, 91, 127, 78, 72, 123, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 82, 96, 65, 96, 4, 82, 96, 36, 95, 253, 91, 95, 97, 27, 105, 130, 97, 18, 185, 86, 91, 145, 80, 97, 27, 116, 131, 97, 18, 185, 86, 91, 146, 80, 130, 130, 3, 144, 80, 129, 129, 17, 21, 97, 27, 140, 87, 97, 27, 139, 97, 23, 165, 86, 91, 91, 146, 145, 80, 80, 86, 91, 95, 97, 27, 156, 130, 97, 18, 185, 86, 91, 145, 80, 97, 27, 167, 131, 97, 18, 185, 86, 91, 146, 80, 130, 130, 2, 97, 27, 181, 129, 97, 18, 185, 86, 91, 145, 80, 130, 130, 4, 132, 20, 131, 21, 23, 97, 27, 204, 87, 97, 27, 203, 97, 23, 165, 86, 91, 91, 80, 146, 145, 80, 80, 86, 91, 95, 96, 255, 130, 22, 144, 80, 145, 144, 80, 86, 91, 95, 97, 27, 233, 130, 97, 27, 211, 86, 91, 145, 80, 97, 27, 244, 131, 97, 27, 211, 86, 91, 146, 80, 130, 130, 1, 144, 80, 96, 255, 129, 17, 21, 97, 28, 13, 87, 97, 28, 12, 97, 23, 165, 86, 91, 91, 146, 145, 80, 80, 86, 91, 127, 78, 72, 123, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 82, 96, 50, 96, 4, 82, 96, 36, 95, 253, 254, 162, 100, 105, 112, 102, 115, 88, 34, 18, 32, 152, 17, 252, 33, 148, 72, 1, 112, 229, 152, 121, 145, 96, 180, 163, 194, 162, 156, 32, 193, 68, 101, 246, 14, 74, 226, 43, 102, 172, 20, 137, 30, 100, 115, 111, 108, 99, 67, 0, 8, 21, 0, 51}) - testERC1155ContractBytecode = Bytecode([]byte{96, 128, 96, 64, 82, 52, 128, 21, 97, 0, 15, 87, 95, 128, 253, 91, 80, 96, 4, 54, 16, 97, 0, 95, 87, 95, 53, 96, 224, 28, 128, 98, 253, 213, 142, 20, 97, 0, 99, 87, 128, 99, 46, 178, 194, 214, 20, 97, 0, 147, 87, 128, 99, 78, 18, 115, 244, 20, 97, 0, 175, 87, 128, 99, 162, 44, 180, 101, 20, 97, 0, 223, 87, 128, 99, 233, 133, 233, 197, 20, 97, 0, 251, 87, 128, 99, 242, 66, 67, 42, 20, 97, 1, 43, 87, 91, 95, 128, 253, 91, 97, 0, 125, 96, 4, 128, 54, 3, 129, 1, 144, 97, 0, 120, 145, 144, 97, 2, 10, 86, 91, 97, 1, 71, 86, 91, 96, 64, 81, 97, 0, 138, 145, 144, 97, 2, 87, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 0, 173, 96, 4, 128, 54, 3, 129, 1, 144, 97, 0, 168, 145, 144, 97, 3, 38, 86, 91, 97, 1, 78, 86, 91, 0, 91, 97, 0, 201, 96, 4, 128, 54, 3, 129, 1, 144, 97, 0, 196, 145, 144, 97, 4, 82, 86, 91, 97, 1, 88, 86, 91, 96, 64, 81, 97, 0, 214, 145, 144, 97, 5, 135, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 0, 249, 96, 4, 128, 54, 3, 129, 1, 144, 97, 0, 244, 145, 144, 97, 5, 220, 86, 91, 97, 1, 98, 86, 91, 0, 91, 97, 1, 21, 96, 4, 128, 54, 3, 129, 1, 144, 97, 1, 16, 145, 144, 97, 6, 26, 86, 91, 97, 1, 102, 86, 91, 96, 64, 81, 97, 1, 34, 145, 144, 97, 6, 103, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 1, 69, 96, 4, 128, 54, 3, 129, 1, 144, 97, 1, 64, 145, 144, 97, 6, 128, 86, 91, 97, 1, 109, 86, 91, 0, 91, 95, 146, 145, 80, 80, 86, 91, 80, 80, 80, 80, 80, 80, 80, 80, 86, 91, 96, 96, 148, 147, 80, 80, 80, 80, 86, 91, 80, 80, 86, 91, 95, 146, 145, 80, 80, 86, 91, 80, 80, 80, 80, 80, 80, 86, 91, 95, 128, 253, 91, 95, 128, 253, 91, 95, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 130, 22, 144, 80, 145, 144, 80, 86, 91, 95, 97, 1, 166, 130, 97, 1, 125, 86, 91, 144, 80, 145, 144, 80, 86, 91, 97, 1, 182, 129, 97, 1, 156, 86, 91, 129, 20, 97, 1, 192, 87, 95, 128, 253, 91, 80, 86, 91, 95, 129, 53, 144, 80, 97, 1, 209, 129, 97, 1, 173, 86, 91, 146, 145, 80, 80, 86, 91, 95, 129, 144, 80, 145, 144, 80, 86, 91, 97, 1, 233, 129, 97, 1, 215, 86, 91, 129, 20, 97, 1, 243, 87, 95, 128, 253, 91, 80, 86, 91, 95, 129, 53, 144, 80, 97, 2, 4, 129, 97, 1, 224, 86, 91, 146, 145, 80, 80, 86, 91, 95, 128, 96, 64, 131, 133, 3, 18, 21, 97, 2, 32, 87, 97, 2, 31, 97, 1, 117, 86, 91, 91, 95, 97, 2, 45, 133, 130, 134, 1, 97, 1, 195, 86, 91, 146, 80, 80, 96, 32, 97, 2, 62, 133, 130, 134, 1, 97, 1, 246, 86, 91, 145, 80, 80, 146, 80, 146, 144, 80, 86, 91, 97, 2, 81, 129, 97, 1, 215, 86, 91, 130, 82, 80, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 97, 2, 106, 95, 131, 1, 132, 97, 2, 72, 86, 91, 146, 145, 80, 80, 86, 91, 95, 128, 253, 91, 95, 128, 253, 91, 95, 128, 253, 91, 95, 128, 131, 96, 31, 132, 1, 18, 97, 2, 145, 87, 97, 2, 144, 97, 2, 112, 86, 91, 91, 130, 53, 144, 80, 103, 255, 255, 255, 255, 255, 255, 255, 255, 129, 17, 21, 97, 2, 174, 87, 97, 2, 173, 97, 2, 116, 86, 91, 91, 96, 32, 131, 1, 145, 80, 131, 96, 32, 130, 2, 131, 1, 17, 21, 97, 2, 202, 87, 97, 2, 201, 97, 2, 120, 86, 91, 91, 146, 80, 146, 144, 80, 86, 91, 95, 128, 131, 96, 31, 132, 1, 18, 97, 2, 230, 87, 97, 2, 229, 97, 2, 112, 86, 91, 91, 130, 53, 144, 80, 103, 255, 255, 255, 255, 255, 255, 255, 255, 129, 17, 21, 97, 3, 3, 87, 97, 3, 2, 97, 2, 116, 86, 91, 91, 96, 32, 131, 1, 145, 80, 131, 96, 1, 130, 2, 131, 1, 17, 21, 97, 3, 31, 87, 97, 3, 30, 97, 2, 120, 86, 91, 91, 146, 80, 146, 144, 80, 86, 91, 95, 128, 95, 128, 95, 128, 95, 128, 96, 160, 137, 139, 3, 18, 21, 97, 3, 66, 87, 97, 3, 65, 97, 1, 117, 86, 91, 91, 95, 97, 3, 79, 139, 130, 140, 1, 97, 1, 195, 86, 91, 152, 80, 80, 96, 32, 97, 3, 96, 139, 130, 140, 1, 97, 1, 195, 86, 91, 151, 80, 80, 96, 64, 137, 1, 53, 103, 255, 255, 255, 255, 255, 255, 255, 255, 129, 17, 21, 97, 3, 129, 87, 97, 3, 128, 97, 1, 121, 86, 91, 91, 97, 3, 141, 139, 130, 140, 1, 97, 2, 124, 86, 91, 150, 80, 150, 80, 80, 96, 96, 137, 1, 53, 103, 255, 255, 255, 255, 255, 255, 255, 255, 129, 17, 21, 97, 3, 176, 87, 97, 3, 175, 97, 1, 121, 86, 91, 91, 97, 3, 188, 139, 130, 140, 1, 97, 2, 124, 86, 91, 148, 80, 148, 80, 80, 96, 128, 137, 1, 53, 103, 255, 255, 255, 255, 255, 255, 255, 255, 129, 17, 21, 97, 3, 223, 87, 97, 3, 222, 97, 1, 121, 86, 91, 91, 97, 3, 235, 139, 130, 140, 1, 97, 2, 209, 86, 91, 146, 80, 146, 80, 80, 146, 149, 152, 80, 146, 149, 152, 144, 147, 150, 80, 86, 91, 95, 128, 131, 96, 31, 132, 1, 18, 97, 4, 18, 87, 97, 4, 17, 97, 2, 112, 86, 91, 91, 130, 53, 144, 80, 103, 255, 255, 255, 255, 255, 255, 255, 255, 129, 17, 21, 97, 4, 47, 87, 97, 4, 46, 97, 2, 116, 86, 91, 91, 96, 32, 131, 1, 145, 80, 131, 96, 32, 130, 2, 131, 1, 17, 21, 97, 4, 75, 87, 97, 4, 74, 97, 2, 120, 86, 91, 91, 146, 80, 146, 144, 80, 86, 91, 95, 128, 95, 128, 96, 64, 133, 135, 3, 18, 21, 97, 4, 106, 87, 97, 4, 105, 97, 1, 117, 86, 91, 91, 95, 133, 1, 53, 103, 255, 255, 255, 255, 255, 255, 255, 255, 129, 17, 21, 97, 4, 135, 87, 97, 4, 134, 97, 1, 121, 86, 91, 91, 97, 4, 147, 135, 130, 136, 1, 97, 3, 253, 86, 91, 148, 80, 148, 80, 80, 96, 32, 133, 1, 53, 103, 255, 255, 255, 255, 255, 255, 255, 255, 129, 17, 21, 97, 4, 182, 87, 97, 4, 181, 97, 1, 121, 86, 91, 91, 97, 4, 194, 135, 130, 136, 1, 97, 2, 124, 86, 91, 146, 80, 146, 80, 80, 146, 149, 145, 148, 80, 146, 80, 86, 91, 95, 129, 81, 144, 80, 145, 144, 80, 86, 91, 95, 130, 130, 82, 96, 32, 130, 1, 144, 80, 146, 145, 80, 80, 86, 91, 95, 129, 144, 80, 96, 32, 130, 1, 144, 80, 145, 144, 80, 86, 91, 97, 5, 2, 129, 97, 1, 215, 86, 91, 130, 82, 80, 80, 86, 91, 95, 97, 5, 19, 131, 131, 97, 4, 249, 86, 91, 96, 32, 131, 1, 144, 80, 146, 145, 80, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 145, 144, 80, 86, 91, 95, 97, 5, 53, 130, 97, 4, 208, 86, 91, 97, 5, 63, 129, 133, 97, 4, 218, 86, 91, 147, 80, 97, 5, 74, 131, 97, 4, 234, 86, 91, 128, 95, 91, 131, 129, 16, 21, 97, 5, 122, 87, 129, 81, 97, 5, 97, 136, 130, 97, 5, 8, 86, 91, 151, 80, 97, 5, 108, 131, 97, 5, 31, 86, 91, 146, 80, 80, 96, 1, 129, 1, 144, 80, 97, 5, 77, 86, 91, 80, 133, 147, 80, 80, 80, 80, 146, 145, 80, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 129, 129, 3, 95, 131, 1, 82, 97, 5, 159, 129, 132, 97, 5, 43, 86, 91, 144, 80, 146, 145, 80, 80, 86, 91, 95, 129, 21, 21, 144, 80, 145, 144, 80, 86, 91, 97, 5, 187, 129, 97, 5, 167, 86, 91, 129, 20, 97, 5, 197, 87, 95, 128, 253, 91, 80, 86, 91, 95, 129, 53, 144, 80, 97, 5, 214, 129, 97, 5, 178, 86, 91, 146, 145, 80, 80, 86, 91, 95, 128, 96, 64, 131, 133, 3, 18, 21, 97, 5, 242, 87, 97, 5, 241, 97, 1, 117, 86, 91, 91, 95, 97, 5, 255, 133, 130, 134, 1, 97, 1, 195, 86, 91, 146, 80, 80, 96, 32, 97, 6, 16, 133, 130, 134, 1, 97, 5, 200, 86, 91, 145, 80, 80, 146, 80, 146, 144, 80, 86, 91, 95, 128, 96, 64, 131, 133, 3, 18, 21, 97, 6, 48, 87, 97, 6, 47, 97, 1, 117, 86, 91, 91, 95, 97, 6, 61, 133, 130, 134, 1, 97, 1, 195, 86, 91, 146, 80, 80, 96, 32, 97, 6, 78, 133, 130, 134, 1, 97, 1, 195, 86, 91, 145, 80, 80, 146, 80, 146, 144, 80, 86, 91, 97, 6, 97, 129, 97, 5, 167, 86, 91, 130, 82, 80, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 97, 6, 122, 95, 131, 1, 132, 97, 6, 88, 86, 91, 146, 145, 80, 80, 86, 91, 95, 128, 95, 128, 95, 128, 96, 160, 135, 137, 3, 18, 21, 97, 6, 154, 87, 97, 6, 153, 97, 1, 117, 86, 91, 91, 95, 97, 6, 167, 137, 130, 138, 1, 97, 1, 195, 86, 91, 150, 80, 80, 96, 32, 97, 6, 184, 137, 130, 138, 1, 97, 1, 195, 86, 91, 149, 80, 80, 96, 64, 97, 6, 201, 137, 130, 138, 1, 97, 1, 246, 86, 91, 148, 80, 80, 96, 96, 97, 6, 218, 137, 130, 138, 1, 97, 1, 246, 86, 91, 147, 80, 80, 96, 128, 135, 1, 53, 103, 255, 255, 255, 255, 255, 255, 255, 255, 129, 17, 21, 97, 6, 251, 87, 97, 6, 250, 97, 1, 121, 86, 91, 91, 97, 7, 7, 137, 130, 138, 1, 97, 2, 209, 86, 91, 146, 80, 146, 80, 80, 146, 149, 80, 146, 149, 80, 146, 149, 86, 254, 162, 100, 105, 112, 102, 115, 88, 34, 18, 32, 148, 159, 178, 116, 208, 174, 11, 170, 125, 189, 81, 142, 193, 10, 233, 27, 120, 223, 28, 202, 63, 46, 164, 30, 109, 18, 61, 127, 117, 110, 98, 132, 100, 115, 111, 108, 99, 67, 0, 8, 21, 0, 51}) + testERC20ContractBytecode = ByteCode([]byte{96, 128, 96, 64, 82, 52, 128, 21, 97, 0, 15, 87, 95, 128, 253, 91, 80, 96, 4, 54, 16, 97, 0, 145, 87, 95, 53, 96, 224, 28, 128, 99, 49, 60, 229, 103, 17, 97, 0, 100, 87, 128, 99, 49, 60, 229, 103, 20, 97, 1, 49, 87, 128, 99, 112, 160, 130, 49, 20, 97, 1, 79, 87, 128, 99, 149, 216, 155, 65, 20, 97, 1, 127, 87, 128, 99, 169, 5, 156, 187, 20, 97, 1, 157, 87, 128, 99, 221, 98, 237, 62, 20, 97, 1, 205, 87, 97, 0, 145, 86, 91, 128, 99, 6, 253, 222, 3, 20, 97, 0, 149, 87, 128, 99, 9, 94, 167, 179, 20, 97, 0, 179, 87, 128, 99, 24, 22, 13, 221, 20, 97, 0, 227, 87, 128, 99, 35, 184, 114, 221, 20, 97, 1, 1, 87, 91, 95, 128, 253, 91, 97, 0, 157, 97, 1, 253, 86, 91, 96, 64, 81, 97, 0, 170, 145, 144, 97, 3, 48, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 0, 205, 96, 4, 128, 54, 3, 129, 1, 144, 97, 0, 200, 145, 144, 97, 3, 225, 86, 91, 97, 2, 58, 86, 91, 96, 64, 81, 97, 0, 218, 145, 144, 97, 4, 57, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 0, 235, 97, 2, 65, 86, 91, 96, 64, 81, 97, 0, 248, 145, 144, 97, 4, 97, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 1, 27, 96, 4, 128, 54, 3, 129, 1, 144, 97, 1, 22, 145, 144, 97, 4, 122, 86, 91, 97, 2, 69, 86, 91, 96, 64, 81, 97, 1, 40, 145, 144, 97, 4, 57, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 1, 57, 97, 2, 77, 86, 91, 96, 64, 81, 97, 1, 70, 145, 144, 97, 4, 229, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 1, 105, 96, 4, 128, 54, 3, 129, 1, 144, 97, 1, 100, 145, 144, 97, 4, 254, 86, 91, 97, 2, 85, 86, 91, 96, 64, 81, 97, 1, 118, 145, 144, 97, 4, 97, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 1, 135, 97, 2, 91, 86, 91, 96, 64, 81, 97, 1, 148, 145, 144, 97, 3, 48, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 1, 183, 96, 4, 128, 54, 3, 129, 1, 144, 97, 1, 178, 145, 144, 97, 3, 225, 86, 91, 97, 2, 152, 86, 91, 96, 64, 81, 97, 1, 196, 145, 144, 97, 4, 57, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 1, 231, 96, 4, 128, 54, 3, 129, 1, 144, 97, 1, 226, 145, 144, 97, 5, 41, 86, 91, 97, 2, 159, 86, 91, 96, 64, 81, 97, 1, 244, 145, 144, 97, 4, 97, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 96, 96, 96, 64, 81, 128, 96, 64, 1, 96, 64, 82, 128, 96, 16, 129, 82, 96, 32, 1, 127, 84, 101, 115, 116, 32, 69, 82, 67, 50, 48, 32, 84, 111, 107, 101, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 80, 144, 80, 144, 86, 91, 95, 146, 145, 80, 80, 86, 91, 95, 144, 86, 91, 95, 147, 146, 80, 80, 80, 86, 91, 95, 96, 18, 144, 80, 144, 86, 91, 95, 145, 144, 80, 86, 91, 96, 96, 96, 64, 81, 128, 96, 64, 1, 96, 64, 82, 128, 96, 3, 129, 82, 96, 32, 1, 127, 84, 69, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 80, 144, 80, 144, 86, 91, 95, 146, 145, 80, 80, 86, 91, 95, 146, 145, 80, 80, 86, 91, 95, 129, 81, 144, 80, 145, 144, 80, 86, 91, 95, 130, 130, 82, 96, 32, 130, 1, 144, 80, 146, 145, 80, 80, 86, 91, 95, 91, 131, 129, 16, 21, 97, 2, 221, 87, 128, 130, 1, 81, 129, 132, 1, 82, 96, 32, 129, 1, 144, 80, 97, 2, 194, 86, 91, 95, 132, 132, 1, 82, 80, 80, 80, 80, 86, 91, 95, 96, 31, 25, 96, 31, 131, 1, 22, 144, 80, 145, 144, 80, 86, 91, 95, 97, 3, 2, 130, 97, 2, 166, 86, 91, 97, 3, 12, 129, 133, 97, 2, 176, 86, 91, 147, 80, 97, 3, 28, 129, 133, 96, 32, 134, 1, 97, 2, 192, 86, 91, 97, 3, 37, 129, 97, 2, 232, 86, 91, 132, 1, 145, 80, 80, 146, 145, 80, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 129, 129, 3, 95, 131, 1, 82, 97, 3, 72, 129, 132, 97, 2, 248, 86, 91, 144, 80, 146, 145, 80, 80, 86, 91, 95, 128, 253, 91, 95, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 130, 22, 144, 80, 145, 144, 80, 86, 91, 95, 97, 3, 125, 130, 97, 3, 84, 86, 91, 144, 80, 145, 144, 80, 86, 91, 97, 3, 141, 129, 97, 3, 115, 86, 91, 129, 20, 97, 3, 151, 87, 95, 128, 253, 91, 80, 86, 91, 95, 129, 53, 144, 80, 97, 3, 168, 129, 97, 3, 132, 86, 91, 146, 145, 80, 80, 86, 91, 95, 129, 144, 80, 145, 144, 80, 86, 91, 97, 3, 192, 129, 97, 3, 174, 86, 91, 129, 20, 97, 3, 202, 87, 95, 128, 253, 91, 80, 86, 91, 95, 129, 53, 144, 80, 97, 3, 219, 129, 97, 3, 183, 86, 91, 146, 145, 80, 80, 86, 91, 95, 128, 96, 64, 131, 133, 3, 18, 21, 97, 3, 247, 87, 97, 3, 246, 97, 3, 80, 86, 91, 91, 95, 97, 4, 4, 133, 130, 134, 1, 97, 3, 154, 86, 91, 146, 80, 80, 96, 32, 97, 4, 21, 133, 130, 134, 1, 97, 3, 205, 86, 91, 145, 80, 80, 146, 80, 146, 144, 80, 86, 91, 95, 129, 21, 21, 144, 80, 145, 144, 80, 86, 91, 97, 4, 51, 129, 97, 4, 31, 86, 91, 130, 82, 80, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 97, 4, 76, 95, 131, 1, 132, 97, 4, 42, 86, 91, 146, 145, 80, 80, 86, 91, 97, 4, 91, 129, 97, 3, 174, 86, 91, 130, 82, 80, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 97, 4, 116, 95, 131, 1, 132, 97, 4, 82, 86, 91, 146, 145, 80, 80, 86, 91, 95, 128, 95, 96, 96, 132, 134, 3, 18, 21, 97, 4, 145, 87, 97, 4, 144, 97, 3, 80, 86, 91, 91, 95, 97, 4, 158, 134, 130, 135, 1, 97, 3, 154, 86, 91, 147, 80, 80, 96, 32, 97, 4, 175, 134, 130, 135, 1, 97, 3, 154, 86, 91, 146, 80, 80, 96, 64, 97, 4, 192, 134, 130, 135, 1, 97, 3, 205, 86, 91, 145, 80, 80, 146, 80, 146, 80, 146, 86, 91, 95, 96, 255, 130, 22, 144, 80, 145, 144, 80, 86, 91, 97, 4, 223, 129, 97, 4, 202, 86, 91, 130, 82, 80, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 97, 4, 248, 95, 131, 1, 132, 97, 4, 214, 86, 91, 146, 145, 80, 80, 86, 91, 95, 96, 32, 130, 132, 3, 18, 21, 97, 5, 19, 87, 97, 5, 18, 97, 3, 80, 86, 91, 91, 95, 97, 5, 32, 132, 130, 133, 1, 97, 3, 154, 86, 91, 145, 80, 80, 146, 145, 80, 80, 86, 91, 95, 128, 96, 64, 131, 133, 3, 18, 21, 97, 5, 63, 87, 97, 5, 62, 97, 3, 80, 86, 91, 91, 95, 97, 5, 76, 133, 130, 134, 1, 97, 3, 154, 86, 91, 146, 80, 80, 96, 32, 97, 5, 93, 133, 130, 134, 1, 97, 3, 154, 86, 91, 145, 80, 80, 146, 80, 146, 144, 80, 86, 254, 162, 100, 105, 112, 102, 115, 88, 34, 18, 32, 72, 111, 79, 210, 211, 6, 225, 165, 48, 231, 52, 251, 88, 109, 115, 207, 52, 76, 165, 40, 78, 234, 53, 186, 174, 133, 170, 150, 196, 225, 9, 80, 100, 115, 111, 108, 99, 67, 0, 8, 21, 0, 51}) + testERC721ContractBytecode = ByteCode([]byte{96, 128, 96, 64, 82, 52, 128, 21, 97, 0, 15, 87, 95, 128, 253, 91, 80, 96, 4, 54, 16, 97, 0, 205, 87, 95, 53, 96, 224, 28, 128, 99, 99, 82, 33, 30, 17, 97, 0, 138, 87, 128, 99, 162, 44, 180, 101, 17, 97, 0, 100, 87, 128, 99, 162, 44, 180, 101, 20, 97, 2, 33, 87, 128, 99, 184, 141, 79, 222, 20, 97, 2, 61, 87, 128, 99, 200, 123, 86, 221, 20, 97, 2, 89, 87, 128, 99, 233, 133, 233, 197, 20, 97, 2, 137, 87, 97, 0, 205, 86, 91, 128, 99, 99, 82, 33, 30, 20, 97, 1, 163, 87, 128, 99, 112, 160, 130, 49, 20, 97, 1, 211, 87, 128, 99, 149, 216, 155, 65, 20, 97, 2, 3, 87, 97, 0, 205, 86, 91, 128, 99, 1, 255, 201, 167, 20, 97, 0, 209, 87, 128, 99, 6, 253, 222, 3, 20, 97, 1, 1, 87, 128, 99, 8, 24, 18, 252, 20, 97, 1, 31, 87, 128, 99, 9, 94, 167, 179, 20, 97, 1, 79, 87, 128, 99, 35, 184, 114, 221, 20, 97, 1, 107, 87, 128, 99, 66, 132, 46, 14, 20, 97, 1, 135, 87, 91, 95, 128, 253, 91, 97, 0, 235, 96, 4, 128, 54, 3, 129, 1, 144, 97, 0, 230, 145, 144, 97, 17, 177, 86, 91, 97, 2, 185, 86, 91, 96, 64, 81, 97, 0, 248, 145, 144, 97, 17, 246, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 1, 9, 97, 3, 138, 86, 91, 96, 64, 81, 97, 1, 22, 145, 144, 97, 18, 153, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 1, 57, 96, 4, 128, 54, 3, 129, 1, 144, 97, 1, 52, 145, 144, 97, 18, 236, 86, 91, 97, 3, 199, 86, 91, 96, 64, 81, 97, 1, 70, 145, 144, 97, 19, 86, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 1, 105, 96, 4, 128, 54, 3, 129, 1, 144, 97, 1, 100, 145, 144, 97, 19, 153, 86, 91, 97, 4, 157, 86, 91, 0, 91, 97, 1, 133, 96, 4, 128, 54, 3, 129, 1, 144, 97, 1, 128, 145, 144, 97, 19, 215, 86, 91, 97, 6, 121, 86, 91, 0, 91, 97, 1, 161, 96, 4, 128, 54, 3, 129, 1, 144, 97, 1, 156, 145, 144, 97, 19, 215, 86, 91, 97, 9, 83, 86, 91, 0, 91, 97, 1, 189, 96, 4, 128, 54, 3, 129, 1, 144, 97, 1, 184, 145, 144, 97, 18, 236, 86, 91, 97, 10, 135, 86, 91, 96, 64, 81, 97, 1, 202, 145, 144, 97, 19, 86, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 1, 237, 96, 4, 128, 54, 3, 129, 1, 144, 97, 1, 232, 145, 144, 97, 20, 39, 86, 91, 97, 11, 45, 86, 91, 96, 64, 81, 97, 1, 250, 145, 144, 97, 20, 97, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 2, 11, 97, 11, 225, 86, 91, 96, 64, 81, 97, 2, 24, 145, 144, 97, 18, 153, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 2, 59, 96, 4, 128, 54, 3, 129, 1, 144, 97, 2, 54, 145, 144, 97, 20, 164, 86, 91, 97, 12, 30, 86, 91, 0, 91, 97, 2, 87, 96, 4, 128, 54, 3, 129, 1, 144, 97, 2, 82, 145, 144, 97, 21, 67, 86, 91, 97, 13, 22, 86, 91, 0, 91, 97, 2, 115, 96, 4, 128, 54, 3, 129, 1, 144, 97, 2, 110, 145, 144, 97, 18, 236, 86, 91, 97, 14, 80, 86, 91, 96, 64, 81, 97, 2, 128, 145, 144, 97, 18, 153, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 2, 163, 96, 4, 128, 54, 3, 129, 1, 144, 97, 2, 158, 145, 144, 97, 21, 199, 86, 91, 97, 14, 129, 86, 91, 96, 64, 81, 97, 2, 176, 145, 144, 97, 17, 246, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 95, 127, 128, 172, 88, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 25, 22, 130, 123, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 25, 22, 20, 128, 97, 3, 131, 87, 80, 127, 1, 255, 201, 167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 25, 22, 130, 123, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 25, 22, 20, 91, 144, 80, 145, 144, 80, 86, 91, 96, 96, 96, 64, 81, 128, 96, 64, 1, 96, 64, 82, 128, 96, 11, 129, 82, 96, 32, 1, 127, 84, 101, 115, 116, 32, 69, 82, 67, 55, 50, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 80, 144, 80, 144, 86, 91, 95, 128, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 95, 128, 132, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 144, 84, 144, 97, 1, 0, 10, 144, 4, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 3, 97, 4, 101, 87, 96, 64, 81, 127, 8, 195, 121, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 96, 4, 1, 97, 4, 92, 144, 97, 22, 79, 86, 91, 96, 64, 81, 128, 145, 3, 144, 253, 91, 96, 2, 95, 131, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 144, 84, 144, 97, 1, 0, 10, 144, 4, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 144, 80, 145, 144, 80, 86, 91, 95, 128, 95, 131, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 144, 84, 144, 97, 1, 0, 10, 144, 4, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 144, 80, 128, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 51, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 20, 128, 97, 5, 139, 87, 80, 96, 3, 95, 130, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 51, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 144, 84, 144, 97, 1, 0, 10, 144, 4, 96, 255, 22, 91, 97, 5, 202, 87, 96, 64, 81, 127, 8, 195, 121, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 96, 4, 1, 97, 5, 193, 144, 97, 22, 183, 86, 91, 96, 64, 81, 128, 145, 3, 144, 253, 91, 130, 96, 2, 95, 132, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 97, 1, 0, 10, 129, 84, 129, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 2, 25, 22, 144, 131, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 2, 23, 144, 85, 80, 129, 131, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 130, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 127, 140, 91, 225, 229, 235, 236, 125, 91, 209, 79, 113, 66, 125, 30, 132, 243, 221, 3, 20, 192, 247, 178, 41, 30, 91, 32, 10, 200, 199, 195, 185, 37, 96, 64, 81, 96, 64, 81, 128, 145, 3, 144, 164, 80, 80, 80, 86, 91, 95, 128, 130, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 144, 84, 144, 97, 1, 0, 10, 144, 4, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 131, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 20, 97, 7, 22, 87, 96, 64, 81, 127, 8, 195, 121, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 96, 4, 1, 97, 7, 13, 144, 97, 23, 31, 86, 91, 96, 64, 81, 128, 145, 3, 144, 253, 91, 95, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 130, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 3, 97, 7, 132, 87, 96, 64, 81, 127, 8, 195, 121, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 96, 4, 1, 97, 7, 123, 144, 97, 23, 135, 86, 91, 96, 64, 81, 128, 145, 3, 144, 253, 91, 97, 7, 143, 131, 51, 131, 97, 14, 171, 86, 91, 97, 7, 206, 87, 96, 64, 81, 127, 8, 195, 121, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 96, 4, 1, 97, 7, 197, 144, 97, 22, 183, 86, 91, 96, 64, 81, 128, 145, 3, 144, 253, 91, 96, 1, 95, 132, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 129, 84, 128, 146, 145, 144, 97, 8, 27, 144, 97, 23, 210, 86, 91, 145, 144, 80, 85, 80, 96, 1, 95, 131, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 129, 84, 128, 146, 145, 144, 97, 8, 109, 144, 97, 23, 249, 86, 91, 145, 144, 80, 85, 80, 129, 95, 128, 131, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 97, 1, 0, 10, 129, 84, 129, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 2, 25, 22, 144, 131, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 2, 23, 144, 85, 80, 96, 2, 95, 130, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 97, 1, 0, 10, 129, 84, 144, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 2, 25, 22, 144, 85, 128, 130, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 132, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 127, 221, 242, 82, 173, 27, 226, 200, 155, 105, 194, 176, 104, 252, 55, 141, 170, 149, 43, 167, 241, 99, 196, 161, 22, 40, 245, 90, 77, 245, 35, 179, 239, 96, 64, 81, 96, 64, 81, 128, 145, 3, 144, 164, 80, 80, 80, 86, 91, 97, 9, 94, 131, 131, 131, 97, 6, 121, 86, 91, 95, 130, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 59, 20, 128, 97, 10, 67, 87, 80, 99, 21, 11, 122, 2, 96, 224, 27, 123, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 25, 22, 130, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 99, 21, 11, 122, 2, 51, 134, 133, 96, 64, 81, 132, 99, 255, 255, 255, 255, 22, 96, 224, 27, 129, 82, 96, 4, 1, 97, 9, 226, 147, 146, 145, 144, 97, 24, 115, 86, 91, 96, 32, 96, 64, 81, 128, 131, 3, 129, 95, 135, 90, 241, 21, 128, 21, 97, 9, 254, 87, 61, 95, 128, 62, 61, 95, 253, 91, 80, 80, 80, 80, 96, 64, 81, 61, 96, 31, 25, 96, 31, 130, 1, 22, 130, 1, 128, 96, 64, 82, 80, 129, 1, 144, 97, 10, 34, 145, 144, 97, 24, 207, 86, 91, 123, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 25, 22, 20, 91, 97, 10, 130, 87, 96, 64, 81, 127, 8, 195, 121, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 96, 4, 1, 97, 10, 121, 144, 97, 25, 68, 86, 91, 96, 64, 81, 128, 145, 3, 144, 253, 91, 80, 80, 80, 86, 91, 95, 128, 95, 131, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 144, 84, 144, 97, 1, 0, 10, 144, 4, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 144, 80, 95, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 129, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 3, 97, 11, 40, 87, 96, 64, 81, 127, 8, 195, 121, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 96, 4, 1, 97, 11, 31, 144, 97, 22, 79, 86, 91, 96, 64, 81, 128, 145, 3, 144, 253, 91, 145, 144, 80, 86, 91, 95, 128, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 130, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 3, 97, 11, 156, 87, 96, 64, 81, 127, 8, 195, 121, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 96, 4, 1, 97, 11, 147, 144, 97, 25, 172, 86, 91, 96, 64, 81, 128, 145, 3, 144, 253, 91, 96, 1, 95, 131, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 84, 144, 80, 145, 144, 80, 86, 91, 96, 96, 96, 64, 81, 128, 96, 64, 1, 96, 64, 82, 128, 96, 3, 129, 82, 96, 32, 1, 127, 84, 69, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 80, 144, 80, 144, 86, 91, 128, 96, 3, 95, 51, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 132, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 97, 1, 0, 10, 129, 84, 129, 96, 255, 2, 25, 22, 144, 131, 21, 21, 2, 23, 144, 85, 80, 129, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 51, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 127, 23, 48, 126, 171, 57, 171, 97, 7, 232, 137, 152, 69, 173, 61, 89, 189, 150, 83, 242, 0, 242, 32, 146, 4, 137, 202, 43, 89, 55, 105, 108, 49, 131, 96, 64, 81, 97, 13, 10, 145, 144, 97, 17, 246, 86, 91, 96, 64, 81, 128, 145, 3, 144, 163, 80, 80, 86, 91, 97, 13, 33, 133, 133, 133, 97, 6, 121, 86, 91, 95, 132, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 59, 20, 128, 97, 14, 10, 87, 80, 99, 21, 11, 122, 2, 96, 224, 27, 123, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 25, 22, 132, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 99, 21, 11, 122, 2, 51, 136, 135, 135, 135, 96, 64, 81, 134, 99, 255, 255, 255, 255, 22, 96, 224, 27, 129, 82, 96, 4, 1, 97, 13, 169, 149, 148, 147, 146, 145, 144, 97, 26, 4, 86, 91, 96, 32, 96, 64, 81, 128, 131, 3, 129, 95, 135, 90, 241, 21, 128, 21, 97, 13, 197, 87, 61, 95, 128, 62, 61, 95, 253, 91, 80, 80, 80, 80, 96, 64, 81, 61, 96, 31, 25, 96, 31, 130, 1, 22, 130, 1, 128, 96, 64, 82, 80, 129, 1, 144, 97, 13, 233, 145, 144, 97, 24, 207, 86, 91, 123, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 25, 22, 20, 91, 97, 14, 73, 87, 96, 64, 81, 127, 8, 195, 121, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 96, 4, 1, 97, 14, 64, 144, 97, 25, 68, 86, 91, 96, 64, 81, 128, 145, 3, 144, 253, 91, 80, 80, 80, 80, 80, 86, 91, 96, 96, 97, 14, 91, 130, 97, 15, 214, 86, 91, 96, 64, 81, 96, 32, 1, 97, 14, 107, 145, 144, 97, 26, 176, 86, 91, 96, 64, 81, 96, 32, 129, 131, 3, 3, 129, 82, 144, 96, 64, 82, 144, 80, 145, 144, 80, 86, 91, 96, 3, 96, 32, 82, 129, 95, 82, 96, 64, 95, 32, 96, 32, 82, 128, 95, 82, 96, 64, 95, 32, 95, 145, 80, 145, 80, 144, 84, 144, 97, 1, 0, 10, 144, 4, 96, 255, 22, 129, 86, 91, 95, 131, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 131, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 20, 128, 97, 15, 103, 87, 80, 96, 3, 95, 133, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 132, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 144, 84, 144, 97, 1, 0, 10, 144, 4, 96, 255, 22, 91, 128, 97, 15, 205, 87, 80, 96, 2, 95, 131, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 95, 32, 95, 144, 84, 144, 97, 1, 0, 10, 144, 4, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 131, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 20, 91, 144, 80, 147, 146, 80, 80, 80, 86, 91, 96, 96, 95, 130, 3, 97, 16, 28, 87, 96, 64, 81, 128, 96, 64, 1, 96, 64, 82, 128, 96, 1, 129, 82, 96, 32, 1, 127, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 80, 144, 80, 97, 17, 79, 86, 91, 95, 130, 144, 80, 95, 91, 95, 130, 20, 97, 16, 75, 87, 128, 128, 97, 16, 52, 144, 97, 23, 249, 86, 91, 145, 80, 80, 96, 10, 130, 97, 16, 68, 145, 144, 97, 27, 2, 86, 91, 145, 80, 97, 16, 34, 86, 91, 95, 129, 103, 255, 255, 255, 255, 255, 255, 255, 255, 129, 17, 21, 97, 16, 102, 87, 97, 16, 101, 97, 27, 50, 86, 91, 91, 96, 64, 81, 144, 128, 130, 82, 128, 96, 31, 1, 96, 31, 25, 22, 96, 32, 1, 130, 1, 96, 64, 82, 128, 21, 97, 16, 152, 87, 129, 96, 32, 1, 96, 1, 130, 2, 128, 54, 131, 55, 128, 130, 1, 145, 80, 80, 144, 80, 91, 80, 144, 80, 95, 130, 144, 80, 91, 95, 134, 20, 97, 17, 71, 87, 96, 1, 129, 97, 16, 180, 145, 144, 97, 27, 95, 86, 91, 144, 80, 95, 96, 10, 128, 136, 97, 16, 197, 145, 144, 97, 27, 2, 86, 91, 97, 16, 207, 145, 144, 97, 27, 146, 86, 91, 135, 97, 16, 218, 145, 144, 97, 27, 95, 86, 91, 96, 48, 97, 16, 230, 145, 144, 97, 27, 223, 86, 91, 144, 80, 95, 129, 96, 248, 27, 144, 80, 128, 132, 132, 129, 81, 129, 16, 97, 17, 3, 87, 97, 17, 2, 97, 28, 19, 86, 91, 91, 96, 32, 1, 1, 144, 126, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 25, 22, 144, 129, 95, 26, 144, 83, 80, 96, 10, 136, 97, 17, 62, 145, 144, 97, 27, 2, 86, 91, 151, 80, 80, 80, 97, 16, 160, 86, 91, 129, 148, 80, 80, 80, 80, 80, 91, 145, 144, 80, 86, 91, 95, 128, 253, 91, 95, 128, 253, 91, 95, 127, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 130, 22, 144, 80, 145, 144, 80, 86, 91, 97, 17, 144, 129, 97, 17, 92, 86, 91, 129, 20, 97, 17, 154, 87, 95, 128, 253, 91, 80, 86, 91, 95, 129, 53, 144, 80, 97, 17, 171, 129, 97, 17, 135, 86, 91, 146, 145, 80, 80, 86, 91, 95, 96, 32, 130, 132, 3, 18, 21, 97, 17, 198, 87, 97, 17, 197, 97, 17, 84, 86, 91, 91, 95, 97, 17, 211, 132, 130, 133, 1, 97, 17, 157, 86, 91, 145, 80, 80, 146, 145, 80, 80, 86, 91, 95, 129, 21, 21, 144, 80, 145, 144, 80, 86, 91, 97, 17, 240, 129, 97, 17, 220, 86, 91, 130, 82, 80, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 97, 18, 9, 95, 131, 1, 132, 97, 17, 231, 86, 91, 146, 145, 80, 80, 86, 91, 95, 129, 81, 144, 80, 145, 144, 80, 86, 91, 95, 130, 130, 82, 96, 32, 130, 1, 144, 80, 146, 145, 80, 80, 86, 91, 95, 91, 131, 129, 16, 21, 97, 18, 70, 87, 128, 130, 1, 81, 129, 132, 1, 82, 96, 32, 129, 1, 144, 80, 97, 18, 43, 86, 91, 95, 132, 132, 1, 82, 80, 80, 80, 80, 86, 91, 95, 96, 31, 25, 96, 31, 131, 1, 22, 144, 80, 145, 144, 80, 86, 91, 95, 97, 18, 107, 130, 97, 18, 15, 86, 91, 97, 18, 117, 129, 133, 97, 18, 25, 86, 91, 147, 80, 97, 18, 133, 129, 133, 96, 32, 134, 1, 97, 18, 41, 86, 91, 97, 18, 142, 129, 97, 18, 81, 86, 91, 132, 1, 145, 80, 80, 146, 145, 80, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 129, 129, 3, 95, 131, 1, 82, 97, 18, 177, 129, 132, 97, 18, 97, 86, 91, 144, 80, 146, 145, 80, 80, 86, 91, 95, 129, 144, 80, 145, 144, 80, 86, 91, 97, 18, 203, 129, 97, 18, 185, 86, 91, 129, 20, 97, 18, 213, 87, 95, 128, 253, 91, 80, 86, 91, 95, 129, 53, 144, 80, 97, 18, 230, 129, 97, 18, 194, 86, 91, 146, 145, 80, 80, 86, 91, 95, 96, 32, 130, 132, 3, 18, 21, 97, 19, 1, 87, 97, 19, 0, 97, 17, 84, 86, 91, 91, 95, 97, 19, 14, 132, 130, 133, 1, 97, 18, 216, 86, 91, 145, 80, 80, 146, 145, 80, 80, 86, 91, 95, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 130, 22, 144, 80, 145, 144, 80, 86, 91, 95, 97, 19, 64, 130, 97, 19, 23, 86, 91, 144, 80, 145, 144, 80, 86, 91, 97, 19, 80, 129, 97, 19, 54, 86, 91, 130, 82, 80, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 97, 19, 105, 95, 131, 1, 132, 97, 19, 71, 86, 91, 146, 145, 80, 80, 86, 91, 97, 19, 120, 129, 97, 19, 54, 86, 91, 129, 20, 97, 19, 130, 87, 95, 128, 253, 91, 80, 86, 91, 95, 129, 53, 144, 80, 97, 19, 147, 129, 97, 19, 111, 86, 91, 146, 145, 80, 80, 86, 91, 95, 128, 96, 64, 131, 133, 3, 18, 21, 97, 19, 175, 87, 97, 19, 174, 97, 17, 84, 86, 91, 91, 95, 97, 19, 188, 133, 130, 134, 1, 97, 19, 133, 86, 91, 146, 80, 80, 96, 32, 97, 19, 205, 133, 130, 134, 1, 97, 18, 216, 86, 91, 145, 80, 80, 146, 80, 146, 144, 80, 86, 91, 95, 128, 95, 96, 96, 132, 134, 3, 18, 21, 97, 19, 238, 87, 97, 19, 237, 97, 17, 84, 86, 91, 91, 95, 97, 19, 251, 134, 130, 135, 1, 97, 19, 133, 86, 91, 147, 80, 80, 96, 32, 97, 20, 12, 134, 130, 135, 1, 97, 19, 133, 86, 91, 146, 80, 80, 96, 64, 97, 20, 29, 134, 130, 135, 1, 97, 18, 216, 86, 91, 145, 80, 80, 146, 80, 146, 80, 146, 86, 91, 95, 96, 32, 130, 132, 3, 18, 21, 97, 20, 60, 87, 97, 20, 59, 97, 17, 84, 86, 91, 91, 95, 97, 20, 73, 132, 130, 133, 1, 97, 19, 133, 86, 91, 145, 80, 80, 146, 145, 80, 80, 86, 91, 97, 20, 91, 129, 97, 18, 185, 86, 91, 130, 82, 80, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 97, 20, 116, 95, 131, 1, 132, 97, 20, 82, 86, 91, 146, 145, 80, 80, 86, 91, 97, 20, 131, 129, 97, 17, 220, 86, 91, 129, 20, 97, 20, 141, 87, 95, 128, 253, 91, 80, 86, 91, 95, 129, 53, 144, 80, 97, 20, 158, 129, 97, 20, 122, 86, 91, 146, 145, 80, 80, 86, 91, 95, 128, 96, 64, 131, 133, 3, 18, 21, 97, 20, 186, 87, 97, 20, 185, 97, 17, 84, 86, 91, 91, 95, 97, 20, 199, 133, 130, 134, 1, 97, 19, 133, 86, 91, 146, 80, 80, 96, 32, 97, 20, 216, 133, 130, 134, 1, 97, 20, 144, 86, 91, 145, 80, 80, 146, 80, 146, 144, 80, 86, 91, 95, 128, 253, 91, 95, 128, 253, 91, 95, 128, 253, 91, 95, 128, 131, 96, 31, 132, 1, 18, 97, 21, 3, 87, 97, 21, 2, 97, 20, 226, 86, 91, 91, 130, 53, 144, 80, 103, 255, 255, 255, 255, 255, 255, 255, 255, 129, 17, 21, 97, 21, 32, 87, 97, 21, 31, 97, 20, 230, 86, 91, 91, 96, 32, 131, 1, 145, 80, 131, 96, 1, 130, 2, 131, 1, 17, 21, 97, 21, 60, 87, 97, 21, 59, 97, 20, 234, 86, 91, 91, 146, 80, 146, 144, 80, 86, 91, 95, 128, 95, 128, 95, 96, 128, 134, 136, 3, 18, 21, 97, 21, 92, 87, 97, 21, 91, 97, 17, 84, 86, 91, 91, 95, 97, 21, 105, 136, 130, 137, 1, 97, 19, 133, 86, 91, 149, 80, 80, 96, 32, 97, 21, 122, 136, 130, 137, 1, 97, 19, 133, 86, 91, 148, 80, 80, 96, 64, 97, 21, 139, 136, 130, 137, 1, 97, 18, 216, 86, 91, 147, 80, 80, 96, 96, 134, 1, 53, 103, 255, 255, 255, 255, 255, 255, 255, 255, 129, 17, 21, 97, 21, 172, 87, 97, 21, 171, 97, 17, 88, 86, 91, 91, 97, 21, 184, 136, 130, 137, 1, 97, 20, 238, 86, 91, 146, 80, 146, 80, 80, 146, 149, 80, 146, 149, 144, 147, 80, 86, 91, 95, 128, 96, 64, 131, 133, 3, 18, 21, 97, 21, 221, 87, 97, 21, 220, 97, 17, 84, 86, 91, 91, 95, 97, 21, 234, 133, 130, 134, 1, 97, 19, 133, 86, 91, 146, 80, 80, 96, 32, 97, 21, 251, 133, 130, 134, 1, 97, 19, 133, 86, 91, 145, 80, 80, 146, 80, 146, 144, 80, 86, 91, 127, 116, 111, 107, 101, 110, 32, 100, 111, 101, 115, 110, 39, 116, 32, 101, 120, 105, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 130, 1, 82, 80, 86, 91, 95, 97, 22, 57, 96, 19, 131, 97, 18, 25, 86, 91, 145, 80, 97, 22, 68, 130, 97, 22, 5, 86, 91, 96, 32, 130, 1, 144, 80, 145, 144, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 129, 129, 3, 95, 131, 1, 82, 97, 22, 102, 129, 97, 22, 45, 86, 91, 144, 80, 145, 144, 80, 86, 91, 127, 110, 111, 116, 32, 97, 117, 116, 104, 111, 114, 105, 122, 101, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 130, 1, 82, 80, 86, 91, 95, 97, 22, 161, 96, 14, 131, 97, 18, 25, 86, 91, 145, 80, 97, 22, 172, 130, 97, 22, 109, 86, 91, 96, 32, 130, 1, 144, 80, 145, 144, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 129, 129, 3, 95, 131, 1, 82, 97, 22, 206, 129, 97, 22, 149, 86, 91, 144, 80, 145, 144, 80, 86, 91, 127, 102, 114, 111, 109, 32, 33, 61, 32, 111, 119, 110, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 130, 1, 82, 80, 86, 91, 95, 97, 23, 9, 96, 13, 131, 97, 18, 25, 86, 91, 145, 80, 97, 23, 20, 130, 97, 22, 213, 86, 91, 96, 32, 130, 1, 144, 80, 145, 144, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 129, 129, 3, 95, 131, 1, 82, 97, 23, 54, 129, 97, 22, 253, 86, 91, 144, 80, 145, 144, 80, 86, 91, 127, 116, 114, 97, 110, 115, 102, 101, 114, 32, 116, 111, 32, 122, 101, 114, 111, 32, 97, 100, 100, 114, 101, 115, 115, 0, 0, 0, 0, 0, 0, 0, 0, 95, 130, 1, 82, 80, 86, 91, 95, 97, 23, 113, 96, 24, 131, 97, 18, 25, 86, 91, 145, 80, 97, 23, 124, 130, 97, 23, 61, 86, 91, 96, 32, 130, 1, 144, 80, 145, 144, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 129, 129, 3, 95, 131, 1, 82, 97, 23, 158, 129, 97, 23, 101, 86, 91, 144, 80, 145, 144, 80, 86, 91, 127, 78, 72, 123, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 82, 96, 17, 96, 4, 82, 96, 36, 95, 253, 91, 95, 97, 23, 220, 130, 97, 18, 185, 86, 91, 145, 80, 95, 130, 3, 97, 23, 238, 87, 97, 23, 237, 97, 23, 165, 86, 91, 91, 96, 1, 130, 3, 144, 80, 145, 144, 80, 86, 91, 95, 97, 24, 3, 130, 97, 18, 185, 86, 91, 145, 80, 127, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 130, 3, 97, 24, 53, 87, 97, 24, 52, 97, 23, 165, 86, 91, 91, 96, 1, 130, 1, 144, 80, 145, 144, 80, 86, 91, 95, 130, 130, 82, 96, 32, 130, 1, 144, 80, 146, 145, 80, 80, 86, 91, 80, 86, 91, 95, 97, 24, 94, 95, 131, 97, 24, 64, 86, 91, 145, 80, 97, 24, 105, 130, 97, 24, 80, 86, 91, 95, 130, 1, 144, 80, 145, 144, 80, 86, 91, 95, 96, 128, 130, 1, 144, 80, 97, 24, 134, 95, 131, 1, 134, 97, 19, 71, 86, 91, 97, 24, 147, 96, 32, 131, 1, 133, 97, 19, 71, 86, 91, 97, 24, 160, 96, 64, 131, 1, 132, 97, 20, 82, 86, 91, 129, 129, 3, 96, 96, 131, 1, 82, 97, 24, 177, 129, 97, 24, 83, 86, 91, 144, 80, 148, 147, 80, 80, 80, 80, 86, 91, 95, 129, 81, 144, 80, 97, 24, 201, 129, 97, 17, 135, 86, 91, 146, 145, 80, 80, 86, 91, 95, 96, 32, 130, 132, 3, 18, 21, 97, 24, 228, 87, 97, 24, 227, 97, 17, 84, 86, 91, 91, 95, 97, 24, 241, 132, 130, 133, 1, 97, 24, 187, 86, 91, 145, 80, 80, 146, 145, 80, 80, 86, 91, 127, 117, 110, 115, 97, 102, 101, 32, 114, 101, 99, 105, 112, 105, 101, 110, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 130, 1, 82, 80, 86, 91, 95, 97, 25, 46, 96, 16, 131, 97, 18, 25, 86, 91, 145, 80, 97, 25, 57, 130, 97, 24, 250, 86, 91, 96, 32, 130, 1, 144, 80, 145, 144, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 129, 129, 3, 95, 131, 1, 82, 97, 25, 91, 129, 97, 25, 34, 86, 91, 144, 80, 145, 144, 80, 86, 91, 127, 111, 119, 110, 101, 114, 32, 61, 32, 122, 101, 114, 111, 32, 97, 100, 100, 114, 101, 115, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 130, 1, 82, 80, 86, 91, 95, 97, 25, 150, 96, 20, 131, 97, 18, 25, 86, 91, 145, 80, 97, 25, 161, 130, 97, 25, 98, 86, 91, 96, 32, 130, 1, 144, 80, 145, 144, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 129, 129, 3, 95, 131, 1, 82, 97, 25, 195, 129, 97, 25, 138, 86, 91, 144, 80, 145, 144, 80, 86, 91, 130, 129, 131, 55, 95, 131, 131, 1, 82, 80, 80, 80, 86, 91, 95, 97, 25, 227, 131, 133, 97, 24, 64, 86, 91, 147, 80, 97, 25, 240, 131, 133, 132, 97, 25, 202, 86, 91, 97, 25, 249, 131, 97, 18, 81, 86, 91, 132, 1, 144, 80, 147, 146, 80, 80, 80, 86, 91, 95, 96, 128, 130, 1, 144, 80, 97, 26, 23, 95, 131, 1, 136, 97, 19, 71, 86, 91, 97, 26, 36, 96, 32, 131, 1, 135, 97, 19, 71, 86, 91, 97, 26, 49, 96, 64, 131, 1, 134, 97, 20, 82, 86, 91, 129, 129, 3, 96, 96, 131, 1, 82, 97, 26, 68, 129, 132, 134, 97, 25, 216, 86, 91, 144, 80, 150, 149, 80, 80, 80, 80, 80, 80, 86, 91, 127, 104, 116, 116, 112, 115, 58, 47, 47, 101, 120, 97, 109, 112, 108, 101, 46, 99, 111, 109, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 80, 86, 91, 95, 129, 144, 80, 146, 145, 80, 80, 86, 91, 95, 97, 26, 138, 130, 97, 18, 15, 86, 91, 97, 26, 148, 129, 133, 97, 26, 118, 86, 91, 147, 80, 97, 26, 164, 129, 133, 96, 32, 134, 1, 97, 18, 41, 86, 91, 128, 132, 1, 145, 80, 80, 146, 145, 80, 80, 86, 91, 95, 97, 26, 186, 130, 97, 26, 80, 86, 91, 96, 20, 130, 1, 145, 80, 97, 26, 202, 130, 132, 97, 26, 128, 86, 91, 145, 80, 129, 144, 80, 146, 145, 80, 80, 86, 91, 127, 78, 72, 123, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 82, 96, 18, 96, 4, 82, 96, 36, 95, 253, 91, 95, 97, 27, 12, 130, 97, 18, 185, 86, 91, 145, 80, 97, 27, 23, 131, 97, 18, 185, 86, 91, 146, 80, 130, 97, 27, 39, 87, 97, 27, 38, 97, 26, 213, 86, 91, 91, 130, 130, 4, 144, 80, 146, 145, 80, 80, 86, 91, 127, 78, 72, 123, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 82, 96, 65, 96, 4, 82, 96, 36, 95, 253, 91, 95, 97, 27, 105, 130, 97, 18, 185, 86, 91, 145, 80, 97, 27, 116, 131, 97, 18, 185, 86, 91, 146, 80, 130, 130, 3, 144, 80, 129, 129, 17, 21, 97, 27, 140, 87, 97, 27, 139, 97, 23, 165, 86, 91, 91, 146, 145, 80, 80, 86, 91, 95, 97, 27, 156, 130, 97, 18, 185, 86, 91, 145, 80, 97, 27, 167, 131, 97, 18, 185, 86, 91, 146, 80, 130, 130, 2, 97, 27, 181, 129, 97, 18, 185, 86, 91, 145, 80, 130, 130, 4, 132, 20, 131, 21, 23, 97, 27, 204, 87, 97, 27, 203, 97, 23, 165, 86, 91, 91, 80, 146, 145, 80, 80, 86, 91, 95, 96, 255, 130, 22, 144, 80, 145, 144, 80, 86, 91, 95, 97, 27, 233, 130, 97, 27, 211, 86, 91, 145, 80, 97, 27, 244, 131, 97, 27, 211, 86, 91, 146, 80, 130, 130, 1, 144, 80, 96, 255, 129, 17, 21, 97, 28, 13, 87, 97, 28, 12, 97, 23, 165, 86, 91, 91, 146, 145, 80, 80, 86, 91, 127, 78, 72, 123, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 82, 96, 50, 96, 4, 82, 96, 36, 95, 253, 254, 162, 100, 105, 112, 102, 115, 88, 34, 18, 32, 152, 17, 252, 33, 148, 72, 1, 112, 229, 152, 121, 145, 96, 180, 163, 194, 162, 156, 32, 193, 68, 101, 246, 14, 74, 226, 43, 102, 172, 20, 137, 30, 100, 115, 111, 108, 99, 67, 0, 8, 21, 0, 51}) + testERC1155ContractBytecode = ByteCode([]byte{96, 128, 96, 64, 82, 52, 128, 21, 97, 0, 15, 87, 95, 128, 253, 91, 80, 96, 4, 54, 16, 97, 0, 95, 87, 95, 53, 96, 224, 28, 128, 98, 253, 213, 142, 20, 97, 0, 99, 87, 128, 99, 46, 178, 194, 214, 20, 97, 0, 147, 87, 128, 99, 78, 18, 115, 244, 20, 97, 0, 175, 87, 128, 99, 162, 44, 180, 101, 20, 97, 0, 223, 87, 128, 99, 233, 133, 233, 197, 20, 97, 0, 251, 87, 128, 99, 242, 66, 67, 42, 20, 97, 1, 43, 87, 91, 95, 128, 253, 91, 97, 0, 125, 96, 4, 128, 54, 3, 129, 1, 144, 97, 0, 120, 145, 144, 97, 2, 10, 86, 91, 97, 1, 71, 86, 91, 96, 64, 81, 97, 0, 138, 145, 144, 97, 2, 87, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 0, 173, 96, 4, 128, 54, 3, 129, 1, 144, 97, 0, 168, 145, 144, 97, 3, 38, 86, 91, 97, 1, 78, 86, 91, 0, 91, 97, 0, 201, 96, 4, 128, 54, 3, 129, 1, 144, 97, 0, 196, 145, 144, 97, 4, 82, 86, 91, 97, 1, 88, 86, 91, 96, 64, 81, 97, 0, 214, 145, 144, 97, 5, 135, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 0, 249, 96, 4, 128, 54, 3, 129, 1, 144, 97, 0, 244, 145, 144, 97, 5, 220, 86, 91, 97, 1, 98, 86, 91, 0, 91, 97, 1, 21, 96, 4, 128, 54, 3, 129, 1, 144, 97, 1, 16, 145, 144, 97, 6, 26, 86, 91, 97, 1, 102, 86, 91, 96, 64, 81, 97, 1, 34, 145, 144, 97, 6, 103, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 1, 69, 96, 4, 128, 54, 3, 129, 1, 144, 97, 1, 64, 145, 144, 97, 6, 128, 86, 91, 97, 1, 109, 86, 91, 0, 91, 95, 146, 145, 80, 80, 86, 91, 80, 80, 80, 80, 80, 80, 80, 80, 86, 91, 96, 96, 148, 147, 80, 80, 80, 80, 86, 91, 80, 80, 86, 91, 95, 146, 145, 80, 80, 86, 91, 80, 80, 80, 80, 80, 80, 86, 91, 95, 128, 253, 91, 95, 128, 253, 91, 95, 115, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 130, 22, 144, 80, 145, 144, 80, 86, 91, 95, 97, 1, 166, 130, 97, 1, 125, 86, 91, 144, 80, 145, 144, 80, 86, 91, 97, 1, 182, 129, 97, 1, 156, 86, 91, 129, 20, 97, 1, 192, 87, 95, 128, 253, 91, 80, 86, 91, 95, 129, 53, 144, 80, 97, 1, 209, 129, 97, 1, 173, 86, 91, 146, 145, 80, 80, 86, 91, 95, 129, 144, 80, 145, 144, 80, 86, 91, 97, 1, 233, 129, 97, 1, 215, 86, 91, 129, 20, 97, 1, 243, 87, 95, 128, 253, 91, 80, 86, 91, 95, 129, 53, 144, 80, 97, 2, 4, 129, 97, 1, 224, 86, 91, 146, 145, 80, 80, 86, 91, 95, 128, 96, 64, 131, 133, 3, 18, 21, 97, 2, 32, 87, 97, 2, 31, 97, 1, 117, 86, 91, 91, 95, 97, 2, 45, 133, 130, 134, 1, 97, 1, 195, 86, 91, 146, 80, 80, 96, 32, 97, 2, 62, 133, 130, 134, 1, 97, 1, 246, 86, 91, 145, 80, 80, 146, 80, 146, 144, 80, 86, 91, 97, 2, 81, 129, 97, 1, 215, 86, 91, 130, 82, 80, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 97, 2, 106, 95, 131, 1, 132, 97, 2, 72, 86, 91, 146, 145, 80, 80, 86, 91, 95, 128, 253, 91, 95, 128, 253, 91, 95, 128, 253, 91, 95, 128, 131, 96, 31, 132, 1, 18, 97, 2, 145, 87, 97, 2, 144, 97, 2, 112, 86, 91, 91, 130, 53, 144, 80, 103, 255, 255, 255, 255, 255, 255, 255, 255, 129, 17, 21, 97, 2, 174, 87, 97, 2, 173, 97, 2, 116, 86, 91, 91, 96, 32, 131, 1, 145, 80, 131, 96, 32, 130, 2, 131, 1, 17, 21, 97, 2, 202, 87, 97, 2, 201, 97, 2, 120, 86, 91, 91, 146, 80, 146, 144, 80, 86, 91, 95, 128, 131, 96, 31, 132, 1, 18, 97, 2, 230, 87, 97, 2, 229, 97, 2, 112, 86, 91, 91, 130, 53, 144, 80, 103, 255, 255, 255, 255, 255, 255, 255, 255, 129, 17, 21, 97, 3, 3, 87, 97, 3, 2, 97, 2, 116, 86, 91, 91, 96, 32, 131, 1, 145, 80, 131, 96, 1, 130, 2, 131, 1, 17, 21, 97, 3, 31, 87, 97, 3, 30, 97, 2, 120, 86, 91, 91, 146, 80, 146, 144, 80, 86, 91, 95, 128, 95, 128, 95, 128, 95, 128, 96, 160, 137, 139, 3, 18, 21, 97, 3, 66, 87, 97, 3, 65, 97, 1, 117, 86, 91, 91, 95, 97, 3, 79, 139, 130, 140, 1, 97, 1, 195, 86, 91, 152, 80, 80, 96, 32, 97, 3, 96, 139, 130, 140, 1, 97, 1, 195, 86, 91, 151, 80, 80, 96, 64, 137, 1, 53, 103, 255, 255, 255, 255, 255, 255, 255, 255, 129, 17, 21, 97, 3, 129, 87, 97, 3, 128, 97, 1, 121, 86, 91, 91, 97, 3, 141, 139, 130, 140, 1, 97, 2, 124, 86, 91, 150, 80, 150, 80, 80, 96, 96, 137, 1, 53, 103, 255, 255, 255, 255, 255, 255, 255, 255, 129, 17, 21, 97, 3, 176, 87, 97, 3, 175, 97, 1, 121, 86, 91, 91, 97, 3, 188, 139, 130, 140, 1, 97, 2, 124, 86, 91, 148, 80, 148, 80, 80, 96, 128, 137, 1, 53, 103, 255, 255, 255, 255, 255, 255, 255, 255, 129, 17, 21, 97, 3, 223, 87, 97, 3, 222, 97, 1, 121, 86, 91, 91, 97, 3, 235, 139, 130, 140, 1, 97, 2, 209, 86, 91, 146, 80, 146, 80, 80, 146, 149, 152, 80, 146, 149, 152, 144, 147, 150, 80, 86, 91, 95, 128, 131, 96, 31, 132, 1, 18, 97, 4, 18, 87, 97, 4, 17, 97, 2, 112, 86, 91, 91, 130, 53, 144, 80, 103, 255, 255, 255, 255, 255, 255, 255, 255, 129, 17, 21, 97, 4, 47, 87, 97, 4, 46, 97, 2, 116, 86, 91, 91, 96, 32, 131, 1, 145, 80, 131, 96, 32, 130, 2, 131, 1, 17, 21, 97, 4, 75, 87, 97, 4, 74, 97, 2, 120, 86, 91, 91, 146, 80, 146, 144, 80, 86, 91, 95, 128, 95, 128, 96, 64, 133, 135, 3, 18, 21, 97, 4, 106, 87, 97, 4, 105, 97, 1, 117, 86, 91, 91, 95, 133, 1, 53, 103, 255, 255, 255, 255, 255, 255, 255, 255, 129, 17, 21, 97, 4, 135, 87, 97, 4, 134, 97, 1, 121, 86, 91, 91, 97, 4, 147, 135, 130, 136, 1, 97, 3, 253, 86, 91, 148, 80, 148, 80, 80, 96, 32, 133, 1, 53, 103, 255, 255, 255, 255, 255, 255, 255, 255, 129, 17, 21, 97, 4, 182, 87, 97, 4, 181, 97, 1, 121, 86, 91, 91, 97, 4, 194, 135, 130, 136, 1, 97, 2, 124, 86, 91, 146, 80, 146, 80, 80, 146, 149, 145, 148, 80, 146, 80, 86, 91, 95, 129, 81, 144, 80, 145, 144, 80, 86, 91, 95, 130, 130, 82, 96, 32, 130, 1, 144, 80, 146, 145, 80, 80, 86, 91, 95, 129, 144, 80, 96, 32, 130, 1, 144, 80, 145, 144, 80, 86, 91, 97, 5, 2, 129, 97, 1, 215, 86, 91, 130, 82, 80, 80, 86, 91, 95, 97, 5, 19, 131, 131, 97, 4, 249, 86, 91, 96, 32, 131, 1, 144, 80, 146, 145, 80, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 145, 144, 80, 86, 91, 95, 97, 5, 53, 130, 97, 4, 208, 86, 91, 97, 5, 63, 129, 133, 97, 4, 218, 86, 91, 147, 80, 97, 5, 74, 131, 97, 4, 234, 86, 91, 128, 95, 91, 131, 129, 16, 21, 97, 5, 122, 87, 129, 81, 97, 5, 97, 136, 130, 97, 5, 8, 86, 91, 151, 80, 97, 5, 108, 131, 97, 5, 31, 86, 91, 146, 80, 80, 96, 1, 129, 1, 144, 80, 97, 5, 77, 86, 91, 80, 133, 147, 80, 80, 80, 80, 146, 145, 80, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 129, 129, 3, 95, 131, 1, 82, 97, 5, 159, 129, 132, 97, 5, 43, 86, 91, 144, 80, 146, 145, 80, 80, 86, 91, 95, 129, 21, 21, 144, 80, 145, 144, 80, 86, 91, 97, 5, 187, 129, 97, 5, 167, 86, 91, 129, 20, 97, 5, 197, 87, 95, 128, 253, 91, 80, 86, 91, 95, 129, 53, 144, 80, 97, 5, 214, 129, 97, 5, 178, 86, 91, 146, 145, 80, 80, 86, 91, 95, 128, 96, 64, 131, 133, 3, 18, 21, 97, 5, 242, 87, 97, 5, 241, 97, 1, 117, 86, 91, 91, 95, 97, 5, 255, 133, 130, 134, 1, 97, 1, 195, 86, 91, 146, 80, 80, 96, 32, 97, 6, 16, 133, 130, 134, 1, 97, 5, 200, 86, 91, 145, 80, 80, 146, 80, 146, 144, 80, 86, 91, 95, 128, 96, 64, 131, 133, 3, 18, 21, 97, 6, 48, 87, 97, 6, 47, 97, 1, 117, 86, 91, 91, 95, 97, 6, 61, 133, 130, 134, 1, 97, 1, 195, 86, 91, 146, 80, 80, 96, 32, 97, 6, 78, 133, 130, 134, 1, 97, 1, 195, 86, 91, 145, 80, 80, 146, 80, 146, 144, 80, 86, 91, 97, 6, 97, 129, 97, 5, 167, 86, 91, 130, 82, 80, 80, 86, 91, 95, 96, 32, 130, 1, 144, 80, 97, 6, 122, 95, 131, 1, 132, 97, 6, 88, 86, 91, 146, 145, 80, 80, 86, 91, 95, 128, 95, 128, 95, 128, 96, 160, 135, 137, 3, 18, 21, 97, 6, 154, 87, 97, 6, 153, 97, 1, 117, 86, 91, 91, 95, 97, 6, 167, 137, 130, 138, 1, 97, 1, 195, 86, 91, 150, 80, 80, 96, 32, 97, 6, 184, 137, 130, 138, 1, 97, 1, 195, 86, 91, 149, 80, 80, 96, 64, 97, 6, 201, 137, 130, 138, 1, 97, 1, 246, 86, 91, 148, 80, 80, 96, 96, 97, 6, 218, 137, 130, 138, 1, 97, 1, 246, 86, 91, 147, 80, 80, 96, 128, 135, 1, 53, 103, 255, 255, 255, 255, 255, 255, 255, 255, 129, 17, 21, 97, 6, 251, 87, 97, 6, 250, 97, 1, 121, 86, 91, 91, 97, 7, 7, 137, 130, 138, 1, 97, 2, 209, 86, 91, 146, 80, 146, 80, 80, 146, 149, 80, 146, 149, 80, 146, 149, 86, 254, 162, 100, 105, 112, 102, 115, 88, 34, 18, 32, 148, 159, 178, 116, 208, 174, 11, 170, 125, 189, 81, 142, 193, 10, 233, 27, 120, 223, 28, 202, 63, 46, 164, 30, 109, 18, 61, 127, 117, 110, 98, 132, 100, 115, 111, 108, 99, 67, 0, 8, 21, 0, 51}) // testERC1155RealWorldBytecode is taken from https://etherscan.io/token/0x76be3b62873462d2142405439777e971754e8e77#code - testERC1155RealWorldBytecode = Bytecode([]byte{96, 128, 96, 64, 82, 52, 128, 21, 97, 0, 16, 87, 96, 0, 128, 253, 91, 80, 96, 4, 54, 16, 97, 1, 195, 87, 96, 0, 53, 96, 224, 28, 128, 99, 149, 216, 155, 65, 17, 97, 0, 249, 87, 128, 99, 229, 200, 176, 61, 17, 97, 0, 151, 87, 128, 99, 235, 18, 214, 30, 17, 97, 0, 113, 87, 128, 99, 235, 18, 214, 30, 20, 97, 3, 159, 87, 128, 99, 242, 66, 67, 42, 20, 97, 3, 178, 87, 128, 99, 242, 253, 227, 139, 20, 97, 3, 197, 87, 128, 99, 245, 41, 138, 202, 20, 97, 3, 216, 87, 97, 1, 195, 86, 91, 128, 99, 229, 200, 176, 61, 20, 97, 3, 124, 87, 128, 99, 232, 163, 212, 133, 20, 97, 3, 132, 87, 128, 99, 233, 133, 233, 197, 20, 97, 3, 140, 87, 97, 1, 195, 86, 91, 128, 99, 185, 196, 217, 251, 17, 97, 0, 211, 87, 128, 99, 185, 196, 217, 251, 20, 97, 3, 46, 87, 128, 99, 192, 172, 153, 131, 20, 97, 3, 78, 87, 128, 99, 198, 191, 50, 98, 20, 97, 3, 86, 87, 128, 99, 205, 83, 208, 142, 20, 97, 3, 105, 87, 97, 1, 195, 86, 91, 128, 99, 149, 216, 155, 65, 20, 97, 3, 0, 87, 128, 99, 153, 224, 221, 124, 20, 97, 3, 8, 87, 128, 99, 162, 44, 180, 101, 20, 97, 3, 27, 87, 97, 1, 195, 86, 91, 128, 99, 78, 18, 115, 244, 17, 97, 1, 102, 87, 128, 99, 125, 247, 62, 39, 17, 97, 1, 64, 87, 128, 99, 125, 247, 62, 39, 20, 97, 2, 189, 87, 128, 99, 141, 165, 203, 91, 20, 97, 2, 208, 87, 128, 99, 143, 50, 213, 155, 20, 97, 2, 229, 87, 128, 99, 147, 142, 61, 123, 20, 97, 2, 237, 87, 97, 1, 195, 86, 91, 128, 99, 78, 18, 115, 244, 20, 97, 2, 129, 87, 128, 99, 99, 8, 241, 205, 20, 97, 2, 148, 87, 128, 99, 113, 80, 24, 166, 20, 97, 2, 181, 87, 97, 1, 195, 86, 91, 128, 99, 14, 49, 106, 183, 17, 97, 1, 162, 87, 128, 99, 14, 49, 106, 183, 20, 97, 2, 38, 87, 128, 99, 14, 137, 52, 28, 20, 97, 2, 59, 87, 128, 99, 14, 189, 76, 127, 20, 97, 2, 78, 87, 128, 99, 46, 178, 194, 214, 20, 97, 2, 110, 87, 97, 1, 195, 86, 91, 128, 98, 253, 213, 142, 20, 97, 1, 200, 87, 128, 99, 1, 255, 201, 167, 20, 97, 1, 241, 87, 128, 99, 6, 253, 222, 3, 20, 97, 2, 17, 87, 91, 96, 0, 128, 253, 91, 97, 1, 219, 97, 1, 214, 54, 96, 4, 97, 31, 231, 86, 91, 97, 3, 235, 86, 91, 96, 64, 81, 97, 1, 232, 145, 144, 97, 43, 219, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 2, 4, 97, 1, 255, 54, 96, 4, 97, 32, 210, 86, 91, 97, 4, 21, 86, 91, 96, 64, 81, 97, 1, 232, 145, 144, 97, 42, 78, 86, 91, 97, 2, 25, 97, 4, 52, 86, 91, 96, 64, 81, 97, 1, 232, 145, 144, 97, 42, 154, 86, 91, 97, 2, 57, 97, 2, 52, 54, 96, 4, 97, 30, 9, 86, 91, 97, 4, 194, 86, 91, 0, 91, 97, 2, 25, 97, 2, 73, 54, 96, 4, 97, 33, 66, 86, 91, 97, 4, 251, 86, 91, 97, 2, 97, 97, 2, 92, 54, 96, 4, 97, 33, 66, 86, 91, 97, 5, 6, 86, 91, 96, 64, 81, 97, 1, 232, 145, 144, 97, 42, 61, 86, 91, 97, 2, 57, 97, 2, 124, 54, 96, 4, 97, 30, 97, 86, 91, 97, 5, 249, 86, 91, 97, 2, 97, 97, 2, 143, 54, 96, 4, 97, 32, 100, 86, 91, 97, 8, 239, 86, 91, 97, 2, 167, 97, 2, 162, 54, 96, 4, 97, 33, 96, 86, 91, 97, 9, 201, 86, 91, 96, 64, 81, 97, 1, 232, 146, 145, 144, 97, 41, 50, 86, 91, 97, 2, 57, 97, 10, 12, 86, 91, 97, 2, 4, 97, 2, 203, 54, 96, 4, 97, 30, 9, 86, 91, 97, 10, 122, 86, 91, 97, 2, 216, 97, 10, 141, 86, 91, 96, 64, 81, 97, 1, 232, 145, 144, 97, 41, 36, 86, 91, 97, 2, 4, 97, 10, 157, 86, 91, 97, 2, 57, 97, 2, 251, 54, 96, 4, 97, 33, 14, 86, 91, 97, 10, 195, 86, 91, 97, 2, 25, 97, 10, 240, 86, 91, 97, 2, 57, 97, 3, 22, 54, 96, 4, 97, 33, 14, 86, 91, 97, 11, 75, 86, 91, 97, 2, 57, 97, 3, 41, 54, 96, 4, 97, 31, 183, 86, 91, 97, 11, 120, 86, 91, 97, 3, 65, 97, 3, 60, 54, 96, 4, 97, 33, 66, 86, 91, 97, 11, 231, 86, 91, 96, 64, 81, 97, 1, 232, 145, 144, 97, 41, 251, 86, 91, 97, 2, 25, 97, 12, 223, 86, 91, 97, 2, 57, 97, 3, 100, 54, 96, 4, 97, 33, 127, 86, 91, 97, 13, 58, 86, 91, 97, 2, 216, 97, 3, 119, 54, 96, 4, 97, 33, 66, 86, 91, 97, 13, 118, 86, 91, 97, 2, 57, 97, 13, 145, 86, 91, 97, 2, 25, 97, 13, 163, 86, 91, 97, 2, 4, 97, 3, 154, 54, 96, 4, 97, 30, 39, 86, 91, 97, 13, 254, 86, 91, 97, 2, 57, 97, 3, 173, 54, 96, 4, 97, 30, 9, 86, 91, 97, 14, 44, 86, 91, 97, 2, 57, 97, 3, 192, 54, 96, 4, 97, 31, 40, 86, 91, 97, 14, 89, 86, 91, 97, 2, 57, 97, 3, 211, 54, 96, 4, 97, 30, 9, 86, 91, 97, 16, 19, 86, 91, 97, 2, 57, 97, 3, 230, 54, 96, 4, 97, 32, 23, 86, 91, 97, 16, 64, 86, 91, 96, 0, 129, 129, 82, 96, 6, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 96, 1, 96, 1, 96, 160, 27, 3, 134, 22, 132, 82, 144, 145, 82, 144, 32, 84, 91, 146, 145, 80, 80, 86, 91, 96, 1, 96, 1, 96, 224, 27, 3, 25, 22, 96, 0, 144, 129, 82, 96, 32, 129, 144, 82, 96, 64, 144, 32, 84, 96, 255, 22, 144, 86, 91, 96, 10, 128, 84, 96, 64, 128, 81, 96, 32, 96, 2, 96, 1, 133, 22, 21, 97, 1, 0, 2, 96, 0, 25, 1, 144, 148, 22, 147, 144, 147, 4, 96, 31, 129, 1, 132, 144, 4, 132, 2, 130, 1, 132, 1, 144, 146, 82, 129, 129, 82, 146, 145, 131, 1, 130, 130, 128, 21, 97, 4, 186, 87, 128, 96, 31, 16, 97, 4, 143, 87, 97, 1, 0, 128, 131, 84, 4, 2, 131, 82, 145, 96, 32, 1, 145, 97, 4, 186, 86, 91, 130, 1, 145, 144, 96, 0, 82, 96, 32, 96, 0, 32, 144, 91, 129, 84, 129, 82, 144, 96, 1, 1, 144, 96, 32, 1, 128, 131, 17, 97, 4, 157, 87, 130, 144, 3, 96, 31, 22, 130, 1, 145, 91, 80, 80, 80, 80, 80, 129, 86, 91, 97, 4, 202, 97, 10, 157, 86, 91, 97, 4, 239, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 59, 86, 91, 96, 64, 81, 128, 145, 3, 144, 253, 91, 97, 4, 248, 129, 97, 17, 56, 86, 91, 80, 86, 91, 96, 96, 97, 4, 15, 130, 97, 17, 128, 86, 91, 96, 0, 129, 129, 82, 96, 9, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 128, 84, 130, 81, 129, 133, 2, 129, 1, 133, 1, 144, 147, 82, 128, 131, 82, 96, 96, 148, 133, 148, 132, 1, 91, 130, 130, 16, 21, 97, 5, 120, 87, 96, 0, 132, 129, 82, 96, 32, 144, 129, 144, 32, 96, 64, 128, 81, 128, 130, 1, 144, 145, 82, 96, 2, 133, 2, 144, 145, 1, 128, 84, 96, 1, 96, 1, 96, 160, 27, 3, 22, 130, 82, 96, 1, 144, 129, 1, 84, 130, 132, 1, 82, 144, 131, 82, 144, 146, 1, 145, 1, 97, 5, 48, 86, 91, 80, 80, 80, 80, 144, 80, 96, 96, 129, 81, 96, 64, 81, 144, 128, 130, 82, 128, 96, 32, 2, 96, 32, 1, 130, 1, 96, 64, 82, 128, 21, 97, 5, 171, 87, 129, 96, 32, 1, 96, 32, 130, 2, 128, 56, 131, 57, 1, 144, 80, 91, 80, 144, 80, 96, 0, 91, 130, 81, 129, 16, 21, 97, 5, 241, 87, 130, 129, 129, 81, 129, 16, 97, 5, 198, 87, 254, 91, 96, 32, 2, 96, 32, 1, 1, 81, 96, 32, 1, 81, 130, 130, 129, 81, 129, 16, 97, 5, 222, 87, 254, 91, 96, 32, 144, 129, 2, 145, 144, 145, 1, 1, 82, 96, 1, 1, 97, 5, 177, 86, 91, 80, 147, 146, 80, 80, 80, 86, 91, 96, 1, 96, 1, 96, 160, 27, 3, 135, 22, 97, 6, 31, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 42, 235, 86, 91, 132, 131, 20, 97, 6, 62, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 123, 86, 91, 96, 1, 96, 1, 96, 160, 27, 3, 136, 22, 51, 20, 128, 97, 6, 125, 87, 80, 96, 1, 96, 1, 96, 160, 27, 3, 136, 22, 96, 0, 144, 129, 82, 96, 7, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 51, 132, 82, 144, 145, 82, 144, 32, 84, 96, 255, 22, 21, 21, 96, 1, 20, 91, 97, 6, 153, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 27, 86, 91, 96, 0, 91, 133, 129, 16, 21, 97, 7, 206, 87, 96, 0, 135, 135, 131, 129, 129, 16, 97, 6, 178, 87, 254, 91, 144, 80, 96, 32, 2, 1, 53, 144, 80, 96, 0, 134, 134, 132, 129, 129, 16, 97, 6, 201, 87, 254, 91, 144, 80, 96, 32, 2, 1, 53, 144, 80, 97, 7, 27, 129, 96, 6, 96, 0, 133, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 96, 0, 32, 96, 0, 142, 96, 1, 96, 1, 96, 160, 27, 3, 22, 96, 1, 96, 1, 96, 160, 27, 3, 22, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 96, 0, 32, 84, 97, 18, 187, 144, 145, 144, 99, 255, 255, 255, 255, 22, 86, 91, 96, 6, 96, 0, 132, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 96, 0, 32, 96, 0, 141, 96, 1, 96, 1, 96, 160, 27, 3, 22, 96, 1, 96, 1, 96, 160, 27, 3, 22, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 96, 0, 32, 129, 144, 85, 80, 97, 7, 158, 96, 6, 96, 0, 132, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 96, 0, 32, 96, 0, 140, 96, 1, 96, 1, 96, 160, 27, 3, 22, 96, 1, 96, 1, 96, 160, 27, 3, 22, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 96, 0, 32, 84, 130, 97, 18, 205, 144, 145, 144, 99, 255, 255, 255, 255, 22, 86, 91, 96, 0, 146, 131, 82, 96, 6, 96, 32, 144, 129, 82, 96, 64, 128, 133, 32, 96, 1, 96, 1, 96, 160, 27, 3, 142, 22, 134, 82, 144, 145, 82, 144, 146, 32, 145, 144, 145, 85, 80, 96, 1, 1, 97, 6, 156, 86, 91, 80, 134, 96, 1, 96, 1, 96, 160, 27, 3, 22, 136, 96, 1, 96, 1, 96, 160, 27, 3, 22, 51, 96, 1, 96, 1, 96, 160, 27, 3, 22, 127, 74, 57, 220, 6, 212, 192, 219, 198, 75, 112, 175, 144, 253, 105, 138, 35, 58, 81, 138, 165, 208, 126, 89, 93, 152, 59, 140, 5, 38, 200, 247, 251, 137, 137, 137, 137, 96, 64, 81, 97, 8, 34, 148, 147, 146, 145, 144, 97, 42, 12, 86, 91, 96, 64, 81, 128, 145, 3, 144, 164, 97, 8, 60, 135, 96, 1, 96, 1, 96, 160, 27, 3, 22, 97, 18, 218, 86, 91, 21, 97, 8, 229, 87, 97, 8, 229, 51, 137, 137, 137, 137, 128, 128, 96, 32, 2, 96, 32, 1, 96, 64, 81, 144, 129, 1, 96, 64, 82, 128, 147, 146, 145, 144, 129, 129, 82, 96, 32, 1, 131, 131, 96, 32, 2, 128, 130, 132, 55, 96, 0, 146, 1, 145, 144, 145, 82, 80, 80, 96, 64, 128, 81, 96, 32, 128, 141, 2, 130, 129, 1, 130, 1, 144, 147, 82, 140, 130, 82, 144, 147, 80, 140, 146, 80, 139, 145, 130, 145, 133, 1, 144, 132, 144, 128, 130, 132, 55, 96, 0, 146, 1, 145, 144, 145, 82, 80, 80, 96, 64, 128, 81, 96, 32, 96, 31, 140, 1, 129, 144, 4, 129, 2, 130, 1, 129, 1, 144, 146, 82, 138, 129, 82, 146, 80, 138, 145, 80, 137, 144, 129, 144, 132, 1, 131, 130, 128, 130, 132, 55, 96, 0, 146, 1, 145, 144, 145, 82, 80, 97, 19, 22, 146, 80, 80, 80, 86, 91, 80, 80, 80, 80, 80, 80, 80, 80, 86, 91, 96, 96, 131, 130, 20, 97, 8, 253, 87, 96, 0, 128, 253, 91, 96, 64, 128, 81, 133, 129, 82, 96, 32, 128, 135, 2, 130, 1, 1, 144, 145, 82, 96, 96, 144, 133, 128, 21, 97, 9, 41, 87, 129, 96, 32, 1, 96, 32, 130, 2, 128, 56, 131, 57, 1, 144, 80, 91, 80, 144, 80, 96, 0, 91, 133, 129, 16, 21, 97, 9, 191, 87, 96, 6, 96, 0, 134, 134, 132, 129, 129, 16, 97, 9, 71, 87, 254, 91, 144, 80, 96, 32, 2, 1, 53, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 96, 0, 32, 96, 0, 136, 136, 132, 129, 129, 16, 97, 9, 106, 87, 254, 91, 144, 80, 96, 32, 2, 1, 96, 32, 97, 9, 127, 145, 144, 129, 1, 144, 97, 30, 9, 86, 91, 96, 1, 96, 1, 96, 160, 27, 3, 22, 96, 1, 96, 1, 96, 160, 27, 3, 22, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 96, 0, 32, 84, 130, 130, 129, 81, 129, 16, 97, 9, 172, 87, 254, 91, 96, 32, 144, 129, 2, 145, 144, 145, 1, 1, 82, 96, 1, 1, 97, 9, 47, 86, 91, 80, 149, 148, 80, 80, 80, 80, 80, 86, 91, 96, 9, 96, 32, 82, 129, 96, 0, 82, 96, 64, 96, 0, 32, 129, 129, 84, 129, 16, 97, 9, 226, 87, 254, 91, 96, 0, 145, 130, 82, 96, 32, 144, 145, 32, 96, 2, 144, 145, 2, 1, 128, 84, 96, 1, 144, 145, 1, 84, 96, 1, 96, 1, 96, 160, 27, 3, 144, 145, 22, 146, 80, 144, 80, 130, 86, 91, 97, 10, 20, 97, 10, 157, 86, 91, 97, 10, 48, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 59, 86, 91, 96, 1, 84, 96, 64, 81, 96, 0, 145, 96, 1, 96, 1, 96, 160, 27, 3, 22, 144, 127, 139, 224, 7, 156, 83, 22, 89, 20, 19, 68, 205, 31, 208, 164, 242, 132, 25, 73, 127, 151, 34, 163, 218, 175, 227, 180, 24, 111, 107, 100, 87, 224, 144, 131, 144, 163, 96, 1, 128, 84, 96, 1, 96, 1, 96, 160, 27, 3, 25, 22, 144, 85, 86, 91, 96, 0, 97, 4, 15, 96, 2, 131, 99, 255, 255, 255, 255, 97, 19, 197, 22, 86, 91, 96, 1, 84, 96, 1, 96, 1, 96, 160, 27, 3, 22, 91, 144, 86, 91, 96, 1, 84, 96, 0, 144, 96, 1, 96, 1, 96, 160, 27, 3, 22, 97, 10, 180, 97, 20, 13, 86, 91, 96, 1, 96, 1, 96, 160, 27, 3, 22, 20, 144, 80, 144, 86, 91, 97, 10, 203, 97, 10, 157, 86, 91, 97, 10, 231, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 59, 86, 91, 97, 4, 248, 129, 97, 20, 17, 86, 91, 96, 11, 128, 84, 96, 64, 128, 81, 96, 32, 96, 2, 96, 1, 133, 22, 21, 97, 1, 0, 2, 96, 0, 25, 1, 144, 148, 22, 147, 144, 147, 4, 96, 31, 129, 1, 132, 144, 4, 132, 2, 130, 1, 132, 1, 144, 146, 82, 129, 129, 82, 146, 145, 131, 1, 130, 130, 128, 21, 97, 4, 186, 87, 128, 96, 31, 16, 97, 4, 143, 87, 97, 1, 0, 128, 131, 84, 4, 2, 131, 82, 145, 96, 32, 1, 145, 97, 4, 186, 86, 91, 97, 11, 83, 97, 10, 157, 86, 91, 97, 11, 111, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 59, 86, 91, 97, 4, 248, 129, 97, 20, 40, 86, 91, 51, 96, 0, 129, 129, 82, 96, 7, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 96, 1, 96, 1, 96, 160, 27, 3, 135, 22, 128, 133, 82, 146, 82, 145, 130, 144, 32, 128, 84, 96, 255, 25, 22, 133, 21, 21, 23, 144, 85, 144, 81, 144, 145, 144, 127, 23, 48, 126, 171, 57, 171, 97, 7, 232, 137, 152, 69, 173, 61, 89, 189, 150, 83, 242, 0, 242, 32, 146, 4, 137, 202, 43, 89, 55, 105, 108, 49, 144, 97, 11, 219, 144, 133, 144, 97, 42, 78, 86, 91, 96, 64, 81, 128, 145, 3, 144, 163, 80, 80, 86, 91, 96, 0, 129, 129, 82, 96, 9, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 128, 84, 130, 81, 129, 133, 2, 129, 1, 133, 1, 144, 147, 82, 128, 131, 82, 96, 96, 148, 133, 148, 132, 1, 91, 130, 130, 16, 21, 97, 12, 89, 87, 96, 0, 132, 129, 82, 96, 32, 144, 129, 144, 32, 96, 64, 128, 81, 128, 130, 1, 144, 145, 82, 96, 2, 133, 2, 144, 145, 1, 128, 84, 96, 1, 96, 1, 96, 160, 27, 3, 22, 130, 82, 96, 1, 144, 129, 1, 84, 130, 132, 1, 82, 144, 131, 82, 144, 146, 1, 145, 1, 97, 12, 17, 86, 91, 80, 80, 80, 80, 144, 80, 96, 96, 129, 81, 96, 64, 81, 144, 128, 130, 82, 128, 96, 32, 2, 96, 32, 1, 130, 1, 96, 64, 82, 128, 21, 97, 12, 140, 87, 129, 96, 32, 1, 96, 32, 130, 2, 128, 56, 131, 57, 1, 144, 80, 91, 80, 144, 80, 96, 0, 91, 130, 81, 129, 16, 21, 97, 5, 241, 87, 130, 129, 129, 81, 129, 16, 97, 12, 167, 87, 254, 91, 96, 32, 2, 96, 32, 1, 1, 81, 96, 0, 1, 81, 130, 130, 129, 81, 129, 16, 97, 12, 191, 87, 254, 91, 96, 1, 96, 1, 96, 160, 27, 3, 144, 146, 22, 96, 32, 146, 131, 2, 145, 144, 145, 1, 144, 145, 1, 82, 96, 1, 1, 97, 12, 146, 86, 91, 96, 3, 128, 84, 96, 64, 128, 81, 96, 32, 96, 2, 96, 1, 133, 22, 21, 97, 1, 0, 2, 96, 0, 25, 1, 144, 148, 22, 147, 144, 147, 4, 96, 31, 129, 1, 132, 144, 4, 132, 2, 130, 1, 132, 1, 144, 146, 82, 129, 129, 82, 146, 145, 131, 1, 130, 130, 128, 21, 97, 4, 186, 87, 128, 96, 31, 16, 97, 4, 143, 87, 97, 1, 0, 128, 131, 84, 4, 2, 131, 82, 145, 96, 32, 1, 145, 97, 4, 186, 86, 91, 97, 13, 66, 97, 10, 157, 86, 91, 97, 13, 94, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 59, 86, 91, 97, 13, 109, 135, 135, 135, 135, 135, 135, 135, 97, 20, 59, 86, 91, 80, 80, 80, 80, 80, 80, 80, 86, 91, 96, 8, 96, 32, 82, 96, 0, 144, 129, 82, 96, 64, 144, 32, 84, 96, 1, 96, 1, 96, 160, 27, 3, 22, 129, 86, 91, 97, 13, 161, 97, 13, 156, 97, 20, 13, 86, 91, 97, 17, 56, 86, 91, 86, 91, 96, 5, 128, 84, 96, 64, 128, 81, 96, 32, 96, 2, 96, 1, 133, 22, 21, 97, 1, 0, 2, 96, 0, 25, 1, 144, 148, 22, 147, 144, 147, 4, 96, 31, 129, 1, 132, 144, 4, 132, 2, 130, 1, 132, 1, 144, 146, 82, 129, 129, 82, 146, 145, 131, 1, 130, 130, 128, 21, 97, 4, 186, 87, 128, 96, 31, 16, 97, 4, 143, 87, 97, 1, 0, 128, 131, 84, 4, 2, 131, 82, 145, 96, 32, 1, 145, 97, 4, 186, 86, 91, 96, 1, 96, 1, 96, 160, 27, 3, 145, 130, 22, 96, 0, 144, 129, 82, 96, 7, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 147, 144, 148, 22, 130, 82, 145, 144, 145, 82, 32, 84, 96, 255, 22, 144, 86, 91, 97, 14, 52, 97, 10, 157, 86, 91, 97, 14, 80, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 59, 86, 91, 97, 4, 248, 129, 97, 20, 226, 86, 91, 96, 1, 96, 1, 96, 160, 27, 3, 133, 22, 97, 14, 127, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 171, 86, 91, 96, 1, 96, 1, 96, 160, 27, 3, 134, 22, 51, 20, 128, 97, 14, 190, 87, 80, 96, 1, 96, 1, 96, 160, 27, 3, 134, 22, 96, 0, 144, 129, 82, 96, 7, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 51, 132, 82, 144, 145, 82, 144, 32, 84, 96, 255, 22, 21, 21, 96, 1, 20, 91, 97, 14, 218, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 27, 86, 91, 96, 0, 132, 129, 82, 96, 6, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 96, 1, 96, 1, 96, 160, 27, 3, 138, 22, 132, 82, 144, 145, 82, 144, 32, 84, 97, 15, 13, 144, 132, 99, 255, 255, 255, 255, 97, 18, 187, 22, 86, 91, 96, 0, 133, 129, 82, 96, 6, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 96, 1, 96, 1, 96, 160, 27, 3, 139, 129, 22, 133, 82, 146, 82, 128, 131, 32, 147, 144, 147, 85, 135, 22, 129, 82, 32, 84, 97, 15, 69, 144, 132, 144, 97, 18, 205, 86, 91, 96, 0, 133, 129, 82, 96, 6, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 96, 1, 96, 1, 96, 160, 27, 3, 128, 139, 22, 128, 134, 82, 145, 144, 147, 82, 146, 129, 144, 32, 147, 144, 147, 85, 145, 81, 144, 145, 136, 22, 144, 51, 144, 127, 195, 213, 129, 104, 197, 174, 115, 151, 115, 29, 6, 61, 91, 191, 61, 101, 120, 84, 66, 115, 67, 244, 192, 131, 36, 15, 122, 172, 170, 45, 15, 98, 144, 97, 15, 168, 144, 137, 144, 137, 144, 97, 44, 29, 86, 91, 96, 64, 81, 128, 145, 3, 144, 164, 97, 15, 194, 133, 96, 1, 96, 1, 96, 160, 27, 3, 22, 97, 18, 218, 86, 91, 21, 97, 16, 11, 87, 97, 16, 11, 51, 135, 135, 135, 135, 135, 135, 128, 128, 96, 31, 1, 96, 32, 128, 145, 4, 2, 96, 32, 1, 96, 64, 81, 144, 129, 1, 96, 64, 82, 128, 147, 146, 145, 144, 129, 129, 82, 96, 32, 1, 131, 131, 128, 130, 132, 55, 96, 0, 146, 1, 145, 144, 145, 82, 80, 97, 21, 42, 146, 80, 80, 80, 86, 91, 80, 80, 80, 80, 80, 80, 86, 91, 97, 16, 27, 97, 10, 157, 86, 91, 97, 16, 55, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 59, 86, 91, 97, 4, 248, 129, 97, 21, 217, 86, 91, 96, 1, 96, 1, 96, 160, 27, 3, 131, 22, 51, 20, 128, 97, 16, 127, 87, 80, 96, 1, 96, 1, 96, 160, 27, 3, 131, 22, 96, 0, 144, 129, 82, 96, 7, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 51, 132, 82, 144, 145, 82, 144, 32, 84, 96, 255, 22, 21, 21, 96, 1, 20, 91, 97, 16, 155, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 11, 86, 91, 96, 0, 130, 129, 82, 96, 6, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 96, 1, 96, 1, 96, 160, 27, 3, 135, 22, 132, 82, 144, 145, 82, 144, 32, 84, 97, 16, 206, 144, 130, 99, 255, 255, 255, 255, 97, 18, 187, 22, 86, 91, 96, 0, 131, 129, 82, 96, 6, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 96, 1, 96, 1, 96, 160, 27, 3, 136, 22, 128, 133, 82, 146, 82, 128, 131, 32, 147, 144, 147, 85, 145, 81, 144, 145, 144, 51, 144, 127, 195, 213, 129, 104, 197, 174, 115, 151, 115, 29, 6, 61, 91, 191, 61, 101, 120, 84, 66, 115, 67, 244, 192, 131, 36, 15, 122, 172, 170, 45, 15, 98, 144, 97, 17, 43, 144, 135, 144, 135, 144, 97, 44, 29, 86, 91, 96, 64, 81, 128, 145, 3, 144, 164, 80, 80, 80, 86, 91, 97, 17, 73, 96, 2, 130, 99, 255, 255, 255, 255, 97, 22, 91, 22, 86, 91, 96, 64, 81, 96, 1, 96, 1, 96, 160, 27, 3, 130, 22, 144, 127, 53, 37, 226, 40, 36, 168, 167, 223, 44, 154, 96, 41, 148, 28, 130, 76, 249, 91, 100, 71, 241, 225, 61, 81, 40, 253, 56, 38, 211, 90, 254, 139, 144, 96, 0, 144, 162, 80, 86, 91, 96, 0, 129, 129, 82, 96, 4, 96, 32, 144, 129, 82, 96, 64, 145, 130, 144, 32, 128, 84, 131, 81, 96, 2, 96, 1, 131, 22, 21, 97, 1, 0, 2, 96, 0, 25, 1, 144, 146, 22, 145, 144, 145, 4, 96, 31, 129, 1, 132, 144, 4, 132, 2, 130, 1, 132, 1, 144, 148, 82, 131, 129, 82, 96, 96, 147, 97, 4, 15, 147, 145, 146, 145, 131, 1, 130, 130, 128, 21, 97, 18, 26, 87, 128, 96, 31, 16, 97, 17, 239, 87, 97, 1, 0, 128, 131, 84, 4, 2, 131, 82, 145, 96, 32, 1, 145, 97, 18, 26, 86, 91, 130, 1, 145, 144, 96, 0, 82, 96, 32, 96, 0, 32, 144, 91, 129, 84, 129, 82, 144, 96, 1, 1, 144, 96, 32, 1, 128, 131, 17, 97, 17, 253, 87, 130, 144, 3, 96, 31, 22, 130, 1, 145, 91, 80, 80, 96, 3, 128, 84, 96, 64, 128, 81, 96, 32, 96, 31, 96, 2, 96, 0, 25, 97, 1, 0, 96, 1, 136, 22, 21, 2, 1, 144, 149, 22, 148, 144, 148, 4, 147, 132, 1, 129, 144, 4, 129, 2, 130, 1, 129, 1, 144, 146, 82, 130, 129, 82, 149, 80, 145, 147, 80, 145, 80, 131, 1, 130, 130, 128, 21, 97, 18, 168, 87, 128, 96, 31, 16, 97, 18, 125, 87, 97, 1, 0, 128, 131, 84, 4, 2, 131, 82, 145, 96, 32, 1, 145, 97, 18, 168, 86, 91, 130, 1, 145, 144, 96, 0, 82, 96, 32, 96, 0, 32, 144, 91, 129, 84, 129, 82, 144, 96, 1, 1, 144, 96, 32, 1, 128, 131, 17, 97, 18, 139, 87, 130, 144, 3, 96, 31, 22, 130, 1, 145, 91, 80, 80, 80, 80, 80, 97, 22, 163, 144, 145, 144, 99, 255, 255, 255, 255, 22, 86, 91, 96, 0, 130, 130, 17, 21, 97, 18, 199, 87, 254, 91, 80, 144, 3, 144, 86, 91, 129, 129, 1, 130, 129, 16, 21, 97, 4, 15, 87, 254, 91, 96, 0, 129, 63, 127, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112, 129, 129, 20, 128, 21, 144, 97, 19, 14, 87, 80, 129, 21, 21, 91, 148, 147, 80, 80, 80, 80, 86, 91, 96, 64, 81, 99, 188, 25, 124, 129, 96, 224, 27, 128, 130, 82, 144, 96, 1, 96, 1, 96, 160, 27, 3, 134, 22, 144, 99, 188, 25, 124, 129, 144, 97, 19, 76, 144, 138, 144, 138, 144, 137, 144, 137, 144, 137, 144, 96, 4, 1, 97, 41, 84, 86, 91, 96, 32, 96, 64, 81, 128, 131, 3, 129, 96, 0, 135, 128, 59, 21, 128, 21, 97, 19, 102, 87, 96, 0, 128, 253, 91, 80, 90, 241, 21, 128, 21, 97, 19, 122, 87, 61, 96, 0, 128, 62, 61, 96, 0, 253, 91, 80, 80, 80, 80, 96, 64, 81, 61, 96, 31, 25, 96, 31, 130, 1, 22, 130, 1, 128, 96, 64, 82, 80, 97, 19, 158, 145, 144, 129, 1, 144, 97, 32, 240, 86, 91, 96, 1, 96, 1, 96, 224, 27, 3, 25, 22, 20, 97, 16, 11, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 43, 86, 91, 96, 0, 96, 1, 96, 1, 96, 160, 27, 3, 130, 22, 97, 19, 237, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 75, 86, 91, 80, 96, 1, 96, 1, 96, 160, 27, 3, 22, 96, 0, 144, 129, 82, 96, 32, 145, 144, 145, 82, 96, 64, 144, 32, 84, 96, 255, 22, 144, 86, 91, 51, 144, 86, 91, 128, 81, 97, 20, 36, 144, 96, 5, 144, 96, 32, 132, 1, 144, 97, 27, 143, 86, 91, 80, 80, 86, 91, 128, 81, 97, 20, 36, 144, 96, 3, 144, 96, 32, 132, 1, 144, 97, 27, 143, 86, 91, 97, 20, 186, 96, 1, 48, 137, 96, 64, 81, 96, 32, 1, 97, 20, 83, 146, 145, 144, 97, 40, 254, 86, 91, 96, 64, 81, 96, 32, 129, 131, 3, 3, 129, 82, 144, 96, 64, 82, 128, 81, 144, 96, 32, 1, 32, 136, 136, 136, 96, 64, 81, 96, 0, 129, 82, 96, 32, 1, 96, 64, 82, 96, 64, 81, 97, 20, 137, 148, 147, 146, 145, 144, 97, 42, 92, 86, 91, 96, 32, 96, 64, 81, 96, 32, 129, 3, 144, 128, 132, 3, 144, 133, 90, 250, 21, 128, 21, 97, 20, 171, 87, 61, 96, 0, 128, 62, 61, 96, 0, 253, 91, 80, 80, 80, 96, 32, 96, 64, 81, 3, 81, 97, 10, 122, 86, 91, 97, 20, 214, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 187, 86, 91, 97, 13, 109, 135, 132, 132, 132, 97, 23, 152, 86, 91, 97, 20, 243, 96, 2, 130, 99, 255, 255, 255, 255, 97, 26, 230, 22, 86, 91, 96, 64, 81, 96, 1, 96, 1, 96, 160, 27, 3, 130, 22, 144, 127, 71, 209, 194, 42, 37, 187, 58, 93, 78, 72, 27, 155, 30, 105, 68, 194, 234, 222, 49, 129, 160, 162, 11, 73, 94, 214, 29, 53, 181, 50, 63, 36, 144, 96, 0, 144, 162, 80, 86, 91, 96, 64, 81, 99, 242, 58, 110, 97, 96, 224, 27, 128, 130, 82, 144, 96, 1, 96, 1, 96, 160, 27, 3, 134, 22, 144, 99, 242, 58, 110, 97, 144, 97, 21, 96, 144, 138, 144, 138, 144, 137, 144, 137, 144, 137, 144, 96, 4, 1, 97, 41, 180, 86, 91, 96, 32, 96, 64, 81, 128, 131, 3, 129, 96, 0, 135, 128, 59, 21, 128, 21, 97, 21, 122, 87, 96, 0, 128, 253, 91, 80, 90, 241, 21, 128, 21, 97, 21, 142, 87, 61, 96, 0, 128, 62, 61, 96, 0, 253, 91, 80, 80, 80, 80, 96, 64, 81, 61, 96, 31, 25, 96, 31, 130, 1, 22, 130, 1, 128, 96, 64, 82, 80, 97, 21, 178, 145, 144, 129, 1, 144, 97, 32, 240, 86, 91, 96, 1, 96, 1, 96, 224, 27, 3, 25, 22, 20, 97, 16, 11, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 155, 86, 91, 96, 1, 96, 1, 96, 160, 27, 3, 129, 22, 97, 21, 255, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 42, 203, 86, 91, 96, 1, 84, 96, 64, 81, 96, 1, 96, 1, 96, 160, 27, 3, 128, 132, 22, 146, 22, 144, 127, 139, 224, 7, 156, 83, 22, 89, 20, 19, 68, 205, 31, 208, 164, 242, 132, 25, 73, 127, 151, 34, 163, 218, 175, 227, 180, 24, 111, 107, 100, 87, 224, 144, 96, 0, 144, 163, 96, 1, 128, 84, 96, 1, 96, 1, 96, 160, 27, 3, 25, 22, 96, 1, 96, 1, 96, 160, 27, 3, 146, 144, 146, 22, 145, 144, 145, 23, 144, 85, 86, 91, 97, 22, 101, 130, 130, 97, 19, 197, 86, 91, 97, 22, 129, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 42, 251, 86, 91, 96, 1, 96, 1, 96, 160, 27, 3, 22, 96, 0, 144, 129, 82, 96, 32, 145, 144, 145, 82, 96, 64, 144, 32, 128, 84, 96, 255, 25, 22, 144, 85, 86, 91, 96, 96, 128, 131, 144, 80, 96, 96, 131, 144, 80, 96, 96, 129, 81, 131, 81, 1, 96, 64, 81, 144, 128, 130, 82, 128, 96, 31, 1, 96, 31, 25, 22, 96, 32, 1, 130, 1, 96, 64, 82, 128, 21, 97, 22, 223, 87, 96, 32, 130, 1, 129, 128, 56, 131, 57, 1, 144, 80, 91, 80, 144, 80, 96, 0, 128, 91, 132, 81, 129, 16, 21, 97, 23, 55, 87, 132, 129, 129, 81, 129, 16, 97, 22, 251, 87, 254, 91, 96, 32, 1, 1, 81, 96, 248, 28, 96, 248, 27, 131, 131, 128, 96, 1, 1, 148, 80, 129, 81, 129, 16, 97, 23, 24, 87, 254, 91, 96, 32, 1, 1, 144, 96, 1, 96, 1, 96, 248, 27, 3, 25, 22, 144, 129, 96, 0, 26, 144, 83, 80, 96, 1, 1, 97, 22, 230, 86, 91, 80, 96, 0, 91, 131, 81, 129, 16, 21, 97, 23, 140, 87, 131, 129, 129, 81, 129, 16, 97, 23, 80, 87, 254, 91, 96, 32, 1, 1, 81, 96, 248, 28, 96, 248, 27, 131, 131, 128, 96, 1, 1, 148, 80, 129, 81, 129, 16, 97, 23, 109, 87, 254, 91, 96, 32, 1, 1, 144, 96, 1, 96, 1, 96, 248, 27, 3, 25, 22, 144, 129, 96, 0, 26, 144, 83, 80, 96, 1, 1, 97, 23, 59, 86, 91, 80, 144, 150, 149, 80, 80, 80, 80, 80, 80, 86, 91, 96, 0, 132, 129, 82, 96, 8, 96, 32, 82, 96, 64, 144, 32, 84, 96, 1, 96, 1, 96, 160, 27, 3, 22, 21, 97, 23, 205, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 91, 86, 91, 129, 97, 23, 234, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 107, 86, 91, 96, 0, 129, 81, 17, 97, 24, 11, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 203, 86, 91, 96, 0, 132, 129, 82, 96, 8, 96, 32, 144, 129, 82, 96, 64, 145, 130, 144, 32, 128, 84, 96, 1, 96, 1, 96, 160, 27, 3, 25, 22, 51, 23, 144, 85, 132, 81, 130, 81, 129, 129, 82, 129, 131, 2, 129, 1, 144, 146, 1, 144, 146, 82, 96, 96, 145, 128, 21, 97, 24, 88, 87, 129, 96, 32, 1, 96, 32, 130, 2, 128, 56, 131, 57, 1, 144, 80, 91, 80, 144, 80, 96, 96, 132, 81, 96, 64, 81, 144, 128, 130, 82, 128, 96, 32, 2, 96, 32, 1, 130, 1, 96, 64, 82, 128, 21, 97, 24, 136, 87, 129, 96, 32, 1, 96, 32, 130, 2, 128, 56, 131, 57, 1, 144, 80, 91, 80, 144, 80, 96, 0, 91, 133, 81, 129, 16, 21, 97, 25, 251, 87, 96, 0, 96, 1, 96, 1, 96, 160, 27, 3, 22, 134, 130, 129, 81, 129, 16, 97, 24, 174, 87, 254, 91, 96, 32, 2, 96, 32, 1, 1, 81, 96, 0, 1, 81, 96, 1, 96, 1, 96, 160, 27, 3, 22, 20, 21, 97, 24, 225, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 139, 86, 91, 133, 129, 129, 81, 129, 16, 97, 24, 237, 87, 254, 91, 96, 32, 2, 96, 32, 1, 1, 81, 96, 32, 1, 81, 96, 0, 20, 21, 97, 25, 25, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 42, 171, 86, 91, 96, 0, 135, 129, 82, 96, 9, 96, 32, 82, 96, 64, 144, 32, 134, 81, 135, 144, 131, 144, 129, 16, 97, 25, 53, 87, 254, 91, 96, 32, 144, 129, 2, 145, 144, 145, 1, 129, 1, 81, 130, 84, 96, 1, 128, 130, 1, 133, 85, 96, 0, 148, 133, 82, 147, 131, 144, 32, 130, 81, 96, 2, 144, 146, 2, 1, 128, 84, 96, 1, 96, 1, 96, 160, 27, 3, 25, 22, 96, 1, 96, 1, 96, 160, 27, 3, 144, 146, 22, 145, 144, 145, 23, 129, 85, 145, 1, 81, 145, 1, 85, 133, 81, 134, 144, 130, 144, 129, 16, 97, 25, 140, 87, 254, 91, 96, 32, 2, 96, 32, 1, 1, 81, 96, 0, 1, 81, 131, 130, 129, 81, 129, 16, 97, 25, 164, 87, 254, 91, 96, 32, 2, 96, 32, 1, 1, 144, 96, 1, 96, 1, 96, 160, 27, 3, 22, 144, 129, 96, 1, 96, 1, 96, 160, 27, 3, 22, 129, 82, 80, 80, 133, 129, 129, 81, 129, 16, 97, 25, 208, 87, 254, 91, 96, 32, 2, 96, 32, 1, 1, 81, 96, 32, 1, 81, 130, 130, 129, 81, 129, 16, 97, 25, 232, 87, 254, 91, 96, 32, 144, 129, 2, 145, 144, 145, 1, 1, 82, 96, 1, 1, 97, 24, 142, 86, 91, 80, 132, 81, 21, 97, 26, 63, 87, 127, 153, 171, 161, 214, 55, 73, 207, 213, 173, 26, 253, 167, 196, 102, 56, 64, 146, 77, 84, 235, 95, 0, 91, 187, 234, 222, 220, 110, 193, 54, 116, 178, 134, 131, 131, 96, 64, 81, 97, 26, 54, 147, 146, 145, 144, 97, 43, 233, 86, 91, 96, 64, 81, 128, 145, 3, 144, 161, 91, 96, 0, 134, 129, 82, 96, 6, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 51, 132, 82, 144, 145, 82, 144, 32, 132, 144, 85, 97, 26, 101, 134, 132, 97, 27, 50, 86, 91, 96, 64, 81, 51, 144, 96, 0, 144, 130, 144, 127, 195, 213, 129, 104, 197, 174, 115, 151, 115, 29, 6, 61, 91, 191, 61, 101, 120, 84, 66, 115, 67, 244, 192, 131, 36, 15, 122, 172, 170, 45, 15, 98, 144, 97, 26, 158, 144, 139, 144, 138, 144, 97, 44, 29, 86, 91, 96, 64, 81, 128, 145, 3, 144, 164, 133, 127, 107, 183, 255, 112, 134, 25, 186, 6, 16, 203, 162, 149, 165, 133, 146, 224, 69, 29, 238, 38, 34, 147, 140, 135, 85, 102, 118, 136, 218, 243, 82, 155, 132, 96, 64, 81, 97, 26, 214, 145, 144, 97, 42, 154, 86, 91, 96, 64, 81, 128, 145, 3, 144, 162, 80, 80, 80, 80, 80, 80, 86, 91, 97, 26, 240, 130, 130, 97, 19, 197, 86, 91, 21, 97, 27, 13, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 42, 187, 86, 91, 96, 1, 96, 1, 96, 160, 27, 3, 22, 96, 0, 144, 129, 82, 96, 32, 145, 144, 145, 82, 96, 64, 144, 32, 128, 84, 96, 255, 25, 22, 96, 1, 23, 144, 85, 86, 91, 96, 0, 130, 129, 82, 96, 8, 96, 32, 82, 96, 64, 144, 32, 84, 96, 1, 96, 1, 96, 160, 27, 3, 22, 97, 27, 102, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 42, 219, 86, 91, 97, 20, 36, 130, 130, 96, 0, 130, 129, 82, 96, 4, 96, 32, 144, 129, 82, 96, 64, 144, 145, 32, 130, 81, 97, 27, 138, 146, 132, 1, 144, 97, 27, 143, 86, 91, 80, 80, 80, 86, 91, 130, 128, 84, 96, 1, 129, 96, 1, 22, 21, 97, 1, 0, 2, 3, 22, 96, 2, 144, 4, 144, 96, 0, 82, 96, 32, 96, 0, 32, 144, 96, 31, 1, 96, 32, 144, 4, 129, 1, 146, 130, 96, 31, 16, 97, 27, 208, 87, 128, 81, 96, 255, 25, 22, 131, 128, 1, 23, 133, 85, 97, 27, 253, 86, 91, 130, 128, 1, 96, 1, 1, 133, 85, 130, 21, 97, 27, 253, 87, 145, 130, 1, 91, 130, 129, 17, 21, 97, 27, 253, 87, 130, 81, 130, 85, 145, 96, 32, 1, 145, 144, 96, 1, 1, 144, 97, 27, 226, 86, 91, 80, 97, 28, 9, 146, 145, 80, 97, 28, 13, 86, 91, 80, 144, 86, 91, 97, 10, 154, 145, 144, 91, 128, 130, 17, 21, 97, 28, 9, 87, 96, 0, 129, 85, 96, 1, 1, 97, 28, 19, 86, 91, 128, 53, 97, 4, 15, 129, 97, 45, 66, 86, 91, 96, 0, 128, 131, 96, 31, 132, 1, 18, 97, 28, 68, 87, 96, 0, 128, 253, 91, 80, 129, 53, 96, 1, 96, 1, 96, 64, 27, 3, 129, 17, 21, 97, 28, 91, 87, 96, 0, 128, 253, 91, 96, 32, 131, 1, 145, 80, 131, 96, 32, 130, 2, 131, 1, 17, 21, 97, 28, 115, 87, 96, 0, 128, 253, 91, 146, 80, 146, 144, 80, 86, 91, 96, 0, 130, 96, 31, 131, 1, 18, 97, 28, 139, 87, 96, 0, 128, 253, 91, 129, 53, 97, 28, 158, 97, 28, 153, 130, 97, 44, 81, 86, 91, 97, 44, 43, 86, 91, 145, 80, 129, 129, 131, 82, 96, 32, 132, 1, 147, 80, 96, 32, 129, 1, 144, 80, 131, 133, 96, 64, 132, 2, 130, 1, 17, 21, 97, 28, 195, 87, 96, 0, 128, 253, 91, 96, 0, 91, 131, 129, 16, 21, 97, 28, 241, 87, 129, 97, 28, 217, 136, 130, 97, 29, 183, 86, 91, 132, 82, 80, 96, 32, 144, 146, 1, 145, 96, 64, 145, 144, 145, 1, 144, 96, 1, 1, 97, 28, 198, 86, 91, 80, 80, 80, 80, 146, 145, 80, 80, 86, 91, 128, 53, 97, 4, 15, 129, 97, 45, 86, 86, 91, 128, 53, 97, 4, 15, 129, 97, 45, 95, 86, 91, 128, 53, 97, 4, 15, 129, 97, 45, 104, 86, 91, 128, 81, 97, 4, 15, 129, 97, 45, 104, 86, 91, 96, 0, 128, 131, 96, 31, 132, 1, 18, 97, 29, 57, 87, 96, 0, 128, 253, 91, 80, 129, 53, 96, 1, 96, 1, 96, 64, 27, 3, 129, 17, 21, 97, 29, 80, 87, 96, 0, 128, 253, 91, 96, 32, 131, 1, 145, 80, 131, 96, 1, 130, 2, 131, 1, 17, 21, 97, 28, 115, 87, 96, 0, 128, 253, 91, 96, 0, 130, 96, 31, 131, 1, 18, 97, 29, 121, 87, 96, 0, 128, 253, 91, 129, 53, 97, 29, 135, 97, 28, 153, 130, 97, 44, 113, 86, 91, 145, 80, 128, 130, 82, 96, 32, 131, 1, 96, 32, 131, 1, 133, 131, 131, 1, 17, 21, 97, 29, 163, 87, 96, 0, 128, 253, 91, 97, 29, 174, 131, 130, 132, 97, 44, 229, 86, 91, 80, 80, 80, 146, 145, 80, 80, 86, 91, 96, 0, 96, 64, 130, 132, 3, 18, 21, 97, 29, 201, 87, 96, 0, 128, 253, 91, 97, 29, 211, 96, 64, 97, 44, 43, 86, 91, 144, 80, 96, 0, 97, 29, 225, 132, 132, 97, 28, 39, 86, 91, 130, 82, 80, 96, 32, 97, 29, 242, 132, 132, 131, 1, 97, 29, 6, 86, 91, 96, 32, 131, 1, 82, 80, 146, 145, 80, 80, 86, 91, 128, 53, 97, 4, 15, 129, 97, 45, 113, 86, 91, 96, 0, 96, 32, 130, 132, 3, 18, 21, 97, 30, 27, 87, 96, 0, 128, 253, 91, 96, 0, 97, 19, 14, 132, 132, 97, 28, 39, 86, 91, 96, 0, 128, 96, 64, 131, 133, 3, 18, 21, 97, 30, 58, 87, 96, 0, 128, 253, 91, 96, 0, 97, 30, 70, 133, 133, 97, 28, 39, 86, 91, 146, 80, 80, 96, 32, 97, 30, 87, 133, 130, 134, 1, 97, 28, 39, 86, 91, 145, 80, 80, 146, 80, 146, 144, 80, 86, 91, 96, 0, 128, 96, 0, 128, 96, 0, 128, 96, 0, 128, 96, 160, 137, 139, 3, 18, 21, 97, 30, 125, 87, 96, 0, 128, 253, 91, 96, 0, 97, 30, 137, 139, 139, 97, 28, 39, 86, 91, 152, 80, 80, 96, 32, 97, 30, 154, 139, 130, 140, 1, 97, 28, 39, 86, 91, 151, 80, 80, 96, 64, 137, 1, 53, 96, 1, 96, 1, 96, 64, 27, 3, 129, 17, 21, 97, 30, 182, 87, 96, 0, 128, 253, 91, 97, 30, 194, 139, 130, 140, 1, 97, 28, 50, 86, 91, 150, 80, 150, 80, 80, 96, 96, 137, 1, 53, 96, 1, 96, 1, 96, 64, 27, 3, 129, 17, 21, 97, 30, 224, 87, 96, 0, 128, 253, 91, 97, 30, 236, 139, 130, 140, 1, 97, 28, 50, 86, 91, 148, 80, 148, 80, 80, 96, 128, 137, 1, 53, 96, 1, 96, 1, 96, 64, 27, 3, 129, 17, 21, 97, 31, 10, 87, 96, 0, 128, 253, 91, 97, 31, 22, 139, 130, 140, 1, 97, 29, 39, 86, 91, 146, 80, 146, 80, 80, 146, 149, 152, 80, 146, 149, 152, 144, 147, 150, 80, 86, 91, 96, 0, 128, 96, 0, 128, 96, 0, 128, 96, 160, 135, 137, 3, 18, 21, 97, 31, 65, 87, 96, 0, 128, 253, 91, 96, 0, 97, 31, 77, 137, 137, 97, 28, 39, 86, 91, 150, 80, 80, 96, 32, 97, 31, 94, 137, 130, 138, 1, 97, 28, 39, 86, 91, 149, 80, 80, 96, 64, 97, 31, 111, 137, 130, 138, 1, 97, 29, 6, 86, 91, 148, 80, 80, 96, 96, 97, 31, 128, 137, 130, 138, 1, 97, 29, 6, 86, 91, 147, 80, 80, 96, 128, 135, 1, 53, 96, 1, 96, 1, 96, 64, 27, 3, 129, 17, 21, 97, 31, 156, 87, 96, 0, 128, 253, 91, 97, 31, 168, 137, 130, 138, 1, 97, 29, 39, 86, 91, 146, 80, 146, 80, 80, 146, 149, 80, 146, 149, 80, 146, 149, 86, 91, 96, 0, 128, 96, 64, 131, 133, 3, 18, 21, 97, 31, 202, 87, 96, 0, 128, 253, 91, 96, 0, 97, 31, 214, 133, 133, 97, 28, 39, 86, 91, 146, 80, 80, 96, 32, 97, 30, 87, 133, 130, 134, 1, 97, 28, 251, 86, 91, 96, 0, 128, 96, 64, 131, 133, 3, 18, 21, 97, 31, 250, 87, 96, 0, 128, 253, 91, 96, 0, 97, 32, 6, 133, 133, 97, 28, 39, 86, 91, 146, 80, 80, 96, 32, 97, 30, 87, 133, 130, 134, 1, 97, 29, 6, 86, 91, 96, 0, 128, 96, 0, 96, 96, 132, 134, 3, 18, 21, 97, 32, 44, 87, 96, 0, 128, 253, 91, 96, 0, 97, 32, 56, 134, 134, 97, 28, 39, 86, 91, 147, 80, 80, 96, 32, 97, 32, 73, 134, 130, 135, 1, 97, 29, 6, 86, 91, 146, 80, 80, 96, 64, 97, 32, 90, 134, 130, 135, 1, 97, 29, 6, 86, 91, 145, 80, 80, 146, 80, 146, 80, 146, 86, 91, 96, 0, 128, 96, 0, 128, 96, 64, 133, 135, 3, 18, 21, 97, 32, 122, 87, 96, 0, 128, 253, 91, 132, 53, 96, 1, 96, 1, 96, 64, 27, 3, 129, 17, 21, 97, 32, 144, 87, 96, 0, 128, 253, 91, 97, 32, 156, 135, 130, 136, 1, 97, 28, 50, 86, 91, 148, 80, 148, 80, 80, 96, 32, 133, 1, 53, 96, 1, 96, 1, 96, 64, 27, 3, 129, 17, 21, 97, 32, 186, 87, 96, 0, 128, 253, 91, 97, 32, 198, 135, 130, 136, 1, 97, 28, 50, 86, 91, 149, 152, 148, 151, 80, 149, 80, 80, 80, 80, 86, 91, 96, 0, 96, 32, 130, 132, 3, 18, 21, 97, 32, 228, 87, 96, 0, 128, 253, 91, 96, 0, 97, 19, 14, 132, 132, 97, 29, 17, 86, 91, 96, 0, 96, 32, 130, 132, 3, 18, 21, 97, 33, 2, 87, 96, 0, 128, 253, 91, 96, 0, 97, 19, 14, 132, 132, 97, 29, 28, 86, 91, 96, 0, 96, 32, 130, 132, 3, 18, 21, 97, 33, 32, 87, 96, 0, 128, 253, 91, 129, 53, 96, 1, 96, 1, 96, 64, 27, 3, 129, 17, 21, 97, 33, 54, 87, 96, 0, 128, 253, 91, 97, 19, 14, 132, 130, 133, 1, 97, 29, 104, 86, 91, 96, 0, 96, 32, 130, 132, 3, 18, 21, 97, 33, 84, 87, 96, 0, 128, 253, 91, 96, 0, 97, 19, 14, 132, 132, 97, 29, 6, 86, 91, 96, 0, 128, 96, 64, 131, 133, 3, 18, 21, 97, 33, 115, 87, 96, 0, 128, 253, 91, 96, 0, 97, 32, 6, 133, 133, 97, 29, 6, 86, 91, 96, 0, 128, 96, 0, 128, 96, 0, 128, 96, 0, 96, 224, 136, 138, 3, 18, 21, 97, 33, 154, 87, 96, 0, 128, 253, 91, 96, 0, 97, 33, 166, 138, 138, 97, 29, 6, 86, 91, 151, 80, 80, 96, 32, 97, 33, 183, 138, 130, 139, 1, 97, 29, 254, 86, 91, 150, 80, 80, 96, 64, 97, 33, 200, 138, 130, 139, 1, 97, 29, 6, 86, 91, 149, 80, 80, 96, 96, 97, 33, 217, 138, 130, 139, 1, 97, 29, 6, 86, 91, 148, 80, 80, 96, 128, 136, 1, 53, 96, 1, 96, 1, 96, 64, 27, 3, 129, 17, 21, 97, 33, 245, 87, 96, 0, 128, 253, 91, 97, 34, 1, 138, 130, 139, 1, 97, 28, 122, 86, 91, 147, 80, 80, 96, 160, 97, 34, 18, 138, 130, 139, 1, 97, 29, 6, 86, 91, 146, 80, 80, 96, 192, 136, 1, 53, 96, 1, 96, 1, 96, 64, 27, 3, 129, 17, 21, 97, 34, 46, 87, 96, 0, 128, 253, 91, 97, 34, 58, 138, 130, 139, 1, 97, 29, 104, 86, 91, 145, 80, 80, 146, 149, 152, 145, 148, 151, 80, 146, 149, 80, 86, 91, 96, 0, 97, 34, 85, 131, 131, 97, 34, 105, 86, 91, 80, 80, 96, 32, 1, 144, 86, 91, 96, 0, 97, 34, 85, 131, 131, 97, 35, 175, 86, 91, 97, 34, 114, 129, 97, 44, 171, 86, 91, 130, 82, 80, 80, 86, 91, 96, 0, 97, 34, 131, 130, 97, 44, 158, 86, 91, 97, 34, 141, 129, 133, 97, 44, 162, 86, 91, 147, 80, 97, 34, 152, 131, 97, 44, 152, 86, 91, 128, 96, 0, 91, 131, 129, 16, 21, 97, 34, 198, 87, 129, 81, 97, 34, 176, 136, 130, 97, 34, 73, 86, 91, 151, 80, 97, 34, 187, 131, 97, 44, 152, 86, 91, 146, 80, 80, 96, 1, 1, 97, 34, 156, 86, 91, 80, 148, 149, 148, 80, 80, 80, 80, 80, 86, 91, 96, 0, 97, 34, 220, 130, 97, 44, 158, 86, 91, 97, 34, 230, 129, 133, 97, 44, 162, 86, 91, 147, 80, 97, 34, 241, 131, 97, 44, 152, 86, 91, 128, 96, 0, 91, 131, 129, 16, 21, 97, 34, 198, 87, 129, 81, 97, 35, 9, 136, 130, 97, 34, 73, 86, 91, 151, 80, 97, 35, 20, 131, 97, 44, 152, 86, 91, 146, 80, 80, 96, 1, 1, 97, 34, 245, 86, 91, 96, 0, 97, 35, 43, 131, 133, 97, 44, 162, 86, 91, 147, 80, 96, 1, 96, 1, 96, 251, 27, 3, 131, 17, 21, 97, 35, 65, 87, 96, 0, 128, 253, 91, 96, 32, 131, 2, 146, 80, 97, 35, 82, 131, 133, 132, 97, 44, 229, 86, 91, 80, 80, 1, 144, 86, 91, 96, 0, 97, 35, 99, 130, 97, 44, 158, 86, 91, 97, 35, 109, 129, 133, 97, 44, 162, 86, 91, 147, 80, 97, 35, 120, 131, 97, 44, 152, 86, 91, 128, 96, 0, 91, 131, 129, 16, 21, 97, 34, 198, 87, 129, 81, 97, 35, 144, 136, 130, 97, 34, 93, 86, 91, 151, 80, 97, 35, 155, 131, 97, 44, 152, 86, 91, 146, 80, 80, 96, 1, 1, 97, 35, 124, 86, 91, 97, 34, 114, 129, 97, 44, 182, 86, 91, 97, 34, 114, 129, 97, 10, 154, 86, 91, 96, 0, 97, 35, 195, 130, 97, 44, 158, 86, 91, 97, 35, 205, 129, 133, 97, 44, 162, 86, 91, 147, 80, 97, 35, 221, 129, 133, 96, 32, 134, 1, 97, 44, 241, 86, 91, 97, 35, 230, 129, 97, 45, 50, 86, 91, 144, 147, 1, 147, 146, 80, 80, 80, 86, 91, 97, 34, 114, 97, 35, 252, 130, 97, 44, 218, 86, 91, 97, 45, 33, 86, 91, 96, 0, 97, 36, 14, 96, 28, 131, 97, 44, 162, 86, 91, 127, 70, 101, 101, 32, 118, 97, 108, 117, 101, 32, 115, 104, 111, 117, 108, 100, 32, 98, 101, 32, 112, 111, 115, 105, 116, 105, 118, 101, 0, 0, 0, 0, 129, 82, 96, 32, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 36, 71, 96, 31, 131, 97, 44, 162, 86, 91, 127, 82, 111, 108, 101, 115, 58, 32, 97, 99, 99, 111, 117, 110, 116, 32, 97, 108, 114, 101, 97, 100, 121, 32, 104, 97, 115, 32, 114, 111, 108, 101, 0, 129, 82, 96, 32, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 36, 128, 96, 38, 131, 97, 44, 162, 86, 91, 127, 79, 119, 110, 97, 98, 108, 101, 58, 32, 110, 101, 119, 32, 111, 119, 110, 101, 114, 32, 105, 115, 32, 116, 104, 101, 32, 122, 101, 114, 111, 32, 97, 129, 82, 101, 100, 100, 114, 101, 115, 115, 96, 208, 27, 96, 32, 130, 1, 82, 96, 64, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 36, 200, 96, 32, 131, 97, 44, 162, 86, 91, 127, 95, 115, 101, 116, 84, 111, 107, 101, 110, 85, 82, 73, 58, 32, 84, 111, 107, 101, 110, 32, 115, 104, 111, 117, 108, 100, 32, 101, 120, 105, 115, 116, 129, 82, 96, 32, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 37, 1, 96, 37, 131, 97, 44, 162, 86, 91, 127, 100, 101, 115, 116, 105, 110, 97, 116, 105, 111, 110, 32, 97, 100, 100, 114, 101, 115, 115, 32, 109, 117, 115, 116, 32, 98, 101, 32, 110, 111, 110, 45, 129, 82, 100, 61, 50, 185, 55, 151, 96, 217, 27, 96, 32, 130, 1, 82, 96, 64, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 37, 72, 96, 33, 131, 97, 44, 162, 86, 91, 127, 82, 111, 108, 101, 115, 58, 32, 97, 99, 99, 111, 117, 110, 116, 32, 100, 111, 101, 115, 32, 110, 111, 116, 32, 104, 97, 118, 101, 32, 114, 111, 108, 129, 82, 96, 101, 96, 248, 27, 96, 32, 130, 1, 82, 96, 64, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 37, 139, 96, 43, 131, 97, 44, 162, 86, 91, 127, 78, 101, 101, 100, 32, 111, 112, 101, 114, 97, 116, 111, 114, 32, 97, 112, 112, 114, 111, 118, 97, 108, 32, 102, 111, 114, 32, 51, 114, 100, 32, 112, 129, 82, 106, 48, 185, 58, 60, 144, 49, 58, 185, 55, 57, 151, 96, 169, 27, 96, 32, 130, 1, 82, 96, 64, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 37, 216, 96, 47, 131, 97, 44, 162, 86, 91, 127, 78, 101, 101, 100, 32, 111, 112, 101, 114, 97, 116, 111, 114, 32, 97, 112, 112, 114, 111, 118, 97, 108, 32, 102, 111, 114, 32, 51, 114, 100, 32, 112, 129, 82, 110, 48, 185, 58, 60, 144, 58, 57, 48, 183, 57, 179, 50, 185, 57, 151, 96, 137, 27, 96, 32, 130, 1, 82, 96, 64, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 38, 41, 96, 62, 131, 97, 44, 162, 86, 91, 127, 99, 111, 110, 116, 114, 97, 99, 116, 32, 114, 101, 116, 117, 114, 110, 101, 100, 32, 97, 110, 32, 117, 110, 107, 110, 111, 119, 110, 32, 118, 97, 108, 129, 82, 127, 117, 101, 32, 102, 114, 111, 109, 32, 111, 110, 69, 82, 67, 49, 49, 53, 53, 66, 97, 116, 99, 104, 82, 101, 99, 101, 105, 118, 101, 100, 0, 0, 96, 32, 130, 1, 82, 96, 64, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 38, 136, 96, 32, 131, 97, 44, 162, 86, 91, 127, 79, 119, 110, 97, 98, 108, 101, 58, 32, 99, 97, 108, 108, 101, 114, 32, 105, 115, 32, 110, 111, 116, 32, 116, 104, 101, 32, 111, 119, 110, 101, 114, 129, 82, 96, 32, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 38, 193, 96, 34, 131, 97, 44, 162, 86, 91, 127, 82, 111, 108, 101, 115, 58, 32, 97, 99, 99, 111, 117, 110, 116, 32, 105, 115, 32, 116, 104, 101, 32, 122, 101, 114, 111, 32, 97, 100, 100, 114, 101, 129, 82, 97, 115, 115, 96, 240, 27, 96, 32, 130, 1, 82, 96, 64, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 39, 5, 96, 23, 131, 97, 44, 162, 86, 91, 127, 84, 111, 107, 101, 110, 32, 105, 115, 32, 97, 108, 114, 101, 97, 100, 121, 32, 109, 105, 110, 116, 101, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 96, 32, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 39, 62, 96, 25, 131, 97, 44, 162, 86, 91, 127, 83, 117, 112, 112, 108, 121, 32, 115, 104, 111, 117, 108, 100, 32, 98, 101, 32, 112, 111, 115, 105, 116, 105, 118, 101, 0, 0, 0, 0, 0, 0, 0, 129, 82, 96, 32, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 39, 119, 96, 41, 131, 97, 44, 162, 86, 91, 127, 95, 105, 100, 115, 32, 97, 110, 100, 32, 95, 118, 97, 108, 117, 101, 115, 32, 97, 114, 114, 97, 121, 32, 108, 101, 110, 103, 104, 116, 32, 109, 117, 129, 82, 104, 57, 186, 16, 54, 176, 186, 49, 180, 23, 96, 185, 27, 96, 32, 130, 1, 82, 96, 64, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 39, 194, 96, 27, 131, 97, 44, 162, 86, 91, 127, 82, 101, 99, 105, 112, 105, 101, 110, 116, 32, 115, 104, 111, 117, 108, 100, 32, 98, 101, 32, 112, 114, 101, 115, 101, 110, 116, 0, 0, 0, 0, 0, 129, 82, 96, 32, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 39, 251, 96, 57, 131, 97, 44, 162, 86, 91, 127, 99, 111, 110, 116, 114, 97, 99, 116, 32, 114, 101, 116, 117, 114, 110, 101, 100, 32, 97, 110, 32, 117, 110, 107, 110, 111, 119, 110, 32, 118, 97, 108, 129, 82, 127, 117, 101, 32, 102, 114, 111, 109, 32, 111, 110, 69, 82, 67, 49, 49, 53, 53, 82, 101, 99, 101, 105, 118, 101, 100, 0, 0, 0, 0, 0, 0, 0, 96, 32, 130, 1, 82, 96, 64, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 40, 90, 96, 21, 131, 97, 44, 162, 86, 91, 116, 47, 186, 55, 144, 54, 186, 185, 186, 16, 49, 50, 144, 55, 55, 183, 22, 189, 50, 185, 55, 151, 96, 89, 27, 129, 82, 96, 32, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 40, 139, 96, 26, 131, 97, 44, 162, 86, 91, 127, 115, 105, 103, 110, 101, 114, 32, 115, 104, 111, 117, 108, 100, 32, 115, 105, 103, 110, 32, 116, 111, 107, 101, 110, 73, 100, 0, 0, 0, 0, 0, 0, 129, 82, 96, 32, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 40, 196, 96, 17, 131, 97, 44, 162, 86, 91, 112, 29, 92, 154, 72, 28, 218, 27, 221, 91, 25, 8, 24, 153, 72, 28, 217, 93, 96, 122, 27, 129, 82, 96, 32, 1, 146, 145, 80, 80, 86, 91, 97, 34, 114, 97, 40, 240, 130, 97, 10, 154, 86, 91, 97, 10, 154, 86, 91, 97, 34, 114, 129, 97, 44, 212, 86, 91, 96, 0, 97, 41, 10, 130, 133, 97, 35, 240, 86, 91, 96, 20, 130, 1, 145, 80, 97, 41, 26, 130, 132, 97, 40, 228, 86, 91, 80, 96, 32, 1, 146, 145, 80, 80, 86, 91, 96, 32, 129, 1, 97, 4, 15, 130, 132, 97, 34, 105, 86, 91, 96, 64, 129, 1, 97, 41, 64, 130, 133, 97, 34, 105, 86, 91, 97, 41, 77, 96, 32, 131, 1, 132, 97, 35, 175, 86, 91, 147, 146, 80, 80, 80, 86, 91, 96, 160, 129, 1, 97, 41, 98, 130, 136, 97, 34, 105, 86, 91, 97, 41, 111, 96, 32, 131, 1, 135, 97, 34, 105, 86, 91, 129, 129, 3, 96, 64, 131, 1, 82, 97, 41, 129, 129, 134, 97, 35, 88, 86, 91, 144, 80, 129, 129, 3, 96, 96, 131, 1, 82, 97, 41, 149, 129, 133, 97, 35, 88, 86, 91, 144, 80, 129, 129, 3, 96, 128, 131, 1, 82, 97, 41, 169, 129, 132, 97, 35, 184, 86, 91, 151, 150, 80, 80, 80, 80, 80, 80, 80, 86, 91, 96, 160, 129, 1, 97, 41, 194, 130, 136, 97, 34, 105, 86, 91, 97, 41, 207, 96, 32, 131, 1, 135, 97, 34, 105, 86, 91, 97, 41, 220, 96, 64, 131, 1, 134, 97, 35, 175, 86, 91, 97, 41, 233, 96, 96, 131, 1, 133, 97, 35, 175, 86, 91, 129, 129, 3, 96, 128, 131, 1, 82, 97, 41, 169, 129, 132, 97, 35, 184, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 41, 77, 129, 132, 97, 34, 209, 86, 91, 96, 64, 128, 130, 82, 129, 1, 97, 42, 30, 129, 134, 136, 97, 35, 31, 86, 91, 144, 80, 129, 129, 3, 96, 32, 131, 1, 82, 97, 42, 51, 129, 132, 134, 97, 35, 31, 86, 91, 150, 149, 80, 80, 80, 80, 80, 80, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 41, 77, 129, 132, 97, 35, 88, 86, 91, 96, 32, 129, 1, 97, 4, 15, 130, 132, 97, 35, 166, 86, 91, 96, 128, 129, 1, 97, 42, 106, 130, 135, 97, 35, 175, 86, 91, 97, 42, 119, 96, 32, 131, 1, 134, 97, 40, 245, 86, 91, 97, 42, 132, 96, 64, 131, 1, 133, 97, 35, 175, 86, 91, 97, 42, 145, 96, 96, 131, 1, 132, 97, 35, 175, 86, 91, 149, 148, 80, 80, 80, 80, 80, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 41, 77, 129, 132, 97, 35, 184, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 36, 1, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 36, 58, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 36, 115, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 36, 187, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 36, 244, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 37, 59, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 37, 126, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 37, 203, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 38, 28, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 38, 123, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 38, 180, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 38, 248, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 39, 49, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 39, 106, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 39, 181, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 39, 238, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 40, 77, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 40, 126, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 40, 183, 86, 91, 96, 32, 129, 1, 97, 4, 15, 130, 132, 97, 35, 175, 86, 91, 96, 96, 129, 1, 97, 43, 247, 130, 134, 97, 35, 175, 86, 91, 129, 129, 3, 96, 32, 131, 1, 82, 97, 44, 9, 129, 133, 97, 34, 120, 86, 91, 144, 80, 129, 129, 3, 96, 64, 131, 1, 82, 97, 42, 145, 129, 132, 97, 35, 88, 86, 91, 96, 64, 129, 1, 97, 41, 64, 130, 133, 97, 35, 175, 86, 91, 96, 64, 81, 129, 129, 1, 96, 1, 96, 1, 96, 64, 27, 3, 129, 17, 130, 130, 16, 23, 21, 97, 44, 73, 87, 96, 0, 128, 253, 91, 96, 64, 82, 145, 144, 80, 86, 91, 96, 0, 96, 1, 96, 1, 96, 64, 27, 3, 130, 17, 21, 97, 44, 103, 87, 96, 0, 128, 253, 91, 80, 96, 32, 144, 129, 2, 1, 144, 86, 91, 96, 0, 96, 1, 96, 1, 96, 64, 27, 3, 130, 17, 21, 97, 44, 135, 87, 96, 0, 128, 253, 91, 80, 96, 32, 96, 31, 145, 144, 145, 1, 96, 31, 25, 22, 1, 144, 86, 91, 96, 32, 1, 144, 86, 91, 81, 144, 86, 91, 144, 129, 82, 96, 32, 1, 144, 86, 91, 96, 0, 97, 4, 15, 130, 97, 44, 200, 86, 91, 21, 21, 144, 86, 91, 96, 1, 96, 1, 96, 224, 27, 3, 25, 22, 144, 86, 91, 96, 1, 96, 1, 96, 160, 27, 3, 22, 144, 86, 91, 96, 255, 22, 144, 86, 91, 96, 0, 97, 4, 15, 130, 97, 44, 171, 86, 91, 130, 129, 131, 55, 80, 96, 0, 145, 1, 82, 86, 91, 96, 0, 91, 131, 129, 16, 21, 97, 45, 12, 87, 129, 129, 1, 81, 131, 130, 1, 82, 96, 32, 1, 97, 44, 244, 86, 91, 131, 129, 17, 21, 97, 45, 27, 87, 96, 0, 132, 132, 1, 82, 91, 80, 80, 80, 80, 86, 91, 96, 0, 97, 4, 15, 130, 96, 0, 97, 4, 15, 130, 97, 45, 60, 86, 91, 96, 31, 1, 96, 31, 25, 22, 144, 86, 91, 96, 96, 27, 144, 86, 91, 97, 45, 75, 129, 97, 44, 171, 86, 91, 129, 20, 97, 4, 248, 87, 96, 0, 128, 253, 91, 97, 45, 75, 129, 97, 44, 182, 86, 91, 97, 45, 75, 129, 97, 10, 154, 86, 91, 97, 45, 75, 129, 97, 44, 187, 86, 91, 97, 45, 75, 129, 97, 44, 212, 86, 254, 163, 101, 98, 122, 122, 114, 49, 88, 32, 112, 99, 189, 218, 52, 161, 239, 153, 96, 81, 62, 78, 84, 154, 131, 156, 21, 193, 23, 214, 39, 16, 168, 42, 61, 224, 61, 137, 189, 46, 22, 202, 108, 101, 120, 112, 101, 114, 105, 109, 101, 110, 116, 97, 108, 245, 100, 115, 111, 108, 99, 67, 0, 5, 17, 0, 64}) + testERC1155RealWorldBytecode = ByteCode([]byte{96, 128, 96, 64, 82, 52, 128, 21, 97, 0, 16, 87, 96, 0, 128, 253, 91, 80, 96, 4, 54, 16, 97, 1, 195, 87, 96, 0, 53, 96, 224, 28, 128, 99, 149, 216, 155, 65, 17, 97, 0, 249, 87, 128, 99, 229, 200, 176, 61, 17, 97, 0, 151, 87, 128, 99, 235, 18, 214, 30, 17, 97, 0, 113, 87, 128, 99, 235, 18, 214, 30, 20, 97, 3, 159, 87, 128, 99, 242, 66, 67, 42, 20, 97, 3, 178, 87, 128, 99, 242, 253, 227, 139, 20, 97, 3, 197, 87, 128, 99, 245, 41, 138, 202, 20, 97, 3, 216, 87, 97, 1, 195, 86, 91, 128, 99, 229, 200, 176, 61, 20, 97, 3, 124, 87, 128, 99, 232, 163, 212, 133, 20, 97, 3, 132, 87, 128, 99, 233, 133, 233, 197, 20, 97, 3, 140, 87, 97, 1, 195, 86, 91, 128, 99, 185, 196, 217, 251, 17, 97, 0, 211, 87, 128, 99, 185, 196, 217, 251, 20, 97, 3, 46, 87, 128, 99, 192, 172, 153, 131, 20, 97, 3, 78, 87, 128, 99, 198, 191, 50, 98, 20, 97, 3, 86, 87, 128, 99, 205, 83, 208, 142, 20, 97, 3, 105, 87, 97, 1, 195, 86, 91, 128, 99, 149, 216, 155, 65, 20, 97, 3, 0, 87, 128, 99, 153, 224, 221, 124, 20, 97, 3, 8, 87, 128, 99, 162, 44, 180, 101, 20, 97, 3, 27, 87, 97, 1, 195, 86, 91, 128, 99, 78, 18, 115, 244, 17, 97, 1, 102, 87, 128, 99, 125, 247, 62, 39, 17, 97, 1, 64, 87, 128, 99, 125, 247, 62, 39, 20, 97, 2, 189, 87, 128, 99, 141, 165, 203, 91, 20, 97, 2, 208, 87, 128, 99, 143, 50, 213, 155, 20, 97, 2, 229, 87, 128, 99, 147, 142, 61, 123, 20, 97, 2, 237, 87, 97, 1, 195, 86, 91, 128, 99, 78, 18, 115, 244, 20, 97, 2, 129, 87, 128, 99, 99, 8, 241, 205, 20, 97, 2, 148, 87, 128, 99, 113, 80, 24, 166, 20, 97, 2, 181, 87, 97, 1, 195, 86, 91, 128, 99, 14, 49, 106, 183, 17, 97, 1, 162, 87, 128, 99, 14, 49, 106, 183, 20, 97, 2, 38, 87, 128, 99, 14, 137, 52, 28, 20, 97, 2, 59, 87, 128, 99, 14, 189, 76, 127, 20, 97, 2, 78, 87, 128, 99, 46, 178, 194, 214, 20, 97, 2, 110, 87, 97, 1, 195, 86, 91, 128, 98, 253, 213, 142, 20, 97, 1, 200, 87, 128, 99, 1, 255, 201, 167, 20, 97, 1, 241, 87, 128, 99, 6, 253, 222, 3, 20, 97, 2, 17, 87, 91, 96, 0, 128, 253, 91, 97, 1, 219, 97, 1, 214, 54, 96, 4, 97, 31, 231, 86, 91, 97, 3, 235, 86, 91, 96, 64, 81, 97, 1, 232, 145, 144, 97, 43, 219, 86, 91, 96, 64, 81, 128, 145, 3, 144, 243, 91, 97, 2, 4, 97, 1, 255, 54, 96, 4, 97, 32, 210, 86, 91, 97, 4, 21, 86, 91, 96, 64, 81, 97, 1, 232, 145, 144, 97, 42, 78, 86, 91, 97, 2, 25, 97, 4, 52, 86, 91, 96, 64, 81, 97, 1, 232, 145, 144, 97, 42, 154, 86, 91, 97, 2, 57, 97, 2, 52, 54, 96, 4, 97, 30, 9, 86, 91, 97, 4, 194, 86, 91, 0, 91, 97, 2, 25, 97, 2, 73, 54, 96, 4, 97, 33, 66, 86, 91, 97, 4, 251, 86, 91, 97, 2, 97, 97, 2, 92, 54, 96, 4, 97, 33, 66, 86, 91, 97, 5, 6, 86, 91, 96, 64, 81, 97, 1, 232, 145, 144, 97, 42, 61, 86, 91, 97, 2, 57, 97, 2, 124, 54, 96, 4, 97, 30, 97, 86, 91, 97, 5, 249, 86, 91, 97, 2, 97, 97, 2, 143, 54, 96, 4, 97, 32, 100, 86, 91, 97, 8, 239, 86, 91, 97, 2, 167, 97, 2, 162, 54, 96, 4, 97, 33, 96, 86, 91, 97, 9, 201, 86, 91, 96, 64, 81, 97, 1, 232, 146, 145, 144, 97, 41, 50, 86, 91, 97, 2, 57, 97, 10, 12, 86, 91, 97, 2, 4, 97, 2, 203, 54, 96, 4, 97, 30, 9, 86, 91, 97, 10, 122, 86, 91, 97, 2, 216, 97, 10, 141, 86, 91, 96, 64, 81, 97, 1, 232, 145, 144, 97, 41, 36, 86, 91, 97, 2, 4, 97, 10, 157, 86, 91, 97, 2, 57, 97, 2, 251, 54, 96, 4, 97, 33, 14, 86, 91, 97, 10, 195, 86, 91, 97, 2, 25, 97, 10, 240, 86, 91, 97, 2, 57, 97, 3, 22, 54, 96, 4, 97, 33, 14, 86, 91, 97, 11, 75, 86, 91, 97, 2, 57, 97, 3, 41, 54, 96, 4, 97, 31, 183, 86, 91, 97, 11, 120, 86, 91, 97, 3, 65, 97, 3, 60, 54, 96, 4, 97, 33, 66, 86, 91, 97, 11, 231, 86, 91, 96, 64, 81, 97, 1, 232, 145, 144, 97, 41, 251, 86, 91, 97, 2, 25, 97, 12, 223, 86, 91, 97, 2, 57, 97, 3, 100, 54, 96, 4, 97, 33, 127, 86, 91, 97, 13, 58, 86, 91, 97, 2, 216, 97, 3, 119, 54, 96, 4, 97, 33, 66, 86, 91, 97, 13, 118, 86, 91, 97, 2, 57, 97, 13, 145, 86, 91, 97, 2, 25, 97, 13, 163, 86, 91, 97, 2, 4, 97, 3, 154, 54, 96, 4, 97, 30, 39, 86, 91, 97, 13, 254, 86, 91, 97, 2, 57, 97, 3, 173, 54, 96, 4, 97, 30, 9, 86, 91, 97, 14, 44, 86, 91, 97, 2, 57, 97, 3, 192, 54, 96, 4, 97, 31, 40, 86, 91, 97, 14, 89, 86, 91, 97, 2, 57, 97, 3, 211, 54, 96, 4, 97, 30, 9, 86, 91, 97, 16, 19, 86, 91, 97, 2, 57, 97, 3, 230, 54, 96, 4, 97, 32, 23, 86, 91, 97, 16, 64, 86, 91, 96, 0, 129, 129, 82, 96, 6, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 96, 1, 96, 1, 96, 160, 27, 3, 134, 22, 132, 82, 144, 145, 82, 144, 32, 84, 91, 146, 145, 80, 80, 86, 91, 96, 1, 96, 1, 96, 224, 27, 3, 25, 22, 96, 0, 144, 129, 82, 96, 32, 129, 144, 82, 96, 64, 144, 32, 84, 96, 255, 22, 144, 86, 91, 96, 10, 128, 84, 96, 64, 128, 81, 96, 32, 96, 2, 96, 1, 133, 22, 21, 97, 1, 0, 2, 96, 0, 25, 1, 144, 148, 22, 147, 144, 147, 4, 96, 31, 129, 1, 132, 144, 4, 132, 2, 130, 1, 132, 1, 144, 146, 82, 129, 129, 82, 146, 145, 131, 1, 130, 130, 128, 21, 97, 4, 186, 87, 128, 96, 31, 16, 97, 4, 143, 87, 97, 1, 0, 128, 131, 84, 4, 2, 131, 82, 145, 96, 32, 1, 145, 97, 4, 186, 86, 91, 130, 1, 145, 144, 96, 0, 82, 96, 32, 96, 0, 32, 144, 91, 129, 84, 129, 82, 144, 96, 1, 1, 144, 96, 32, 1, 128, 131, 17, 97, 4, 157, 87, 130, 144, 3, 96, 31, 22, 130, 1, 145, 91, 80, 80, 80, 80, 80, 129, 86, 91, 97, 4, 202, 97, 10, 157, 86, 91, 97, 4, 239, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 59, 86, 91, 96, 64, 81, 128, 145, 3, 144, 253, 91, 97, 4, 248, 129, 97, 17, 56, 86, 91, 80, 86, 91, 96, 96, 97, 4, 15, 130, 97, 17, 128, 86, 91, 96, 0, 129, 129, 82, 96, 9, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 128, 84, 130, 81, 129, 133, 2, 129, 1, 133, 1, 144, 147, 82, 128, 131, 82, 96, 96, 148, 133, 148, 132, 1, 91, 130, 130, 16, 21, 97, 5, 120, 87, 96, 0, 132, 129, 82, 96, 32, 144, 129, 144, 32, 96, 64, 128, 81, 128, 130, 1, 144, 145, 82, 96, 2, 133, 2, 144, 145, 1, 128, 84, 96, 1, 96, 1, 96, 160, 27, 3, 22, 130, 82, 96, 1, 144, 129, 1, 84, 130, 132, 1, 82, 144, 131, 82, 144, 146, 1, 145, 1, 97, 5, 48, 86, 91, 80, 80, 80, 80, 144, 80, 96, 96, 129, 81, 96, 64, 81, 144, 128, 130, 82, 128, 96, 32, 2, 96, 32, 1, 130, 1, 96, 64, 82, 128, 21, 97, 5, 171, 87, 129, 96, 32, 1, 96, 32, 130, 2, 128, 56, 131, 57, 1, 144, 80, 91, 80, 144, 80, 96, 0, 91, 130, 81, 129, 16, 21, 97, 5, 241, 87, 130, 129, 129, 81, 129, 16, 97, 5, 198, 87, 254, 91, 96, 32, 2, 96, 32, 1, 1, 81, 96, 32, 1, 81, 130, 130, 129, 81, 129, 16, 97, 5, 222, 87, 254, 91, 96, 32, 144, 129, 2, 145, 144, 145, 1, 1, 82, 96, 1, 1, 97, 5, 177, 86, 91, 80, 147, 146, 80, 80, 80, 86, 91, 96, 1, 96, 1, 96, 160, 27, 3, 135, 22, 97, 6, 31, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 42, 235, 86, 91, 132, 131, 20, 97, 6, 62, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 123, 86, 91, 96, 1, 96, 1, 96, 160, 27, 3, 136, 22, 51, 20, 128, 97, 6, 125, 87, 80, 96, 1, 96, 1, 96, 160, 27, 3, 136, 22, 96, 0, 144, 129, 82, 96, 7, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 51, 132, 82, 144, 145, 82, 144, 32, 84, 96, 255, 22, 21, 21, 96, 1, 20, 91, 97, 6, 153, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 27, 86, 91, 96, 0, 91, 133, 129, 16, 21, 97, 7, 206, 87, 96, 0, 135, 135, 131, 129, 129, 16, 97, 6, 178, 87, 254, 91, 144, 80, 96, 32, 2, 1, 53, 144, 80, 96, 0, 134, 134, 132, 129, 129, 16, 97, 6, 201, 87, 254, 91, 144, 80, 96, 32, 2, 1, 53, 144, 80, 97, 7, 27, 129, 96, 6, 96, 0, 133, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 96, 0, 32, 96, 0, 142, 96, 1, 96, 1, 96, 160, 27, 3, 22, 96, 1, 96, 1, 96, 160, 27, 3, 22, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 96, 0, 32, 84, 97, 18, 187, 144, 145, 144, 99, 255, 255, 255, 255, 22, 86, 91, 96, 6, 96, 0, 132, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 96, 0, 32, 96, 0, 141, 96, 1, 96, 1, 96, 160, 27, 3, 22, 96, 1, 96, 1, 96, 160, 27, 3, 22, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 96, 0, 32, 129, 144, 85, 80, 97, 7, 158, 96, 6, 96, 0, 132, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 96, 0, 32, 96, 0, 140, 96, 1, 96, 1, 96, 160, 27, 3, 22, 96, 1, 96, 1, 96, 160, 27, 3, 22, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 96, 0, 32, 84, 130, 97, 18, 205, 144, 145, 144, 99, 255, 255, 255, 255, 22, 86, 91, 96, 0, 146, 131, 82, 96, 6, 96, 32, 144, 129, 82, 96, 64, 128, 133, 32, 96, 1, 96, 1, 96, 160, 27, 3, 142, 22, 134, 82, 144, 145, 82, 144, 146, 32, 145, 144, 145, 85, 80, 96, 1, 1, 97, 6, 156, 86, 91, 80, 134, 96, 1, 96, 1, 96, 160, 27, 3, 22, 136, 96, 1, 96, 1, 96, 160, 27, 3, 22, 51, 96, 1, 96, 1, 96, 160, 27, 3, 22, 127, 74, 57, 220, 6, 212, 192, 219, 198, 75, 112, 175, 144, 253, 105, 138, 35, 58, 81, 138, 165, 208, 126, 89, 93, 152, 59, 140, 5, 38, 200, 247, 251, 137, 137, 137, 137, 96, 64, 81, 97, 8, 34, 148, 147, 146, 145, 144, 97, 42, 12, 86, 91, 96, 64, 81, 128, 145, 3, 144, 164, 97, 8, 60, 135, 96, 1, 96, 1, 96, 160, 27, 3, 22, 97, 18, 218, 86, 91, 21, 97, 8, 229, 87, 97, 8, 229, 51, 137, 137, 137, 137, 128, 128, 96, 32, 2, 96, 32, 1, 96, 64, 81, 144, 129, 1, 96, 64, 82, 128, 147, 146, 145, 144, 129, 129, 82, 96, 32, 1, 131, 131, 96, 32, 2, 128, 130, 132, 55, 96, 0, 146, 1, 145, 144, 145, 82, 80, 80, 96, 64, 128, 81, 96, 32, 128, 141, 2, 130, 129, 1, 130, 1, 144, 147, 82, 140, 130, 82, 144, 147, 80, 140, 146, 80, 139, 145, 130, 145, 133, 1, 144, 132, 144, 128, 130, 132, 55, 96, 0, 146, 1, 145, 144, 145, 82, 80, 80, 96, 64, 128, 81, 96, 32, 96, 31, 140, 1, 129, 144, 4, 129, 2, 130, 1, 129, 1, 144, 146, 82, 138, 129, 82, 146, 80, 138, 145, 80, 137, 144, 129, 144, 132, 1, 131, 130, 128, 130, 132, 55, 96, 0, 146, 1, 145, 144, 145, 82, 80, 97, 19, 22, 146, 80, 80, 80, 86, 91, 80, 80, 80, 80, 80, 80, 80, 80, 86, 91, 96, 96, 131, 130, 20, 97, 8, 253, 87, 96, 0, 128, 253, 91, 96, 64, 128, 81, 133, 129, 82, 96, 32, 128, 135, 2, 130, 1, 1, 144, 145, 82, 96, 96, 144, 133, 128, 21, 97, 9, 41, 87, 129, 96, 32, 1, 96, 32, 130, 2, 128, 56, 131, 57, 1, 144, 80, 91, 80, 144, 80, 96, 0, 91, 133, 129, 16, 21, 97, 9, 191, 87, 96, 6, 96, 0, 134, 134, 132, 129, 129, 16, 97, 9, 71, 87, 254, 91, 144, 80, 96, 32, 2, 1, 53, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 96, 0, 32, 96, 0, 136, 136, 132, 129, 129, 16, 97, 9, 106, 87, 254, 91, 144, 80, 96, 32, 2, 1, 96, 32, 97, 9, 127, 145, 144, 129, 1, 144, 97, 30, 9, 86, 91, 96, 1, 96, 1, 96, 160, 27, 3, 22, 96, 1, 96, 1, 96, 160, 27, 3, 22, 129, 82, 96, 32, 1, 144, 129, 82, 96, 32, 1, 96, 0, 32, 84, 130, 130, 129, 81, 129, 16, 97, 9, 172, 87, 254, 91, 96, 32, 144, 129, 2, 145, 144, 145, 1, 1, 82, 96, 1, 1, 97, 9, 47, 86, 91, 80, 149, 148, 80, 80, 80, 80, 80, 86, 91, 96, 9, 96, 32, 82, 129, 96, 0, 82, 96, 64, 96, 0, 32, 129, 129, 84, 129, 16, 97, 9, 226, 87, 254, 91, 96, 0, 145, 130, 82, 96, 32, 144, 145, 32, 96, 2, 144, 145, 2, 1, 128, 84, 96, 1, 144, 145, 1, 84, 96, 1, 96, 1, 96, 160, 27, 3, 144, 145, 22, 146, 80, 144, 80, 130, 86, 91, 97, 10, 20, 97, 10, 157, 86, 91, 97, 10, 48, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 59, 86, 91, 96, 1, 84, 96, 64, 81, 96, 0, 145, 96, 1, 96, 1, 96, 160, 27, 3, 22, 144, 127, 139, 224, 7, 156, 83, 22, 89, 20, 19, 68, 205, 31, 208, 164, 242, 132, 25, 73, 127, 151, 34, 163, 218, 175, 227, 180, 24, 111, 107, 100, 87, 224, 144, 131, 144, 163, 96, 1, 128, 84, 96, 1, 96, 1, 96, 160, 27, 3, 25, 22, 144, 85, 86, 91, 96, 0, 97, 4, 15, 96, 2, 131, 99, 255, 255, 255, 255, 97, 19, 197, 22, 86, 91, 96, 1, 84, 96, 1, 96, 1, 96, 160, 27, 3, 22, 91, 144, 86, 91, 96, 1, 84, 96, 0, 144, 96, 1, 96, 1, 96, 160, 27, 3, 22, 97, 10, 180, 97, 20, 13, 86, 91, 96, 1, 96, 1, 96, 160, 27, 3, 22, 20, 144, 80, 144, 86, 91, 97, 10, 203, 97, 10, 157, 86, 91, 97, 10, 231, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 59, 86, 91, 97, 4, 248, 129, 97, 20, 17, 86, 91, 96, 11, 128, 84, 96, 64, 128, 81, 96, 32, 96, 2, 96, 1, 133, 22, 21, 97, 1, 0, 2, 96, 0, 25, 1, 144, 148, 22, 147, 144, 147, 4, 96, 31, 129, 1, 132, 144, 4, 132, 2, 130, 1, 132, 1, 144, 146, 82, 129, 129, 82, 146, 145, 131, 1, 130, 130, 128, 21, 97, 4, 186, 87, 128, 96, 31, 16, 97, 4, 143, 87, 97, 1, 0, 128, 131, 84, 4, 2, 131, 82, 145, 96, 32, 1, 145, 97, 4, 186, 86, 91, 97, 11, 83, 97, 10, 157, 86, 91, 97, 11, 111, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 59, 86, 91, 97, 4, 248, 129, 97, 20, 40, 86, 91, 51, 96, 0, 129, 129, 82, 96, 7, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 96, 1, 96, 1, 96, 160, 27, 3, 135, 22, 128, 133, 82, 146, 82, 145, 130, 144, 32, 128, 84, 96, 255, 25, 22, 133, 21, 21, 23, 144, 85, 144, 81, 144, 145, 144, 127, 23, 48, 126, 171, 57, 171, 97, 7, 232, 137, 152, 69, 173, 61, 89, 189, 150, 83, 242, 0, 242, 32, 146, 4, 137, 202, 43, 89, 55, 105, 108, 49, 144, 97, 11, 219, 144, 133, 144, 97, 42, 78, 86, 91, 96, 64, 81, 128, 145, 3, 144, 163, 80, 80, 86, 91, 96, 0, 129, 129, 82, 96, 9, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 128, 84, 130, 81, 129, 133, 2, 129, 1, 133, 1, 144, 147, 82, 128, 131, 82, 96, 96, 148, 133, 148, 132, 1, 91, 130, 130, 16, 21, 97, 12, 89, 87, 96, 0, 132, 129, 82, 96, 32, 144, 129, 144, 32, 96, 64, 128, 81, 128, 130, 1, 144, 145, 82, 96, 2, 133, 2, 144, 145, 1, 128, 84, 96, 1, 96, 1, 96, 160, 27, 3, 22, 130, 82, 96, 1, 144, 129, 1, 84, 130, 132, 1, 82, 144, 131, 82, 144, 146, 1, 145, 1, 97, 12, 17, 86, 91, 80, 80, 80, 80, 144, 80, 96, 96, 129, 81, 96, 64, 81, 144, 128, 130, 82, 128, 96, 32, 2, 96, 32, 1, 130, 1, 96, 64, 82, 128, 21, 97, 12, 140, 87, 129, 96, 32, 1, 96, 32, 130, 2, 128, 56, 131, 57, 1, 144, 80, 91, 80, 144, 80, 96, 0, 91, 130, 81, 129, 16, 21, 97, 5, 241, 87, 130, 129, 129, 81, 129, 16, 97, 12, 167, 87, 254, 91, 96, 32, 2, 96, 32, 1, 1, 81, 96, 0, 1, 81, 130, 130, 129, 81, 129, 16, 97, 12, 191, 87, 254, 91, 96, 1, 96, 1, 96, 160, 27, 3, 144, 146, 22, 96, 32, 146, 131, 2, 145, 144, 145, 1, 144, 145, 1, 82, 96, 1, 1, 97, 12, 146, 86, 91, 96, 3, 128, 84, 96, 64, 128, 81, 96, 32, 96, 2, 96, 1, 133, 22, 21, 97, 1, 0, 2, 96, 0, 25, 1, 144, 148, 22, 147, 144, 147, 4, 96, 31, 129, 1, 132, 144, 4, 132, 2, 130, 1, 132, 1, 144, 146, 82, 129, 129, 82, 146, 145, 131, 1, 130, 130, 128, 21, 97, 4, 186, 87, 128, 96, 31, 16, 97, 4, 143, 87, 97, 1, 0, 128, 131, 84, 4, 2, 131, 82, 145, 96, 32, 1, 145, 97, 4, 186, 86, 91, 97, 13, 66, 97, 10, 157, 86, 91, 97, 13, 94, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 59, 86, 91, 97, 13, 109, 135, 135, 135, 135, 135, 135, 135, 97, 20, 59, 86, 91, 80, 80, 80, 80, 80, 80, 80, 86, 91, 96, 8, 96, 32, 82, 96, 0, 144, 129, 82, 96, 64, 144, 32, 84, 96, 1, 96, 1, 96, 160, 27, 3, 22, 129, 86, 91, 97, 13, 161, 97, 13, 156, 97, 20, 13, 86, 91, 97, 17, 56, 86, 91, 86, 91, 96, 5, 128, 84, 96, 64, 128, 81, 96, 32, 96, 2, 96, 1, 133, 22, 21, 97, 1, 0, 2, 96, 0, 25, 1, 144, 148, 22, 147, 144, 147, 4, 96, 31, 129, 1, 132, 144, 4, 132, 2, 130, 1, 132, 1, 144, 146, 82, 129, 129, 82, 146, 145, 131, 1, 130, 130, 128, 21, 97, 4, 186, 87, 128, 96, 31, 16, 97, 4, 143, 87, 97, 1, 0, 128, 131, 84, 4, 2, 131, 82, 145, 96, 32, 1, 145, 97, 4, 186, 86, 91, 96, 1, 96, 1, 96, 160, 27, 3, 145, 130, 22, 96, 0, 144, 129, 82, 96, 7, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 147, 144, 148, 22, 130, 82, 145, 144, 145, 82, 32, 84, 96, 255, 22, 144, 86, 91, 97, 14, 52, 97, 10, 157, 86, 91, 97, 14, 80, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 59, 86, 91, 97, 4, 248, 129, 97, 20, 226, 86, 91, 96, 1, 96, 1, 96, 160, 27, 3, 133, 22, 97, 14, 127, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 171, 86, 91, 96, 1, 96, 1, 96, 160, 27, 3, 134, 22, 51, 20, 128, 97, 14, 190, 87, 80, 96, 1, 96, 1, 96, 160, 27, 3, 134, 22, 96, 0, 144, 129, 82, 96, 7, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 51, 132, 82, 144, 145, 82, 144, 32, 84, 96, 255, 22, 21, 21, 96, 1, 20, 91, 97, 14, 218, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 27, 86, 91, 96, 0, 132, 129, 82, 96, 6, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 96, 1, 96, 1, 96, 160, 27, 3, 138, 22, 132, 82, 144, 145, 82, 144, 32, 84, 97, 15, 13, 144, 132, 99, 255, 255, 255, 255, 97, 18, 187, 22, 86, 91, 96, 0, 133, 129, 82, 96, 6, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 96, 1, 96, 1, 96, 160, 27, 3, 139, 129, 22, 133, 82, 146, 82, 128, 131, 32, 147, 144, 147, 85, 135, 22, 129, 82, 32, 84, 97, 15, 69, 144, 132, 144, 97, 18, 205, 86, 91, 96, 0, 133, 129, 82, 96, 6, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 96, 1, 96, 1, 96, 160, 27, 3, 128, 139, 22, 128, 134, 82, 145, 144, 147, 82, 146, 129, 144, 32, 147, 144, 147, 85, 145, 81, 144, 145, 136, 22, 144, 51, 144, 127, 195, 213, 129, 104, 197, 174, 115, 151, 115, 29, 6, 61, 91, 191, 61, 101, 120, 84, 66, 115, 67, 244, 192, 131, 36, 15, 122, 172, 170, 45, 15, 98, 144, 97, 15, 168, 144, 137, 144, 137, 144, 97, 44, 29, 86, 91, 96, 64, 81, 128, 145, 3, 144, 164, 97, 15, 194, 133, 96, 1, 96, 1, 96, 160, 27, 3, 22, 97, 18, 218, 86, 91, 21, 97, 16, 11, 87, 97, 16, 11, 51, 135, 135, 135, 135, 135, 135, 128, 128, 96, 31, 1, 96, 32, 128, 145, 4, 2, 96, 32, 1, 96, 64, 81, 144, 129, 1, 96, 64, 82, 128, 147, 146, 145, 144, 129, 129, 82, 96, 32, 1, 131, 131, 128, 130, 132, 55, 96, 0, 146, 1, 145, 144, 145, 82, 80, 97, 21, 42, 146, 80, 80, 80, 86, 91, 80, 80, 80, 80, 80, 80, 86, 91, 97, 16, 27, 97, 10, 157, 86, 91, 97, 16, 55, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 59, 86, 91, 97, 4, 248, 129, 97, 21, 217, 86, 91, 96, 1, 96, 1, 96, 160, 27, 3, 131, 22, 51, 20, 128, 97, 16, 127, 87, 80, 96, 1, 96, 1, 96, 160, 27, 3, 131, 22, 96, 0, 144, 129, 82, 96, 7, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 51, 132, 82, 144, 145, 82, 144, 32, 84, 96, 255, 22, 21, 21, 96, 1, 20, 91, 97, 16, 155, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 11, 86, 91, 96, 0, 130, 129, 82, 96, 6, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 96, 1, 96, 1, 96, 160, 27, 3, 135, 22, 132, 82, 144, 145, 82, 144, 32, 84, 97, 16, 206, 144, 130, 99, 255, 255, 255, 255, 97, 18, 187, 22, 86, 91, 96, 0, 131, 129, 82, 96, 6, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 96, 1, 96, 1, 96, 160, 27, 3, 136, 22, 128, 133, 82, 146, 82, 128, 131, 32, 147, 144, 147, 85, 145, 81, 144, 145, 144, 51, 144, 127, 195, 213, 129, 104, 197, 174, 115, 151, 115, 29, 6, 61, 91, 191, 61, 101, 120, 84, 66, 115, 67, 244, 192, 131, 36, 15, 122, 172, 170, 45, 15, 98, 144, 97, 17, 43, 144, 135, 144, 135, 144, 97, 44, 29, 86, 91, 96, 64, 81, 128, 145, 3, 144, 164, 80, 80, 80, 86, 91, 97, 17, 73, 96, 2, 130, 99, 255, 255, 255, 255, 97, 22, 91, 22, 86, 91, 96, 64, 81, 96, 1, 96, 1, 96, 160, 27, 3, 130, 22, 144, 127, 53, 37, 226, 40, 36, 168, 167, 223, 44, 154, 96, 41, 148, 28, 130, 76, 249, 91, 100, 71, 241, 225, 61, 81, 40, 253, 56, 38, 211, 90, 254, 139, 144, 96, 0, 144, 162, 80, 86, 91, 96, 0, 129, 129, 82, 96, 4, 96, 32, 144, 129, 82, 96, 64, 145, 130, 144, 32, 128, 84, 131, 81, 96, 2, 96, 1, 131, 22, 21, 97, 1, 0, 2, 96, 0, 25, 1, 144, 146, 22, 145, 144, 145, 4, 96, 31, 129, 1, 132, 144, 4, 132, 2, 130, 1, 132, 1, 144, 148, 82, 131, 129, 82, 96, 96, 147, 97, 4, 15, 147, 145, 146, 145, 131, 1, 130, 130, 128, 21, 97, 18, 26, 87, 128, 96, 31, 16, 97, 17, 239, 87, 97, 1, 0, 128, 131, 84, 4, 2, 131, 82, 145, 96, 32, 1, 145, 97, 18, 26, 86, 91, 130, 1, 145, 144, 96, 0, 82, 96, 32, 96, 0, 32, 144, 91, 129, 84, 129, 82, 144, 96, 1, 1, 144, 96, 32, 1, 128, 131, 17, 97, 17, 253, 87, 130, 144, 3, 96, 31, 22, 130, 1, 145, 91, 80, 80, 96, 3, 128, 84, 96, 64, 128, 81, 96, 32, 96, 31, 96, 2, 96, 0, 25, 97, 1, 0, 96, 1, 136, 22, 21, 2, 1, 144, 149, 22, 148, 144, 148, 4, 147, 132, 1, 129, 144, 4, 129, 2, 130, 1, 129, 1, 144, 146, 82, 130, 129, 82, 149, 80, 145, 147, 80, 145, 80, 131, 1, 130, 130, 128, 21, 97, 18, 168, 87, 128, 96, 31, 16, 97, 18, 125, 87, 97, 1, 0, 128, 131, 84, 4, 2, 131, 82, 145, 96, 32, 1, 145, 97, 18, 168, 86, 91, 130, 1, 145, 144, 96, 0, 82, 96, 32, 96, 0, 32, 144, 91, 129, 84, 129, 82, 144, 96, 1, 1, 144, 96, 32, 1, 128, 131, 17, 97, 18, 139, 87, 130, 144, 3, 96, 31, 22, 130, 1, 145, 91, 80, 80, 80, 80, 80, 97, 22, 163, 144, 145, 144, 99, 255, 255, 255, 255, 22, 86, 91, 96, 0, 130, 130, 17, 21, 97, 18, 199, 87, 254, 91, 80, 144, 3, 144, 86, 91, 129, 129, 1, 130, 129, 16, 21, 97, 4, 15, 87, 254, 91, 96, 0, 129, 63, 127, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112, 129, 129, 20, 128, 21, 144, 97, 19, 14, 87, 80, 129, 21, 21, 91, 148, 147, 80, 80, 80, 80, 86, 91, 96, 64, 81, 99, 188, 25, 124, 129, 96, 224, 27, 128, 130, 82, 144, 96, 1, 96, 1, 96, 160, 27, 3, 134, 22, 144, 99, 188, 25, 124, 129, 144, 97, 19, 76, 144, 138, 144, 138, 144, 137, 144, 137, 144, 137, 144, 96, 4, 1, 97, 41, 84, 86, 91, 96, 32, 96, 64, 81, 128, 131, 3, 129, 96, 0, 135, 128, 59, 21, 128, 21, 97, 19, 102, 87, 96, 0, 128, 253, 91, 80, 90, 241, 21, 128, 21, 97, 19, 122, 87, 61, 96, 0, 128, 62, 61, 96, 0, 253, 91, 80, 80, 80, 80, 96, 64, 81, 61, 96, 31, 25, 96, 31, 130, 1, 22, 130, 1, 128, 96, 64, 82, 80, 97, 19, 158, 145, 144, 129, 1, 144, 97, 32, 240, 86, 91, 96, 1, 96, 1, 96, 224, 27, 3, 25, 22, 20, 97, 16, 11, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 43, 86, 91, 96, 0, 96, 1, 96, 1, 96, 160, 27, 3, 130, 22, 97, 19, 237, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 75, 86, 91, 80, 96, 1, 96, 1, 96, 160, 27, 3, 22, 96, 0, 144, 129, 82, 96, 32, 145, 144, 145, 82, 96, 64, 144, 32, 84, 96, 255, 22, 144, 86, 91, 51, 144, 86, 91, 128, 81, 97, 20, 36, 144, 96, 5, 144, 96, 32, 132, 1, 144, 97, 27, 143, 86, 91, 80, 80, 86, 91, 128, 81, 97, 20, 36, 144, 96, 3, 144, 96, 32, 132, 1, 144, 97, 27, 143, 86, 91, 97, 20, 186, 96, 1, 48, 137, 96, 64, 81, 96, 32, 1, 97, 20, 83, 146, 145, 144, 97, 40, 254, 86, 91, 96, 64, 81, 96, 32, 129, 131, 3, 3, 129, 82, 144, 96, 64, 82, 128, 81, 144, 96, 32, 1, 32, 136, 136, 136, 96, 64, 81, 96, 0, 129, 82, 96, 32, 1, 96, 64, 82, 96, 64, 81, 97, 20, 137, 148, 147, 146, 145, 144, 97, 42, 92, 86, 91, 96, 32, 96, 64, 81, 96, 32, 129, 3, 144, 128, 132, 3, 144, 133, 90, 250, 21, 128, 21, 97, 20, 171, 87, 61, 96, 0, 128, 62, 61, 96, 0, 253, 91, 80, 80, 80, 96, 32, 96, 64, 81, 3, 81, 97, 10, 122, 86, 91, 97, 20, 214, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 187, 86, 91, 97, 13, 109, 135, 132, 132, 132, 97, 23, 152, 86, 91, 97, 20, 243, 96, 2, 130, 99, 255, 255, 255, 255, 97, 26, 230, 22, 86, 91, 96, 64, 81, 96, 1, 96, 1, 96, 160, 27, 3, 130, 22, 144, 127, 71, 209, 194, 42, 37, 187, 58, 93, 78, 72, 27, 155, 30, 105, 68, 194, 234, 222, 49, 129, 160, 162, 11, 73, 94, 214, 29, 53, 181, 50, 63, 36, 144, 96, 0, 144, 162, 80, 86, 91, 96, 64, 81, 99, 242, 58, 110, 97, 96, 224, 27, 128, 130, 82, 144, 96, 1, 96, 1, 96, 160, 27, 3, 134, 22, 144, 99, 242, 58, 110, 97, 144, 97, 21, 96, 144, 138, 144, 138, 144, 137, 144, 137, 144, 137, 144, 96, 4, 1, 97, 41, 180, 86, 91, 96, 32, 96, 64, 81, 128, 131, 3, 129, 96, 0, 135, 128, 59, 21, 128, 21, 97, 21, 122, 87, 96, 0, 128, 253, 91, 80, 90, 241, 21, 128, 21, 97, 21, 142, 87, 61, 96, 0, 128, 62, 61, 96, 0, 253, 91, 80, 80, 80, 80, 96, 64, 81, 61, 96, 31, 25, 96, 31, 130, 1, 22, 130, 1, 128, 96, 64, 82, 80, 97, 21, 178, 145, 144, 129, 1, 144, 97, 32, 240, 86, 91, 96, 1, 96, 1, 96, 224, 27, 3, 25, 22, 20, 97, 16, 11, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 155, 86, 91, 96, 1, 96, 1, 96, 160, 27, 3, 129, 22, 97, 21, 255, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 42, 203, 86, 91, 96, 1, 84, 96, 64, 81, 96, 1, 96, 1, 96, 160, 27, 3, 128, 132, 22, 146, 22, 144, 127, 139, 224, 7, 156, 83, 22, 89, 20, 19, 68, 205, 31, 208, 164, 242, 132, 25, 73, 127, 151, 34, 163, 218, 175, 227, 180, 24, 111, 107, 100, 87, 224, 144, 96, 0, 144, 163, 96, 1, 128, 84, 96, 1, 96, 1, 96, 160, 27, 3, 25, 22, 96, 1, 96, 1, 96, 160, 27, 3, 146, 144, 146, 22, 145, 144, 145, 23, 144, 85, 86, 91, 97, 22, 101, 130, 130, 97, 19, 197, 86, 91, 97, 22, 129, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 42, 251, 86, 91, 96, 1, 96, 1, 96, 160, 27, 3, 22, 96, 0, 144, 129, 82, 96, 32, 145, 144, 145, 82, 96, 64, 144, 32, 128, 84, 96, 255, 25, 22, 144, 85, 86, 91, 96, 96, 128, 131, 144, 80, 96, 96, 131, 144, 80, 96, 96, 129, 81, 131, 81, 1, 96, 64, 81, 144, 128, 130, 82, 128, 96, 31, 1, 96, 31, 25, 22, 96, 32, 1, 130, 1, 96, 64, 82, 128, 21, 97, 22, 223, 87, 96, 32, 130, 1, 129, 128, 56, 131, 57, 1, 144, 80, 91, 80, 144, 80, 96, 0, 128, 91, 132, 81, 129, 16, 21, 97, 23, 55, 87, 132, 129, 129, 81, 129, 16, 97, 22, 251, 87, 254, 91, 96, 32, 1, 1, 81, 96, 248, 28, 96, 248, 27, 131, 131, 128, 96, 1, 1, 148, 80, 129, 81, 129, 16, 97, 23, 24, 87, 254, 91, 96, 32, 1, 1, 144, 96, 1, 96, 1, 96, 248, 27, 3, 25, 22, 144, 129, 96, 0, 26, 144, 83, 80, 96, 1, 1, 97, 22, 230, 86, 91, 80, 96, 0, 91, 131, 81, 129, 16, 21, 97, 23, 140, 87, 131, 129, 129, 81, 129, 16, 97, 23, 80, 87, 254, 91, 96, 32, 1, 1, 81, 96, 248, 28, 96, 248, 27, 131, 131, 128, 96, 1, 1, 148, 80, 129, 81, 129, 16, 97, 23, 109, 87, 254, 91, 96, 32, 1, 1, 144, 96, 1, 96, 1, 96, 248, 27, 3, 25, 22, 144, 129, 96, 0, 26, 144, 83, 80, 96, 1, 1, 97, 23, 59, 86, 91, 80, 144, 150, 149, 80, 80, 80, 80, 80, 80, 86, 91, 96, 0, 132, 129, 82, 96, 8, 96, 32, 82, 96, 64, 144, 32, 84, 96, 1, 96, 1, 96, 160, 27, 3, 22, 21, 97, 23, 205, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 91, 86, 91, 129, 97, 23, 234, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 107, 86, 91, 96, 0, 129, 81, 17, 97, 24, 11, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 203, 86, 91, 96, 0, 132, 129, 82, 96, 8, 96, 32, 144, 129, 82, 96, 64, 145, 130, 144, 32, 128, 84, 96, 1, 96, 1, 96, 160, 27, 3, 25, 22, 51, 23, 144, 85, 132, 81, 130, 81, 129, 129, 82, 129, 131, 2, 129, 1, 144, 146, 1, 144, 146, 82, 96, 96, 145, 128, 21, 97, 24, 88, 87, 129, 96, 32, 1, 96, 32, 130, 2, 128, 56, 131, 57, 1, 144, 80, 91, 80, 144, 80, 96, 96, 132, 81, 96, 64, 81, 144, 128, 130, 82, 128, 96, 32, 2, 96, 32, 1, 130, 1, 96, 64, 82, 128, 21, 97, 24, 136, 87, 129, 96, 32, 1, 96, 32, 130, 2, 128, 56, 131, 57, 1, 144, 80, 91, 80, 144, 80, 96, 0, 91, 133, 81, 129, 16, 21, 97, 25, 251, 87, 96, 0, 96, 1, 96, 1, 96, 160, 27, 3, 22, 134, 130, 129, 81, 129, 16, 97, 24, 174, 87, 254, 91, 96, 32, 2, 96, 32, 1, 1, 81, 96, 0, 1, 81, 96, 1, 96, 1, 96, 160, 27, 3, 22, 20, 21, 97, 24, 225, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 43, 139, 86, 91, 133, 129, 129, 81, 129, 16, 97, 24, 237, 87, 254, 91, 96, 32, 2, 96, 32, 1, 1, 81, 96, 32, 1, 81, 96, 0, 20, 21, 97, 25, 25, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 42, 171, 86, 91, 96, 0, 135, 129, 82, 96, 9, 96, 32, 82, 96, 64, 144, 32, 134, 81, 135, 144, 131, 144, 129, 16, 97, 25, 53, 87, 254, 91, 96, 32, 144, 129, 2, 145, 144, 145, 1, 129, 1, 81, 130, 84, 96, 1, 128, 130, 1, 133, 85, 96, 0, 148, 133, 82, 147, 131, 144, 32, 130, 81, 96, 2, 144, 146, 2, 1, 128, 84, 96, 1, 96, 1, 96, 160, 27, 3, 25, 22, 96, 1, 96, 1, 96, 160, 27, 3, 144, 146, 22, 145, 144, 145, 23, 129, 85, 145, 1, 81, 145, 1, 85, 133, 81, 134, 144, 130, 144, 129, 16, 97, 25, 140, 87, 254, 91, 96, 32, 2, 96, 32, 1, 1, 81, 96, 0, 1, 81, 131, 130, 129, 81, 129, 16, 97, 25, 164, 87, 254, 91, 96, 32, 2, 96, 32, 1, 1, 144, 96, 1, 96, 1, 96, 160, 27, 3, 22, 144, 129, 96, 1, 96, 1, 96, 160, 27, 3, 22, 129, 82, 80, 80, 133, 129, 129, 81, 129, 16, 97, 25, 208, 87, 254, 91, 96, 32, 2, 96, 32, 1, 1, 81, 96, 32, 1, 81, 130, 130, 129, 81, 129, 16, 97, 25, 232, 87, 254, 91, 96, 32, 144, 129, 2, 145, 144, 145, 1, 1, 82, 96, 1, 1, 97, 24, 142, 86, 91, 80, 132, 81, 21, 97, 26, 63, 87, 127, 153, 171, 161, 214, 55, 73, 207, 213, 173, 26, 253, 167, 196, 102, 56, 64, 146, 77, 84, 235, 95, 0, 91, 187, 234, 222, 220, 110, 193, 54, 116, 178, 134, 131, 131, 96, 64, 81, 97, 26, 54, 147, 146, 145, 144, 97, 43, 233, 86, 91, 96, 64, 81, 128, 145, 3, 144, 161, 91, 96, 0, 134, 129, 82, 96, 6, 96, 32, 144, 129, 82, 96, 64, 128, 131, 32, 51, 132, 82, 144, 145, 82, 144, 32, 132, 144, 85, 97, 26, 101, 134, 132, 97, 27, 50, 86, 91, 96, 64, 81, 51, 144, 96, 0, 144, 130, 144, 127, 195, 213, 129, 104, 197, 174, 115, 151, 115, 29, 6, 61, 91, 191, 61, 101, 120, 84, 66, 115, 67, 244, 192, 131, 36, 15, 122, 172, 170, 45, 15, 98, 144, 97, 26, 158, 144, 139, 144, 138, 144, 97, 44, 29, 86, 91, 96, 64, 81, 128, 145, 3, 144, 164, 133, 127, 107, 183, 255, 112, 134, 25, 186, 6, 16, 203, 162, 149, 165, 133, 146, 224, 69, 29, 238, 38, 34, 147, 140, 135, 85, 102, 118, 136, 218, 243, 82, 155, 132, 96, 64, 81, 97, 26, 214, 145, 144, 97, 42, 154, 86, 91, 96, 64, 81, 128, 145, 3, 144, 162, 80, 80, 80, 80, 80, 80, 86, 91, 97, 26, 240, 130, 130, 97, 19, 197, 86, 91, 21, 97, 27, 13, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 42, 187, 86, 91, 96, 1, 96, 1, 96, 160, 27, 3, 22, 96, 0, 144, 129, 82, 96, 32, 145, 144, 145, 82, 96, 64, 144, 32, 128, 84, 96, 255, 25, 22, 96, 1, 23, 144, 85, 86, 91, 96, 0, 130, 129, 82, 96, 8, 96, 32, 82, 96, 64, 144, 32, 84, 96, 1, 96, 1, 96, 160, 27, 3, 22, 97, 27, 102, 87, 96, 64, 81, 98, 70, 27, 205, 96, 229, 27, 129, 82, 96, 4, 1, 97, 4, 230, 144, 97, 42, 219, 86, 91, 97, 20, 36, 130, 130, 96, 0, 130, 129, 82, 96, 4, 96, 32, 144, 129, 82, 96, 64, 144, 145, 32, 130, 81, 97, 27, 138, 146, 132, 1, 144, 97, 27, 143, 86, 91, 80, 80, 80, 86, 91, 130, 128, 84, 96, 1, 129, 96, 1, 22, 21, 97, 1, 0, 2, 3, 22, 96, 2, 144, 4, 144, 96, 0, 82, 96, 32, 96, 0, 32, 144, 96, 31, 1, 96, 32, 144, 4, 129, 1, 146, 130, 96, 31, 16, 97, 27, 208, 87, 128, 81, 96, 255, 25, 22, 131, 128, 1, 23, 133, 85, 97, 27, 253, 86, 91, 130, 128, 1, 96, 1, 1, 133, 85, 130, 21, 97, 27, 253, 87, 145, 130, 1, 91, 130, 129, 17, 21, 97, 27, 253, 87, 130, 81, 130, 85, 145, 96, 32, 1, 145, 144, 96, 1, 1, 144, 97, 27, 226, 86, 91, 80, 97, 28, 9, 146, 145, 80, 97, 28, 13, 86, 91, 80, 144, 86, 91, 97, 10, 154, 145, 144, 91, 128, 130, 17, 21, 97, 28, 9, 87, 96, 0, 129, 85, 96, 1, 1, 97, 28, 19, 86, 91, 128, 53, 97, 4, 15, 129, 97, 45, 66, 86, 91, 96, 0, 128, 131, 96, 31, 132, 1, 18, 97, 28, 68, 87, 96, 0, 128, 253, 91, 80, 129, 53, 96, 1, 96, 1, 96, 64, 27, 3, 129, 17, 21, 97, 28, 91, 87, 96, 0, 128, 253, 91, 96, 32, 131, 1, 145, 80, 131, 96, 32, 130, 2, 131, 1, 17, 21, 97, 28, 115, 87, 96, 0, 128, 253, 91, 146, 80, 146, 144, 80, 86, 91, 96, 0, 130, 96, 31, 131, 1, 18, 97, 28, 139, 87, 96, 0, 128, 253, 91, 129, 53, 97, 28, 158, 97, 28, 153, 130, 97, 44, 81, 86, 91, 97, 44, 43, 86, 91, 145, 80, 129, 129, 131, 82, 96, 32, 132, 1, 147, 80, 96, 32, 129, 1, 144, 80, 131, 133, 96, 64, 132, 2, 130, 1, 17, 21, 97, 28, 195, 87, 96, 0, 128, 253, 91, 96, 0, 91, 131, 129, 16, 21, 97, 28, 241, 87, 129, 97, 28, 217, 136, 130, 97, 29, 183, 86, 91, 132, 82, 80, 96, 32, 144, 146, 1, 145, 96, 64, 145, 144, 145, 1, 144, 96, 1, 1, 97, 28, 198, 86, 91, 80, 80, 80, 80, 146, 145, 80, 80, 86, 91, 128, 53, 97, 4, 15, 129, 97, 45, 86, 86, 91, 128, 53, 97, 4, 15, 129, 97, 45, 95, 86, 91, 128, 53, 97, 4, 15, 129, 97, 45, 104, 86, 91, 128, 81, 97, 4, 15, 129, 97, 45, 104, 86, 91, 96, 0, 128, 131, 96, 31, 132, 1, 18, 97, 29, 57, 87, 96, 0, 128, 253, 91, 80, 129, 53, 96, 1, 96, 1, 96, 64, 27, 3, 129, 17, 21, 97, 29, 80, 87, 96, 0, 128, 253, 91, 96, 32, 131, 1, 145, 80, 131, 96, 1, 130, 2, 131, 1, 17, 21, 97, 28, 115, 87, 96, 0, 128, 253, 91, 96, 0, 130, 96, 31, 131, 1, 18, 97, 29, 121, 87, 96, 0, 128, 253, 91, 129, 53, 97, 29, 135, 97, 28, 153, 130, 97, 44, 113, 86, 91, 145, 80, 128, 130, 82, 96, 32, 131, 1, 96, 32, 131, 1, 133, 131, 131, 1, 17, 21, 97, 29, 163, 87, 96, 0, 128, 253, 91, 97, 29, 174, 131, 130, 132, 97, 44, 229, 86, 91, 80, 80, 80, 146, 145, 80, 80, 86, 91, 96, 0, 96, 64, 130, 132, 3, 18, 21, 97, 29, 201, 87, 96, 0, 128, 253, 91, 97, 29, 211, 96, 64, 97, 44, 43, 86, 91, 144, 80, 96, 0, 97, 29, 225, 132, 132, 97, 28, 39, 86, 91, 130, 82, 80, 96, 32, 97, 29, 242, 132, 132, 131, 1, 97, 29, 6, 86, 91, 96, 32, 131, 1, 82, 80, 146, 145, 80, 80, 86, 91, 128, 53, 97, 4, 15, 129, 97, 45, 113, 86, 91, 96, 0, 96, 32, 130, 132, 3, 18, 21, 97, 30, 27, 87, 96, 0, 128, 253, 91, 96, 0, 97, 19, 14, 132, 132, 97, 28, 39, 86, 91, 96, 0, 128, 96, 64, 131, 133, 3, 18, 21, 97, 30, 58, 87, 96, 0, 128, 253, 91, 96, 0, 97, 30, 70, 133, 133, 97, 28, 39, 86, 91, 146, 80, 80, 96, 32, 97, 30, 87, 133, 130, 134, 1, 97, 28, 39, 86, 91, 145, 80, 80, 146, 80, 146, 144, 80, 86, 91, 96, 0, 128, 96, 0, 128, 96, 0, 128, 96, 0, 128, 96, 160, 137, 139, 3, 18, 21, 97, 30, 125, 87, 96, 0, 128, 253, 91, 96, 0, 97, 30, 137, 139, 139, 97, 28, 39, 86, 91, 152, 80, 80, 96, 32, 97, 30, 154, 139, 130, 140, 1, 97, 28, 39, 86, 91, 151, 80, 80, 96, 64, 137, 1, 53, 96, 1, 96, 1, 96, 64, 27, 3, 129, 17, 21, 97, 30, 182, 87, 96, 0, 128, 253, 91, 97, 30, 194, 139, 130, 140, 1, 97, 28, 50, 86, 91, 150, 80, 150, 80, 80, 96, 96, 137, 1, 53, 96, 1, 96, 1, 96, 64, 27, 3, 129, 17, 21, 97, 30, 224, 87, 96, 0, 128, 253, 91, 97, 30, 236, 139, 130, 140, 1, 97, 28, 50, 86, 91, 148, 80, 148, 80, 80, 96, 128, 137, 1, 53, 96, 1, 96, 1, 96, 64, 27, 3, 129, 17, 21, 97, 31, 10, 87, 96, 0, 128, 253, 91, 97, 31, 22, 139, 130, 140, 1, 97, 29, 39, 86, 91, 146, 80, 146, 80, 80, 146, 149, 152, 80, 146, 149, 152, 144, 147, 150, 80, 86, 91, 96, 0, 128, 96, 0, 128, 96, 0, 128, 96, 160, 135, 137, 3, 18, 21, 97, 31, 65, 87, 96, 0, 128, 253, 91, 96, 0, 97, 31, 77, 137, 137, 97, 28, 39, 86, 91, 150, 80, 80, 96, 32, 97, 31, 94, 137, 130, 138, 1, 97, 28, 39, 86, 91, 149, 80, 80, 96, 64, 97, 31, 111, 137, 130, 138, 1, 97, 29, 6, 86, 91, 148, 80, 80, 96, 96, 97, 31, 128, 137, 130, 138, 1, 97, 29, 6, 86, 91, 147, 80, 80, 96, 128, 135, 1, 53, 96, 1, 96, 1, 96, 64, 27, 3, 129, 17, 21, 97, 31, 156, 87, 96, 0, 128, 253, 91, 97, 31, 168, 137, 130, 138, 1, 97, 29, 39, 86, 91, 146, 80, 146, 80, 80, 146, 149, 80, 146, 149, 80, 146, 149, 86, 91, 96, 0, 128, 96, 64, 131, 133, 3, 18, 21, 97, 31, 202, 87, 96, 0, 128, 253, 91, 96, 0, 97, 31, 214, 133, 133, 97, 28, 39, 86, 91, 146, 80, 80, 96, 32, 97, 30, 87, 133, 130, 134, 1, 97, 28, 251, 86, 91, 96, 0, 128, 96, 64, 131, 133, 3, 18, 21, 97, 31, 250, 87, 96, 0, 128, 253, 91, 96, 0, 97, 32, 6, 133, 133, 97, 28, 39, 86, 91, 146, 80, 80, 96, 32, 97, 30, 87, 133, 130, 134, 1, 97, 29, 6, 86, 91, 96, 0, 128, 96, 0, 96, 96, 132, 134, 3, 18, 21, 97, 32, 44, 87, 96, 0, 128, 253, 91, 96, 0, 97, 32, 56, 134, 134, 97, 28, 39, 86, 91, 147, 80, 80, 96, 32, 97, 32, 73, 134, 130, 135, 1, 97, 29, 6, 86, 91, 146, 80, 80, 96, 64, 97, 32, 90, 134, 130, 135, 1, 97, 29, 6, 86, 91, 145, 80, 80, 146, 80, 146, 80, 146, 86, 91, 96, 0, 128, 96, 0, 128, 96, 64, 133, 135, 3, 18, 21, 97, 32, 122, 87, 96, 0, 128, 253, 91, 132, 53, 96, 1, 96, 1, 96, 64, 27, 3, 129, 17, 21, 97, 32, 144, 87, 96, 0, 128, 253, 91, 97, 32, 156, 135, 130, 136, 1, 97, 28, 50, 86, 91, 148, 80, 148, 80, 80, 96, 32, 133, 1, 53, 96, 1, 96, 1, 96, 64, 27, 3, 129, 17, 21, 97, 32, 186, 87, 96, 0, 128, 253, 91, 97, 32, 198, 135, 130, 136, 1, 97, 28, 50, 86, 91, 149, 152, 148, 151, 80, 149, 80, 80, 80, 80, 86, 91, 96, 0, 96, 32, 130, 132, 3, 18, 21, 97, 32, 228, 87, 96, 0, 128, 253, 91, 96, 0, 97, 19, 14, 132, 132, 97, 29, 17, 86, 91, 96, 0, 96, 32, 130, 132, 3, 18, 21, 97, 33, 2, 87, 96, 0, 128, 253, 91, 96, 0, 97, 19, 14, 132, 132, 97, 29, 28, 86, 91, 96, 0, 96, 32, 130, 132, 3, 18, 21, 97, 33, 32, 87, 96, 0, 128, 253, 91, 129, 53, 96, 1, 96, 1, 96, 64, 27, 3, 129, 17, 21, 97, 33, 54, 87, 96, 0, 128, 253, 91, 97, 19, 14, 132, 130, 133, 1, 97, 29, 104, 86, 91, 96, 0, 96, 32, 130, 132, 3, 18, 21, 97, 33, 84, 87, 96, 0, 128, 253, 91, 96, 0, 97, 19, 14, 132, 132, 97, 29, 6, 86, 91, 96, 0, 128, 96, 64, 131, 133, 3, 18, 21, 97, 33, 115, 87, 96, 0, 128, 253, 91, 96, 0, 97, 32, 6, 133, 133, 97, 29, 6, 86, 91, 96, 0, 128, 96, 0, 128, 96, 0, 128, 96, 0, 96, 224, 136, 138, 3, 18, 21, 97, 33, 154, 87, 96, 0, 128, 253, 91, 96, 0, 97, 33, 166, 138, 138, 97, 29, 6, 86, 91, 151, 80, 80, 96, 32, 97, 33, 183, 138, 130, 139, 1, 97, 29, 254, 86, 91, 150, 80, 80, 96, 64, 97, 33, 200, 138, 130, 139, 1, 97, 29, 6, 86, 91, 149, 80, 80, 96, 96, 97, 33, 217, 138, 130, 139, 1, 97, 29, 6, 86, 91, 148, 80, 80, 96, 128, 136, 1, 53, 96, 1, 96, 1, 96, 64, 27, 3, 129, 17, 21, 97, 33, 245, 87, 96, 0, 128, 253, 91, 97, 34, 1, 138, 130, 139, 1, 97, 28, 122, 86, 91, 147, 80, 80, 96, 160, 97, 34, 18, 138, 130, 139, 1, 97, 29, 6, 86, 91, 146, 80, 80, 96, 192, 136, 1, 53, 96, 1, 96, 1, 96, 64, 27, 3, 129, 17, 21, 97, 34, 46, 87, 96, 0, 128, 253, 91, 97, 34, 58, 138, 130, 139, 1, 97, 29, 104, 86, 91, 145, 80, 80, 146, 149, 152, 145, 148, 151, 80, 146, 149, 80, 86, 91, 96, 0, 97, 34, 85, 131, 131, 97, 34, 105, 86, 91, 80, 80, 96, 32, 1, 144, 86, 91, 96, 0, 97, 34, 85, 131, 131, 97, 35, 175, 86, 91, 97, 34, 114, 129, 97, 44, 171, 86, 91, 130, 82, 80, 80, 86, 91, 96, 0, 97, 34, 131, 130, 97, 44, 158, 86, 91, 97, 34, 141, 129, 133, 97, 44, 162, 86, 91, 147, 80, 97, 34, 152, 131, 97, 44, 152, 86, 91, 128, 96, 0, 91, 131, 129, 16, 21, 97, 34, 198, 87, 129, 81, 97, 34, 176, 136, 130, 97, 34, 73, 86, 91, 151, 80, 97, 34, 187, 131, 97, 44, 152, 86, 91, 146, 80, 80, 96, 1, 1, 97, 34, 156, 86, 91, 80, 148, 149, 148, 80, 80, 80, 80, 80, 86, 91, 96, 0, 97, 34, 220, 130, 97, 44, 158, 86, 91, 97, 34, 230, 129, 133, 97, 44, 162, 86, 91, 147, 80, 97, 34, 241, 131, 97, 44, 152, 86, 91, 128, 96, 0, 91, 131, 129, 16, 21, 97, 34, 198, 87, 129, 81, 97, 35, 9, 136, 130, 97, 34, 73, 86, 91, 151, 80, 97, 35, 20, 131, 97, 44, 152, 86, 91, 146, 80, 80, 96, 1, 1, 97, 34, 245, 86, 91, 96, 0, 97, 35, 43, 131, 133, 97, 44, 162, 86, 91, 147, 80, 96, 1, 96, 1, 96, 251, 27, 3, 131, 17, 21, 97, 35, 65, 87, 96, 0, 128, 253, 91, 96, 32, 131, 2, 146, 80, 97, 35, 82, 131, 133, 132, 97, 44, 229, 86, 91, 80, 80, 1, 144, 86, 91, 96, 0, 97, 35, 99, 130, 97, 44, 158, 86, 91, 97, 35, 109, 129, 133, 97, 44, 162, 86, 91, 147, 80, 97, 35, 120, 131, 97, 44, 152, 86, 91, 128, 96, 0, 91, 131, 129, 16, 21, 97, 34, 198, 87, 129, 81, 97, 35, 144, 136, 130, 97, 34, 93, 86, 91, 151, 80, 97, 35, 155, 131, 97, 44, 152, 86, 91, 146, 80, 80, 96, 1, 1, 97, 35, 124, 86, 91, 97, 34, 114, 129, 97, 44, 182, 86, 91, 97, 34, 114, 129, 97, 10, 154, 86, 91, 96, 0, 97, 35, 195, 130, 97, 44, 158, 86, 91, 97, 35, 205, 129, 133, 97, 44, 162, 86, 91, 147, 80, 97, 35, 221, 129, 133, 96, 32, 134, 1, 97, 44, 241, 86, 91, 97, 35, 230, 129, 97, 45, 50, 86, 91, 144, 147, 1, 147, 146, 80, 80, 80, 86, 91, 97, 34, 114, 97, 35, 252, 130, 97, 44, 218, 86, 91, 97, 45, 33, 86, 91, 96, 0, 97, 36, 14, 96, 28, 131, 97, 44, 162, 86, 91, 127, 70, 101, 101, 32, 118, 97, 108, 117, 101, 32, 115, 104, 111, 117, 108, 100, 32, 98, 101, 32, 112, 111, 115, 105, 116, 105, 118, 101, 0, 0, 0, 0, 129, 82, 96, 32, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 36, 71, 96, 31, 131, 97, 44, 162, 86, 91, 127, 82, 111, 108, 101, 115, 58, 32, 97, 99, 99, 111, 117, 110, 116, 32, 97, 108, 114, 101, 97, 100, 121, 32, 104, 97, 115, 32, 114, 111, 108, 101, 0, 129, 82, 96, 32, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 36, 128, 96, 38, 131, 97, 44, 162, 86, 91, 127, 79, 119, 110, 97, 98, 108, 101, 58, 32, 110, 101, 119, 32, 111, 119, 110, 101, 114, 32, 105, 115, 32, 116, 104, 101, 32, 122, 101, 114, 111, 32, 97, 129, 82, 101, 100, 100, 114, 101, 115, 115, 96, 208, 27, 96, 32, 130, 1, 82, 96, 64, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 36, 200, 96, 32, 131, 97, 44, 162, 86, 91, 127, 95, 115, 101, 116, 84, 111, 107, 101, 110, 85, 82, 73, 58, 32, 84, 111, 107, 101, 110, 32, 115, 104, 111, 117, 108, 100, 32, 101, 120, 105, 115, 116, 129, 82, 96, 32, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 37, 1, 96, 37, 131, 97, 44, 162, 86, 91, 127, 100, 101, 115, 116, 105, 110, 97, 116, 105, 111, 110, 32, 97, 100, 100, 114, 101, 115, 115, 32, 109, 117, 115, 116, 32, 98, 101, 32, 110, 111, 110, 45, 129, 82, 100, 61, 50, 185, 55, 151, 96, 217, 27, 96, 32, 130, 1, 82, 96, 64, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 37, 72, 96, 33, 131, 97, 44, 162, 86, 91, 127, 82, 111, 108, 101, 115, 58, 32, 97, 99, 99, 111, 117, 110, 116, 32, 100, 111, 101, 115, 32, 110, 111, 116, 32, 104, 97, 118, 101, 32, 114, 111, 108, 129, 82, 96, 101, 96, 248, 27, 96, 32, 130, 1, 82, 96, 64, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 37, 139, 96, 43, 131, 97, 44, 162, 86, 91, 127, 78, 101, 101, 100, 32, 111, 112, 101, 114, 97, 116, 111, 114, 32, 97, 112, 112, 114, 111, 118, 97, 108, 32, 102, 111, 114, 32, 51, 114, 100, 32, 112, 129, 82, 106, 48, 185, 58, 60, 144, 49, 58, 185, 55, 57, 151, 96, 169, 27, 96, 32, 130, 1, 82, 96, 64, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 37, 216, 96, 47, 131, 97, 44, 162, 86, 91, 127, 78, 101, 101, 100, 32, 111, 112, 101, 114, 97, 116, 111, 114, 32, 97, 112, 112, 114, 111, 118, 97, 108, 32, 102, 111, 114, 32, 51, 114, 100, 32, 112, 129, 82, 110, 48, 185, 58, 60, 144, 58, 57, 48, 183, 57, 179, 50, 185, 57, 151, 96, 137, 27, 96, 32, 130, 1, 82, 96, 64, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 38, 41, 96, 62, 131, 97, 44, 162, 86, 91, 127, 99, 111, 110, 116, 114, 97, 99, 116, 32, 114, 101, 116, 117, 114, 110, 101, 100, 32, 97, 110, 32, 117, 110, 107, 110, 111, 119, 110, 32, 118, 97, 108, 129, 82, 127, 117, 101, 32, 102, 114, 111, 109, 32, 111, 110, 69, 82, 67, 49, 49, 53, 53, 66, 97, 116, 99, 104, 82, 101, 99, 101, 105, 118, 101, 100, 0, 0, 96, 32, 130, 1, 82, 96, 64, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 38, 136, 96, 32, 131, 97, 44, 162, 86, 91, 127, 79, 119, 110, 97, 98, 108, 101, 58, 32, 99, 97, 108, 108, 101, 114, 32, 105, 115, 32, 110, 111, 116, 32, 116, 104, 101, 32, 111, 119, 110, 101, 114, 129, 82, 96, 32, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 38, 193, 96, 34, 131, 97, 44, 162, 86, 91, 127, 82, 111, 108, 101, 115, 58, 32, 97, 99, 99, 111, 117, 110, 116, 32, 105, 115, 32, 116, 104, 101, 32, 122, 101, 114, 111, 32, 97, 100, 100, 114, 101, 129, 82, 97, 115, 115, 96, 240, 27, 96, 32, 130, 1, 82, 96, 64, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 39, 5, 96, 23, 131, 97, 44, 162, 86, 91, 127, 84, 111, 107, 101, 110, 32, 105, 115, 32, 97, 108, 114, 101, 97, 100, 121, 32, 109, 105, 110, 116, 101, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 82, 96, 32, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 39, 62, 96, 25, 131, 97, 44, 162, 86, 91, 127, 83, 117, 112, 112, 108, 121, 32, 115, 104, 111, 117, 108, 100, 32, 98, 101, 32, 112, 111, 115, 105, 116, 105, 118, 101, 0, 0, 0, 0, 0, 0, 0, 129, 82, 96, 32, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 39, 119, 96, 41, 131, 97, 44, 162, 86, 91, 127, 95, 105, 100, 115, 32, 97, 110, 100, 32, 95, 118, 97, 108, 117, 101, 115, 32, 97, 114, 114, 97, 121, 32, 108, 101, 110, 103, 104, 116, 32, 109, 117, 129, 82, 104, 57, 186, 16, 54, 176, 186, 49, 180, 23, 96, 185, 27, 96, 32, 130, 1, 82, 96, 64, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 39, 194, 96, 27, 131, 97, 44, 162, 86, 91, 127, 82, 101, 99, 105, 112, 105, 101, 110, 116, 32, 115, 104, 111, 117, 108, 100, 32, 98, 101, 32, 112, 114, 101, 115, 101, 110, 116, 0, 0, 0, 0, 0, 129, 82, 96, 32, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 39, 251, 96, 57, 131, 97, 44, 162, 86, 91, 127, 99, 111, 110, 116, 114, 97, 99, 116, 32, 114, 101, 116, 117, 114, 110, 101, 100, 32, 97, 110, 32, 117, 110, 107, 110, 111, 119, 110, 32, 118, 97, 108, 129, 82, 127, 117, 101, 32, 102, 114, 111, 109, 32, 111, 110, 69, 82, 67, 49, 49, 53, 53, 82, 101, 99, 101, 105, 118, 101, 100, 0, 0, 0, 0, 0, 0, 0, 96, 32, 130, 1, 82, 96, 64, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 40, 90, 96, 21, 131, 97, 44, 162, 86, 91, 116, 47, 186, 55, 144, 54, 186, 185, 186, 16, 49, 50, 144, 55, 55, 183, 22, 189, 50, 185, 55, 151, 96, 89, 27, 129, 82, 96, 32, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 40, 139, 96, 26, 131, 97, 44, 162, 86, 91, 127, 115, 105, 103, 110, 101, 114, 32, 115, 104, 111, 117, 108, 100, 32, 115, 105, 103, 110, 32, 116, 111, 107, 101, 110, 73, 100, 0, 0, 0, 0, 0, 0, 129, 82, 96, 32, 1, 146, 145, 80, 80, 86, 91, 96, 0, 97, 40, 196, 96, 17, 131, 97, 44, 162, 86, 91, 112, 29, 92, 154, 72, 28, 218, 27, 221, 91, 25, 8, 24, 153, 72, 28, 217, 93, 96, 122, 27, 129, 82, 96, 32, 1, 146, 145, 80, 80, 86, 91, 97, 34, 114, 97, 40, 240, 130, 97, 10, 154, 86, 91, 97, 10, 154, 86, 91, 97, 34, 114, 129, 97, 44, 212, 86, 91, 96, 0, 97, 41, 10, 130, 133, 97, 35, 240, 86, 91, 96, 20, 130, 1, 145, 80, 97, 41, 26, 130, 132, 97, 40, 228, 86, 91, 80, 96, 32, 1, 146, 145, 80, 80, 86, 91, 96, 32, 129, 1, 97, 4, 15, 130, 132, 97, 34, 105, 86, 91, 96, 64, 129, 1, 97, 41, 64, 130, 133, 97, 34, 105, 86, 91, 97, 41, 77, 96, 32, 131, 1, 132, 97, 35, 175, 86, 91, 147, 146, 80, 80, 80, 86, 91, 96, 160, 129, 1, 97, 41, 98, 130, 136, 97, 34, 105, 86, 91, 97, 41, 111, 96, 32, 131, 1, 135, 97, 34, 105, 86, 91, 129, 129, 3, 96, 64, 131, 1, 82, 97, 41, 129, 129, 134, 97, 35, 88, 86, 91, 144, 80, 129, 129, 3, 96, 96, 131, 1, 82, 97, 41, 149, 129, 133, 97, 35, 88, 86, 91, 144, 80, 129, 129, 3, 96, 128, 131, 1, 82, 97, 41, 169, 129, 132, 97, 35, 184, 86, 91, 151, 150, 80, 80, 80, 80, 80, 80, 80, 86, 91, 96, 160, 129, 1, 97, 41, 194, 130, 136, 97, 34, 105, 86, 91, 97, 41, 207, 96, 32, 131, 1, 135, 97, 34, 105, 86, 91, 97, 41, 220, 96, 64, 131, 1, 134, 97, 35, 175, 86, 91, 97, 41, 233, 96, 96, 131, 1, 133, 97, 35, 175, 86, 91, 129, 129, 3, 96, 128, 131, 1, 82, 97, 41, 169, 129, 132, 97, 35, 184, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 41, 77, 129, 132, 97, 34, 209, 86, 91, 96, 64, 128, 130, 82, 129, 1, 97, 42, 30, 129, 134, 136, 97, 35, 31, 86, 91, 144, 80, 129, 129, 3, 96, 32, 131, 1, 82, 97, 42, 51, 129, 132, 134, 97, 35, 31, 86, 91, 150, 149, 80, 80, 80, 80, 80, 80, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 41, 77, 129, 132, 97, 35, 88, 86, 91, 96, 32, 129, 1, 97, 4, 15, 130, 132, 97, 35, 166, 86, 91, 96, 128, 129, 1, 97, 42, 106, 130, 135, 97, 35, 175, 86, 91, 97, 42, 119, 96, 32, 131, 1, 134, 97, 40, 245, 86, 91, 97, 42, 132, 96, 64, 131, 1, 133, 97, 35, 175, 86, 91, 97, 42, 145, 96, 96, 131, 1, 132, 97, 35, 175, 86, 91, 149, 148, 80, 80, 80, 80, 80, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 41, 77, 129, 132, 97, 35, 184, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 36, 1, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 36, 58, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 36, 115, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 36, 187, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 36, 244, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 37, 59, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 37, 126, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 37, 203, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 38, 28, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 38, 123, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 38, 180, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 38, 248, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 39, 49, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 39, 106, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 39, 181, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 39, 238, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 40, 77, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 40, 126, 86, 91, 96, 32, 128, 130, 82, 129, 1, 97, 4, 15, 129, 97, 40, 183, 86, 91, 96, 32, 129, 1, 97, 4, 15, 130, 132, 97, 35, 175, 86, 91, 96, 96, 129, 1, 97, 43, 247, 130, 134, 97, 35, 175, 86, 91, 129, 129, 3, 96, 32, 131, 1, 82, 97, 44, 9, 129, 133, 97, 34, 120, 86, 91, 144, 80, 129, 129, 3, 96, 64, 131, 1, 82, 97, 42, 145, 129, 132, 97, 35, 88, 86, 91, 96, 64, 129, 1, 97, 41, 64, 130, 133, 97, 35, 175, 86, 91, 96, 64, 81, 129, 129, 1, 96, 1, 96, 1, 96, 64, 27, 3, 129, 17, 130, 130, 16, 23, 21, 97, 44, 73, 87, 96, 0, 128, 253, 91, 96, 64, 82, 145, 144, 80, 86, 91, 96, 0, 96, 1, 96, 1, 96, 64, 27, 3, 130, 17, 21, 97, 44, 103, 87, 96, 0, 128, 253, 91, 80, 96, 32, 144, 129, 2, 1, 144, 86, 91, 96, 0, 96, 1, 96, 1, 96, 64, 27, 3, 130, 17, 21, 97, 44, 135, 87, 96, 0, 128, 253, 91, 80, 96, 32, 96, 31, 145, 144, 145, 1, 96, 31, 25, 22, 1, 144, 86, 91, 96, 32, 1, 144, 86, 91, 81, 144, 86, 91, 144, 129, 82, 96, 32, 1, 144, 86, 91, 96, 0, 97, 4, 15, 130, 97, 44, 200, 86, 91, 21, 21, 144, 86, 91, 96, 1, 96, 1, 96, 224, 27, 3, 25, 22, 144, 86, 91, 96, 1, 96, 1, 96, 160, 27, 3, 22, 144, 86, 91, 96, 255, 22, 144, 86, 91, 96, 0, 97, 4, 15, 130, 97, 44, 171, 86, 91, 130, 129, 131, 55, 80, 96, 0, 145, 1, 82, 86, 91, 96, 0, 91, 131, 129, 16, 21, 97, 45, 12, 87, 129, 129, 1, 81, 131, 130, 1, 82, 96, 32, 1, 97, 44, 244, 86, 91, 131, 129, 17, 21, 97, 45, 27, 87, 96, 0, 132, 132, 1, 82, 91, 80, 80, 80, 80, 86, 91, 96, 0, 97, 4, 15, 130, 96, 0, 97, 4, 15, 130, 97, 45, 60, 86, 91, 96, 31, 1, 96, 31, 25, 22, 144, 86, 91, 96, 96, 27, 144, 86, 91, 97, 45, 75, 129, 97, 44, 171, 86, 91, 129, 20, 97, 4, 248, 87, 96, 0, 128, 253, 91, 97, 45, 75, 129, 97, 44, 182, 86, 91, 97, 45, 75, 129, 97, 10, 154, 86, 91, 97, 45, 75, 129, 97, 44, 187, 86, 91, 97, 45, 75, 129, 97, 44, 212, 86, 254, 163, 101, 98, 122, 122, 114, 49, 88, 32, 112, 99, 189, 218, 52, 161, 239, 153, 96, 81, 62, 78, 84, 154, 131, 156, 21, 193, 23, 214, 39, 16, 168, 42, 61, 224, 61, 137, 189, 46, 22, 202, 108, 101, 120, 112, 101, 114, 105, 109, 101, 110, 116, 97, 108, 245, 100, 115, 111, 108, 99, 67, 0, 5, 17, 0, 64}) ) diff --git a/eth/tracers/blocknative/decoder/types.go b/eth/tracers/blocknative/decoder/types.go new file mode 100644 index 000000000000..7ad0d0a3a531 --- /dev/null +++ b/eth/tracers/blocknative/decoder/types.go @@ -0,0 +1,149 @@ +package decoder + +import ( + "encoding/json" + "fmt" + "github.com/ethereum/go-ethereum/common" + "math/big" +) + +type CallFrame struct { + *Contract + *CallData +} + +type Contract struct { + Type ContractType `json:"type,omitempty"` + interfaces []Interface +} + +type CallData struct { + MethodID MethodID `json:"methodID"` + Args []string `json:"args,omitempty"` + Transfers []*Transfer `json:"-"` +} + +type Transfer struct { + Asset *Asset `json:"asset,omitempty"` + From common.Address `json:"from"` + To common.Address `json:"to"` + Value *Amount `json:"value"` + TokenID *big.Int `json:"tokenID,omitempty"` +} + +type Asset struct { + AssetID + *AssetMetadata +} + +type AssetID struct { + Address common.Address `json:"address"` + TokenID *big.Int `json:"tokenID,omitempty"` +} + +type AssetMetadata struct { + Type AssetType `json:"type,omitempty"` + Name string `json:"name,omitempty"` + Symbol string `json:"symbol,omitempty"` + Decimals uint8 `json:"decimals,omitempty"` + URI string `json:"uri,omitempty"` +} + +type ContractType uint8 + +func (ct ContractType) String() string { + return contractTypes[ct] +} + +func (ct ContractType) MarshalJSON() ([]byte, error) { + return json.Marshal(ct.String()) +} + +func (ct *ContractType) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return err + } + *ct = contractTypesByName[s] + return nil +} + +const ( + ContractTypeUnknown ContractType = iota + ContractTypeERC20 + ContractTypeERC721 + ContractTypeERC1155 + ContractTypeOPStack +) + +var ( + contractTypes = map[ContractType]string{ + ContractTypeUnknown: "", + ContractTypeERC20: "erc20", + ContractTypeERC721: "erc721", + ContractTypeERC1155: "erc1155", + ContractTypeOPStack: "op_stack", + } + contractTypesByName = reverseMap(contractTypes) +) + +func reverseMap[K comparable, V comparable](in map[K]V) map[V]K { + out := make(map[V]K, len(in)) + for k, v := range in { + out[v] = k + } + return out +} + +type Amount big.Int + +func NewAmount(i *big.Int) *Amount { + return (*Amount)(i) +} + +func (a *Amount) SetBytes(b []byte) { + *a = *(*Amount)(big.NewInt(0).SetBytes(b)) +} + +func (a *Amount) Add(x *Amount, y *Amount) { + a.ToInt().Add(x.ToInt(), y.ToInt()) +} + +func (a *Amount) AddInt(x *Amount, y *big.Int) { + a.ToInt().Add(x.ToInt(), y) +} + +func (a *Amount) Neg() *Amount { + neg := new(big.Int).Neg(a.ToInt()) + return NewAmount(neg) +} + +func (a *Amount) ToInt() *big.Int { + return (*big.Int)(a) +} + +func (a *Amount) String() string { + return a.ToInt().String() +} + +func (a *Amount) MarshalJSON() ([]byte, error) { + return json.Marshal(a.ToInt().String()) +} + +func (a *Amount) UnmarshalJSON(data []byte) error { + if data == nil || len(data) == 0 { + *a = *NewAmount(big.NewInt(0)) + return nil + } + + var s string + if err := json.Unmarshal(data, &s); err != nil { + return err + } + aInt, ok := new(big.Int).SetString(s, 10) + if !ok { + return fmt.Errorf("failed to convert string to Amount") + } + *a = *(*Amount)(aInt) + return nil +} diff --git a/eth/tracers/blocknative/decoding.go b/eth/tracers/blocknative/decoding.go new file mode 100644 index 000000000000..4500422c44cc --- /dev/null +++ b/eth/tracers/blocknative/decoding.go @@ -0,0 +1,26 @@ +package blocknative + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" + "math" +) + +type decoderEVM struct { + *vm.EVM +} + +func (d decoderEVM) GetCode(addr common.Address) []byte { + return d.StateDB.GetCode(addr) +} + +func (d decoderEVM) CallCode(addr common.Address, method []byte) ([]byte, error) { + code := d.StateDB.GetCode(addr) + contract := vm.NewContract(vm.AccountRef(common.Address{}), vm.AccountRef(addr), common.Big0, math.MaxUint64) + contract.SetCallCode(&addr, d.StateDB.GetCodeHash(addr), code) + ret, err := d.Interpreter().Run(contract, method, false) + if err != nil { + return nil, err + } + return ret, nil +} diff --git a/eth/tracers/blocknative/txnOpCodeTracer.go b/eth/tracers/blocknative/txnOpCodeTracer.go index 9b6075a28363..19ebc35f16ac 100644 --- a/eth/tracers/blocknative/txnOpCodeTracer.go +++ b/eth/tracers/blocknative/txnOpCodeTracer.go @@ -14,23 +14,24 @@ import ( "github.com/ethereum/go-ethereum/log" ) -var metadataReader = decoder.NewAssetDecoder() +var ( + decoderCache = decoder.NewCaches() +) // txnOpCodeTracer is a go implementation of the Tracer interface which // only returns a restricted trace of a transaction consisting of transaction // op codes and relevant gas data. // This is intended for Blocknative usage. type txnOpCodeTracer struct { - env *vm.EVM // EVM context for execution of transaction to occur within - trace Trace // Accumulated execution data the caller is interested in - callStack []CallFrame // Data structure for op codes making up our trace - interrupt uint32 // Atomic flag to signal execution interruption - reason error // Textual reason for the interruption (not always specific for us) - opts TracerOpts - startTime time.Time + opts TracerOpts + env *vm.EVM + decoder *decoder.Decoder - balanceTracker *balanceTracker - metadataDecoder *decoder.AssetDecoder + trace Trace + startTime time.Time + callStack []CallFrame + interrupt uint32 + reason error } // NewTxnOpCodeTracer returns a new txnOpCodeTracer tracer with the given @@ -38,7 +39,6 @@ type txnOpCodeTracer struct { func NewTxnOpCodeTracer(cfg json.RawMessage) (Tracer, error) { var opts TracerOpts - // Decode raw json opts into our struct. if cfg != nil { if err := json.Unmarshal(cfg, &opts); err != nil { return nil, err @@ -49,11 +49,11 @@ func NewTxnOpCodeTracer(cfg json.RawMessage) (Tracer, error) { } func NewTxnOpCodeTracerWithOpts(opts TracerOpts) (Tracer, error) { - // First callframe contains tx context info and is populated on start and end. + opts.Decode = opts.Decode || opts.BalanceChanges + var t = txnOpCodeTracer{ - opts: opts, - callStack: make([]CallFrame, 1), - metadataDecoder: metadataReader, + opts: opts, + callStack: make([]CallFrame, 1), } if !t.opts.DisableBlockContext { @@ -66,12 +66,10 @@ func NewTxnOpCodeTracerWithOpts(opts TracerOpts) (Tracer, error) { // GetTrace returns the resulting Trace object. func (t *txnOpCodeTracer) GetTrace() (*Trace, error) { - // Get the final balance changes - if t.opts.BalanceChanges { - t.trace.BalanceChanges = t.balanceTracker.formatNetBalanceChanges() + if t.opts.Decode { + t.trace.BalanceChanges = t.decoder.GetBalanceChanges() } - // Only want the top level trace, all other indexes hold sub-traces to which we do not particularly need t.trace.CallFrame = t.callStack[0] return &t.trace, nil } @@ -95,14 +93,17 @@ func (t *txnOpCodeTracer) CaptureStart(env *vm.EVM, from common.Address, to comm t.startTime = time.Now() t.env = env - // Blocks only contain `Random` post-merge, but we still have pre-merge tests. - random := "" - if env.Context.Random != nil { - random = bytesToHex(env.Context.Random.Bytes()) + if t.opts.Decode { + t.decoder = decoder.New(decoderCache, decoderEVM{env}) } - // Populate the block context from the vm environment. if !t.opts.DisableBlockContext { + // Blocks only contain `Random` post-merge, but we still have pre-merge tests. + random := "" + if env.Context.Random != nil { + random = bytesToHex(env.Context.Random.Bytes()) + } + t.trace.BlockContext.Number = env.Context.BlockNumber.Uint64() t.trace.BlockContext.BaseFee = env.Context.BaseFee.Uint64() t.trace.BlockContext.Time = env.Context.Time @@ -111,7 +112,7 @@ func (t *txnOpCodeTracer) CaptureStart(env *vm.EVM, from common.Address, to comm t.trace.BlockContext.Random = random } - // This is the initial call + // Create a call-frame for the top level call. t.callStack[0] = CallFrame{ Type: "CALL", From: addrToHex(from), @@ -121,19 +122,14 @@ func (t *txnOpCodeTracer) CaptureStart(env *vm.EVM, from common.Address, to comm Value: bigToHex(value), } if create { - // TODO: Here we can note creation of contracts for potential future tracing t.callStack[0].Type = "CREATE" } - // If we want balance changes then create a tracker and handle the - // top-level call. - if t.opts.BalanceChanges { - assetGetterFn := func(assetID decoder.AssetID) (*decoder.Asset, error) { - return t.metadataDecoder.Decode(t.env, assetID) + // Try adding decode information but don't fail if we can't. + if t.opts.Decode { + if decoded, err := t.decoder.DecodeCallFrame(from, to, value, input); err == nil { + t.callStack[0].Decoded = decoded } - - t.balanceTracker = newBalanceChangeTracker(t.env.StateDB, assetGetterFn) - t.balanceTracker.captureCall(from, to, value, input) } } @@ -153,8 +149,8 @@ func (t *txnOpCodeTracer) CaptureEnd(output []byte, gasUsed uint64, err error) { } // Add gas payments to balance changes - if t.opts.BalanceChanges { - t.balanceTracker.captureGas(t.env.TxContext.Origin, t.env.Context.Coinbase, gasUsed, t.env.TxContext.GasPrice, t.env.Context.BaseFee) + if t.opts.Decode { + t.decoder.CaptureGas(t.env.TxContext.Origin, t.env.Context.Coinbase, gasUsed, t.env.TxContext.GasPrice, t.env.Context.BaseFee) } // Add total time duration for this trace request @@ -184,7 +180,7 @@ func (t *txnOpCodeTracer) CaptureEnter(typ vm.OpCode, from common.Address, to co return } - // Apart from the starting call detected by CaptureStart, here we track every new transaction opcode + // Create CallFrame, decode it, and all it to the end of the callstack. call := CallFrame{ Type: typ.String(), From: addrToHex(from), @@ -193,12 +189,13 @@ func (t *txnOpCodeTracer) CaptureEnter(typ vm.OpCode, from common.Address, to co Gas: uintToHex(gas), Value: bigToHex(value), } - t.callStack = append(t.callStack, call) - - // If we want to create NBC from decoded transactions, do so here - if t.opts.BalanceChanges { - t.balanceTracker.captureCall(from, to, value, input) + if t.opts.Decode { + if decoded, err := t.decoder.DecodeCallFrame(from, to, value, input); err == nil { + call.Decoded = decoded + } } + + t.callStack = append(t.callStack, call) } // CaptureExit is called when EVM exits a scope, even if the scope didn't execute any code. @@ -212,12 +209,10 @@ func (t *txnOpCodeTracer) CaptureExit(output []byte, gasUsed uint64, err error) // We have a call frame, so finalize it. finalizeCallFrame(&t.callStack[size-1], output, gasUsed, err) - // We have a parent call frame, so nest this one into it. + // If we have a parent call frame nest this one into it. if size <= 1 { return } - - // Pop call and append to parent. end := size - 1 call := t.callStack[end] t.callStack = t.callStack[:end] @@ -246,9 +241,9 @@ func (t *txnOpCodeTracer) SetStateRoot(root common.Hash) { func finalizeCallFrame(call *CallFrame, output []byte, gasUsed uint64, err error) { call.GasUsed = uintToHex(gasUsed) - if err == nil { - call.Output = bytesToHex(output) - } else { + + // If there was an error then try decoding it and stop. + if err != nil { call.Error = err.Error() if err.Error() == "execution reverted" && len(output) > 0 { call.Output = bytesToHex(output) @@ -259,5 +254,9 @@ func finalizeCallFrame(call *CallFrame, output []byte, gasUsed uint64, err error if call.Type == "CREATE" || call.Type == "CREATE2" { call.To = "" } + return } + + // The call was successful so decode the output. + call.Output = bytesToHex(output) } diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/delegatecall.json b/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/delegatecall.json index f464d39b3b82..ec87a8c2b9cb 100644 --- a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/delegatecall.json +++ b/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/delegatecall.json @@ -132,7 +132,7 @@ "tracerConfig": { "balanceChanges": true }, - "result":{ + "result": { "type": "CALL", "from": "0x3de712784baf97260455ae25fb74f574ec9c1add", "to": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", @@ -150,7 +150,14 @@ "gas": "0x77e82", "gasUsed": "0x54c", "input": "0x8c172fa2d9a4ffe21d19763887176173d08241e8393c1dfd208f29193dfecdf854b664ac", - "output": "0x446374989d279847d0dbc6708a9c76a419fe9831d42c78bc89473f559a00d91500000000000000000000000061d76c05cd2aa9ed5135e21e52fff188b02089d4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000092f1dbea03ce08225e31e95cc926ddbe0198e6f2000000000000000000000000529c4cb814029b8bb32acb516ea3a4b07fdae350846fd373887ade3ab7703750294876afa61cf56303f5f014a4d80d04f508a1f100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "output": "0x446374989d279847d0dbc6708a9c76a419fe9831d42c78bc89473f559a00d91500000000000000000000000061d76c05cd2aa9ed5135e21e52fff188b02089d4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000092f1dbea03ce08225e31e95cc926ddbe0198e6f2000000000000000000000000529c4cb814029b8bb32acb516ea3a4b07fdae350846fd373887ade3ab7703750294876afa61cf56303f5f014a4d80d04f508a1f100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "decoded": { + "type": "erc20", + "methodID": "0x8c172fa2", + "args": [ + "0xd9a4ffe21d19763887176173d08241e8393c1dfd208f29193dfecdf854b664ac" + ] + } }, { "type": "CALL", @@ -170,7 +177,13 @@ "gas": "0x770ef", "gasUsed": "0xc24", "input": "0x24d4e90a0000000000000000000000000000000000000000000000020000000000000000", - "output": "0x000000000000000000000000000000000000000000000000b17217f7d1cf79ab" + "output": "0x000000000000000000000000000000000000000000000000b17217f7d1cf79ab", + "decoded": { + "methodID": "0x24d4e90a", + "args": [ + "0x0000000000000000000000000000000000000000000000020000000000000000" + ] + } }, { "type": "DELEGATECALL", @@ -180,7 +193,13 @@ "gas": "0x75eb2", "gasUsed": "0x265", "input": "0x872fb2b5000000000000000000000000000000000000000000000000c330b3f7006420b8", - "output": "0x00000000000000000000000000000000000000000000000224bf7df2c80f0878" + "output": "0x00000000000000000000000000000000000000000000000224bf7df2c80f0878", + "decoded": { + "methodID": "0x872fb2b5", + "args": [ + "0x000000000000000000000000000000000000000000000000c330b3f7006420b8" + ] + } }, { "type": "DELEGATECALL", @@ -190,7 +209,13 @@ "gas": "0x75aad", "gasUsed": "0x25b", "input": "0x872fb2b50000000000000000000000000000000000000000000000000000000000000000", - "output": "0x00000000000000000000000000000000000000000000000100000016aee6e8ef" + "output": "0x00000000000000000000000000000000000000000000000100000016aee6e8ef", + "decoded": { + "methodID": "0x872fb2b5", + "args": [ + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + } }, { "type": "DELEGATECALL", @@ -200,7 +225,13 @@ "gas": "0x75737", "gasUsed": "0xc24", "input": "0x24d4e90a00000000000000000000000000000000000000000000000324bf7e0976f5f167", - "output": "0x0000000000000000000000000000000000000000000000012535c5e5f87ee0d2" + "output": "0x0000000000000000000000000000000000000000000000012535c5e5f87ee0d2", + "decoded": { + "methodID": "0x24d4e90a", + "args": [ + "0x00000000000000000000000000000000000000000000000324bf7e0976f5f167" + ] + } }, { "type": "DELEGATECALL", @@ -210,7 +241,13 @@ "gas": "0x748c7", "gasUsed": "0x265", "input": "0x872fb2b5000000000000000000000000000000000000000000000000c330b3f7006420b8", - "output": "0x00000000000000000000000000000000000000000000000224bf7df2c80f0878" + "output": "0x00000000000000000000000000000000000000000000000224bf7df2c80f0878", + "decoded": { + "methodID": "0x872fb2b5", + "args": [ + "0x000000000000000000000000000000000000000000000000c330b3f7006420b8" + ] + } }, { "type": "DELEGATECALL", @@ -220,7 +257,13 @@ "gas": "0x744c2", "gasUsed": "0x265", "input": "0x872fb2b500000000000000000000000000000000000000000000000237d37fe5d297a500", - "output": "0x0000000000000000000000000000000000000000000000093088c407fcbbce38" + "output": "0x0000000000000000000000000000000000000000000000093088c407fcbbce38", + "decoded": { + "methodID": "0x872fb2b5", + "args": [ + "0x00000000000000000000000000000000000000000000000237d37fe5d297a500" + ] + } }, { "type": "DELEGATECALL", @@ -230,9 +273,28 @@ "gas": "0x74142", "gasUsed": "0xc99", "input": "0x24d4e90a00000000000000000000000000000000000000000000000b554841fac4cad6b0", - "output": "0x0000000000000000000000000000000000000000000000026d7fc130d6a74cbe" + "output": "0x0000000000000000000000000000000000000000000000026d7fc130d6a74cbe", + "decoded": { + "methodID": "0x24d4e90a", + "args": [ + "0x00000000000000000000000000000000000000000000000b554841fac4cad6b0" + ] + } } - ] + ], + "decoded": { + "methodID": "0x0439978d", + "args": [ + "0xe9efd3ab89acad6a3edf9828c3b00ed1c4a74e974d05d32d3b2fb15aa16fc377", + "0x0000000000000000000000000000000000000000000000004563918244f40000", + "0x00000000000000000000000000000000000000000000000000000000000000a0", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x000000000000000000000000000000000000000000000000de0b6b3a76400000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x00000000000000000000000000000000000000000000000026566ea1ec2f6a9b", + "0x00000000000000000000000000000000000000000000000072aa5b7e04d56a9b" + ] + } }, { "type": "CALL", @@ -242,7 +304,34 @@ "gas": "0x731be", "gasUsed": "0x241", "input": "0xc51cf179000000000000000000000000000000000000000000000000de0b6b3a76400000", - "output": "0x0000000000000000000000000000000000000000000000000071ea279ec31402" + "output": "0x0000000000000000000000000000000000000000000000000071ea279ec31402", + "decoded": { + "type": "erc20", + "methodID": "0xc51cf179", + "args": [ + "0x000000000000000000000000000000000000000000000000de0b6b3a76400000" + ] + } + }, + { + "type": "CALL", + "from": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", + "to": "0x0000000000000000000000000000000000000004", + "value": "0x0", + "gas": "0xf", + "gasUsed": "0xf", + "input": "0x", + "output": "0x" + }, + { + "type": "CALL", + "from": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", + "to": "0x0000000000000000000000000000000000000004", + "value": "0x0", + "gas": "0xf", + "gasUsed": "0xf", + "input": "0x", + "output": "0x" }, { "type": "CALL", @@ -253,28 +342,15 @@ "gasUsed": "0x468b", "input": "0x23b872dd0000000000000000000000003de712784baf97260455ae25fb74f574ec9c1add0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba500000000000000000000000000000000000000000000000080d29fa5cccfadac", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "calls": [ - { - "type": "CALL", - "from": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0", - "gas": "0xf", - "gasUsed": "0xf", - "input": "0x", - "output": "0x" - }, - { - "type": "CALL", - "from": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0", - "gas": "0xf", - "gasUsed": "0xf", - "input": "0x", - "output": "0x" - } - ] + "decoded": { + "type": "erc20", + "methodID": "0x23b872dd", + "args": [ + "0x3dE712784baf97260455aE25fb74f574EC9c1add", + "0x6CA7f214AB2ddbB9A8E1A1e2C8550e3164E9dbA5", + "9282657316418596268" + ] + } }, { "type": "CALL", @@ -284,7 +360,15 @@ "gas": "0x6e627", "gasUsed": "0x56d6", "input": "0x095ea7b30000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd00000000000000000000000000000000000000000000000080d29fa5cccfadac", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "type": "erc20", + "methodID": "0x095ea7b3", + "args": [ + "0x0000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd", + "0x00000000000000000000000000000000000000000000000080d29fa5cccfadac" + ] + } }, { "type": "CALL", @@ -304,7 +388,16 @@ "gas": "0x629ff", "gasUsed": "0x468b", "input": "0x23b872dd0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba50000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd00000000000000000000000000000000000000000000000080d29fa5cccfadac", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "type": "erc20", + "methodID": "0x23b872dd", + "args": [ + "0x6CA7f214AB2ddbB9A8E1A1e2C8550e3164E9dbA5", + "0x5aaE5c59D642E5fD45b427Df6eD478b49d55FEfD", + "9282657316418596268" + ] + } }, { "type": "CALL", @@ -314,7 +407,15 @@ "gas": "0x5e0df", "gasUsed": "0x31af", "input": "0xa9059cbb000000000000000000000000950ca4a06c78934a148b7a3ff3ea8fc366f77a060000000000000000000000000000000000000000000000000041f50e27d56848", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "type": "erc20", + "methodID": "0xa9059cbb", + "args": [ + "0x950CA4a06c78934a148B7a3Ff3Ea8fC366f77A06", + "18565314632837192" + ] + } }, { "type": "CALL", @@ -324,7 +425,15 @@ "gas": "0x5ac6b", "gasUsed": "0x29ae", "input": "0x475a9fa90000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba50000000000000000000000000000000000000000000000008090aa97a4fa4564", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "type": "erc20", + "methodID": "0x475a9fa9", + "args": [ + "0x0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", + "0x0000000000000000000000000000000000000000000000008090aa97a4fa4564" + ] + } }, { "type": "CALL", @@ -334,9 +443,25 @@ "gas": "0x57fed", "gasUsed": "0x29ae", "input": "0x475a9fa90000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba50000000000000000000000000000000000000000000000008090aa97a4fa4564", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "type": "erc20", + "methodID": "0x475a9fa9", + "args": [ + "0x0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", + "0x0000000000000000000000000000000000000000000000008090aa97a4fa4564" + ] + } } - ] + ], + "decoded": { + "type": "erc20", + "methodID": "0x07d5b826", + "args": [ + "0xd9a4ffe21d19763887176173d08241e8393c1dfd208f29193dfecdf854b664ac", + "0x00000000000000000000000000000000000000000000000080d29fa5cccfadac" + ] + } }, { "type": "CALL", @@ -346,7 +471,35 @@ "gas": "0x56030", "gasUsed": "0x265", "input": "0x1f0c1e0cd9a4ffe21d19763887176173d08241e8393c1dfd208f29193dfecdf854b664ac0000000000000000000000000000000000000000000000000000000000000001", - "output": "0x000000000000000000000000f4cbd7e037b80c2e67b80512d482685f15b1fb28" + "output": "0x000000000000000000000000f4cbd7e037b80c2e67b80512d482685f15b1fb28", + "decoded": { + "type": "erc20", + "methodID": "0x1f0c1e0c", + "args": [ + "0xd9a4ffe21d19763887176173d08241e8393c1dfd208f29193dfecdf854b664ac", + "0x0000000000000000000000000000000000000000000000000000000000000001" + ] + } + }, + { + "type": "CALL", + "from": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", + "to": "0x0000000000000000000000000000000000000004", + "value": "0x0", + "gas": "0xf", + "gasUsed": "0xf", + "input": "0x", + "output": "0x" + }, + { + "type": "CALL", + "from": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", + "to": "0x0000000000000000000000000000000000000004", + "value": "0x0", + "gas": "0xf", + "gasUsed": "0xf", + "input": "0x", + "output": "0x" }, { "type": "CALL", @@ -358,26 +511,6 @@ "input": "0xa9059cbb0000000000000000000000003de712784baf97260455ae25fb74f574ec9c1add000000000000000000000000000000000000000000000000de0b6b3a76400000", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "calls": [ - { - "type": "CALL", - "from": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0", - "gas": "0xf", - "gasUsed": "0xf", - "input": "0x", - "output": "0x" - }, - { - "type": "CALL", - "from": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0", - "gas": "0xf", - "gasUsed": "0xf", - "input": "0x", - "output": "0x" - }, { "type": "DELEGATECALL", "from": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", @@ -386,11 +519,36 @@ "gas": "0x55a8a", "gasUsed": "0x30f7", "input": "0x88d5fecb00000000000000000000000000000000000000000000000000000000000000010000000000000000000000003de712784baf97260455ae25fb74f574ec9c1add000000000000000000000000000000000000000000000000de0b6b3a76400000", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "methodID": "0x88d5fecb", + "args": [ + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000003de712784baf97260455ae25fb74f574ec9c1add", + "0x000000000000000000000000000000000000000000000000de0b6b3a76400000" + ] + } } - ] + ], + "decoded": { + "type": "erc20", + "methodID": "0xa9059cbb", + "args": [ + "0x3dE712784baf97260455aE25fb74f574EC9c1add", + "16000000000000000000" + ] + } } ], + "decoded": { + "methodID": "0xbbd4f854", + "args": [ + "0xe9efd3ab89acad6a3edf9828c3b00ed1c4a74e974d05d32d3b2fb15aa16fc377", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x000000000000000000000000000000000000000000000000de0b6b3a76400000", + "0x00000000000000000000000000000000000000000000000080d29fa5cccfadac" + ] + }, "blockContext": { "number": 2340153, "stateRoot": "0xfd6b6b8e67375609b44379ad18b293b1d6369d8e93e17f8240600a3f990caeae", @@ -407,10 +565,10 @@ "delta": "-3074620000000000", "asset": { "address": "0x0000000000000000000000000000000000000000", + "type": "eth", "name": "Ether", "symbol": "ETH", - "decimals": 18, - "type": "eth" + "decimals": 18 }, "breakdown": [ { @@ -427,8 +585,6 @@ "delta": "-9282657316418596268", "asset": { "address": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "name": "", - "symbol": "", "type": "erc20" }, "breakdown": [ @@ -442,8 +598,6 @@ "delta": "16000000000000000000", "asset": { "address": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", - "name": "", - "symbol": "", "type": "erc20" }, "breakdown": [ @@ -462,8 +616,6 @@ "delta": "9264092001785759076", "asset": { "address": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "name": "", - "symbol": "", "type": "erc20" }, "breakdown": [ @@ -486,10 +638,10 @@ "delta": "3072050896721920", "asset": { "address": "0x0000000000000000000000000000000000000000", + "type": "eth", "name": "Ether", "symbol": "ETH", - "decimals": 18, - "type": "eth" + "decimals": 18 }, "breakdown": [ { @@ -507,8 +659,6 @@ "delta": "0", "asset": { "address": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "name": "", - "symbol": "", "type": "erc20" }, "breakdown": [ @@ -526,8 +676,6 @@ "delta": "-16000000000000000000", "asset": { "address": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", - "name": "", - "symbol": "", "type": "erc20" }, "breakdown": [ @@ -546,8 +694,6 @@ "delta": "18565314632837192", "asset": { "address": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "name": "", - "symbol": "", "type": "erc20" }, "breakdown": [ diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/balance_changes_erc20_transfer.json b/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/erc20_transfer.json similarity index 96% rename from eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/balance_changes_erc20_transfer.json rename to eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/erc20_transfer.json index a003d61bdd35..42aeeac1da89 100644 --- a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/balance_changes_erc20_transfer.json +++ b/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/erc20_transfer.json @@ -11,7 +11,7 @@ "number": "16967879", "stateRoot": "0xb0fe203965f60ee45cf6686f06e2f9b0fe228446b668b3a5c1466b4eabca1dca", "timestamp": "1674198911", - "totalDifficulty": "5.8750003716598352816469e+22", + "totalDifficulty": "5.8750003716598352816469e+22", "alloc": { "0xf527A5Ee2155fAD99A5bBB23c9e52B0a11b99dD4": { "balance": "0x3C3A38E5AB72FC0000", @@ -20,7 +20,7 @@ "0x4675c7e5baafbffbca748158becba61ef3b0a263": { "balance": "0xF6F4BEE9A8FB32" }, - "0xc3761EB917CD790B30dAD99f6Cc5b4Ff93C4F9eA" : { + "0xc3761EB917CD790B30dAD99f6Cc5b4Ff93C4F9eA": { "balance": "0x0", "code": "0x60606040526002805460ff19166012179055341561001c57600080fd5b604051610a1f380380610a1f833981016040528080519190602001805182019190602001805160025460ff16600a0a85026003819055600160a060020a03331660009081526004602052604081209190915592019190508280516100849291602001906100a1565b5060018180516100989291602001906100a1565b5050505061013c565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100e257805160ff191683800117855561010f565b8280016001018555821561010f579182015b8281111561010f5782518255916020019190600101906100f4565b5061011b92915061011f565b5090565b61013991905b8082111561011b5760008155600101610125565b90565b6108d48061014b6000396000f3006060604052600436106100b95763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde0381146100be578063095ea7b31461014857806318160ddd1461017e57806323b872dd146101a3578063313ce567146101cb57806342966c68146101f457806370a082311461020a57806379cc67901461022957806395d89b411461024b578063a9059cbb1461025e578063cae9ca5114610282578063dd62ed3e146102e7575b600080fd5b34156100c957600080fd5b6100d161030c565b60405160208082528190810183818151815260200191508051906020019080838360005b8381101561010d5780820151838201526020016100f5565b50505050905090810190601f16801561013a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015357600080fd5b61016a600160a060020a03600435166024356103aa565b604051901515815260200160405180910390f35b341561018957600080fd5b6101916103da565b60405190815260200160405180910390f35b34156101ae57600080fd5b61016a600160a060020a03600435811690602435166044356103e0565b34156101d657600080fd5b6101de610457565b60405160ff909116815260200160405180910390f35b34156101ff57600080fd5b61016a600435610460565b341561021557600080fd5b610191600160a060020a03600435166104eb565b341561023457600080fd5b61016a600160a060020a03600435166024356104fd565b341561025657600080fd5b6100d16105d9565b341561026957600080fd5b610280600160a060020a0360043516602435610644565b005b341561028d57600080fd5b61016a60048035600160a060020a03169060248035919060649060443590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965061065395505050505050565b34156102f257600080fd5b610191600160a060020a0360043581169060243516610785565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103a25780601f10610377576101008083540402835291602001916103a2565b820191906000526020600020905b81548152906001019060200180831161038557829003601f168201915b505050505081565b600160a060020a033381166000908152600560209081526040808320938616835292905220819055600192915050565b60035481565b600160a060020a0380841660009081526005602090815260408083203390941683529290529081205482111561041557600080fd5b600160a060020a038085166000908152600560209081526040808320339094168352929052208054839003905561044d8484846107a2565b5060019392505050565b60025460ff1681565b600160a060020a0333166000908152600460205260408120548290101561048657600080fd5b600160a060020a03331660008181526004602052604090819020805485900390556003805485900390557fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca59084905190815260200160405180910390a2506001919050565b60046020526000908152604090205481565b600160a060020a0382166000908152600460205260408120548290101561052357600080fd5b600160a060020a038084166000908152600560209081526040808320339094168352929052205482111561055657600080fd5b600160a060020a038084166000818152600460209081526040808320805488900390556005825280832033909516835293905282902080548590039055600380548590039055907fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca59084905190815260200160405180910390a250600192915050565b60018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103a25780601f10610377576101008083540402835291602001916103a2565b61064f3383836107a2565b5050565b60008361066081856103aa565b1561077d5780600160a060020a0316638f4ffcb1338630876040518563ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018085600160a060020a0316600160a060020a0316815260200184815260200183600160a060020a0316600160a060020a0316815260200180602001828103825283818151815260200191508051906020019080838360005b838110156107165780820151838201526020016106fe565b50505050905090810190601f1680156107435780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b151561076457600080fd5b6102c65a03f1151561077557600080fd5b505050600191505b509392505050565b600560209081526000928352604080842090915290825290205481565b6000600160a060020a03831615156107b957600080fd5b600160a060020a038416600090815260046020526040902054829010156107df57600080fd5b600160a060020a0383166000908152600460205260409020548281011161080557600080fd5b50600160a060020a0380831660008181526004602052604080822080549488168084528284208054888103909155938590528154870190915591909301927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a3600160a060020a038084166000908152600460205260408082205492871682529020540181146108a257fe5b505050505600a165627a7a72305820604ef788ac8abdaedc46b8f7086ffceec1d1e365e29400b7d236b16d0498065000290000000000000000000000000000000000000000000000000000002540be4000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000005455243323000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054552433230000000000000000000000000000000000000000000000000000000", "storage": { @@ -44,7 +44,7 @@ } }, "tracerConfig": { - "balanceChanges": true + "decode": true }, "context": { "number": "16967879", @@ -63,6 +63,14 @@ "gasUsed": "0x60b4", "input": "0xa9059cbb000000000000000000000000fba9f22d040e53e5fac36698080cee3dd3792262000000000000000000000000000000000000000000000207b733832c88c007ca", "output": "0x6060604052600436106100b95763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde0381146100be578063095ea7b31461014857806318160ddd1461017e57806323b872dd146101a3578063313ce567146101cb57806342966c68146101f457806370a082311461020a57806379cc67901461022957806395d89b411461024b578063a9059cbb1461025e578063cae9ca5114610282578063dd62ed3e146102e7575b600080fd5b34156100c957600080fd5b6100d161030c565b60405160208082528190810183818151815260200191508051906020019080838360005b8381101561010d5780820151838201526020016100f5565b50505050905090810190601f16801561013a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015357600080fd5b61016a600160a060020a03600435166024356103aa565b604051901515815260200160405180910390f35b341561018957600080fd5b6101916103da565b60405190815260200160405180910390f35b34156101ae57600080fd5b61016a600160a060020a03600435811690602435166044356103e0565b34156101d657600080fd5b6101de610457565b60405160ff909116815260200160405180910390f35b34156101ff57600080fd5b61016a600435610460565b341561021557600080fd5b610191600160a060020a03600435166104eb565b341561023457600080fd5b61016a600160a060020a03600435166024356104fd565b341561025657600080fd5b6100d16105d9565b341561026957600080fd5b610280600160a060020a0360043516602435610644565b005b341561028d57600080fd5b61016a60048035600160a060020a03169060248035919060649060443590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965061065395505050505050565b34156102f257600080fd5b610191600160a060020a0360043581169060243516610785565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103a25780601f10610377576101008083540402835291602001916103a2565b820191906000526020600020905b81548152906001019060200180831161038557829003601f168201915b505050505081565b600160a060020a033381166000908152600560209081526040808320938616835292905220819055600192915050565b60035481565b600160a060020a0380841660009081526005602090815260408083203390941683529290529081205482111561041557600080fd5b600160a060020a038085166000908152600560209081526040808320339094168352929052208054839003905561044d8484846107a2565b5060019392505050565b60025460ff1681565b600160a060020a0333166000908152600460205260408120548290101561048657600080fd5b600160a060020a03331660008181526004602052604090819020805485900390556003805485900390557fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca59084905190815260200160405180910390a2506001919050565b60046020526000908152604090205481565b600160a060020a0382166000908152600460205260408120548290101561052357600080fd5b600160a060020a038084166000908152600560209081526040808320339094168352929052205482111561055657600080fd5b600160a060020a038084166000818152600460209081526040808320805488900390556005825280832033909516835293905282902080548590039055600380548590039055907fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca59084905190815260200160405180910390a250600192915050565b60018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103a25780601f10610377576101008083540402835291602001916103a2565b61064f3383836107a2565b5050565b60008361066081856103aa565b1561077d5780600160a060020a0316638f4ffcb1338630876040518563ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018085600160a060020a0316600160a060020a0316815260200184815260200183600160a060020a0316600160a060020a0316815260200180602001828103825283818151815260200191508051906020019080838360005b838110156107165780820151838201526020016106fe565b50505050905090810190601f1680156107435780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b151561076457600080fd5b6102c65a03f1151561077557600080fd5b505050600191505b509392505050565b600560209081526000928352604080842090915290825290205481565b6000600160a060020a03831615156107b957600080fd5b600160a060020a038416600090815260046020526040902054829010156107df57600080fd5b600160a060020a0383166000908152600460205260409020548281011161080557600080fd5b50600160a060020a0380831660008181526004602052604080822080549488168084528284208054888103909155938590528154870190915591909301927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a3600160a060020a038084166000908152600460205260408082205492871682529020540181146108a257fe5b505050505600a165627a7a72305820604ef788ac8abdaedc46b8f7086ffceec1d1e365e29400b7d236b16d049806500029", + "decoded": { + "type": "erc20", + "methodID": "0xa9059cbb", + "args": [ + "0xFbA9F22D040e53e5FAc36698080cee3dD3792262", + "9587061213415306430410" + ] + }, "blockContext": { "number": 16967879, "stateRoot": "0xb4c1f5fda0d1aaa56f040ad7e7fb9d527603a0223236c11aeafad13162bcaf12", @@ -73,53 +81,56 @@ }, "balanceChanges": [ { - "address": "0xfba9f22d040e53e5fac36698080cee3dd3792262", + "address": "0x4675c7e5baafbffbca748158becba61ef3b0a263", "balanceChanges": [ { - "delta": "9587061213415306430410", + "delta": "605696149742400", "asset": { - "address": "0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea", - "name": "", - "symbol": "", - "decimals": 41, - "type": "erc20" + "address": "0x0000000000000000000000000000000000000000", + "type": "eth", + "name": "Ether", + "symbol": "ETH", + "decimals": 18 }, "breakdown": [ { "counterparty": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", - "amount": "9587061213415306430410" + "amount": "605696149742400" } ] } ] }, { - "address": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", + "address": "0xfba9f22d040e53e5fac36698080cee3dd3792262", "balanceChanges": [ { - "delta": "-9587061213415306430410", + "delta": "9587061213415306430410", "asset": { "address": "0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea", - "name": "", - "symbol": "", - "decimals": 41, - "type": "erc20" + "type": "erc20", + "decimals": 41 }, "breakdown": [ { - "counterparty": "0xfba9f22d040e53e5fac36698080cee3dd3792262", - "amount": "-9587061213415306430410" + "counterparty": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", + "amount": "9587061213415306430410" } ] - }, + } + ] + }, + { + "address": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", + "balanceChanges": [ { "delta": "-606109864092480", "asset": { "address": "0x0000000000000000000000000000000000000000", + "type": "eth", "name": "Ether", "symbol": "ETH", - "decimals": 18, - "type": "eth" + "decimals": 18 }, "breakdown": [ { @@ -131,25 +142,18 @@ "amount": "-605696149742400" } ] - } - ] - }, - { - "address": "0x4675c7e5baafbffbca748158becba61ef3b0a263", - "balanceChanges": [ + }, { - "delta": "605696149742400", + "delta": "-9587061213415306430410", "asset": { - "address": "0x0000000000000000000000000000000000000000", - "name": "Ether", - "symbol": "ETH", - "decimals": 18, - "type": "eth" + "address": "0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea", + "type": "erc20", + "decimals": 41 }, "breakdown": [ { - "counterparty": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", - "amount": "605696149742400" + "counterparty": "0xfba9f22d040e53e5fac36698080cee3dd3792262", + "amount": "-9587061213415306430410" } ] } diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/erc20_transfer_netbalchanges_txns.json b/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/erc20_transfer2.json similarity index 97% rename from eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/erc20_transfer_netbalchanges_txns.json rename to eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/erc20_transfer2.json index c236b5893adb..abf313e832c2 100644 --- a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/erc20_transfer_netbalchanges_txns.json +++ b/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/erc20_transfer2.json @@ -70,6 +70,13 @@ "gasUsed": "0x6ccd", "input": "0xa9059cbb000000000000000000000000dbf03b407c01e7cd3cbea99509d93f8dddc8c6fb0000000000000000000000000000000000000000000000000000000000989680", "output": "0x", + "decoded": { + "methodID": "0xa9059cbb", + "args": [ + "0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB", + "10000000" + ] + }, "blockContext": { "number": 765825, "stateRoot": "0x1f1f6c87fe91d6d6024316d28d51481cf05cd68345dc26425a175786ab77a14f", @@ -80,35 +87,32 @@ }, "balanceChanges": [ { - "address": "0xdbf03b407c01e7cd3cbea99509d93f8dddc8c6fb", + "address": "0xd1220a0cf47c7b9be7a2e6ba89f429762e7b9adb", "balanceChanges": [ { - "delta": "10000000", + "delta": "-1392650000000000", "asset": { - "address": "0xf4eced2f682ce333f96f2d8966c613ded8fc95dd", - "type": "unknown", - "name": "", - "symbol": "" + "address": "0x0000000000000000000000000000000000000000", + "type": "eth", + "name": "Ether", + "symbol": "ETH", + "decimals": 18 }, "breakdown": [ { - "counterparty": "0xd1220a0cf47c7b9be7a2e6ba89f429762e7b9adb", - "amount": "10000000" + "counterparty": "0x0000000000000000000000000000000000000000", + "amount": "-465470423040" + }, + { + "counterparty": "0xe2fe6b13287f28e193333fdfe7fedf2f6df6124a", + "amount": "-1392184529576960" } ] - } - ] - }, - { - "address": "0xd1220a0cf47c7b9be7a2e6ba89f429762e7b9adb", - "balanceChanges": [ + }, { "delta": "-10000000", "asset": { - "address": "0xf4eced2f682ce333f96f2d8966c613ded8fc95dd", - "type": "unknown", - "name": "", - "symbol": "" + "address": "0xf4eced2f682ce333f96f2d8966c613ded8fc95dd" }, "breakdown": [ { @@ -116,24 +120,21 @@ "amount": "-10000000" } ] - }, + } + ] + }, + { + "address": "0xdbf03b407c01e7cd3cbea99509d93f8dddc8c6fb", + "balanceChanges": [ { - "delta": "-1392650000000000", + "delta": "10000000", "asset": { - "address": "0x0000000000000000000000000000000000000000", - "type": "eth", - "name": "Ether", - "symbol": "ETH", - "decimals": 18 + "address": "0xf4eced2f682ce333f96f2d8966c613ded8fc95dd" }, "breakdown": [ { - "counterparty": "0x0000000000000000000000000000000000000000", - "amount": "-465470423040" - }, - { - "counterparty": "0xe2fe6b13287f28e193333fdfe7fedf2f6df6124a", - "amount": "-1392184529576960" + "counterparty": "0xd1220a0cf47c7b9be7a2e6ba89f429762e7b9adb", + "amount": "10000000" } ] } diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/inner_create.json b/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/inner_create.json index 344e98f8c3f1..b3d3a082a11b 100644 --- a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/inner_create.json +++ b/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/inner_create.json @@ -231,7 +231,10 @@ "gas": "0x1f51ad", "gasUsed": "0xe7", "input": "0x0a16697a", - "output": "0x000000000000000000000000000000000000000000000000000000000010365c" + "output": "0x000000000000000000000000000000000000000000000000000000000010365c", + "decoded": { + "methodID": "0x0a16697a" + } }, { "type": "CALL", @@ -241,7 +244,10 @@ "gas": "0x1f4fd8", "gasUsed": "0xe7", "input": "0x0a16697a", - "output": "0x000000000000000000000000000000000000000000000000000000000010365c" + "output": "0x000000000000000000000000000000000000000000000000000000000010365c", + "decoded": { + "methodID": "0x0a16697a" + } }, { "type": "CALL", @@ -251,7 +257,10 @@ "gas": "0x1f4e03", "gasUsed": "0xe7", "input": "0x0a16697a", - "output": "0x000000000000000000000000000000000000000000000000000000000010365c" + "output": "0x000000000000000000000000000000000000000000000000000000000010365c", + "decoded": { + "methodID": "0x0a16697a" + } }, { "type": "CALL", @@ -261,7 +270,10 @@ "gas": "0x1f4c34", "gasUsed": "0x2c4", "input": "0xa06db7dc", - "output": "0x00000000000000000000000000000000000000000000000000000000000000ff" + "output": "0x00000000000000000000000000000000000000000000000000000000000000ff", + "decoded": { + "methodID": "0xa06db7dc" + } }, { "type": "CALL", @@ -271,9 +283,18 @@ "gas": "0x1f488d", "gasUsed": "0xe7", "input": "0x0a16697a", - "output": "0x000000000000000000000000000000000000000000000000000000000010365c" + "output": "0x000000000000000000000000000000000000000000000000000000000010365c", + "decoded": { + "methodID": "0x0a16697a" + } } - ] + ], + "decoded": { + "methodID": "0x5054d98a", + "args": [ + "0x0000000000000000000000000000000000000000000000000000000000000003" + ] + } }, { "type": "CALLCODE", @@ -293,7 +314,10 @@ "gas": "0x1f430e", "gasUsed": "0xe7", "input": "0x0a16697a", - "output": "0x000000000000000000000000000000000000000000000000000000000010365c" + "output": "0x000000000000000000000000000000000000000000000000000000000010365c", + "decoded": { + "methodID": "0x0a16697a" + } }, { "type": "CALL", @@ -303,7 +327,10 @@ "gas": "0x1f413e", "gasUsed": "0x2c4", "input": "0xa06db7dc", - "output": "0x00000000000000000000000000000000000000000000000000000000000000ff" + "output": "0x00000000000000000000000000000000000000000000000000000000000000ff", + "decoded": { + "methodID": "0xa06db7dc" + } }, { "type": "CALL", @@ -313,7 +340,10 @@ "gas": "0x1f3dcd", "gasUsed": "0xe7", "input": "0x0a16697a", - "output": "0x000000000000000000000000000000000000000000000000000000000010365c" + "output": "0x000000000000000000000000000000000000000000000000000000000010365c", + "decoded": { + "methodID": "0x0a16697a" + } }, { "type": "CALL", @@ -323,7 +353,10 @@ "gas": "0x1f3bca", "gasUsed": "0xe7", "input": "0x0a16697a", - "output": "0x000000000000000000000000000000000000000000000000000000000010365c" + "output": "0x000000000000000000000000000000000000000000000000000000000010365c", + "decoded": { + "methodID": "0x0a16697a" + } }, { "type": "CALL", @@ -333,9 +366,20 @@ "gas": "0x1f39f4", "gasUsed": "0x2c4", "input": "0xa06db7dc", - "output": "0x00000000000000000000000000000000000000000000000000000000000000ff" + "output": "0x00000000000000000000000000000000000000000000000000000000000000ff", + "decoded": { + "methodID": "0xa06db7dc" + } } - ] + ], + "decoded": { + "methodID": "0xa1873db6", + "args": [ + "0x0000000000000000000000000000000000000000000000000000000000000003", + "0x000000000000000000000000b834e3edfc1a927bdcecb67a9d0eccbd752a5bb3", + "0x00000000000000000000000000000000000000000000000000000000001fa874" + ] + } }, { "type": "CALLCODE", @@ -365,7 +409,10 @@ "gas": "0x1d5753", "gasUsed": "0xe7", "input": "0x0a16697a", - "output": "0x000000000000000000000000000000000000000000000000000000000010365c" + "output": "0x000000000000000000000000000000000000000000000000000000000010365c", + "decoded": { + "methodID": "0x0a16697a" + } }, { "type": "CALL", @@ -385,7 +432,10 @@ "gas": "0x1d365c", "gasUsed": "0x114", "input": "0x8e46afa9", - "output": "0x00000000000000000000000000000000000000000000000000000000000000ff" + "output": "0x00000000000000000000000000000000000000000000000000000000000000ff", + "decoded": { + "methodID": "0x8e46afa9" + } }, { "type": "CALLCODE", @@ -395,7 +445,10 @@ "gas": "0x1d3458", "gasUsed": "0x141", "input": "0x971c803f", - "output": "0x000000000000000000000000000000000000000000000000000000000000000a" + "output": "0x000000000000000000000000000000000000000000000000000000000000000a", + "decoded": { + "methodID": "0x971c803f" + } }, { "type": "CALL", @@ -455,13 +508,51 @@ "gas": "0xe2039", "gasUsed": "0x3624d", "input": "0xbacd69580000000000000000000000000000000000000000000000000000000000000001000000000000000000000000651913977e8140c323997fce5e03c19e0015eebf0000000000000000000000000000000000000000000000000000000000103847", - "output": "0x" + "output": "0x", + "decoded": { + "methodID": "0xbacd6958", + "args": [ + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x000000000000000000000000651913977e8140c323997fce5e03c19e0015eebf", + "0x0000000000000000000000000000000000000000000000000000000000103847" + ] + } } - ] + ], + "decoded": { + "methodID": "0x50d4e411", + "args": [ + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000007dd677b54fc954824a7bc49bd26cbdfa12c75adf", + "0x0000000000000000000000007dd677b54fc954824a7bc49bd26cbdfa12c75adf", + "0x3defb96200000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000000000000000000000000000000000001a0", + "0x00000000000000000000000000000000000000000000000000000000000000ff", + "0x000000000000000000000000000000000000000000000000000000000000000a", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000103847", + "0x00000000000000000000000000000000000000000000000000000000001e8480", + "0x0000000000000000000000000000000000000000000000000011f8119429ed3a", + "0x00000000000000000000000000000000000000000000000000002e002d006b55", + "0x00000000000000000000000000000000000000000000000029a2241af62c0000", + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + } } - ] + ], + "decoded": { + "methodID": "0x8c0e156d", + "args": [ + "0x3defb96200000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000103847", + "0x00000000000000000000000000000000000000000000000000000000001e8480" + ] + } } - ] + ], + "decoded": { + "methodID": "0x3defb962" + } }, { "type": "CALL", @@ -471,7 +562,10 @@ "gas": "0xbed5c", "gasUsed": "0x2bf", "input": "0x938b5f32", - "output": "0x0000000000000000000000006c8f2a135f6ed072de4503bd7c4999a1a17f824b" + "output": "0x0000000000000000000000006c8f2a135f6ed072de4503bd7c4999a1a17f824b", + "decoded": { + "methodID": "0x938b5f32" + } }, { "type": "CALL", @@ -491,7 +585,14 @@ "gas": "0xbe349", "gasUsed": "0x238", "input": "0xed5bd7ea0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000741467b251fca923d6229c4b439078b55dca233b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "methodID": "0xed5bd7ea", + "args": [ + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x000000000000000000000000741467b251fca923d6229c4b439078b55dca233b" + ] + } }, { "type": "CALL", @@ -501,7 +602,10 @@ "gas": "0xb7e5e", "gasUsed": "0x323", "input": "0xc6502da8", - "output": "0x0000000000000000000000000000000000000000000000000011f79bd42b0c7c" + "output": "0x0000000000000000000000000000000000000000000000000011f79bd42b0c7c", + "decoded": { + "methodID": "0xc6502da8" + } }, { "type": "CALL", @@ -511,7 +615,10 @@ "gas": "0xb7a9b", "gasUsed": "0x356", "input": "0xc6803622", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "methodID": "0xc6803622" + } }, { "type": "CALL", @@ -521,9 +628,15 @@ "gas": "0xb765e", "gasUsed": "0x3de", "input": "0xd379be23", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" + "output": "0x0000000000000000000000000000000000000000000000000000000000000000", + "decoded": { + "methodID": "0xd379be23" + } } - ] + ], + "decoded": { + "methodID": "0xe6470fbe" + } }, { "type": "CALL", @@ -533,7 +646,10 @@ "gas": "0xbd195", "gasUsed": "0x323", "input": "0xc6502da8", - "output": "0x0000000000000000000000000000000000000000000000000011f79bd42b0c7c" + "output": "0x0000000000000000000000000000000000000000000000000011f79bd42b0c7c", + "decoded": { + "methodID": "0xc6502da8" + } }, { "type": "CALL", @@ -543,7 +659,10 @@ "gas": "0xbcd3c", "gasUsed": "0x21b", "input": "0x625cc465", - "output": "0x00000000000000000000000000000000000000000000000000002dfeff8fca5d" + "output": "0x00000000000000000000000000000000000000000000000000002dfeff8fca5d", + "decoded": { + "methodID": "0x625cc465" + } }, { "type": "CALLCODE", @@ -565,7 +684,14 @@ "input": "0x", "output": "0x" } - ] + ], + "decoded": { + "methodID": "0x12c82bcc", + "args": [ + "0x000000000000000000000000b834e3edfc1a927bdcecb67a9d0eccbd752a5bb3", + "0x00000000000000000000000000000000000000000000000001035c689778647c" + ] + } }, { "type": "CALLCODE", @@ -587,9 +713,26 @@ "input": "0x", "output": "0x" } - ] + ], + "decoded": { + "methodID": "0x12c82bcc", + "args": [ + "0x000000000000000000000000d3cda913deb6f67967b99d67acdfa1712c293601", + "0x00000000000000000000000000000000000000000000000000002dfeff8fca5d" + ] + } } - ] + ], + "decoded": { + "methodID": "0xda46be0a", + "args": [ + "0x0000000000000000000000000000000000000000000000000000000000000003", + "0x00000000000000000000000000000000000000000000000000000000001fa874", + "0x000000000000000000000000b834e3edfc1a927bdcecb67a9d0eccbd752a5bb3", + "0x00000000000000000000000000000000000000000000000000000000000186a0", + "0x0000000000000000000000000000000000000000000000000000000000012cc8" + ] + } }, { "type": "CALLCODE", @@ -621,11 +764,28 @@ "input": "0x", "output": "0x" } - ] + ], + "decoded": { + "methodID": "0x12c82bcc", + "args": [ + "0x0000000000000000000000007dd677b54fc954824a7bc49bd26cbdfa12c75adf", + "0x00000000000000000000000000000000000000000000000028c288eb0779ea1f" + ] + } } - ] + ], + "decoded": { + "methodID": "0xc17e6817", + "args": [ + "0x0000000000000000000000007dd677b54fc954824a7bc49bd26cbdfa12c75adf", + "0x00000000000000000000000000000000000000000000000028c288eb0779ea1f" + ] + } } ], + "decoded": { + "methodID": "0x61461954" + }, "blockContext": { "number": 1062503, "stateRoot": "0xf33ed6bf51d6a1a0a8c160c99bc265f8578fa68e56730c810a085e8a63aa49c4", @@ -639,7 +799,7 @@ "address": "0x6c8f2a135f6ed072de4503bd7c4999a1a17f824b", "balanceChanges": [ { - "delta": "0", + "delta": "3000000000000000000", "asset": { "address": "0x0000000000000000000000000000000000000000", "type": "eth", @@ -651,10 +811,6 @@ { "counterparty": "0x7dd677b54fc954824a7bc49bd26cbdfa12c75adf", "amount": "3000000000000000000" - }, - { - "counterparty": "0x651913977e8140c323997fce5e03c19e0015eebf", - "amount": "-3000000000000000000" } ] } @@ -664,7 +820,7 @@ "address": "0x7dd677b54fc954824a7bc49bd26cbdfa12c75adf", "balanceChanges": [ { - "delta": "-62939549976892897", + "delta": "-3000000000000000000", "asset": { "address": "0x0000000000000000000000000000000000000000", "type": "eth", @@ -676,31 +832,6 @@ { "counterparty": "0x6c8f2a135f6ed072de4503bd7c4999a1a17f824b", "amount": "-3000000000000000000" - }, - { - "counterparty": "0x741467b251fca923d6229c4b439078b55dca233b", - "amount": "2937060450023107103" - } - ] - } - ] - }, - { - "address": "0x651913977e8140c323997fce5e03c19e0015eebf", - "balanceChanges": [ - { - "delta": "3000000000000000000", - "asset": { - "address": "0x0000000000000000000000000000000000000000", - "type": "eth", - "name": "Ether", - "symbol": "ETH", - "decimals": 18 - }, - "breakdown": [ - { - "counterparty": "0x6c8f2a135f6ed072de4503bd7c4999a1a17f824b", - "amount": "3000000000000000000" } ] } @@ -710,7 +841,7 @@ "address": "0xb834e3edfc1a927bdcecb67a9d0eccbd752a5bb3", "balanceChanges": [ { - "delta": "7409523255663740", + "delta": "-65594100000000000", "asset": { "address": "0x0000000000000000000000000000000000000000", "type": "eth", @@ -719,10 +850,6 @@ "decimals": 18 }, "breakdown": [ - { - "counterparty": "0x741467b251fca923d6229c4b439078b55dca233b", - "amount": "73003623255663740" - }, { "counterparty": "0x0000000000000000000000000000000000000000", "amount": "-21923752181760" @@ -735,56 +862,6 @@ } ] }, - { - "address": "0x741467b251fca923d6229c4b439078b55dca233b", - "balanceChanges": [ - { - "delta": "-3010114646511327480", - "asset": { - "address": "0x0000000000000000000000000000000000000000", - "type": "eth", - "name": "Ether", - "symbol": "ETH", - "decimals": 18 - }, - "breakdown": [ - { - "counterparty": "0xb834e3edfc1a927bdcecb67a9d0eccbd752a5bb3", - "amount": "-73003623255663740" - }, - { - "counterparty": "0xd3cda913deb6f67967b99d67acdfa1712c293601", - "amount": "-50573232556637" - }, - { - "counterparty": "0x7dd677b54fc954824a7bc49bd26cbdfa12c75adf", - "amount": "-2937060450023107103" - } - ] - } - ] - }, - { - "address": "0xd3cda913deb6f67967b99d67acdfa1712c293601", - "balanceChanges": [ - { - "delta": "50573232556637", - "asset": { - "address": "0x0000000000000000000000000000000000000000", - "type": "eth", - "name": "Ether", - "symbol": "ETH", - "decimals": 18 - }, - "breakdown": [ - { - "counterparty": "0x741467b251fca923d6229c4b439078b55dca233b", - "amount": "50573232556637" - } - ] - } - ] - }, { "address": "0x2a65aca4d5fc5b5c859090a6c34d164135398226", "balanceChanges": [ diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/multi_contracts_netbalchanges_txns.json b/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/multi_contracts_transfers.json similarity index 86% rename from eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/multi_contracts_netbalchanges_txns.json rename to eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/multi_contracts_transfers.json index 4c5e064b43fc..866969690066 100644 --- a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/multi_contracts_netbalchanges_txns.json +++ b/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/multi_contracts_transfers.json @@ -316,7 +316,10 @@ "gas": "0x34affa", "gasUsed": "0x1ef", "input": "0x4b6753bc", - "output": "0x0000000000000000000000000000000000000000000000000000000057870858" + "output": "0x0000000000000000000000000000000000000000000000000000000057870858", + "decoded": { + "methodID": "0x4b6753bc" + } }, { "type": "CALL", @@ -326,7 +329,13 @@ "gas": "0x34abef", "gasUsed": "0x314", "input": "0x70a08231000000000000000000000000c0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89", - "output": "0x00000000000000000000000000000000000000000001819451f999d617dafa93" + "output": "0x00000000000000000000000000000000000000000001819451f999d617dafa93", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x000000000000000000000000c0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89" + ] + } }, { "type": "CALL", @@ -336,7 +345,13 @@ "gas": "0x34a705", "gasUsed": "0x314", "input": "0x70a08231000000000000000000000000c0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89", - "output": "0x00000000000000000000000000000000000000000001819451f999d617dafa93" + "output": "0x00000000000000000000000000000000000000000001819451f999d617dafa93", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x000000000000000000000000c0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89" + ] + } }, { "type": "CALL", @@ -356,9 +371,23 @@ "gas": "0x343e8c", "gasUsed": "0x9a62", "input": "0xa9059cbb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd00000000000000000000000000000000000000000001819451f999d617dafa93", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "methodID": "0xa9059cbb", + "args": [ + "0x4FD27b205895e698fa350F7ea57CeC8a21927FCD", + "1820847120949253496306323" + ] + } } - ] + ], + "decoded": { + "methodID": "0xa9059cbb", + "args": [ + "0x4FD27b205895e698fa350F7ea57CeC8a21927FCD", + "1820847120949253496306323" + ] + } }, { "type": "CALL", @@ -378,7 +407,13 @@ "gas": "0x339a3b", "gasUsed": "0x329", "input": "0x81f03fcb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" + "output": "0x0000000000000000000000000000000000000000000000000000000000000000", + "decoded": { + "methodID": "0x81f03fcb", + "args": [ + "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" + ] + } }, { "type": "CALL", @@ -388,7 +423,10 @@ "gas": "0x3395a4", "gasUsed": "0x15f", "input": "0x0e708203", - "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193" + "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193", + "decoded": { + "methodID": "0x0e708203" + } }, { "type": "CALL", @@ -398,7 +436,10 @@ "gas": "0x339363", "gasUsed": "0x113", "input": "0xd2cc718f", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" + "output": "0x0000000000000000000000000000000000000000000000000000000000000000", + "decoded": { + "methodID": "0xd2cc718f" + } }, { "type": "CALL", @@ -408,7 +449,13 @@ "gas": "0x339129", "gasUsed": "0x329", "input": "0x81f03fcb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" + "output": "0x0000000000000000000000000000000000000000000000000000000000000000", + "decoded": { + "methodID": "0x81f03fcb", + "args": [ + "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" + ] + } }, { "type": "CALL", @@ -418,7 +465,10 @@ "gas": "0x338cfa", "gasUsed": "0x13f", "input": "0x18160ddd", - "output": "0x00000000000000000000000000000000000000000003034f5ca7d45e17df199b" + "output": "0x00000000000000000000000000000000000000000003034f5ca7d45e17df199b", + "decoded": { + "methodID": "0x18160ddd" + } }, { "type": "CALL", @@ -428,9 +478,21 @@ "gas": "0x338a75", "gasUsed": "0x314", "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x00000000000000000000000000000000000000000001819451f999d617dafa93" + "output": "0x00000000000000000000000000000000000000000001819451f999d617dafa93", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" + ] + } } - ] + ], + "decoded": { + "methodID": "0xa8618f71", + "args": [ + "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" + ] + } }, { "type": "CALL", @@ -440,7 +502,13 @@ "gas": "0x33e6f2", "gasUsed": "0x314", "input": "0x70a08231000000000000000000000000f835a0247b0063c04ef22006ebe57c5f11977cc4", - "output": "0x00000000000000000000000000000000000000000001819451f999d617dafa76" + "output": "0x00000000000000000000000000000000000000000001819451f999d617dafa76", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x000000000000000000000000f835a0247b0063c04ef22006ebe57c5f11977cc4" + ] + } }, { "type": "CALL", @@ -450,7 +518,13 @@ "gas": "0x33e208", "gasUsed": "0x314", "input": "0x70a08231000000000000000000000000f835a0247b0063c04ef22006ebe57c5f11977cc4", - "output": "0x00000000000000000000000000000000000000000001819451f999d617dafa76" + "output": "0x00000000000000000000000000000000000000000001819451f999d617dafa76", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x000000000000000000000000f835a0247b0063c04ef22006ebe57c5f11977cc4" + ] + } }, { "type": "CALL", @@ -470,9 +544,23 @@ "gas": "0x337992", "gasUsed": "0x5fca", "input": "0xa9059cbb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd00000000000000000000000000000000000000000001819451f999d617dafa76", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "methodID": "0xa9059cbb", + "args": [ + "0x4FD27b205895e698fa350F7ea57CeC8a21927FCD", + "1820847120949253496306294" + ] + } } - ] + ], + "decoded": { + "methodID": "0xa9059cbb", + "args": [ + "0x4FD27b205895e698fa350F7ea57CeC8a21927FCD", + "1820847120949253496306294" + ] + } }, { "type": "CALL", @@ -492,7 +580,13 @@ "gas": "0x330fd9", "gasUsed": "0x329", "input": "0x81f03fcb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" + "output": "0x0000000000000000000000000000000000000000000000000000000000000000", + "decoded": { + "methodID": "0x81f03fcb", + "args": [ + "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" + ] + } }, { "type": "CALL", @@ -502,7 +596,10 @@ "gas": "0x330b42", "gasUsed": "0x15f", "input": "0x0e708203", - "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193" + "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193", + "decoded": { + "methodID": "0x0e708203" + } }, { "type": "CALL", @@ -512,7 +609,10 @@ "gas": "0x330901", "gasUsed": "0x113", "input": "0xd2cc718f", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" + "output": "0x0000000000000000000000000000000000000000000000000000000000000000", + "decoded": { + "methodID": "0xd2cc718f" + } }, { "type": "CALL", @@ -522,7 +622,13 @@ "gas": "0x3306c7", "gasUsed": "0x329", "input": "0x81f03fcb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" + "output": "0x0000000000000000000000000000000000000000000000000000000000000000", + "decoded": { + "methodID": "0x81f03fcb", + "args": [ + "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" + ] + } }, { "type": "CALL", @@ -532,7 +638,10 @@ "gas": "0x330298", "gasUsed": "0x13f", "input": "0x18160ddd", - "output": "0x00000000000000000000000000000000000000000003034f5ca7d45e17df199b" + "output": "0x00000000000000000000000000000000000000000003034f5ca7d45e17df199b", + "decoded": { + "methodID": "0x18160ddd" + } }, { "type": "CALL", @@ -542,9 +651,21 @@ "gas": "0x330013", "gasUsed": "0x314", "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f509" + "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f509", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" + ] + } } - ] + ], + "decoded": { + "methodID": "0xa8618f71", + "args": [ + "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" + ] + } }, { "type": "CALL", @@ -564,7 +685,10 @@ "gas": "0x32e30d", "gasUsed": "0x15f", "input": "0x0e708203", - "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193" + "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193", + "decoded": { + "methodID": "0x0e708203" + } }, { "type": "CALL", @@ -574,7 +698,10 @@ "gas": "0x32e037", "gasUsed": "0x15f", "input": "0x0e708203", - "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193" + "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193", + "decoded": { + "methodID": "0x0e708203" + } }, { "type": "CALL", @@ -584,7 +711,10 @@ "gas": "0x32dd7b", "gasUsed": "0x113", "input": "0xd2cc718f", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" + "output": "0x0000000000000000000000000000000000000000000000000000000000000000", + "decoded": { + "methodID": "0xd2cc718f" + } }, { "type": "CALL", @@ -594,7 +724,13 @@ "gas": "0x32daf9", "gasUsed": "0x329", "input": "0x81f03fcb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" + "output": "0x0000000000000000000000000000000000000000000000000000000000000000", + "decoded": { + "methodID": "0x81f03fcb", + "args": [ + "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" + ] + } }, { "type": "CALL", @@ -604,7 +740,10 @@ "gas": "0x32d6ab", "gasUsed": "0x13f", "input": "0x18160ddd", - "output": "0x00000000000000000000000000000000000000000003034f5ca7d45e17df199b" + "output": "0x00000000000000000000000000000000000000000003034f5ca7d45e17df199b", + "decoded": { + "methodID": "0x18160ddd" + } }, { "type": "CALL", @@ -614,7 +753,13 @@ "gas": "0x32d400", "gasUsed": "0x314", "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f509" + "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f509", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" + ] + } }, { "type": "CALL", @@ -624,7 +769,13 @@ "gas": "0x32c975", "gasUsed": "0x314", "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f509" + "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f509", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" + ] + } }, { "type": "CALL", @@ -644,7 +795,13 @@ "gas": "0x320fe1", "gasUsed": "0x314", "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f509" + "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f509", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" + ] + } }, { "type": "CALL", @@ -654,9 +811,23 @@ "gas": "0x320b5b", "gasUsed": "0x9a62", "input": "0xa9059cbb0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccd", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "methodID": "0xa9059cbb", + "args": [ + "0x6e715Ab4F598eACF0016b9b35Ef33e4141844CcC", + "1821204263806396353449165" + ] + } } - ] + ], + "decoded": { + "methodID": "0xd0679d34", + "args": [ + "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc", + "0x0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccd" + ] + } }, { "type": "CALL", @@ -676,7 +847,10 @@ "gas": "0x3115cc", "gasUsed": "0x113", "input": "0xd2cc718f", - "output": "0x000000000000000000000000000000000000000000000004563918244f400000" + "output": "0x000000000000000000000000000000000000000000000004563918244f400000", + "decoded": { + "methodID": "0xd2cc718f" + } }, { "type": "CALL", @@ -686,7 +860,13 @@ "gas": "0x311382", "gasUsed": "0x314", "input": "0x70a082310000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc", - "output": "0x0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccd" + "output": "0x0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccd", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc" + ] + } }, { "type": "CALL", @@ -696,7 +876,13 @@ "gas": "0x310f37", "gasUsed": "0x329", "input": "0x81f03fcb0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" + "output": "0x0000000000000000000000000000000000000000000000000000000000000000", + "decoded": { + "methodID": "0x81f03fcb", + "args": [ + "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc" + ] + } }, { "type": "CALL", @@ -716,7 +902,10 @@ "gas": "0x30a397", "gasUsed": "0x113", "input": "0xd2cc718f", - "output": "0x000000000000000000000000000000000000000000000004563918244f400000" + "output": "0x000000000000000000000000000000000000000000000004563918244f400000", + "decoded": { + "methodID": "0xd2cc718f" + } }, { "type": "CALL", @@ -726,7 +915,10 @@ "gas": "0x309fc1", "gasUsed": "0x113", "input": "0xd2cc718f", - "output": "0x000000000000000000000000000000000000000000000004563918244f400000" + "output": "0x000000000000000000000000000000000000000000000004563918244f400000", + "decoded": { + "methodID": "0xd2cc718f" + } }, { "type": "CALL", @@ -756,7 +948,10 @@ "gas": "0x2fbb97", "gasUsed": "0x15f", "input": "0x0e708203", - "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193" + "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193", + "decoded": { + "methodID": "0x0e708203" + } }, { "type": "CALL", @@ -776,7 +971,10 @@ "gas": "0x2f3d25", "gasUsed": "0x113", "input": "0xd2cc718f", - "output": "0x000000000000000000000000000000000000000000000004563918244f400000" + "output": "0x000000000000000000000000000000000000000000000004563918244f400000", + "decoded": { + "methodID": "0xd2cc718f" + } }, { "type": "CALL", @@ -786,7 +984,10 @@ "gas": "0x2f394f", "gasUsed": "0x113", "input": "0xd2cc718f", - "output": "0x000000000000000000000000000000000000000000000004563918244f400000" + "output": "0x000000000000000000000000000000000000000000000004563918244f400000", + "decoded": { + "methodID": "0xd2cc718f" + } }, { "type": "CALL", @@ -816,7 +1017,10 @@ "gas": "0x2e5525", "gasUsed": "0x15f", "input": "0x0e708203", - "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193" + "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193", + "decoded": { + "methodID": "0x0e708203" + } }, { "type": "CALL", @@ -826,7 +1030,13 @@ "gas": "0x2e5168", "gasUsed": "0x314", "input": "0x70a082310000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc", - "output": "0x0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccd" + "output": "0x0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccd", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc" + ] + } }, { "type": "CALL", @@ -836,19 +1046,46 @@ "gas": "0x2e4d69", "gasUsed": "0x5fca", "input": "0xa9059cbb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccc", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "methodID": "0xa9059cbb", + "args": [ + "0x4FD27b205895e698fa350F7ea57CeC8a21927FCD", + "1821204263806396353449164" + ] + } } ] } - ] + ], + "decoded": { + "methodID": "0x0221038a", + "args": [ + "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc", + "0x0000000000000000000000000000000000000000000000022b1c8c12279fffff" + ] + } } - ] + ], + "decoded": { + "methodID": "0xcc9ae3f6" + } } ] } - ] + ], + "decoded": { + "methodID": "0x0221038a", + "args": [ + "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc", + "0x0000000000000000000000000000000000000000000000022b1c8c12279fffff" + ] + } } - ] + ], + "decoded": { + "methodID": "0xcc9ae3f6" + } }, { "type": "CALL", @@ -858,9 +1095,19 @@ "gas": "0x2fc505", "gasUsed": "0xd4fa", "input": "0xa9059cbb0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f0000000000000000000000000000000000000000000000000000000000000001", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "methodID": "0xa9059cbb", + "args": [ + "0x6DBfc63479ffC031f23e94dC91bEFa38Bec2c25f", + "1" + ] + } } - ] + ], + "decoded": { + "methodID": "0xfc340716" + } }, { "type": "CALL", @@ -880,7 +1127,13 @@ "gas": "0x2eea7c", "gasUsed": "0x329", "input": "0x81f03fcb0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f", - "output": "0x000000000000000000000000000000000000000000000004563918244f3ffffe" + "output": "0x000000000000000000000000000000000000000000000004563918244f3ffffe", + "decoded": { + "methodID": "0x81f03fcb", + "args": [ + "0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f" + ] + } }, { "type": "CALL", @@ -890,7 +1143,13 @@ "gas": "0x2ee4cb", "gasUsed": "0x314", "input": "0x70a08231000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526", - "output": "0x000000000000000000000000000000000000000000000026b8b4a0b1e8292492" + "output": "0x000000000000000000000000000000000000000000000026b8b4a0b1e8292492", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526" + ] + } }, { "type": "CALL", @@ -900,7 +1159,13 @@ "gas": "0x2edfff", "gasUsed": "0x314", "input": "0x70a082310000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f" + ] + } }, { "type": "CALL", @@ -920,7 +1185,13 @@ "gas": "0x2e7519", "gasUsed": "0x314", "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f508" + "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f508", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" + ] + } }, { "type": "CALL", @@ -930,9 +1201,23 @@ "gas": "0x2e7093", "gasUsed": "0x5fca", "input": "0xa9059cbb0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f0000000000000000000000000000000000000000000000000000000000000063", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "methodID": "0xa9059cbb", + "args": [ + "0x6DBfc63479ffC031f23e94dC91bEFa38Bec2c25f", + "99" + ] + } } - ] + ], + "decoded": { + "methodID": "0xd0679d34", + "args": [ + "0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f", + "0x0000000000000000000000000000000000000000000000000000000000000063" + ] + } }, { "type": "CALL", @@ -942,7 +1227,13 @@ "gas": "0x2e6f59", "gasUsed": "0x329", "input": "0x81f03fcb000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" + "output": "0x0000000000000000000000000000000000000000000000000000000000000000", + "decoded": { + "methodID": "0x81f03fcb", + "args": [ + "0x000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526" + ] + } }, { "type": "CALL", @@ -962,7 +1253,10 @@ "gas": "0x2e06f9", "gasUsed": "0x15f", "input": "0x0e708203", - "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193" + "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193", + "decoded": { + "methodID": "0x0e708203" + } }, { "type": "CALL", @@ -972,7 +1266,10 @@ "gas": "0x2e04b8", "gasUsed": "0x113", "input": "0xd2cc718f", - "output": "0x000000000000000000000000000000000000000000000004563918244f400000" + "output": "0x000000000000000000000000000000000000000000000004563918244f400000", + "decoded": { + "methodID": "0xd2cc718f" + } }, { "type": "CALL", @@ -982,7 +1279,13 @@ "gas": "0x2e027b", "gasUsed": "0x329", "input": "0x81f03fcb000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" + "output": "0x0000000000000000000000000000000000000000000000000000000000000000", + "decoded": { + "methodID": "0x81f03fcb", + "args": [ + "0x000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526" + ] + } }, { "type": "CALL", @@ -992,7 +1295,10 @@ "gas": "0x2dfe4c", "gasUsed": "0x13f", "input": "0x18160ddd", - "output": "0x00000000000000000000000000000000000000000003034f5ca7d45e17df199b" + "output": "0x00000000000000000000000000000000000000000003034f5ca7d45e17df199b", + "decoded": { + "methodID": "0x18160ddd" + } }, { "type": "CALL", @@ -1002,9 +1308,21 @@ "gas": "0x2dfbc7", "gasUsed": "0x314", "input": "0x70a08231000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526", - "output": "0x000000000000000000000000000000000000000000000026b8b4a0b1e8292492" + "output": "0x000000000000000000000000000000000000000000000026b8b4a0b1e8292492", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526" + ] + } } - ] + ], + "decoded": { + "methodID": "0x65f13792", + "args": [ + "0x000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526" + ] + } }, { "type": "CALL", @@ -1014,7 +1332,13 @@ "gas": "0x2e5281", "gasUsed": "0x329", "input": "0x81f03fcb0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f", - "output": "0x000000000000000000000000000000000000000000000004563918244f3ffffe" + "output": "0x000000000000000000000000000000000000000000000004563918244f3ffffe", + "decoded": { + "methodID": "0x81f03fcb", + "args": [ + "0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f" + ] + } }, { "type": "CALL", @@ -1024,7 +1348,13 @@ "gas": "0x2e4dcc", "gasUsed": "0x314", "input": "0x70a082310000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f", - "output": "0x0000000000000000000000000000000000000000000000000000000000000064" + "output": "0x0000000000000000000000000000000000000000000000000000000000000064", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f" + ] + } }, { "type": "CALL", @@ -1034,7 +1364,13 @@ "gas": "0x2e4857", "gasUsed": "0x314", "input": "0x70a08231000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526", - "output": "0x000000000000000000000000000000000000000000000026b8b4a0b1e8292492" + "output": "0x000000000000000000000000000000000000000000000026b8b4a0b1e8292492", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526" + ] + } }, { "type": "CALL", @@ -1044,9 +1380,19 @@ "gas": "0x2e3bae", "gasUsed": "0x9a62", "input": "0xa9059cbb000000000000000000000000da4a4626d3e16e094de3225a751aab7128e965260000000000000000000000000000000000000000000000000000000000000064", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "methodID": "0xa9059cbb", + "args": [ + "0xDa4a4626d3E16e094De3225A751aAb7128e96526", + "100" + ] + } } - ] + ], + "decoded": { + "methodID": "0xd95f98ce" + } }, { "type": "CALL", @@ -1056,7 +1402,13 @@ "gas": "0x2e00dc", "gasUsed": "0x314", "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" + "output": "0x0000000000000000000000000000000000000000000000000000000000000000", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b" + ] + } }, { "type": "CALL", @@ -1076,7 +1428,13 @@ "gas": "0x2d9648", "gasUsed": "0x314", "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f4a5" + "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f4a5", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" + ] + } }, { "type": "CALL", @@ -1086,9 +1444,23 @@ "gas": "0x2d91c2", "gasUsed": "0x9a62", "input": "0xa9059cbb0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b0000000000000000000000000000000000000000000000000000000000000001", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "methodID": "0xa9059cbb", + "args": [ + "0x7498BB5749c9801f1F7e490baf5F966DBFe4e97B", + "1" + ] + } } - ] + ], + "decoded": { + "methodID": "0xd0679d34", + "args": [ + "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", + "0x0000000000000000000000000000000000000000000000000000000000000001" + ] + } }, { "type": "CALL", @@ -1098,7 +1470,10 @@ "gas": "0x2d57a6", "gasUsed": "0x112", "input": "0x400e3949", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" + "output": "0x0000000000000000000000000000000000000000000000000000000000000000", + "decoded": { + "methodID": "0x400e3949" + } }, { "type": "CALL", @@ -1118,7 +1493,13 @@ "gas": "0x2ceffb", "gasUsed": "0x314", "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b" + ] + } }, { "type": "CALL", @@ -1170,9 +1551,25 @@ "input": "0x", "error": "out of gas" } - ] + ], + "decoded": { + "methodID": "0x612e45a3", + "args": [ + "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000000000000000000000000000000000000c0", + "0x00000000000000000000000000000000000000000000000000000000000000e0", + "0x0000000000000000000000000000000000000000000000000000000000093a80", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + } } - ] + ], + "decoded": { + "methodID": "0xff2f4bd2" + } }, { "type": "CALL", @@ -1182,7 +1579,10 @@ "gas": "0x2a0c87", "gasUsed": "0x112", "input": "0x400e3949", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "methodID": "0x400e3949" + } }, { "type": "CALL", @@ -1202,7 +1602,13 @@ "gas": "0x29a4dc", "gasUsed": "0x314", "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b" + ] + } }, { "type": "CALL", @@ -1254,9 +1660,25 @@ "input": "0x", "error": "out of gas" } - ] + ], + "decoded": { + "methodID": "0x612e45a3", + "args": [ + "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000000000000000000000000000000000000c0", + "0x00000000000000000000000000000000000000000000000000000000000000e0", + "0x0000000000000000000000000000000000000000000000000000000000093a80", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + } } - ] + ], + "decoded": { + "methodID": "0xff2f4bd2" + } }, { "type": "CALL", @@ -1266,7 +1688,10 @@ "gas": "0x26fc00", "gasUsed": "0x112", "input": "0x400e3949", - "output": "0x0000000000000000000000000000000000000000000000000000000000000002" + "output": "0x0000000000000000000000000000000000000000000000000000000000000002", + "decoded": { + "methodID": "0x400e3949" + } }, { "type": "CALL", @@ -1286,7 +1711,13 @@ "gas": "0x269455", "gasUsed": "0x314", "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b" + ] + } }, { "type": "CALL", @@ -1338,9 +1769,25 @@ "input": "0x", "error": "out of gas" } - ] + ], + "decoded": { + "methodID": "0x612e45a3", + "args": [ + "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000000000000000000000000000000000000c0", + "0x00000000000000000000000000000000000000000000000000000000000000e0", + "0x0000000000000000000000000000000000000000000000000000000000093a80", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + } } - ] + ], + "decoded": { + "methodID": "0xff2f4bd2" + } }, { "type": "CALL", @@ -1350,7 +1797,10 @@ "gas": "0x23eb79", "gasUsed": "0x112", "input": "0x400e3949", - "output": "0x0000000000000000000000000000000000000000000000000000000000000003" + "output": "0x0000000000000000000000000000000000000000000000000000000000000003", + "decoded": { + "methodID": "0x400e3949" + } }, { "type": "CALL", @@ -1370,7 +1820,13 @@ "gas": "0x2383ce", "gasUsed": "0x314", "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b" + ] + } }, { "type": "CALL", @@ -1422,9 +1878,25 @@ "input": "0x", "error": "out of gas" } - ] + ], + "decoded": { + "methodID": "0x612e45a3", + "args": [ + "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000000000000000000000000000000000000c0", + "0x00000000000000000000000000000000000000000000000000000000000000e0", + "0x0000000000000000000000000000000000000000000000000000000000093a80", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + } } - ] + ], + "decoded": { + "methodID": "0xff2f4bd2" + } }, { "type": "CALL", @@ -1434,7 +1906,10 @@ "gas": "0x20daf2", "gasUsed": "0x112", "input": "0x400e3949", - "output": "0x0000000000000000000000000000000000000000000000000000000000000004" + "output": "0x0000000000000000000000000000000000000000000000000000000000000004", + "decoded": { + "methodID": "0x400e3949" + } }, { "type": "CALL", @@ -1454,7 +1929,13 @@ "gas": "0x207347", "gasUsed": "0x314", "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b" + ] + } }, { "type": "CALL", @@ -1506,9 +1987,25 @@ "input": "0x", "error": "out of gas" } - ] + ], + "decoded": { + "methodID": "0x612e45a3", + "args": [ + "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000000000000000000000000000000000000c0", + "0x00000000000000000000000000000000000000000000000000000000000000e0", + "0x0000000000000000000000000000000000000000000000000000000000093a80", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + } } - ] + ], + "decoded": { + "methodID": "0xff2f4bd2" + } }, { "type": "CALL", @@ -1518,7 +2015,10 @@ "gas": "0x1dca6b", "gasUsed": "0x112", "input": "0x400e3949", - "output": "0x0000000000000000000000000000000000000000000000000000000000000005" + "output": "0x0000000000000000000000000000000000000000000000000000000000000005", + "decoded": { + "methodID": "0x400e3949" + } }, { "type": "CALL", @@ -1538,7 +2038,13 @@ "gas": "0x1d62c0", "gasUsed": "0x314", "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b" + ] + } }, { "type": "CALL", @@ -1590,9 +2096,25 @@ "input": "0x", "error": "out of gas" } - ] + ], + "decoded": { + "methodID": "0x612e45a3", + "args": [ + "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000000000000000000000000000000000000c0", + "0x00000000000000000000000000000000000000000000000000000000000000e0", + "0x0000000000000000000000000000000000000000000000000000000000093a80", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + } } - ] + ], + "decoded": { + "methodID": "0xff2f4bd2" + } }, { "type": "CALL", @@ -1602,7 +2124,10 @@ "gas": "0x1ab9e4", "gasUsed": "0x112", "input": "0x400e3949", - "output": "0x0000000000000000000000000000000000000000000000000000000000000006" + "output": "0x0000000000000000000000000000000000000000000000000000000000000006", + "decoded": { + "methodID": "0x400e3949" + } }, { "type": "CALL", @@ -1622,7 +2147,13 @@ "gas": "0x1a5239", "gasUsed": "0x314", "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b" + ] + } }, { "type": "CALL", @@ -1674,9 +2205,25 @@ "input": "0x", "error": "out of gas" } - ] + ], + "decoded": { + "methodID": "0x612e45a3", + "args": [ + "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000000000000000000000000000000000000c0", + "0x00000000000000000000000000000000000000000000000000000000000000e0", + "0x0000000000000000000000000000000000000000000000000000000000093a80", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + } } - ] + ], + "decoded": { + "methodID": "0xff2f4bd2" + } }, { "type": "CALL", @@ -1686,7 +2233,10 @@ "gas": "0x17a95d", "gasUsed": "0x112", "input": "0x400e3949", - "output": "0x0000000000000000000000000000000000000000000000000000000000000007" + "output": "0x0000000000000000000000000000000000000000000000000000000000000007", + "decoded": { + "methodID": "0x400e3949" + } }, { "type": "CALL", @@ -1706,7 +2256,13 @@ "gas": "0x1741b2", "gasUsed": "0x314", "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b" + ] + } }, { "type": "CALL", @@ -1758,9 +2314,25 @@ "input": "0x", "error": "out of gas" } - ] + ], + "decoded": { + "methodID": "0x612e45a3", + "args": [ + "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000000000000000000000000000000000000c0", + "0x00000000000000000000000000000000000000000000000000000000000000e0", + "0x0000000000000000000000000000000000000000000000000000000000093a80", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + } } - ] + ], + "decoded": { + "methodID": "0xff2f4bd2" + } }, { "type": "CALL", @@ -1770,7 +2342,10 @@ "gas": "0x1498d6", "gasUsed": "0x112", "input": "0x400e3949", - "output": "0x0000000000000000000000000000000000000000000000000000000000000008" + "output": "0x0000000000000000000000000000000000000000000000000000000000000008", + "decoded": { + "methodID": "0x400e3949" + } }, { "type": "CALL", @@ -1790,7 +2365,13 @@ "gas": "0x14312b", "gasUsed": "0x314", "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b" + ] + } }, { "type": "CALL", @@ -1842,9 +2423,25 @@ "input": "0x", "error": "out of gas" } - ] + ], + "decoded": { + "methodID": "0x612e45a3", + "args": [ + "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000000000000000000000000000000000000c0", + "0x00000000000000000000000000000000000000000000000000000000000000e0", + "0x0000000000000000000000000000000000000000000000000000000000093a80", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + } } - ] + ], + "decoded": { + "methodID": "0xff2f4bd2" + } }, { "type": "CALL", @@ -1854,7 +2451,10 @@ "gas": "0x11884f", "gasUsed": "0x112", "input": "0x400e3949", - "output": "0x0000000000000000000000000000000000000000000000000000000000000009" + "output": "0x0000000000000000000000000000000000000000000000000000000000000009", + "decoded": { + "methodID": "0x400e3949" + } }, { "type": "CALL", @@ -1874,7 +2474,13 @@ "gas": "0x1120a4", "gasUsed": "0x314", "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b" + ] + } }, { "type": "CALL", @@ -1926,9 +2532,25 @@ "input": "0x", "error": "out of gas" } - ] + ], + "decoded": { + "methodID": "0x612e45a3", + "args": [ + "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000000000000000000000000000000000000c0", + "0x00000000000000000000000000000000000000000000000000000000000000e0", + "0x0000000000000000000000000000000000000000000000000000000000093a80", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + } } - ] + ], + "decoded": { + "methodID": "0xff2f4bd2" + } }, { "type": "CALL", @@ -1938,7 +2560,10 @@ "gas": "0xe77c8", "gasUsed": "0x112", "input": "0x400e3949", - "output": "0x000000000000000000000000000000000000000000000000000000000000000a" + "output": "0x000000000000000000000000000000000000000000000000000000000000000a", + "decoded": { + "methodID": "0x400e3949" + } }, { "type": "CALL", @@ -1958,7 +2583,13 @@ "gas": "0xe0f53", "gasUsed": "0x314", "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f4a4" + "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f4a4", + "decoded": { + "methodID": "0x70a08231", + "args": [ + "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" + ] + } }, { "type": "CALL", @@ -1968,7 +2599,14 @@ "gas": "0xe096d", "gasUsed": "0x9a62", "input": "0xa9059cbb0000000000000000000000007ccbc69292c7a6d7b538c91f3b283de97906cf3000000000000000000000000000000000000000000001010d8bfbbbe40fe7518c", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "methodID": "0xa9059cbb", + "args": [ + "0x7ccbc69292C7A6D7B538c91F3B283De97906cF30", + "1213898080632835664204172" + ] + } }, { "type": "CALL", @@ -1978,7 +2616,14 @@ "gas": "0xd6871", "gasUsed": "0x9a62", "input": "0xa9059cbb0000000000000000000000001b9ec8ba24630b75a7a958153ffff56dd6d4b6a200000000000000000000000000000000000000000001010d8bfbbbe40fe7518c", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "methodID": "0xa9059cbb", + "args": [ + "0x1B9ec8bA24630B75a7A958153FfFF56dD6D4B6A2", + "1213898080632835664204172" + ] + } }, { "type": "CALL", @@ -1988,11 +2633,24 @@ "gas": "0xcc775", "gasUsed": "0x9a62", "input": "0xa9059cbb000000000000000000000000c3a2c744ad1f5253c736875b93bacce5b01b060b00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "methodID": "0xa9059cbb", + "args": [ + "0xc3A2C744ad1F5253C736875B93bAcCe5B01B060B", + "1213898080632835664204172" + ] + } } - ] + ], + "decoded": { + "methodID": "0x975057e7" + } } ], + "decoded": { + "methodID": "0xbe9a6555" + }, "blockContext": { "number": 1881284, "stateRoot": "0xea7933c6685792615eab2989925958331d4401cf932b58b70f5cf21897279c01", @@ -2003,68 +2661,25 @@ }, "balanceChanges": [ { - "address": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f", + "address": "0xbe3ae5cb97c253dda67181c6e34e43f5c275e08b", "balanceChanges": [ { - "delta": "0", + "delta": "-65798375000000000", "asset": { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "type": "unknown", - "name": "", - "symbol": "" + "address": "0x0000000000000000000000000000000000000000", + "type": "eth", + "name": "Ether", + "symbol": "ETH", + "decimals": 18 }, "breakdown": [ { - "counterparty": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "amount": "1" - }, - { - "counterparty": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "amount": "99" + "counterparty": "0x0000000000000000000000000000000000000000", + "amount": "-43984055500800" }, { - "counterparty": "0xda4a4626d3e16e094de3225a751aab7128e96526", - "amount": "-100" - } - ] - } - ] - }, - { - "address": "0xda4a4626d3e16e094de3225a751aab7128e96526", - "balanceChanges": [ - { - "delta": "100", - "asset": { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "type": "unknown", - "name": "", - "symbol": "" - }, - "breakdown": [ - { - "counterparty": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f", - "amount": "100" - } - ] - } - ] - }, - { - "address": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "balanceChanges": [ - { - "delta": "1", - "asset": { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "type": "unknown", - "name": "", - "symbol": "" - }, - "breakdown": [ - { - "counterparty": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "amount": "1" + "counterparty": "0xea674fdde714fd979de3edf0f56aa9716b898ec8", + "amount": "-65754390944499200" } ] } @@ -2076,10 +2691,7 @@ { "delta": "1820847120949253496306323", "asset": { - "address": "0xc0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89", - "type": "unknown", - "name": "", - "symbol": "" + "address": "0xc0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89" }, "breakdown": [ { @@ -2091,10 +2703,7 @@ { "delta": "0", "asset": { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "type": "unknown", - "name": "", - "symbol": "" + "address": "0x304a554a310c7e546dfe434669c62820b7d83490" }, "breakdown": [ { @@ -2138,10 +2747,7 @@ { "delta": "1820847120949253496306294", "asset": { - "address": "0xf835a0247b0063c04ef22006ebe57c5f11977cc4", - "type": "unknown", - "name": "", - "symbol": "" + "address": "0xf835a0247b0063c04ef22006ebe57c5f11977cc4" }, "breakdown": [ { @@ -2153,136 +2759,88 @@ ] }, { - "address": "0xc0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89", + "address": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f", "balanceChanges": [ { - "delta": "-1820847120949253496306323", + "delta": "0", "asset": { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "type": "unknown", - "name": "", - "symbol": "" + "address": "0x304a554a310c7e546dfe434669c62820b7d83490" }, "breakdown": [ + { + "counterparty": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", + "amount": "1" + }, { "counterparty": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "amount": "-1820847120949253496306323" + "amount": "99" + }, + { + "counterparty": "0xda4a4626d3e16e094de3225a751aab7128e96526", + "amount": "-100" } ] } ] }, { - "address": "0xf835a0247b0063c04ef22006ebe57c5f11977cc4", + "address": "0xda4a4626d3e16e094de3225a751aab7128e96526", "balanceChanges": [ { - "delta": "-1820847120949253496306294", + "delta": "100", "asset": { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "type": "unknown", - "name": "", - "symbol": "" + "address": "0x304a554a310c7e546dfe434669c62820b7d83490" }, "breakdown": [ { - "counterparty": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "amount": "-1820847120949253496306294" + "counterparty": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f", + "amount": "100" } ] } ] }, { - "address": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", + "address": "0x7ccbc69292c7a6d7b538c91f3b283de97906cf30", "balanceChanges": [ { - "delta": "0", + "delta": "1213898080632835664204172", "asset": { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "type": "unknown", - "name": "", - "symbol": "" + "address": "0x304a554a310c7e546dfe434669c62820b7d83490" }, "breakdown": [ { "counterparty": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "amount": "1821204263806396353449165" - }, - { - "counterparty": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "amount": "-1821204263806396353449164" - }, - { - "counterparty": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f", - "amount": "-1" - } - ] - }, - { - "delta": "-2", - "asset": { - "address": "0x0000000000000000000000000000000000000000", - "type": "eth", - "name": "Ether", - "symbol": "ETH", - "decimals": 18 - }, - "breakdown": [ - { - "counterparty": "0xad3ecf23c0c8983b07163708be6d763b5f056193", - "amount": "-80000000000000000000" - }, - { - "counterparty": "0xad3ecf23c0c8983b07163708be6d763b5f056193", - "amount": "39999999999999999999" - }, - { - "counterparty": "0xad3ecf23c0c8983b07163708be6d763b5f056193", - "amount": "39999999999999999999" + "amount": "1213898080632835664204172" } ] } ] }, { - "address": "0xad3ecf23c0c8983b07163708be6d763b5f056193", + "address": "0xc3a2c744ad1f5253c736875b93bacce5b01b060b", "balanceChanges": [ { - "delta": "2", + "delta": "1213898080632835664204172", "asset": { - "address": "0x0000000000000000000000000000000000000000", - "type": "eth", - "name": "Ether", - "symbol": "ETH", - "decimals": 18 + "address": "0x304a554a310c7e546dfe434669c62820b7d83490" }, "breakdown": [ { - "counterparty": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "amount": "80000000000000000000" - }, - { - "counterparty": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "amount": "-39999999999999999999" - }, - { - "counterparty": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "amount": "-39999999999999999999" + "counterparty": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", + "amount": "1213898080632835664204172" } ] } ] }, { - "address": "0xc3a2c744ad1f5253c736875b93bacce5b01b060b", + "address": "0x1b9ec8ba24630b75a7a958153ffff56dd6d4b6a2", "balanceChanges": [ { "delta": "1213898080632835664204172", "asset": { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "type": "unknown", - "name": "", - "symbol": "" + "address": "0x304a554a310c7e546dfe434669c62820b7d83490" }, "breakdown": [ { @@ -2315,35 +2873,41 @@ ] }, { - "address": "0x7ccbc69292c7a6d7b538c91f3b283de97906cf30", + "address": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", "balanceChanges": [ { - "delta": "1213898080632835664204172", + "delta": "-1820847120949253496306323", "asset": { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "type": "unknown", - "name": "", - "symbol": "" + "address": "0xc0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89" }, "breakdown": [ { "counterparty": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "amount": "1213898080632835664204172" + "amount": "-1820847120949253496306323" + } + ] + }, + { + "delta": "-1820847120949253496306294", + "asset": { + "address": "0xf835a0247b0063c04ef22006ebe57c5f11977cc4" + }, + "breakdown": [ + { + "counterparty": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", + "amount": "-1820847120949253496306294" } ] } ] }, { - "address": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", + "address": "0xc0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89", "balanceChanges": [ { "delta": "-1820847120949253496306323", "asset": { - "address": "0xc0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89", - "type": "unknown", - "name": "", - "symbol": "" + "address": "0x304a554a310c7e546dfe434669c62820b7d83490" }, "breakdown": [ { @@ -2351,14 +2915,16 @@ "amount": "-1820847120949253496306323" } ] - }, + } + ] + }, + { + "address": "0xf835a0247b0063c04ef22006ebe57c5f11977cc4", + "balanceChanges": [ { "delta": "-1820847120949253496306294", "asset": { - "address": "0xf835a0247b0063c04ef22006ebe57c5f11977cc4", - "type": "unknown", - "name": "", - "symbol": "" + "address": "0x304a554a310c7e546dfe434669c62820b7d83490" }, "breakdown": [ { @@ -2370,45 +2936,42 @@ ] }, { - "address": "0x1b9ec8ba24630b75a7a958153ffff56dd6d4b6a2", + "address": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", "balanceChanges": [ { - "delta": "1213898080632835664204172", + "delta": "0", "asset": { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "type": "unknown", - "name": "", - "symbol": "" + "address": "0x304a554a310c7e546dfe434669c62820b7d83490" }, "breakdown": [ { "counterparty": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "amount": "1213898080632835664204172" + "amount": "1821204263806396353449165" + }, + { + "counterparty": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", + "amount": "-1821204263806396353449164" + }, + { + "counterparty": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f", + "amount": "-1" } ] } ] }, { - "address": "0xbe3ae5cb97c253dda67181c6e34e43f5c275e08b", + "address": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", "balanceChanges": [ { - "delta": "-65798375000000000", + "delta": "1", "asset": { - "address": "0x0000000000000000000000000000000000000000", - "type": "eth", - "name": "Ether", - "symbol": "ETH", - "decimals": 18 + "address": "0x304a554a310c7e546dfe434669c62820b7d83490" }, "breakdown": [ { - "counterparty": "0x0000000000000000000000000000000000000000", - "amount": "-43984055500800" - }, - { - "counterparty": "0xea674fdde714fd979de3edf0f56aa9716b898ec8", - "amount": "-65754390944499200" + "counterparty": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", + "amount": "1" } ] } diff --git a/eth/tracers/internal/tracetest/txnOpCodeTracer_test.go b/eth/tracers/internal/tracetest/txnOpCodeTracer_test.go index 0b8849f604cd..2cd3ed6544de 100644 --- a/eth/tracers/internal/tracetest/txnOpCodeTracer_test.go +++ b/eth/tracers/internal/tracetest/txnOpCodeTracer_test.go @@ -17,6 +17,7 @@ import ( "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/eth/tracers/blocknative" + "github.com/ethereum/go-ethereum/eth/tracers/blocknative/decoder" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/tests" ) @@ -32,14 +33,14 @@ type txnOpCodeTracerTest struct { func TestTxnOpCodeTracer(t *testing.T) { log.Root().SetHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(true))) - testTxnOpCodeTracer("txnOpCodeTracer", "txnOpCode_tracer", t) + //testTxnOpCodeTracer("txnOpCodeTracer", "txnOpCode_tracer", t) testTxnOpCodeTracer("txnOpCodeTracer", "txnOpCode_tracer_with_netbalchanges", t) } func testTxnOpCodeTracer(tracerName string, dirPath string, t *testing.T) { files, err := os.ReadDir(filepath.Join("testdata", dirPath)) if err != nil { - t.Fatalf("failed to retrieve tracer test suite: %v", err) + t.Fatalf("failed to retrieve tracer tgest suite: %v", err) } for _, file := range files { if !strings.HasSuffix(file.Name(), ".json") { @@ -47,7 +48,7 @@ func testTxnOpCodeTracer(tracerName string, dirPath string, t *testing.T) { } file := file t.Run(camel(strings.TrimSuffix(file.Name(), ".json")), func(t *testing.T) { - t.Parallel() + //t.Parallel() var ( test = new(txnOpCodeTracerTest) @@ -103,6 +104,7 @@ func testTxnOpCodeTracer(tracerName string, dirPath string, t *testing.T) { if _, err = st.TransitionDb(); err != nil { t.Fatalf("failed to execute transaction: %v", err) } + res, err := tracer.GetResult() if err != nil { t.Fatalf("failed to retrieve trace result: %v", err) @@ -114,27 +116,27 @@ func testTxnOpCodeTracer(tracerName string, dirPath string, t *testing.T) { if !tracesEqual(ret, test.Result) { // Below are prints to show differences if we fail, can always just check against the specific test json files too! - // x, _ := json.MarshalIndent(ret, " ", " ") - // y, _ := json.MarshalIndent(test.Result, "", "") - // fmt.Println("Trace return: ") - // fmt.Println(string(x)) - // fmt.Println("test.Result") - // fmt.Println(string(y)) - //t.Fatal("traces mismatch") - // t.Fatalf("trace mismatch: \nhave %+v\nwant %+v", ret, test.Result) - t.Fatalf("trace mismatch: \nhave %+v\nwant %+v", ret, test.Result) + //fmt.Println("Trace return: ") + //x, _ := json.Marshal(ret) + ////x, _ := json.MarshalIndent(ret, "", " ") + //y, _ := json.Marshal(test.Result) + //fmt.Println(string(x)) + //fmt.Println("test.Result") + //fmt.Println(string(y)) + t.Fatal("traces mismatch") + //t.Fatalf("trace mismatch: \nhave %+v\nwant %+v", ret, test.Result) } }) } } -type NBCByAddress blocknative.NetBalanceChanges +type NBCByAddress decoder.NetBalanceChanges func (a NBCByAddress) Len() int { return len(a) } func (a NBCByAddress) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a NBCByAddress) Less(i, j int) bool { return a[i].Address.String() < a[j].Address.String() } -type BalanceChangesByAssetAddress []blocknative.BalanceChange +type BalanceChangesByAssetAddress []decoder.BalanceChange func (a BalanceChangesByAssetAddress) Len() int { return len(a) } func (a BalanceChangesByAssetAddress) Swap(i, j int) { a[i], a[j] = a[j], a[i] } @@ -147,7 +149,8 @@ func tracesEqual(x, y *blocknative.Trace) bool { x.Time = "" y.Time = "" - // Sort the balance changes + // Sort the balance changes because we don't care about the order of the + // breakdown. if len(x.BalanceChanges) != len(y.BalanceChanges) { return false } From 10ae14eb767d34671271dd0f6116a3412f293992 Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Mon, 18 Sep 2023 05:25:57 -0400 Subject: [PATCH 10/40] cleanup: Do some renaming and add godoc. --- eth/tracers/blocknative/decoder/asset.go | 28 +++++++++++-------- eth/tracers/blocknative/decoder/decoder.go | 12 ++++++-- .../{interfaces_types.go => interfaces.go} | 0 eth/tracers/blocknative/decoding.go | 26 ----------------- eth/tracers/blocknative/txnOpCodeTracer.go | 19 +++++++++++++ 5 files changed, 45 insertions(+), 40 deletions(-) rename eth/tracers/blocknative/decoder/{interfaces_types.go => interfaces.go} (100%) delete mode 100644 eth/tracers/blocknative/decoding.go diff --git a/eth/tracers/blocknative/decoder/asset.go b/eth/tracers/blocknative/decoder/asset.go index 03a0bbf11e0e..c797752b8a0b 100644 --- a/eth/tracers/blocknative/decoder/asset.go +++ b/eth/tracers/blocknative/decoder/asset.go @@ -21,7 +21,13 @@ var ( } ) -func DecodeAsset(evmCall EVMCallFn, contract *Contract, assetID AssetID) (*AssetMetadata, error) { +// evmCallFn executes the given method on the code for the given address. +// The result is returned as raw, ABI-encoded bytes. +type evmCallFn func(addr common.Address, method []byte) ([]byte, error) + +// DecodeAsset decodes the metadata for an asset by calling various methods on +// the underlying contract inside the EVM and decoding the results. +func DecodeAsset(evmCall evmCallFn, contract *Contract, assetID AssetID) (*AssetMetadata, error) { var metadata AssetMetadata switch { case contract.IsERC20(): @@ -35,7 +41,7 @@ func DecodeAsset(evmCall EVMCallFn, contract *Contract, assetID AssetID) (*Asset } // decodeERC20Metadata decodes the metadata for an ERC20 token from the EVM. -func decodeERC20Metadata(evmCall EVMCallFn, addr common.Address) AssetMetadata { +func decodeERC20Metadata(evmCall evmCallFn, addr common.Address) AssetMetadata { var err error metadata := AssetMetadata{Type: AssetTypeERC20} @@ -53,7 +59,7 @@ func decodeERC20Metadata(evmCall EVMCallFn, addr common.Address) AssetMetadata { } // decodeERC721Metadata decodes the metadata for an ERC721 token from the EVM. -func decodeERC721Metadata(evmCall EVMCallFn, addr common.Address, tokenID *big.Int) AssetMetadata { +func decodeERC721Metadata(evmCall evmCallFn, addr common.Address, tokenID *big.Int) AssetMetadata { var err error metadata := AssetMetadata{Type: AssetTypeERC721} @@ -71,7 +77,7 @@ func decodeERC721Metadata(evmCall EVMCallFn, addr common.Address, tokenID *big.I } // decodeERC1155Metadata decodes the metadata for an ERC1155 token from the EVM. -func decodeERC1155Metadata(evmCall EVMCallFn, addr common.Address, tokenID *big.Int) AssetMetadata { +func decodeERC1155Metadata(evmCall evmCallFn, addr common.Address, tokenID *big.Int) AssetMetadata { var err error metadata := AssetMetadata{Type: AssetTypeERC1155} @@ -83,22 +89,22 @@ func decodeERC1155Metadata(evmCall EVMCallFn, addr common.Address, tokenID *big. } // decodeMetadataName decodes the name of an asset from the EVM. -func decodeMetadataName(evmCall EVMCallFn, addr common.Address) (string, error) { +func decodeMetadataName(evmCall evmCallFn, addr common.Address) (string, error) { return callAndDecodeString(evmCall, addr, methodIDName) } // decodeMetadataSymbol decodes the symbol of an asset from the EVM. -func decodeMetadataSymbol(evmCall EVMCallFn, addr common.Address) (string, error) { +func decodeMetadataSymbol(evmCall evmCallFn, addr common.Address) (string, error) { return callAndDecodeString(evmCall, addr, methodIDSymbol) } // decodeMetadataDecimals decodes the decimals of an asset from the EVM. -func decodeMetadataDecimals(evmCall EVMCallFn, addr common.Address) (uint8, error) { +func decodeMetadataDecimals(evmCall evmCallFn, addr common.Address) (uint8, error) { return callAndDecodeUint8(evmCall, addr, methodIDDecimals) } // decodeMetadataTokenURI decodes the tokenURI of an asset from the EVM. -func decodeMetadataTokenURI(evmCall EVMCallFn, addr common.Address, tokenID *big.Int) (string, error) { +func decodeMetadataTokenURI(evmCall evmCallFn, addr common.Address, tokenID *big.Int) (string, error) { tokenIDBytes := tokenID.Bytes() if len(tokenIDBytes) > 32 { return "", fmt.Errorf("tokenID is too large") @@ -109,7 +115,7 @@ func decodeMetadataTokenURI(evmCall EVMCallFn, addr common.Address, tokenID *big } // decodeMetadataURI decodes the URI of an asset from the EVM. -func decodeMetadataURI(evmCall EVMCallFn, addr common.Address, tokenID *big.Int) (string, error) { +func decodeMetadataURI(evmCall evmCallFn, addr common.Address, tokenID *big.Int) (string, error) { tokenIDBytes := tokenID.Bytes() if len(tokenIDBytes) > 32 { return "", fmt.Errorf("tokenID is too large") @@ -120,7 +126,7 @@ func decodeMetadataURI(evmCall EVMCallFn, addr common.Address, tokenID *big.Int) } // callAndDecodeString calls a method and decodes the result as a string. -func callAndDecodeString(evmCall EVMCallFn, addr common.Address, method []byte) (string, error) { +func callAndDecodeString(evmCall evmCallFn, addr common.Address, method []byte) (string, error) { // Load bytes from the EVM. stringBytes, err := evmCall(addr, method) if err != nil { @@ -144,7 +150,7 @@ func callAndDecodeString(evmCall EVMCallFn, addr common.Address, method []byte) } // callAndDecodeUint8 calls a method and decodes the result as a uint8. -func callAndDecodeUint8(evmCall EVMCallFn, addr common.Address, method []byte) (uint8, error) { +func callAndDecodeUint8(evmCall evmCallFn, addr common.Address, method []byte) (uint8, error) { // Load bytes from the EVM. uint8Bytes, err := evmCall(addr, method) if err != nil { diff --git a/eth/tracers/blocknative/decoder/decoder.go b/eth/tracers/blocknative/decoder/decoder.go index 1b547204e49d..2e4b5161f450 100644 --- a/eth/tracers/blocknative/decoder/decoder.go +++ b/eth/tracers/blocknative/decoder/decoder.go @@ -27,6 +27,9 @@ func New(caches *Caches, evm evm) *Decoder { } } +// DecodeCallFrame decodes the given call frame into its method and arguments. +// If the call frame is determined to represent one or more Asset transfers we +// add those too. func (d *Decoder) DecodeCallFrame(sender common.Address, receiver common.Address, value *big.Int, input []byte) (*CallFrame, error) { contract, err := d.DecodeContract(receiver) if err != nil { @@ -95,6 +98,8 @@ func (d *Decoder) DecodeContract(addr common.Address) (*Contract, error) { return contract, nil } +// GetBalanceChanges returns the net balance changes for the currently decoded +// call-frames. func (d *Decoder) GetBalanceChanges() NetBalanceChanges { return d.balances.formatNetBalanceChanges() } @@ -106,6 +111,9 @@ func (d *Decoder) CaptureGas(origin common.Address, coinbase common.Address, gas d.balances.captureGas(origin, coinbase, gasUsed, gasFee, gasBaseFee) } +// decodeAsset finds the metadata for the given assetID. It heuristically uses +// information from the decoded contract when possible. +// Results are cached. func (d *Decoder) decodeAsset(contract *Contract, assetID AssetID) (*AssetMetadata, error) { // Check for native ETH and skip the cache check entire. if assetID.Address == ethAddress { @@ -134,10 +142,8 @@ func (d *Decoder) decodeAsset(contract *Contract, assetID AssetID) (*AssetMetada return asset, nil } +// evm is the functionality we need from the EVM to decode. type evm interface { GetCode(common.Address) []byte CallCode(common.Address, []byte) ([]byte, error) } - -type EVMCallFn func(addr common.Address, method []byte) ([]byte, error) -type GetCodeFn func(addr common.Address) []byte diff --git a/eth/tracers/blocknative/decoder/interfaces_types.go b/eth/tracers/blocknative/decoder/interfaces.go similarity index 100% rename from eth/tracers/blocknative/decoder/interfaces_types.go rename to eth/tracers/blocknative/decoder/interfaces.go diff --git a/eth/tracers/blocknative/decoding.go b/eth/tracers/blocknative/decoding.go deleted file mode 100644 index 4500422c44cc..000000000000 --- a/eth/tracers/blocknative/decoding.go +++ /dev/null @@ -1,26 +0,0 @@ -package blocknative - -import ( - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/vm" - "math" -) - -type decoderEVM struct { - *vm.EVM -} - -func (d decoderEVM) GetCode(addr common.Address) []byte { - return d.StateDB.GetCode(addr) -} - -func (d decoderEVM) CallCode(addr common.Address, method []byte) ([]byte, error) { - code := d.StateDB.GetCode(addr) - contract := vm.NewContract(vm.AccountRef(common.Address{}), vm.AccountRef(addr), common.Big0, math.MaxUint64) - contract.SetCallCode(&addr, d.StateDB.GetCodeHash(addr), code) - ret, err := d.Interpreter().Run(contract, method, false) - if err != nil { - return nil, err - } - return ret, nil -} diff --git a/eth/tracers/blocknative/txnOpCodeTracer.go b/eth/tracers/blocknative/txnOpCodeTracer.go index 19ebc35f16ac..3aab3721ed55 100644 --- a/eth/tracers/blocknative/txnOpCodeTracer.go +++ b/eth/tracers/blocknative/txnOpCodeTracer.go @@ -260,3 +260,22 @@ func finalizeCallFrame(call *CallFrame, output []byte, gasUsed uint64, err error // The call was successful so decode the output. call.Output = bytesToHex(output) } + +type decoderEVM struct { + *vm.EVM +} + +func (d decoderEVM) GetCode(addr common.Address) []byte { + return d.StateDB.GetCode(addr) +} + +func (d decoderEVM) CallCode(addr common.Address, method []byte) ([]byte, error) { + code := d.StateDB.GetCode(addr) + contract := vm.NewContract(vm.AccountRef(common.Address{}), vm.AccountRef(addr), common.Big0, math.MaxUint64) + contract.SetCallCode(&addr, d.StateDB.GetCodeHash(addr), code) + ret, err := d.Interpreter().Run(contract, method, false) + if err != nil { + return nil, err + } + return ret, nil +} From 3d400c86a83a6bf3d351723bee5a081609e5da87 Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Mon, 18 Sep 2023 06:32:29 -0400 Subject: [PATCH 11/40] fix: Add missing import. --- eth/tracers/blocknative/txnOpCodeTracer.go | 1 + 1 file changed, 1 insertion(+) diff --git a/eth/tracers/blocknative/txnOpCodeTracer.go b/eth/tracers/blocknative/txnOpCodeTracer.go index 3aab3721ed55..7c89c050d980 100644 --- a/eth/tracers/blocknative/txnOpCodeTracer.go +++ b/eth/tracers/blocknative/txnOpCodeTracer.go @@ -3,6 +3,7 @@ package blocknative import ( "encoding/json" "fmt" + "math" "math/big" "sync/atomic" "time" From 14d132e22f7b9647e271917a27cc5fe1dad93db1 Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Mon, 18 Sep 2023 07:38:29 -0400 Subject: [PATCH 12/40] Revert "use makefile to build" This reverts commit 9c555054882355e283e8231d16af718d45f42d3b. --- .github/workflows/release.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index aeac28f23cbf..5604e00c6e56 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ jobs: - uses: actions/checkout@v2 - name: Build geth run: | - make && cd ./build/bin + cd cmd/geth && /opt/go/1.19.5/bin/go build tar -czvf geth-$(basename ${GITHUB_REF})-linux-arm64.tar.gz geth echo $(md5sum geth | awk '{print $1}') > geth-$(basename ${GITHUB_REF})-linux-arm64.tar.gz.md5 - name: Upload geth to release page @@ -31,4 +31,10 @@ jobs: goarch: amd64 project_path: ./cmd/geth binary_name: geth - build_command: make && mv ./build/bin/geth ./geth + - uses: wangyoucao577/go-release-action@v1.39 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + goos: linux + goarch: amd64 + project_path: ./cmd/bootnode + binary_name: bootnode From 0506a507ec37352a7a759087cf3dfd8ec7e5ae5e Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Mon, 18 Sep 2023 08:13:22 -0400 Subject: [PATCH 13/40] tests: Add DecodeCallData benchmarks. --- .../blocknative/decoder/calldata_test.go | 72 ++++++++++++------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/eth/tracers/blocknative/decoder/calldata_test.go b/eth/tracers/blocknative/decoder/calldata_test.go index 10cbc3dcc1cb..8f9ae5fae339 100644 --- a/eth/tracers/blocknative/decoder/calldata_test.go +++ b/eth/tracers/blocknative/decoder/calldata_test.go @@ -10,20 +10,39 @@ import ( "github.com/stretchr/testify/require" ) +type decodeCallDataTest struct { + name string + args decodeCallDataTestArgs + want *CallData +} + +type decodeCallDataTestArgs struct { + sender common.Address + input string + contract *Contract +} + func TestDecodeCalldata(t *testing.T) { - type args struct { - sender common.Address - input string - contract *Contract + tests := getTestCases() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + executeTests(t, tt) + }) + } +} + +func BenchmarkDecodeCalldata(B *testing.B) { + tests := getTestCases() + for i := 0; i < B.N; i++ { + executeTests(B, tests[i%len(tests)]) } - tests := []struct { - name string - args args - want *CallData - }{ +} + +func getTestCases() []decodeCallDataTest { + return []decodeCallDataTest{ { "erc20 transferFrom(address,address,uint256)", - args{ + decodeCallDataTestArgs{ common.Address{}, "23b872dd0000000000000000000000005470c5a6fce7447afd2c9be3a0f25e362c093661000000000000000000000000479ee0363a7ac2ef34cba7ee82d2c2e0652d466900000000000000000000000000000000000000000000000000000000000018c5", &Contract{interfaces: []Interface{interfaceTypeERC20}}, @@ -41,7 +60,7 @@ func TestDecodeCalldata(t *testing.T) { }, { "erc721 transferFrom(address,address,uint256)", - args{ + decodeCallDataTestArgs{ common.Address{}, "23b872dd0000000000000000000000005470c5a6fce7447afd2c9be3a0f25e362c093661000000000000000000000000479ee0363a7ac2ef34cba7ee82d2c2e0652d466900000000000000000000000000000000000000000000000000000000000018c5", &Contract{interfaces: []Interface{interfaceTypeERC721}}, @@ -52,14 +71,14 @@ func TestDecodeCalldata(t *testing.T) { Transfers: []*Transfer{{ From: common.HexToAddress("0x5470c5a6Fce7447aFd2C9BE3A0F25e362C093661"), To: common.HexToAddress("0x479ee0363a7Ac2ef34cba7ee82D2C2E0652D4669"), - Value: NewAmount(big.NewInt(1)), + Value: NewAmount(common.Big1), TokenID: big.NewInt(6341), }}, }, }, { "erc20+erc721 transferFrom(address,address,uint256)", - args{ + decodeCallDataTestArgs{ common.Address{}, "23b872dd0000000000000000000000005470c5a6fce7447afd2c9be3a0f25e362c093661000000000000000000000000479ee0363a7ac2ef34cba7ee82d2c2e0652d466900000000000000000000000000000000000000000000000000000000000018c5", &Contract{interfaces: []Interface{interfaceTypeERC20, interfaceTypeERC721}}, @@ -77,7 +96,7 @@ func TestDecodeCalldata(t *testing.T) { }, { "erc1155 safeTransferFrom(address,address,uint256,uint256,bytes)", - args{ + decodeCallDataTestArgs{ common.Address{}, "f242432a000000000000000000000000cb89354a1c6e7abd1972a68466db238e48a3b0c800000000000000000000000020964f741d2dffd2ccec658ca086e21af1d7df8e000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000360c6ebe", &Contract{interfaces: []Interface{interfaceTypeERC20, interfaceTypeERC721}}, @@ -88,14 +107,14 @@ func TestDecodeCalldata(t *testing.T) { Transfers: []*Transfer{{ From: common.HexToAddress("0xcb89354a1c6e7ABd1972a68466Db238e48a3B0C8"), To: common.HexToAddress("0x20964f741d2dffd2ccec658ca086e21af1d7df8e"), - Value: NewAmount(big.NewInt(1)), + Value: NewAmount(common.Big1), TokenID: big.NewInt(29), }}, }, }, { "erc1155 safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)", - args{ + decodeCallDataTestArgs{ common.Address{}, "2eb2c2d6000000000000000000000000381e840f4ebe33d0153e9a312105554594a98c42000000000000000000000000a2b876dbb382d40cecee2acc670f55ad95c4767e00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000006ed00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000", &Contract{interfaces: []Interface{interfaceTypeERC20, interfaceTypeERC721}}, @@ -111,19 +130,18 @@ func TestDecodeCalldata(t *testing.T) { }, }, } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - input, err := hex.DecodeString(tt.args.input) - require.NoError(t, err) +} - got, err := decodeCallData(tt.args.sender, tt.args.contract, input) - require.NoError(t, err) +func executeTests(t testing.TB, tt decodeCallDataTest) { + input, err := hex.DecodeString(tt.args.input) + require.NoError(t, err) - gotJSON, _ := json.Marshal(got) - wantJSON, _ := json.Marshal(tt.want) - require.Equal(t, string(gotJSON), string(wantJSON)) - }) - } + got, err := decodeCallData(tt.args.sender, tt.args.contract, input) + require.NoError(t, err) + + gotJSON, _ := json.Marshal(got) + wantJSON, _ := json.Marshal(tt.want) + require.Equal(t, string(gotJSON), string(wantJSON)) } func parseBigInt(s string) *big.Int { From d706b393063aa6d16adf4485c7760697a5d99345 Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Mon, 18 Sep 2023 08:13:45 -0400 Subject: [PATCH 14/40] tweak: Use lru.Cache instead of lru.BasicLRU. --- eth/tracers/blocknative/decoder/cache.go | 12 ++++-------- eth/tracers/blocknative/decoder/decoder.go | 10 ---------- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/eth/tracers/blocknative/decoder/cache.go b/eth/tracers/blocknative/decoder/cache.go index f392b7875cf3..34155f883f47 100644 --- a/eth/tracers/blocknative/decoder/cache.go +++ b/eth/tracers/blocknative/decoder/cache.go @@ -1,8 +1,6 @@ package decoder import ( - "sync" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/lru" ) @@ -13,15 +11,13 @@ const ( ) type Caches struct { - contractsMu sync.RWMutex - contracts lru.BasicLRU[common.Address, *Contract] - assetsMu sync.RWMutex - assets lru.BasicLRU[AssetID, *AssetMetadata] + contracts *lru.Cache[common.Address, *Contract] + assets *lru.Cache[AssetID, *AssetMetadata] } func NewCaches() *Caches { return &Caches{ - contracts: lru.NewBasicLRU[common.Address, *Contract](cacheSizeContracts), - assets: lru.NewBasicLRU[AssetID, *AssetMetadata](cacheSizeAssets), + contracts: lru.NewCache[common.Address, *Contract](cacheSizeContracts), + assets: lru.NewCache[AssetID, *AssetMetadata](cacheSizeAssets), } } diff --git a/eth/tracers/blocknative/decoder/decoder.go b/eth/tracers/blocknative/decoder/decoder.go index 2e4b5161f450..c0f0e26488dd 100644 --- a/eth/tracers/blocknative/decoder/decoder.go +++ b/eth/tracers/blocknative/decoder/decoder.go @@ -66,9 +66,7 @@ func (d *Decoder) DecodeCallFrame(sender common.Address, receiver common.Address // DecodeContract decodes the contract at the given address. func (d *Decoder) DecodeContract(addr common.Address) (*Contract, error) { // Check the cache for an existing entry. - d.caches.contractsMu.RLock() contract, ok := d.caches.contracts.Get(addr) - d.caches.contractsMu.RUnlock() if ok { if contract == nil { return nil, ErrAccountNotAContract @@ -81,9 +79,7 @@ func (d *Decoder) DecodeContract(addr common.Address) (*Contract, error) { // have code. bytecode := ByteCode(d.evm.GetCode(addr)) if len(bytecode) == 0 { - d.caches.contractsMu.Lock() d.caches.contracts.Add(addr, nil) - d.caches.contractsMu.Unlock() return nil, ErrAccountNotAContract } @@ -92,9 +88,7 @@ func (d *Decoder) DecodeContract(addr common.Address) (*Contract, error) { if err != nil { return nil, err } - d.caches.contractsMu.Lock() d.caches.contracts.Add(addr, contract) - d.caches.contractsMu.Unlock() return contract, nil } @@ -121,9 +115,7 @@ func (d *Decoder) decodeAsset(contract *Contract, assetID AssetID) (*AssetMetada } // Check the cache for an existing entry. - d.caches.assetsMu.RLock() asset, ok := d.caches.assets.Get(assetID) - d.caches.assetsMu.RUnlock() if ok { return asset, nil } @@ -135,9 +127,7 @@ func (d *Decoder) decodeAsset(contract *Contract, assetID AssetID) (*AssetMetada return nil, err } - d.caches.assetsMu.Lock() d.caches.assets.Add(assetID, asset) - d.caches.assetsMu.Unlock() return asset, nil } From fa0e506b2d811c5961d8a9f003833c92eeeb3d1c Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Mon, 18 Sep 2023 09:29:52 -0400 Subject: [PATCH 15/40] fix: Check for nil value. --- eth/tracers/blocknative/decoder/balances.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eth/tracers/blocknative/decoder/balances.go b/eth/tracers/blocknative/decoder/balances.go index 09e9907d9447..e3e16e60c03e 100644 --- a/eth/tracers/blocknative/decoder/balances.go +++ b/eth/tracers/blocknative/decoder/balances.go @@ -21,7 +21,7 @@ func newBalances() *balances { // captureCall decodes potential balance change data out of calldata. func (bt *balances) captureCall(sender common.Address, receiver common.Address, value *Amount, decoded *CallFrame) { // Add the native transfer. - if value.ToInt().Sign() > 0 { + if value != nil && value.ToInt().Sign() > 0 { bt.balanceChanges.addAssetTransfer(EthAsset, sender, receiver, value) } From 786e306743d51df8206f88003a85b66693e4fb0d Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Mon, 18 Sep 2023 09:33:33 -0400 Subject: [PATCH 16/40] tests: Re-enable original tracer tests. --- eth/tracers/internal/tracetest/txnOpCodeTracer_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eth/tracers/internal/tracetest/txnOpCodeTracer_test.go b/eth/tracers/internal/tracetest/txnOpCodeTracer_test.go index 2cd3ed6544de..5860a2de1e65 100644 --- a/eth/tracers/internal/tracetest/txnOpCodeTracer_test.go +++ b/eth/tracers/internal/tracetest/txnOpCodeTracer_test.go @@ -33,7 +33,7 @@ type txnOpCodeTracerTest struct { func TestTxnOpCodeTracer(t *testing.T) { log.Root().SetHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(true))) - //testTxnOpCodeTracer("txnOpCodeTracer", "txnOpCode_tracer", t) + testTxnOpCodeTracer("txnOpCodeTracer", "txnOpCode_tracer", t) testTxnOpCodeTracer("txnOpCodeTracer", "txnOpCode_tracer_with_netbalchanges", t) } From 2293a9ce3b76c2a25fdd7c9d76281a1c40d63d6d Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Mon, 18 Sep 2023 11:47:41 -0400 Subject: [PATCH 17/40] feature: Add signature to callframe decode. --- eth/tracers/blocknative/decoder/calldata.go | 1 + .../blocknative/decoder/calldata_test.go | 23 +- eth/tracers/blocknative/decoder/methods.go | 75 ++- eth/tracers/blocknative/decoder/types.go | 3 +- .../delegatecall.json | 47 +- .../erc20_transfer.json | 3 +- .../erc20_transfer2.json | 3 +- .../inner_create.json | 106 ++--- .../multi_contracts_transfers.json | 449 ++++++++++-------- 9 files changed, 401 insertions(+), 309 deletions(-) diff --git a/eth/tracers/blocknative/decoder/calldata.go b/eth/tracers/blocknative/decoder/calldata.go index 016b4048a587..dbe89b6a9293 100644 --- a/eth/tracers/blocknative/decoder/calldata.go +++ b/eth/tracers/blocknative/decoder/calldata.go @@ -124,6 +124,7 @@ func decodeCallData(sender common.Address, contract *Contract, input []byte) (*C return &CallData{ MethodID: method, + Signature: method.Signature(), Args: args, Transfers: transfers, }, nil diff --git a/eth/tracers/blocknative/decoder/calldata_test.go b/eth/tracers/blocknative/decoder/calldata_test.go index 8f9ae5fae339..f7aebe26d8e9 100644 --- a/eth/tracers/blocknative/decoder/calldata_test.go +++ b/eth/tracers/blocknative/decoder/calldata_test.go @@ -48,8 +48,9 @@ func getTestCases() []decodeCallDataTest { &Contract{interfaces: []Interface{interfaceTypeERC20}}, }, &CallData{ - MethodID: methodIDTransferFrom, - Args: []string{"0x5470c5a6Fce7447aFd2C9BE3A0F25e362C093661", "0x479ee0363a7Ac2ef34cba7ee82D2C2E0652D4669", "6341"}, + MethodID: methodIDTransferFrom, + Signature: methodSignatures[methodIDTransferFrom.String()], + Args: []string{"0x5470c5a6Fce7447aFd2C9BE3A0F25e362C093661", "0x479ee0363a7Ac2ef34cba7ee82D2C2E0652D4669", "6341"}, Transfers: []*Transfer{{ From: common.HexToAddress("0x5470c5a6Fce7447aFd2C9BE3A0F25e362C093661"), To: common.HexToAddress("0x479ee0363a7Ac2ef34cba7ee82D2C2E0652D4669"), @@ -66,8 +67,9 @@ func getTestCases() []decodeCallDataTest { &Contract{interfaces: []Interface{interfaceTypeERC721}}, }, &CallData{ - MethodID: methodIDTransferFrom, - Args: []string{"0x5470c5a6Fce7447aFd2C9BE3A0F25e362C093661", "0x479ee0363a7Ac2ef34cba7ee82D2C2E0652D4669", "6341"}, + MethodID: methodIDTransferFrom, + Signature: methodSignatures[methodIDTransferFrom.String()], + Args: []string{"0x5470c5a6Fce7447aFd2C9BE3A0F25e362C093661", "0x479ee0363a7Ac2ef34cba7ee82D2C2E0652D4669", "6341"}, Transfers: []*Transfer{{ From: common.HexToAddress("0x5470c5a6Fce7447aFd2C9BE3A0F25e362C093661"), To: common.HexToAddress("0x479ee0363a7Ac2ef34cba7ee82D2C2E0652D4669"), @@ -84,8 +86,9 @@ func getTestCases() []decodeCallDataTest { &Contract{interfaces: []Interface{interfaceTypeERC20, interfaceTypeERC721}}, }, &CallData{ - MethodID: methodIDTransferFrom, - Args: []string{"0x5470c5a6Fce7447aFd2C9BE3A0F25e362C093661", "0x479ee0363a7Ac2ef34cba7ee82D2C2E0652D4669", "6341"}, + MethodID: methodIDTransferFrom, + Signature: methodSignatures[methodIDTransferFrom.String()], + Args: []string{"0x5470c5a6Fce7447aFd2C9BE3A0F25e362C093661", "0x479ee0363a7Ac2ef34cba7ee82D2C2E0652D4669", "6341"}, Transfers: []*Transfer{{ From: common.HexToAddress("0x5470c5a6fce7447afd2c9be3a0f25e362c093661"), To: common.HexToAddress("0x479ee0363a7Ac2ef34cba7ee82D2C2E0652D4669"), @@ -102,8 +105,9 @@ func getTestCases() []decodeCallDataTest { &Contract{interfaces: []Interface{interfaceTypeERC20, interfaceTypeERC721}}, }, &CallData{ - MethodID: methodIDSafeTransferFrom3, - Args: []string{"0xcb89354a1c6e7ABd1972a68466Db238e48a3B0C8", "0x20964f741d2dfFD2cCec658CA086e21aF1D7dF8E", "29", "1"}, + MethodID: methodIDSafeTransferFrom3, + Signature: methodSignatures[methodIDSafeTransferFrom3.String()], + Args: []string{"0xcb89354a1c6e7ABd1972a68466Db238e48a3B0C8", "0x20964f741d2dfFD2cCec658CA086e21aF1D7dF8E", "29", "1"}, Transfers: []*Transfer{{ From: common.HexToAddress("0xcb89354a1c6e7ABd1972a68466Db238e48a3B0C8"), To: common.HexToAddress("0x20964f741d2dffd2ccec658ca086e21af1d7df8e"), @@ -120,7 +124,8 @@ func getTestCases() []decodeCallDataTest { &Contract{interfaces: []Interface{interfaceTypeERC20, interfaceTypeERC721}}, }, &CallData{ - MethodID: methodIDSafeBatchTransferFrom, + MethodID: methodIDSafeBatchTransferFrom, + Signature: methodSignatures[methodIDSafeBatchTransferFrom.String()], Transfers: []*Transfer{{ From: common.HexToAddress("0x381E840F4eBe33d0153e9A312105554594A98C42"), To: common.HexToAddress("0xA2b876dbb382d40cECeE2ACC670f55AD95c4767e"), diff --git a/eth/tracers/blocknative/decoder/methods.go b/eth/tracers/blocknative/decoder/methods.go index 5d0c8bd7d1e1..1400c2087972 100644 --- a/eth/tracers/blocknative/decoder/methods.go +++ b/eth/tracers/blocknative/decoder/methods.go @@ -17,33 +17,33 @@ var ( ErrMethodIDTooLong = fmt.Errorf("methodID is too long") // ERC20 - methodIDTransfer = methodIDToBytes(0xa9059cbb) // transfer(address,uint256) - methodIDTransferFrom = methodIDToBytes(0x23b872dd) // transferFrom(address,address,uint256) - methodIDTotalSupply = methodIDToBytes(0x18160ddd) // totalSupply() - methodIDBalanceOf = methodIDToBytes(0x70a08231) // balanceOf(address) - methodIDApprove = methodIDToBytes(0x095ea7b3) // approve(address,uint256) - methodIDAllowance = methodIDToBytes(0xdd62ed3e) // allowance(address,address) + methodIDTransfer = methodIDToBytes(0xa9059cbb) + methodIDTransferFrom = methodIDToBytes(0x23b872dd) + methodIDTotalSupply = methodIDToBytes(0x18160ddd) + methodIDBalanceOf = methodIDToBytes(0x70a08231) + methodIDApprove = methodIDToBytes(0x095ea7b3) + methodIDAllowance = methodIDToBytes(0xdd62ed3e) // ERC721 - methodIDSafeTransferFrom = methodIDToBytes(0x42842e0e) // safeTransferFrom(address,address,uint256) - methodIDSafeTransferFrom2 = methodIDToBytes(0xb88d4fde) // safeTransferFrom(address,address,uint256,bytes) - methodIDOwnerOf = methodIDToBytes(0x6352211e) // ownerOf(uint256) - methodIDSetApprovalForAll = methodIDToBytes(0xa22cb465) // setApprovalForAll(address,bool) - methodIDGetApproved = methodIDToBytes(0x081812fc) // getApproved(uint256) - methodIDIsApprovedForAll = methodIDToBytes(0xe985e9c5) // isApprovedForAll(address,address) + methodIDSafeTransferFrom = methodIDToBytes(0x42842e0e) + methodIDSafeTransferFrom2 = methodIDToBytes(0xb88d4fde) + methodIDOwnerOf = methodIDToBytes(0x6352211e) + methodIDSetApprovalForAll = methodIDToBytes(0xa22cb465) + methodIDGetApproved = methodIDToBytes(0x081812fc) + methodIDIsApprovedForAll = methodIDToBytes(0xe985e9c5) // ERC1155 - methodIDBalanceOf2 = methodIDToBytes(0x00fdd58e) // balanceOf(address,uint256) - methodIDBalanceOfBatch = methodIDToBytes(0x4e1273f4) // balanceOfBatch(address[],uint256[]) - methodIDSafeTransferFrom3 = methodIDToBytes(0xf242432a) // safeTransferFrom(address,address,uint256,uint256,bytes) - methodIDSafeBatchTransferFrom = methodIDToBytes(0x2eb2c2d6) // safeBatchTransferFrom(address,address,uint256[],uint256[],bytes) + methodIDBalanceOf2 = methodIDToBytes(0x00fdd58e) + methodIDBalanceOfBatch = methodIDToBytes(0x4e1273f4) + methodIDSafeTransferFrom3 = methodIDToBytes(0xf242432a) + methodIDSafeBatchTransferFrom = methodIDToBytes(0x2eb2c2d6) // Metadata - methodIDName = methodIDToBytes(0x06fdde03) // name() - methodIDSymbol = methodIDToBytes(0x95d89b41) // symbol() - methodIDDecimals = methodIDToBytes(0x313ce567) // decimals() - methodIDTokenURI = methodIDToBytes(0xc87b56dd) // tokenURI(uint256) - methodIDURI = methodIDToBytes(0x0e89341c) // uri(uint256) + methodIDName = methodIDToBytes(0x06fdde03) + methodIDSymbol = methodIDToBytes(0x95d89b41) + methodIDDecimals = methodIDToBytes(0x313ce567) + methodIDTokenURI = methodIDToBytes(0xc87b56dd) + methodIDURI = methodIDToBytes(0x0e89341c) // Interfaces by list of methodIDs interfaceMethodsERC20 = []MethodID{methodIDName, methodIDSymbol, methodIDDecimals, methodIDTransfer, methodIDTransferFrom, methodIDTotalSupply, methodIDBalanceOf, methodIDApprove, methodIDAllowance} @@ -51,6 +51,34 @@ var ( interfaceMethodsERC1155 = []MethodID{methodIDSafeTransferFrom3, methodIDSafeBatchTransferFrom, methodIDBalanceOf2, methodIDBalanceOfBatch, methodIDSetApprovalForAll, methodIDIsApprovedForAll} ) +// methodSignatures is a map of methodID strings to their signatures. +var methodSignatures = map[string]string{ + methodIDTransfer.String(): "transfer(address,uint256)", + methodIDTransferFrom.String(): "transferFrom(address,address,uint256)", + methodIDTotalSupply.String(): "totalSupply()", + methodIDBalanceOf.String(): "balanceOf(address)", + methodIDApprove.String(): "approve(address,uint256)", + methodIDAllowance.String(): "allowance(address,address)", + + methodIDSafeTransferFrom.String(): "safeTransferFrom(address,address,uint256)", + methodIDSafeTransferFrom2.String(): "safeTransferFrom(address,address,uint256,bytes)", + methodIDOwnerOf.String(): "ownerOf(uint256)", + methodIDSetApprovalForAll.String(): "setApprovalForAll(address,bool)", + methodIDGetApproved.String(): "getApproved(uint256)", + methodIDIsApprovedForAll.String(): "isApprovedForAll(address,address)", + + methodIDBalanceOf2.String(): "balanceOf(address,uint256)", + methodIDBalanceOfBatch.String(): "balanceOfBatch(address[],uint256[])", + methodIDSafeTransferFrom3.String(): "safeTransferFrom(address,address,uint256,uint256,bytes)", + methodIDSafeBatchTransferFrom.String(): "safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)", + + methodIDName.String(): "name()", + methodIDSymbol.String(): "symbol()", + methodIDDecimals.String(): "decimals()", + methodIDTokenURI.String(): "tokenURI(uint256)", + methodIDURI.String(): "uri(uint256)", +} + type MethodID []byte func (m MethodID) Is(other MethodID) bool { @@ -61,6 +89,10 @@ func (m MethodID) String() string { return "0x" + hex.EncodeToString(m) } +func (m MethodID) Signature() string { + return methodSignatures[m.String()] +} + func (m MethodID) MarshalJSON() ([]byte, error) { return json.Marshal(m.String()) } @@ -88,7 +120,6 @@ func (m *MethodID) UnmarshalJSON(b []byte) error { // Decode hex into m. methodIDBytes := make([]byte, 4) if _, err := hex.Decode(methodIDBytes, b); err != nil { - panic(err) return err } diff --git a/eth/tracers/blocknative/decoder/types.go b/eth/tracers/blocknative/decoder/types.go index 7ad0d0a3a531..251470e80268 100644 --- a/eth/tracers/blocknative/decoder/types.go +++ b/eth/tracers/blocknative/decoder/types.go @@ -18,7 +18,8 @@ type Contract struct { } type CallData struct { - MethodID MethodID `json:"methodID"` + MethodID MethodID `json:"method"` + Signature string `json:"signature,omitempty"` Args []string `json:"args,omitempty"` Transfers []*Transfer `json:"-"` } diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/delegatecall.json b/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/delegatecall.json index ec87a8c2b9cb..151c773bfb9b 100644 --- a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/delegatecall.json +++ b/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/delegatecall.json @@ -153,7 +153,7 @@ "output": "0x446374989d279847d0dbc6708a9c76a419fe9831d42c78bc89473f559a00d91500000000000000000000000061d76c05cd2aa9ed5135e21e52fff188b02089d4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000092f1dbea03ce08225e31e95cc926ddbe0198e6f2000000000000000000000000529c4cb814029b8bb32acb516ea3a4b07fdae350846fd373887ade3ab7703750294876afa61cf56303f5f014a4d80d04f508a1f100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "decoded": { "type": "erc20", - "methodID": "0x8c172fa2", + "method": "0x8c172fa2", "args": [ "0xd9a4ffe21d19763887176173d08241e8393c1dfd208f29193dfecdf854b664ac" ] @@ -179,7 +179,7 @@ "input": "0x24d4e90a0000000000000000000000000000000000000000000000020000000000000000", "output": "0x000000000000000000000000000000000000000000000000b17217f7d1cf79ab", "decoded": { - "methodID": "0x24d4e90a", + "method": "0x24d4e90a", "args": [ "0x0000000000000000000000000000000000000000000000020000000000000000" ] @@ -195,7 +195,7 @@ "input": "0x872fb2b5000000000000000000000000000000000000000000000000c330b3f7006420b8", "output": "0x00000000000000000000000000000000000000000000000224bf7df2c80f0878", "decoded": { - "methodID": "0x872fb2b5", + "method": "0x872fb2b5", "args": [ "0x000000000000000000000000000000000000000000000000c330b3f7006420b8" ] @@ -211,7 +211,7 @@ "input": "0x872fb2b50000000000000000000000000000000000000000000000000000000000000000", "output": "0x00000000000000000000000000000000000000000000000100000016aee6e8ef", "decoded": { - "methodID": "0x872fb2b5", + "method": "0x872fb2b5", "args": [ "0x0000000000000000000000000000000000000000000000000000000000000000" ] @@ -227,7 +227,7 @@ "input": "0x24d4e90a00000000000000000000000000000000000000000000000324bf7e0976f5f167", "output": "0x0000000000000000000000000000000000000000000000012535c5e5f87ee0d2", "decoded": { - "methodID": "0x24d4e90a", + "method": "0x24d4e90a", "args": [ "0x00000000000000000000000000000000000000000000000324bf7e0976f5f167" ] @@ -243,7 +243,7 @@ "input": "0x872fb2b5000000000000000000000000000000000000000000000000c330b3f7006420b8", "output": "0x00000000000000000000000000000000000000000000000224bf7df2c80f0878", "decoded": { - "methodID": "0x872fb2b5", + "method": "0x872fb2b5", "args": [ "0x000000000000000000000000000000000000000000000000c330b3f7006420b8" ] @@ -259,7 +259,7 @@ "input": "0x872fb2b500000000000000000000000000000000000000000000000237d37fe5d297a500", "output": "0x0000000000000000000000000000000000000000000000093088c407fcbbce38", "decoded": { - "methodID": "0x872fb2b5", + "method": "0x872fb2b5", "args": [ "0x00000000000000000000000000000000000000000000000237d37fe5d297a500" ] @@ -275,7 +275,7 @@ "input": "0x24d4e90a00000000000000000000000000000000000000000000000b554841fac4cad6b0", "output": "0x0000000000000000000000000000000000000000000000026d7fc130d6a74cbe", "decoded": { - "methodID": "0x24d4e90a", + "method": "0x24d4e90a", "args": [ "0x00000000000000000000000000000000000000000000000b554841fac4cad6b0" ] @@ -283,7 +283,7 @@ } ], "decoded": { - "methodID": "0x0439978d", + "method": "0x0439978d", "args": [ "0xe9efd3ab89acad6a3edf9828c3b00ed1c4a74e974d05d32d3b2fb15aa16fc377", "0x0000000000000000000000000000000000000000000000004563918244f40000", @@ -307,7 +307,7 @@ "output": "0x0000000000000000000000000000000000000000000000000071ea279ec31402", "decoded": { "type": "erc20", - "methodID": "0xc51cf179", + "method": "0xc51cf179", "args": [ "0x000000000000000000000000000000000000000000000000de0b6b3a76400000" ] @@ -344,7 +344,8 @@ "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { "type": "erc20", - "methodID": "0x23b872dd", + "method": "0x23b872dd", + "signature": "transferFrom(address,address,uint256)", "args": [ "0x3dE712784baf97260455aE25fb74f574EC9c1add", "0x6CA7f214AB2ddbB9A8E1A1e2C8550e3164E9dbA5", @@ -363,7 +364,8 @@ "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { "type": "erc20", - "methodID": "0x095ea7b3", + "method": "0x095ea7b3", + "signature": "approve(address,uint256)", "args": [ "0x0000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd", "0x00000000000000000000000000000000000000000000000080d29fa5cccfadac" @@ -391,7 +393,8 @@ "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { "type": "erc20", - "methodID": "0x23b872dd", + "method": "0x23b872dd", + "signature": "transferFrom(address,address,uint256)", "args": [ "0x6CA7f214AB2ddbB9A8E1A1e2C8550e3164E9dbA5", "0x5aaE5c59D642E5fD45b427Df6eD478b49d55FEfD", @@ -410,7 +413,8 @@ "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { "type": "erc20", - "methodID": "0xa9059cbb", + "method": "0xa9059cbb", + "signature": "transfer(address,uint256)", "args": [ "0x950CA4a06c78934a148B7a3Ff3Ea8fC366f77A06", "18565314632837192" @@ -428,7 +432,7 @@ "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { "type": "erc20", - "methodID": "0x475a9fa9", + "method": "0x475a9fa9", "args": [ "0x0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", "0x0000000000000000000000000000000000000000000000008090aa97a4fa4564" @@ -446,7 +450,7 @@ "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { "type": "erc20", - "methodID": "0x475a9fa9", + "method": "0x475a9fa9", "args": [ "0x0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", "0x0000000000000000000000000000000000000000000000008090aa97a4fa4564" @@ -456,7 +460,7 @@ ], "decoded": { "type": "erc20", - "methodID": "0x07d5b826", + "method": "0x07d5b826", "args": [ "0xd9a4ffe21d19763887176173d08241e8393c1dfd208f29193dfecdf854b664ac", "0x00000000000000000000000000000000000000000000000080d29fa5cccfadac" @@ -474,7 +478,7 @@ "output": "0x000000000000000000000000f4cbd7e037b80c2e67b80512d482685f15b1fb28", "decoded": { "type": "erc20", - "methodID": "0x1f0c1e0c", + "method": "0x1f0c1e0c", "args": [ "0xd9a4ffe21d19763887176173d08241e8393c1dfd208f29193dfecdf854b664ac", "0x0000000000000000000000000000000000000000000000000000000000000001" @@ -521,7 +525,7 @@ "input": "0x88d5fecb00000000000000000000000000000000000000000000000000000000000000010000000000000000000000003de712784baf97260455ae25fb74f574ec9c1add000000000000000000000000000000000000000000000000de0b6b3a76400000", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { - "methodID": "0x88d5fecb", + "method": "0x88d5fecb", "args": [ "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000003de712784baf97260455ae25fb74f574ec9c1add", @@ -532,7 +536,8 @@ ], "decoded": { "type": "erc20", - "methodID": "0xa9059cbb", + "method": "0xa9059cbb", + "signature": "transfer(address,uint256)", "args": [ "0x3dE712784baf97260455aE25fb74f574EC9c1add", "16000000000000000000" @@ -541,7 +546,7 @@ } ], "decoded": { - "methodID": "0xbbd4f854", + "method": "0xbbd4f854", "args": [ "0xe9efd3ab89acad6a3edf9828c3b00ed1c4a74e974d05d32d3b2fb15aa16fc377", "0x0000000000000000000000000000000000000000000000000000000000000001", diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/erc20_transfer.json b/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/erc20_transfer.json index 42aeeac1da89..15b584d635da 100644 --- a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/erc20_transfer.json +++ b/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/erc20_transfer.json @@ -65,7 +65,8 @@ "output": "0x6060604052600436106100b95763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde0381146100be578063095ea7b31461014857806318160ddd1461017e57806323b872dd146101a3578063313ce567146101cb57806342966c68146101f457806370a082311461020a57806379cc67901461022957806395d89b411461024b578063a9059cbb1461025e578063cae9ca5114610282578063dd62ed3e146102e7575b600080fd5b34156100c957600080fd5b6100d161030c565b60405160208082528190810183818151815260200191508051906020019080838360005b8381101561010d5780820151838201526020016100f5565b50505050905090810190601f16801561013a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015357600080fd5b61016a600160a060020a03600435166024356103aa565b604051901515815260200160405180910390f35b341561018957600080fd5b6101916103da565b60405190815260200160405180910390f35b34156101ae57600080fd5b61016a600160a060020a03600435811690602435166044356103e0565b34156101d657600080fd5b6101de610457565b60405160ff909116815260200160405180910390f35b34156101ff57600080fd5b61016a600435610460565b341561021557600080fd5b610191600160a060020a03600435166104eb565b341561023457600080fd5b61016a600160a060020a03600435166024356104fd565b341561025657600080fd5b6100d16105d9565b341561026957600080fd5b610280600160a060020a0360043516602435610644565b005b341561028d57600080fd5b61016a60048035600160a060020a03169060248035919060649060443590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965061065395505050505050565b34156102f257600080fd5b610191600160a060020a0360043581169060243516610785565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103a25780601f10610377576101008083540402835291602001916103a2565b820191906000526020600020905b81548152906001019060200180831161038557829003601f168201915b505050505081565b600160a060020a033381166000908152600560209081526040808320938616835292905220819055600192915050565b60035481565b600160a060020a0380841660009081526005602090815260408083203390941683529290529081205482111561041557600080fd5b600160a060020a038085166000908152600560209081526040808320339094168352929052208054839003905561044d8484846107a2565b5060019392505050565b60025460ff1681565b600160a060020a0333166000908152600460205260408120548290101561048657600080fd5b600160a060020a03331660008181526004602052604090819020805485900390556003805485900390557fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca59084905190815260200160405180910390a2506001919050565b60046020526000908152604090205481565b600160a060020a0382166000908152600460205260408120548290101561052357600080fd5b600160a060020a038084166000908152600560209081526040808320339094168352929052205482111561055657600080fd5b600160a060020a038084166000818152600460209081526040808320805488900390556005825280832033909516835293905282902080548590039055600380548590039055907fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca59084905190815260200160405180910390a250600192915050565b60018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103a25780601f10610377576101008083540402835291602001916103a2565b61064f3383836107a2565b5050565b60008361066081856103aa565b1561077d5780600160a060020a0316638f4ffcb1338630876040518563ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018085600160a060020a0316600160a060020a0316815260200184815260200183600160a060020a0316600160a060020a0316815260200180602001828103825283818151815260200191508051906020019080838360005b838110156107165780820151838201526020016106fe565b50505050905090810190601f1680156107435780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b151561076457600080fd5b6102c65a03f1151561077557600080fd5b505050600191505b509392505050565b600560209081526000928352604080842090915290825290205481565b6000600160a060020a03831615156107b957600080fd5b600160a060020a038416600090815260046020526040902054829010156107df57600080fd5b600160a060020a0383166000908152600460205260409020548281011161080557600080fd5b50600160a060020a0380831660008181526004602052604080822080549488168084528284208054888103909155938590528154870190915591909301927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a3600160a060020a038084166000908152600460205260408082205492871682529020540181146108a257fe5b505050505600a165627a7a72305820604ef788ac8abdaedc46b8f7086ffceec1d1e365e29400b7d236b16d049806500029", "decoded": { "type": "erc20", - "methodID": "0xa9059cbb", + "method": "0xa9059cbb", + "signature": "transfer(address,uint256)", "args": [ "0xFbA9F22D040e53e5FAc36698080cee3dD3792262", "9587061213415306430410" diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/erc20_transfer2.json b/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/erc20_transfer2.json index abf313e832c2..6cd2e776bf4f 100644 --- a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/erc20_transfer2.json +++ b/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/erc20_transfer2.json @@ -71,7 +71,8 @@ "input": "0xa9059cbb000000000000000000000000dbf03b407c01e7cd3cbea99509d93f8dddc8c6fb0000000000000000000000000000000000000000000000000000000000989680", "output": "0x", "decoded": { - "methodID": "0xa9059cbb", + "method": "0xa9059cbb", + "signature": "transfer(address,uint256)", "args": [ "0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB", "10000000" diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/inner_create.json b/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/inner_create.json index b3d3a082a11b..962e9c334143 100644 --- a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/inner_create.json +++ b/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/inner_create.json @@ -233,7 +233,7 @@ "input": "0x0a16697a", "output": "0x000000000000000000000000000000000000000000000000000000000010365c", "decoded": { - "methodID": "0x0a16697a" + "method": "0x0a16697a" } }, { @@ -246,7 +246,7 @@ "input": "0x0a16697a", "output": "0x000000000000000000000000000000000000000000000000000000000010365c", "decoded": { - "methodID": "0x0a16697a" + "method": "0x0a16697a" } }, { @@ -259,7 +259,7 @@ "input": "0x0a16697a", "output": "0x000000000000000000000000000000000000000000000000000000000010365c", "decoded": { - "methodID": "0x0a16697a" + "method": "0x0a16697a" } }, { @@ -272,7 +272,7 @@ "input": "0xa06db7dc", "output": "0x00000000000000000000000000000000000000000000000000000000000000ff", "decoded": { - "methodID": "0xa06db7dc" + "method": "0xa06db7dc" } }, { @@ -285,12 +285,12 @@ "input": "0x0a16697a", "output": "0x000000000000000000000000000000000000000000000000000000000010365c", "decoded": { - "methodID": "0x0a16697a" + "method": "0x0a16697a" } } ], "decoded": { - "methodID": "0x5054d98a", + "method": "0x5054d98a", "args": [ "0x0000000000000000000000000000000000000000000000000000000000000003" ] @@ -316,7 +316,7 @@ "input": "0x0a16697a", "output": "0x000000000000000000000000000000000000000000000000000000000010365c", "decoded": { - "methodID": "0x0a16697a" + "method": "0x0a16697a" } }, { @@ -329,7 +329,7 @@ "input": "0xa06db7dc", "output": "0x00000000000000000000000000000000000000000000000000000000000000ff", "decoded": { - "methodID": "0xa06db7dc" + "method": "0xa06db7dc" } }, { @@ -342,7 +342,7 @@ "input": "0x0a16697a", "output": "0x000000000000000000000000000000000000000000000000000000000010365c", "decoded": { - "methodID": "0x0a16697a" + "method": "0x0a16697a" } }, { @@ -355,7 +355,7 @@ "input": "0x0a16697a", "output": "0x000000000000000000000000000000000000000000000000000000000010365c", "decoded": { - "methodID": "0x0a16697a" + "method": "0x0a16697a" } }, { @@ -368,12 +368,12 @@ "input": "0xa06db7dc", "output": "0x00000000000000000000000000000000000000000000000000000000000000ff", "decoded": { - "methodID": "0xa06db7dc" + "method": "0xa06db7dc" } } ], "decoded": { - "methodID": "0xa1873db6", + "method": "0xa1873db6", "args": [ "0x0000000000000000000000000000000000000000000000000000000000000003", "0x000000000000000000000000b834e3edfc1a927bdcecb67a9d0eccbd752a5bb3", @@ -411,7 +411,7 @@ "input": "0x0a16697a", "output": "0x000000000000000000000000000000000000000000000000000000000010365c", "decoded": { - "methodID": "0x0a16697a" + "method": "0x0a16697a" } }, { @@ -434,7 +434,7 @@ "input": "0x8e46afa9", "output": "0x00000000000000000000000000000000000000000000000000000000000000ff", "decoded": { - "methodID": "0x8e46afa9" + "method": "0x8e46afa9" } }, { @@ -447,7 +447,7 @@ "input": "0x971c803f", "output": "0x000000000000000000000000000000000000000000000000000000000000000a", "decoded": { - "methodID": "0x971c803f" + "method": "0x971c803f" } }, { @@ -510,7 +510,7 @@ "input": "0xbacd69580000000000000000000000000000000000000000000000000000000000000001000000000000000000000000651913977e8140c323997fce5e03c19e0015eebf0000000000000000000000000000000000000000000000000000000000103847", "output": "0x", "decoded": { - "methodID": "0xbacd6958", + "method": "0xbacd6958", "args": [ "0x0000000000000000000000000000000000000000000000000000000000000001", "0x000000000000000000000000651913977e8140c323997fce5e03c19e0015eebf", @@ -520,7 +520,7 @@ } ], "decoded": { - "methodID": "0x50d4e411", + "method": "0x50d4e411", "args": [ "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000007dd677b54fc954824a7bc49bd26cbdfa12c75adf", @@ -541,7 +541,7 @@ } ], "decoded": { - "methodID": "0x8c0e156d", + "method": "0x8c0e156d", "args": [ "0x3defb96200000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000103847", @@ -551,7 +551,7 @@ } ], "decoded": { - "methodID": "0x3defb962" + "method": "0x3defb962" } }, { @@ -564,7 +564,7 @@ "input": "0x938b5f32", "output": "0x0000000000000000000000006c8f2a135f6ed072de4503bd7c4999a1a17f824b", "decoded": { - "methodID": "0x938b5f32" + "method": "0x938b5f32" } }, { @@ -587,7 +587,7 @@ "input": "0xed5bd7ea0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000741467b251fca923d6229c4b439078b55dca233b", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { - "methodID": "0xed5bd7ea", + "method": "0xed5bd7ea", "args": [ "0x0000000000000000000000000000000000000000000000000000000000000001", "0x000000000000000000000000741467b251fca923d6229c4b439078b55dca233b" @@ -604,7 +604,7 @@ "input": "0xc6502da8", "output": "0x0000000000000000000000000000000000000000000000000011f79bd42b0c7c", "decoded": { - "methodID": "0xc6502da8" + "method": "0xc6502da8" } }, { @@ -617,7 +617,7 @@ "input": "0xc6803622", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { - "methodID": "0xc6803622" + "method": "0xc6803622" } }, { @@ -630,12 +630,12 @@ "input": "0xd379be23", "output": "0x0000000000000000000000000000000000000000000000000000000000000000", "decoded": { - "methodID": "0xd379be23" + "method": "0xd379be23" } } ], "decoded": { - "methodID": "0xe6470fbe" + "method": "0xe6470fbe" } }, { @@ -648,7 +648,7 @@ "input": "0xc6502da8", "output": "0x0000000000000000000000000000000000000000000000000011f79bd42b0c7c", "decoded": { - "methodID": "0xc6502da8" + "method": "0xc6502da8" } }, { @@ -661,7 +661,7 @@ "input": "0x625cc465", "output": "0x00000000000000000000000000000000000000000000000000002dfeff8fca5d", "decoded": { - "methodID": "0x625cc465" + "method": "0x625cc465" } }, { @@ -686,7 +686,7 @@ } ], "decoded": { - "methodID": "0x12c82bcc", + "method": "0x12c82bcc", "args": [ "0x000000000000000000000000b834e3edfc1a927bdcecb67a9d0eccbd752a5bb3", "0x00000000000000000000000000000000000000000000000001035c689778647c" @@ -715,7 +715,7 @@ } ], "decoded": { - "methodID": "0x12c82bcc", + "method": "0x12c82bcc", "args": [ "0x000000000000000000000000d3cda913deb6f67967b99d67acdfa1712c293601", "0x00000000000000000000000000000000000000000000000000002dfeff8fca5d" @@ -724,7 +724,7 @@ } ], "decoded": { - "methodID": "0xda46be0a", + "method": "0xda46be0a", "args": [ "0x0000000000000000000000000000000000000000000000000000000000000003", "0x00000000000000000000000000000000000000000000000000000000001fa874", @@ -766,7 +766,7 @@ } ], "decoded": { - "methodID": "0x12c82bcc", + "method": "0x12c82bcc", "args": [ "0x0000000000000000000000007dd677b54fc954824a7bc49bd26cbdfa12c75adf", "0x00000000000000000000000000000000000000000000000028c288eb0779ea1f" @@ -775,7 +775,7 @@ } ], "decoded": { - "methodID": "0xc17e6817", + "method": "0xc17e6817", "args": [ "0x0000000000000000000000007dd677b54fc954824a7bc49bd26cbdfa12c75adf", "0x00000000000000000000000000000000000000000000000028c288eb0779ea1f" @@ -784,7 +784,7 @@ } ], "decoded": { - "methodID": "0x61461954" + "method": "0x61461954" }, "blockContext": { "number": 1062503, @@ -796,10 +796,10 @@ }, "balanceChanges": [ { - "address": "0x6c8f2a135f6ed072de4503bd7c4999a1a17f824b", + "address": "0x2a65aca4d5fc5b5c859090a6c34d164135398226", "balanceChanges": [ { - "delta": "3000000000000000000", + "delta": "65572176247818240", "asset": { "address": "0x0000000000000000000000000000000000000000", "type": "eth", @@ -809,18 +809,18 @@ }, "breakdown": [ { - "counterparty": "0x7dd677b54fc954824a7bc49bd26cbdfa12c75adf", - "amount": "3000000000000000000" + "counterparty": "0xb834e3edfc1a927bdcecb67a9d0eccbd752a5bb3", + "amount": "65572176247818240" } ] } ] }, { - "address": "0x7dd677b54fc954824a7bc49bd26cbdfa12c75adf", + "address": "0x6c8f2a135f6ed072de4503bd7c4999a1a17f824b", "balanceChanges": [ { - "delta": "-3000000000000000000", + "delta": "3000000000000000000", "asset": { "address": "0x0000000000000000000000000000000000000000", "type": "eth", @@ -830,18 +830,18 @@ }, "breakdown": [ { - "counterparty": "0x6c8f2a135f6ed072de4503bd7c4999a1a17f824b", - "amount": "-3000000000000000000" + "counterparty": "0x7dd677b54fc954824a7bc49bd26cbdfa12c75adf", + "amount": "3000000000000000000" } ] } ] }, { - "address": "0xb834e3edfc1a927bdcecb67a9d0eccbd752a5bb3", + "address": "0x7dd677b54fc954824a7bc49bd26cbdfa12c75adf", "balanceChanges": [ { - "delta": "-65594100000000000", + "delta": "-3000000000000000000", "asset": { "address": "0x0000000000000000000000000000000000000000", "type": "eth", @@ -851,22 +851,18 @@ }, "breakdown": [ { - "counterparty": "0x0000000000000000000000000000000000000000", - "amount": "-21923752181760" - }, - { - "counterparty": "0x2a65aca4d5fc5b5c859090a6c34d164135398226", - "amount": "-65572176247818240" + "counterparty": "0x6c8f2a135f6ed072de4503bd7c4999a1a17f824b", + "amount": "-3000000000000000000" } ] } ] }, { - "address": "0x2a65aca4d5fc5b5c859090a6c34d164135398226", + "address": "0xb834e3edfc1a927bdcecb67a9d0eccbd752a5bb3", "balanceChanges": [ { - "delta": "65572176247818240", + "delta": "-65594100000000000", "asset": { "address": "0x0000000000000000000000000000000000000000", "type": "eth", @@ -876,8 +872,12 @@ }, "breakdown": [ { - "counterparty": "0xb834e3edfc1a927bdcecb67a9d0eccbd752a5bb3", - "amount": "65572176247818240" + "counterparty": "0x0000000000000000000000000000000000000000", + "amount": "-21923752181760" + }, + { + "counterparty": "0x2a65aca4d5fc5b5c859090a6c34d164135398226", + "amount": "-65572176247818240" } ] } diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/multi_contracts_transfers.json b/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/multi_contracts_transfers.json index 866969690066..8de65afbc324 100644 --- a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/multi_contracts_transfers.json +++ b/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/multi_contracts_transfers.json @@ -318,7 +318,7 @@ "input": "0x4b6753bc", "output": "0x0000000000000000000000000000000000000000000000000000000057870858", "decoded": { - "methodID": "0x4b6753bc" + "method": "0x4b6753bc" } }, { @@ -331,7 +331,8 @@ "input": "0x70a08231000000000000000000000000c0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89", "output": "0x00000000000000000000000000000000000000000001819451f999d617dafa93", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x000000000000000000000000c0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89" ] @@ -347,7 +348,8 @@ "input": "0x70a08231000000000000000000000000c0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89", "output": "0x00000000000000000000000000000000000000000001819451f999d617dafa93", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x000000000000000000000000c0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89" ] @@ -373,7 +375,8 @@ "input": "0xa9059cbb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd00000000000000000000000000000000000000000001819451f999d617dafa93", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { - "methodID": "0xa9059cbb", + "method": "0xa9059cbb", + "signature": "transfer(address,uint256)", "args": [ "0x4FD27b205895e698fa350F7ea57CeC8a21927FCD", "1820847120949253496306323" @@ -382,7 +385,8 @@ } ], "decoded": { - "methodID": "0xa9059cbb", + "method": "0xa9059cbb", + "signature": "transfer(address,uint256)", "args": [ "0x4FD27b205895e698fa350F7ea57CeC8a21927FCD", "1820847120949253496306323" @@ -409,7 +413,7 @@ "input": "0x81f03fcb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", "output": "0x0000000000000000000000000000000000000000000000000000000000000000", "decoded": { - "methodID": "0x81f03fcb", + "method": "0x81f03fcb", "args": [ "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" ] @@ -425,7 +429,7 @@ "input": "0x0e708203", "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193", "decoded": { - "methodID": "0x0e708203" + "method": "0x0e708203" } }, { @@ -438,7 +442,7 @@ "input": "0xd2cc718f", "output": "0x0000000000000000000000000000000000000000000000000000000000000000", "decoded": { - "methodID": "0xd2cc718f" + "method": "0xd2cc718f" } }, { @@ -451,7 +455,7 @@ "input": "0x81f03fcb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", "output": "0x0000000000000000000000000000000000000000000000000000000000000000", "decoded": { - "methodID": "0x81f03fcb", + "method": "0x81f03fcb", "args": [ "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" ] @@ -467,7 +471,8 @@ "input": "0x18160ddd", "output": "0x00000000000000000000000000000000000000000003034f5ca7d45e17df199b", "decoded": { - "methodID": "0x18160ddd" + "method": "0x18160ddd", + "signature": "totalSupply()" } }, { @@ -480,7 +485,8 @@ "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", "output": "0x00000000000000000000000000000000000000000001819451f999d617dafa93", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" ] @@ -488,7 +494,7 @@ } ], "decoded": { - "methodID": "0xa8618f71", + "method": "0xa8618f71", "args": [ "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" ] @@ -504,7 +510,8 @@ "input": "0x70a08231000000000000000000000000f835a0247b0063c04ef22006ebe57c5f11977cc4", "output": "0x00000000000000000000000000000000000000000001819451f999d617dafa76", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x000000000000000000000000f835a0247b0063c04ef22006ebe57c5f11977cc4" ] @@ -520,7 +527,8 @@ "input": "0x70a08231000000000000000000000000f835a0247b0063c04ef22006ebe57c5f11977cc4", "output": "0x00000000000000000000000000000000000000000001819451f999d617dafa76", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x000000000000000000000000f835a0247b0063c04ef22006ebe57c5f11977cc4" ] @@ -546,7 +554,8 @@ "input": "0xa9059cbb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd00000000000000000000000000000000000000000001819451f999d617dafa76", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { - "methodID": "0xa9059cbb", + "method": "0xa9059cbb", + "signature": "transfer(address,uint256)", "args": [ "0x4FD27b205895e698fa350F7ea57CeC8a21927FCD", "1820847120949253496306294" @@ -555,7 +564,8 @@ } ], "decoded": { - "methodID": "0xa9059cbb", + "method": "0xa9059cbb", + "signature": "transfer(address,uint256)", "args": [ "0x4FD27b205895e698fa350F7ea57CeC8a21927FCD", "1820847120949253496306294" @@ -582,7 +592,7 @@ "input": "0x81f03fcb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", "output": "0x0000000000000000000000000000000000000000000000000000000000000000", "decoded": { - "methodID": "0x81f03fcb", + "method": "0x81f03fcb", "args": [ "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" ] @@ -598,7 +608,7 @@ "input": "0x0e708203", "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193", "decoded": { - "methodID": "0x0e708203" + "method": "0x0e708203" } }, { @@ -611,7 +621,7 @@ "input": "0xd2cc718f", "output": "0x0000000000000000000000000000000000000000000000000000000000000000", "decoded": { - "methodID": "0xd2cc718f" + "method": "0xd2cc718f" } }, { @@ -624,7 +634,7 @@ "input": "0x81f03fcb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", "output": "0x0000000000000000000000000000000000000000000000000000000000000000", "decoded": { - "methodID": "0x81f03fcb", + "method": "0x81f03fcb", "args": [ "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" ] @@ -640,7 +650,8 @@ "input": "0x18160ddd", "output": "0x00000000000000000000000000000000000000000003034f5ca7d45e17df199b", "decoded": { - "methodID": "0x18160ddd" + "method": "0x18160ddd", + "signature": "totalSupply()" } }, { @@ -653,7 +664,8 @@ "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f509", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" ] @@ -661,7 +673,7 @@ } ], "decoded": { - "methodID": "0xa8618f71", + "method": "0xa8618f71", "args": [ "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" ] @@ -687,7 +699,7 @@ "input": "0x0e708203", "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193", "decoded": { - "methodID": "0x0e708203" + "method": "0x0e708203" } }, { @@ -700,7 +712,7 @@ "input": "0x0e708203", "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193", "decoded": { - "methodID": "0x0e708203" + "method": "0x0e708203" } }, { @@ -713,7 +725,7 @@ "input": "0xd2cc718f", "output": "0x0000000000000000000000000000000000000000000000000000000000000000", "decoded": { - "methodID": "0xd2cc718f" + "method": "0xd2cc718f" } }, { @@ -726,7 +738,7 @@ "input": "0x81f03fcb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", "output": "0x0000000000000000000000000000000000000000000000000000000000000000", "decoded": { - "methodID": "0x81f03fcb", + "method": "0x81f03fcb", "args": [ "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" ] @@ -742,7 +754,8 @@ "input": "0x18160ddd", "output": "0x00000000000000000000000000000000000000000003034f5ca7d45e17df199b", "decoded": { - "methodID": "0x18160ddd" + "method": "0x18160ddd", + "signature": "totalSupply()" } }, { @@ -755,7 +768,8 @@ "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f509", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" ] @@ -771,7 +785,8 @@ "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f509", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" ] @@ -797,7 +812,8 @@ "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f509", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" ] @@ -813,7 +829,8 @@ "input": "0xa9059cbb0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccd", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { - "methodID": "0xa9059cbb", + "method": "0xa9059cbb", + "signature": "transfer(address,uint256)", "args": [ "0x6e715Ab4F598eACF0016b9b35Ef33e4141844CcC", "1821204263806396353449165" @@ -822,7 +839,7 @@ } ], "decoded": { - "methodID": "0xd0679d34", + "method": "0xd0679d34", "args": [ "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc", "0x0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccd" @@ -849,7 +866,7 @@ "input": "0xd2cc718f", "output": "0x000000000000000000000000000000000000000000000004563918244f400000", "decoded": { - "methodID": "0xd2cc718f" + "method": "0xd2cc718f" } }, { @@ -862,7 +879,8 @@ "input": "0x70a082310000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc", "output": "0x0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccd", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc" ] @@ -878,7 +896,7 @@ "input": "0x81f03fcb0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc", "output": "0x0000000000000000000000000000000000000000000000000000000000000000", "decoded": { - "methodID": "0x81f03fcb", + "method": "0x81f03fcb", "args": [ "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc" ] @@ -904,7 +922,7 @@ "input": "0xd2cc718f", "output": "0x000000000000000000000000000000000000000000000004563918244f400000", "decoded": { - "methodID": "0xd2cc718f" + "method": "0xd2cc718f" } }, { @@ -917,7 +935,7 @@ "input": "0xd2cc718f", "output": "0x000000000000000000000000000000000000000000000004563918244f400000", "decoded": { - "methodID": "0xd2cc718f" + "method": "0xd2cc718f" } }, { @@ -950,7 +968,7 @@ "input": "0x0e708203", "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193", "decoded": { - "methodID": "0x0e708203" + "method": "0x0e708203" } }, { @@ -973,7 +991,7 @@ "input": "0xd2cc718f", "output": "0x000000000000000000000000000000000000000000000004563918244f400000", "decoded": { - "methodID": "0xd2cc718f" + "method": "0xd2cc718f" } }, { @@ -986,7 +1004,7 @@ "input": "0xd2cc718f", "output": "0x000000000000000000000000000000000000000000000004563918244f400000", "decoded": { - "methodID": "0xd2cc718f" + "method": "0xd2cc718f" } }, { @@ -1019,7 +1037,7 @@ "input": "0x0e708203", "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193", "decoded": { - "methodID": "0x0e708203" + "method": "0x0e708203" } }, { @@ -1032,7 +1050,8 @@ "input": "0x70a082310000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc", "output": "0x0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccd", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc" ] @@ -1048,7 +1067,8 @@ "input": "0xa9059cbb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccc", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { - "methodID": "0xa9059cbb", + "method": "0xa9059cbb", + "signature": "transfer(address,uint256)", "args": [ "0x4FD27b205895e698fa350F7ea57CeC8a21927FCD", "1821204263806396353449164" @@ -1059,7 +1079,7 @@ } ], "decoded": { - "methodID": "0x0221038a", + "method": "0x0221038a", "args": [ "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc", "0x0000000000000000000000000000000000000000000000022b1c8c12279fffff" @@ -1068,14 +1088,14 @@ } ], "decoded": { - "methodID": "0xcc9ae3f6" + "method": "0xcc9ae3f6" } } ] } ], "decoded": { - "methodID": "0x0221038a", + "method": "0x0221038a", "args": [ "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc", "0x0000000000000000000000000000000000000000000000022b1c8c12279fffff" @@ -1084,7 +1104,7 @@ } ], "decoded": { - "methodID": "0xcc9ae3f6" + "method": "0xcc9ae3f6" } }, { @@ -1097,7 +1117,8 @@ "input": "0xa9059cbb0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f0000000000000000000000000000000000000000000000000000000000000001", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { - "methodID": "0xa9059cbb", + "method": "0xa9059cbb", + "signature": "transfer(address,uint256)", "args": [ "0x6DBfc63479ffC031f23e94dC91bEFa38Bec2c25f", "1" @@ -1106,7 +1127,7 @@ } ], "decoded": { - "methodID": "0xfc340716" + "method": "0xfc340716" } }, { @@ -1129,7 +1150,7 @@ "input": "0x81f03fcb0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f", "output": "0x000000000000000000000000000000000000000000000004563918244f3ffffe", "decoded": { - "methodID": "0x81f03fcb", + "method": "0x81f03fcb", "args": [ "0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f" ] @@ -1145,7 +1166,8 @@ "input": "0x70a08231000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526", "output": "0x000000000000000000000000000000000000000000000026b8b4a0b1e8292492", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526" ] @@ -1161,7 +1183,8 @@ "input": "0x70a082310000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f" ] @@ -1187,7 +1210,8 @@ "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f508", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" ] @@ -1203,7 +1227,8 @@ "input": "0xa9059cbb0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f0000000000000000000000000000000000000000000000000000000000000063", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { - "methodID": "0xa9059cbb", + "method": "0xa9059cbb", + "signature": "transfer(address,uint256)", "args": [ "0x6DBfc63479ffC031f23e94dC91bEFa38Bec2c25f", "99" @@ -1212,7 +1237,7 @@ } ], "decoded": { - "methodID": "0xd0679d34", + "method": "0xd0679d34", "args": [ "0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f", "0x0000000000000000000000000000000000000000000000000000000000000063" @@ -1229,7 +1254,7 @@ "input": "0x81f03fcb000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526", "output": "0x0000000000000000000000000000000000000000000000000000000000000000", "decoded": { - "methodID": "0x81f03fcb", + "method": "0x81f03fcb", "args": [ "0x000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526" ] @@ -1255,7 +1280,7 @@ "input": "0x0e708203", "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193", "decoded": { - "methodID": "0x0e708203" + "method": "0x0e708203" } }, { @@ -1268,7 +1293,7 @@ "input": "0xd2cc718f", "output": "0x000000000000000000000000000000000000000000000004563918244f400000", "decoded": { - "methodID": "0xd2cc718f" + "method": "0xd2cc718f" } }, { @@ -1281,7 +1306,7 @@ "input": "0x81f03fcb000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526", "output": "0x0000000000000000000000000000000000000000000000000000000000000000", "decoded": { - "methodID": "0x81f03fcb", + "method": "0x81f03fcb", "args": [ "0x000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526" ] @@ -1297,7 +1322,8 @@ "input": "0x18160ddd", "output": "0x00000000000000000000000000000000000000000003034f5ca7d45e17df199b", "decoded": { - "methodID": "0x18160ddd" + "method": "0x18160ddd", + "signature": "totalSupply()" } }, { @@ -1310,7 +1336,8 @@ "input": "0x70a08231000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526", "output": "0x000000000000000000000000000000000000000000000026b8b4a0b1e8292492", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526" ] @@ -1318,7 +1345,7 @@ } ], "decoded": { - "methodID": "0x65f13792", + "method": "0x65f13792", "args": [ "0x000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526" ] @@ -1334,7 +1361,7 @@ "input": "0x81f03fcb0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f", "output": "0x000000000000000000000000000000000000000000000004563918244f3ffffe", "decoded": { - "methodID": "0x81f03fcb", + "method": "0x81f03fcb", "args": [ "0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f" ] @@ -1350,7 +1377,8 @@ "input": "0x70a082310000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f", "output": "0x0000000000000000000000000000000000000000000000000000000000000064", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f" ] @@ -1366,7 +1394,8 @@ "input": "0x70a08231000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526", "output": "0x000000000000000000000000000000000000000000000026b8b4a0b1e8292492", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526" ] @@ -1382,7 +1411,8 @@ "input": "0xa9059cbb000000000000000000000000da4a4626d3e16e094de3225a751aab7128e965260000000000000000000000000000000000000000000000000000000000000064", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { - "methodID": "0xa9059cbb", + "method": "0xa9059cbb", + "signature": "transfer(address,uint256)", "args": [ "0xDa4a4626d3E16e094De3225A751aAb7128e96526", "100" @@ -1391,7 +1421,7 @@ } ], "decoded": { - "methodID": "0xd95f98ce" + "method": "0xd95f98ce" } }, { @@ -1404,7 +1434,8 @@ "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", "output": "0x0000000000000000000000000000000000000000000000000000000000000000", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b" ] @@ -1430,7 +1461,8 @@ "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f4a5", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" ] @@ -1446,7 +1478,8 @@ "input": "0xa9059cbb0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b0000000000000000000000000000000000000000000000000000000000000001", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { - "methodID": "0xa9059cbb", + "method": "0xa9059cbb", + "signature": "transfer(address,uint256)", "args": [ "0x7498BB5749c9801f1F7e490baf5F966DBFe4e97B", "1" @@ -1455,7 +1488,7 @@ } ], "decoded": { - "methodID": "0xd0679d34", + "method": "0xd0679d34", "args": [ "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", "0x0000000000000000000000000000000000000000000000000000000000000001" @@ -1472,7 +1505,7 @@ "input": "0x400e3949", "output": "0x0000000000000000000000000000000000000000000000000000000000000000", "decoded": { - "methodID": "0x400e3949" + "method": "0x400e3949" } }, { @@ -1495,7 +1528,8 @@ "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b" ] @@ -1553,7 +1587,7 @@ } ], "decoded": { - "methodID": "0x612e45a3", + "method": "0x612e45a3", "args": [ "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -1568,7 +1602,7 @@ } ], "decoded": { - "methodID": "0xff2f4bd2" + "method": "0xff2f4bd2" } }, { @@ -1581,7 +1615,7 @@ "input": "0x400e3949", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { - "methodID": "0x400e3949" + "method": "0x400e3949" } }, { @@ -1604,7 +1638,8 @@ "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b" ] @@ -1662,7 +1697,7 @@ } ], "decoded": { - "methodID": "0x612e45a3", + "method": "0x612e45a3", "args": [ "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -1677,7 +1712,7 @@ } ], "decoded": { - "methodID": "0xff2f4bd2" + "method": "0xff2f4bd2" } }, { @@ -1690,7 +1725,7 @@ "input": "0x400e3949", "output": "0x0000000000000000000000000000000000000000000000000000000000000002", "decoded": { - "methodID": "0x400e3949" + "method": "0x400e3949" } }, { @@ -1713,7 +1748,8 @@ "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b" ] @@ -1771,7 +1807,7 @@ } ], "decoded": { - "methodID": "0x612e45a3", + "method": "0x612e45a3", "args": [ "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -1786,7 +1822,7 @@ } ], "decoded": { - "methodID": "0xff2f4bd2" + "method": "0xff2f4bd2" } }, { @@ -1799,7 +1835,7 @@ "input": "0x400e3949", "output": "0x0000000000000000000000000000000000000000000000000000000000000003", "decoded": { - "methodID": "0x400e3949" + "method": "0x400e3949" } }, { @@ -1822,7 +1858,8 @@ "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b" ] @@ -1880,7 +1917,7 @@ } ], "decoded": { - "methodID": "0x612e45a3", + "method": "0x612e45a3", "args": [ "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -1895,7 +1932,7 @@ } ], "decoded": { - "methodID": "0xff2f4bd2" + "method": "0xff2f4bd2" } }, { @@ -1908,7 +1945,7 @@ "input": "0x400e3949", "output": "0x0000000000000000000000000000000000000000000000000000000000000004", "decoded": { - "methodID": "0x400e3949" + "method": "0x400e3949" } }, { @@ -1931,7 +1968,8 @@ "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b" ] @@ -1989,7 +2027,7 @@ } ], "decoded": { - "methodID": "0x612e45a3", + "method": "0x612e45a3", "args": [ "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -2004,7 +2042,7 @@ } ], "decoded": { - "methodID": "0xff2f4bd2" + "method": "0xff2f4bd2" } }, { @@ -2017,7 +2055,7 @@ "input": "0x400e3949", "output": "0x0000000000000000000000000000000000000000000000000000000000000005", "decoded": { - "methodID": "0x400e3949" + "method": "0x400e3949" } }, { @@ -2040,7 +2078,8 @@ "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b" ] @@ -2098,7 +2137,7 @@ } ], "decoded": { - "methodID": "0x612e45a3", + "method": "0x612e45a3", "args": [ "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -2113,7 +2152,7 @@ } ], "decoded": { - "methodID": "0xff2f4bd2" + "method": "0xff2f4bd2" } }, { @@ -2126,7 +2165,7 @@ "input": "0x400e3949", "output": "0x0000000000000000000000000000000000000000000000000000000000000006", "decoded": { - "methodID": "0x400e3949" + "method": "0x400e3949" } }, { @@ -2149,7 +2188,8 @@ "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b" ] @@ -2207,7 +2247,7 @@ } ], "decoded": { - "methodID": "0x612e45a3", + "method": "0x612e45a3", "args": [ "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -2222,7 +2262,7 @@ } ], "decoded": { - "methodID": "0xff2f4bd2" + "method": "0xff2f4bd2" } }, { @@ -2235,7 +2275,7 @@ "input": "0x400e3949", "output": "0x0000000000000000000000000000000000000000000000000000000000000007", "decoded": { - "methodID": "0x400e3949" + "method": "0x400e3949" } }, { @@ -2258,7 +2298,8 @@ "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b" ] @@ -2316,7 +2357,7 @@ } ], "decoded": { - "methodID": "0x612e45a3", + "method": "0x612e45a3", "args": [ "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -2331,7 +2372,7 @@ } ], "decoded": { - "methodID": "0xff2f4bd2" + "method": "0xff2f4bd2" } }, { @@ -2344,7 +2385,7 @@ "input": "0x400e3949", "output": "0x0000000000000000000000000000000000000000000000000000000000000008", "decoded": { - "methodID": "0x400e3949" + "method": "0x400e3949" } }, { @@ -2367,7 +2408,8 @@ "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b" ] @@ -2425,7 +2467,7 @@ } ], "decoded": { - "methodID": "0x612e45a3", + "method": "0x612e45a3", "args": [ "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -2440,7 +2482,7 @@ } ], "decoded": { - "methodID": "0xff2f4bd2" + "method": "0xff2f4bd2" } }, { @@ -2453,7 +2495,7 @@ "input": "0x400e3949", "output": "0x0000000000000000000000000000000000000000000000000000000000000009", "decoded": { - "methodID": "0x400e3949" + "method": "0x400e3949" } }, { @@ -2476,7 +2518,8 @@ "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b" ] @@ -2534,7 +2577,7 @@ } ], "decoded": { - "methodID": "0x612e45a3", + "method": "0x612e45a3", "args": [ "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -2549,7 +2592,7 @@ } ], "decoded": { - "methodID": "0xff2f4bd2" + "method": "0xff2f4bd2" } }, { @@ -2562,7 +2605,7 @@ "input": "0x400e3949", "output": "0x000000000000000000000000000000000000000000000000000000000000000a", "decoded": { - "methodID": "0x400e3949" + "method": "0x400e3949" } }, { @@ -2585,7 +2628,8 @@ "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f4a4", "decoded": { - "methodID": "0x70a08231", + "method": "0x70a08231", + "signature": "balanceOf(address)", "args": [ "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" ] @@ -2601,7 +2645,8 @@ "input": "0xa9059cbb0000000000000000000000007ccbc69292c7a6d7b538c91f3b283de97906cf3000000000000000000000000000000000000000000001010d8bfbbbe40fe7518c", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { - "methodID": "0xa9059cbb", + "method": "0xa9059cbb", + "signature": "transfer(address,uint256)", "args": [ "0x7ccbc69292C7A6D7B538c91F3B283De97906cF30", "1213898080632835664204172" @@ -2618,7 +2663,8 @@ "input": "0xa9059cbb0000000000000000000000001b9ec8ba24630b75a7a958153ffff56dd6d4b6a200000000000000000000000000000000000000000001010d8bfbbbe40fe7518c", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { - "methodID": "0xa9059cbb", + "method": "0xa9059cbb", + "signature": "transfer(address,uint256)", "args": [ "0x1B9ec8bA24630B75a7A958153FfFF56dD6D4B6A2", "1213898080632835664204172" @@ -2635,7 +2681,8 @@ "input": "0xa9059cbb000000000000000000000000c3a2c744ad1f5253c736875b93bacce5b01b060b00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { - "methodID": "0xa9059cbb", + "method": "0xa9059cbb", + "signature": "transfer(address,uint256)", "args": [ "0xc3A2C744ad1F5253C736875B93bAcCe5B01B060B", "1213898080632835664204172" @@ -2644,12 +2691,12 @@ } ], "decoded": { - "methodID": "0x975057e7" + "method": "0x975057e7" } } ], "decoded": { - "methodID": "0xbe9a6555" + "method": "0xbe9a6555" }, "blockContext": { "number": 1881284, @@ -2661,45 +2708,54 @@ }, "balanceChanges": [ { - "address": "0xbe3ae5cb97c253dda67181c6e34e43f5c275e08b", + "address": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", "balanceChanges": [ { - "delta": "-65798375000000000", + "delta": "-1820847120949253496306323", "asset": { - "address": "0x0000000000000000000000000000000000000000", - "type": "eth", - "name": "Ether", - "symbol": "ETH", - "decimals": 18 + "address": "0xc0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89" }, "breakdown": [ { - "counterparty": "0x0000000000000000000000000000000000000000", - "amount": "-43984055500800" - }, + "counterparty": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", + "amount": "-1820847120949253496306323" + } + ] + }, + { + "delta": "-1820847120949253496306294", + "asset": { + "address": "0xf835a0247b0063c04ef22006ebe57c5f11977cc4" + }, + "breakdown": [ { - "counterparty": "0xea674fdde714fd979de3edf0f56aa9716b898ec8", - "amount": "-65754390944499200" + "counterparty": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", + "amount": "-1820847120949253496306294" } ] } ] }, { - "address": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", + "address": "0x1b9ec8ba24630b75a7a958153ffff56dd6d4b6a2", "balanceChanges": [ { - "delta": "1820847120949253496306323", + "delta": "1213898080632835664204172", "asset": { - "address": "0xc0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89" + "address": "0x304a554a310c7e546dfe434669c62820b7d83490" }, "breakdown": [ { - "counterparty": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "amount": "1820847120949253496306323" + "counterparty": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", + "amount": "1213898080632835664204172" } ] - }, + } + ] + }, + { + "address": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", + "balanceChanges": [ { "delta": "0", "asset": { @@ -2744,6 +2800,18 @@ } ] }, + { + "delta": "1820847120949253496306323", + "asset": { + "address": "0xc0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89" + }, + "breakdown": [ + { + "counterparty": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", + "amount": "1820847120949253496306323" + } + ] + }, { "delta": "1820847120949253496306294", "asset": { @@ -2784,58 +2852,49 @@ ] }, { - "address": "0xda4a4626d3e16e094de3225a751aab7128e96526", + "address": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", "balanceChanges": [ { - "delta": "100", + "delta": "0", "asset": { "address": "0x304a554a310c7e546dfe434669c62820b7d83490" }, "breakdown": [ { - "counterparty": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f", - "amount": "100" - } - ] - } - ] - }, - { - "address": "0x7ccbc69292c7a6d7b538c91f3b283de97906cf30", - "balanceChanges": [ - { - "delta": "1213898080632835664204172", - "asset": { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490" - }, - "breakdown": [ + "counterparty": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", + "amount": "1821204263806396353449165" + }, { "counterparty": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "amount": "1213898080632835664204172" + "amount": "-1821204263806396353449164" + }, + { + "counterparty": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f", + "amount": "-1" } ] } ] }, { - "address": "0xc3a2c744ad1f5253c736875b93bacce5b01b060b", + "address": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", "balanceChanges": [ { - "delta": "1213898080632835664204172", + "delta": "1", "asset": { "address": "0x304a554a310c7e546dfe434669c62820b7d83490" }, "breakdown": [ { "counterparty": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "amount": "1213898080632835664204172" + "amount": "1" } ] } ] }, { - "address": "0x1b9ec8ba24630b75a7a958153ffff56dd6d4b6a2", + "address": "0x7ccbc69292c7a6d7b538c91f3b283de97906cf30", "balanceChanges": [ { "delta": "1213898080632835664204172", @@ -2852,10 +2911,10 @@ ] }, { - "address": "0xea674fdde714fd979de3edf0f56aa9716b898ec8", + "address": "0xbe3ae5cb97c253dda67181c6e34e43f5c275e08b", "balanceChanges": [ { - "delta": "65754390944499200", + "delta": "-65798375000000000", "asset": { "address": "0x0000000000000000000000000000000000000000", "type": "eth", @@ -2865,20 +2924,24 @@ }, "breakdown": [ { - "counterparty": "0xbe3ae5cb97c253dda67181c6e34e43f5c275e08b", - "amount": "65754390944499200" + "counterparty": "0x0000000000000000000000000000000000000000", + "amount": "-43984055500800" + }, + { + "counterparty": "0xea674fdde714fd979de3edf0f56aa9716b898ec8", + "amount": "-65754390944499200" } ] } ] }, { - "address": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", + "address": "0xc0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89", "balanceChanges": [ { "delta": "-1820847120949253496306323", "asset": { - "address": "0xc0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89" + "address": "0x304a554a310c7e546dfe434669c62820b7d83490" }, "breakdown": [ { @@ -2886,92 +2949,76 @@ "amount": "-1820847120949253496306323" } ] - }, - { - "delta": "-1820847120949253496306294", - "asset": { - "address": "0xf835a0247b0063c04ef22006ebe57c5f11977cc4" - }, - "breakdown": [ - { - "counterparty": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "amount": "-1820847120949253496306294" - } - ] } ] }, { - "address": "0xc0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89", + "address": "0xda4a4626d3e16e094de3225a751aab7128e96526", "balanceChanges": [ { - "delta": "-1820847120949253496306323", + "delta": "100", "asset": { "address": "0x304a554a310c7e546dfe434669c62820b7d83490" }, "breakdown": [ { - "counterparty": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "amount": "-1820847120949253496306323" + "counterparty": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f", + "amount": "100" } ] } ] }, { - "address": "0xf835a0247b0063c04ef22006ebe57c5f11977cc4", + "address": "0xea674fdde714fd979de3edf0f56aa9716b898ec8", "balanceChanges": [ { - "delta": "-1820847120949253496306294", + "delta": "65754390944499200", "asset": { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490" + "address": "0x0000000000000000000000000000000000000000", + "type": "eth", + "name": "Ether", + "symbol": "ETH", + "decimals": 18 }, "breakdown": [ { - "counterparty": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "amount": "-1820847120949253496306294" + "counterparty": "0xbe3ae5cb97c253dda67181c6e34e43f5c275e08b", + "amount": "65754390944499200" } ] } ] }, { - "address": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", + "address": "0xf835a0247b0063c04ef22006ebe57c5f11977cc4", "balanceChanges": [ { - "delta": "0", + "delta": "-1820847120949253496306294", "asset": { "address": "0x304a554a310c7e546dfe434669c62820b7d83490" }, "breakdown": [ { "counterparty": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "amount": "1821204263806396353449165" - }, - { - "counterparty": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "amount": "-1821204263806396353449164" - }, - { - "counterparty": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f", - "amount": "-1" + "amount": "-1820847120949253496306294" } ] } ] }, { - "address": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", + "address": "0xc3a2c744ad1f5253c736875b93bacce5b01b060b", "balanceChanges": [ { - "delta": "1", + "delta": "1213898080632835664204172", "asset": { "address": "0x304a554a310c7e546dfe434669c62820b7d83490" }, "breakdown": [ { "counterparty": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "amount": "1" + "amount": "1213898080632835664204172" } ] } From 19cd7d6bd7f2ff18a859a0145aacf5566c18d609 Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Tue, 19 Sep 2023 22:02:39 -0400 Subject: [PATCH 18/40] fix: Update go.sum. --- go.sum | 478 ++++++++++++--------------------------------------------- 1 file changed, 99 insertions(+), 379 deletions(-) diff --git a/go.sum b/go.sum index 9c6fd74e4a1b..81614dc14650 100644 --- a/go.sum +++ b/go.sum @@ -1,36 +1,4 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1 h1:qoVeMsc9/fh/yhxVaA0obYjVH/oI/ihrOoMwsLS9KSA= github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1/go.mod h1:fBF9PQNqB8scdgpZ3ufzaLntG0AG7C1WjPMsiFOmfHM= @@ -40,13 +8,11 @@ github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0 h1:Px2UA+2RvSSvv+RvJ github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0/go.mod h1:tPaiy8S5bQ+S5sOiDlINkp7+Ef339+Nz5L5XO+cnOHo= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= -github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= -github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= -github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= +github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= +github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= +github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= -github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= @@ -55,11 +21,6 @@ github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9 github.com/VictoriaMetrics/fastcache v1.6.0 h1:C/3Oi3EiBCqufydp1neRZkqcwmEiuRT9c3fqvvgKm5o= github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= @@ -82,12 +43,10 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.1.1/go.mod h1:Wi0EBZwiz/K44YliU0EKxq github.com/aws/smithy-go v1.1.0 h1:D6CSsM3gdxaGaqXnPgOBCeL6Mophqzu7KJOu7zW78sU= github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bits-and-blooms/bitset v1.5.0 h1:NpE8frKRLGHIcEzkR+gZhiioW1+WbYV6fKwD6ZIpQT8= -github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bits-and-blooms/bitset v1.7.0 h1:YjAGVd3XmtK9ktAbX8Zg2g2PwLIMjGREZJHlV4j7NEo= +github.com/bits-and-blooms/bitset v1.7.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k= github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= @@ -95,37 +54,31 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cloudflare-go v0.14.0 h1:gFqGlGl/5f9UGXAaKapCGUfaTCgRKKnzu2VvzMZlOFA= github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cockroachdb/datadriven v1.0.0/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/datadriven v1.0.3-0.20230801171734-e384cf455877 h1:1MLK4YpFtIEo3ZtMA5C795Wtv5VuUnrXX7mQG+aHg6o= -github.com/cockroachdb/errors v1.6.1/go.mod h1:tm6FTP5G81vwJ5lC0SizQo374JNCOPrHyXGitRJoDqM= -github.com/cockroachdb/errors v1.8.1 h1:A5+txlVZfOqFBDa4mGz2bUWSp0aHElvHX2bKkdbQu+Y= -github.com/cockroachdb/errors v1.8.1/go.mod h1:qGwQn6JmZ+oMjuLwjWzUNqblqk0xl4CVV3SQbGwK7Ac= -github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f h1:o/kfcElHqOiXqcou5a3rIlMc7oJbMQkeLk0VQJ7zgqY= -github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= +github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= +github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= +github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= github.com/cockroachdb/pebble v0.0.0-20230906160148-46873a6a7a06 h1:T+Np/xtzIjYM/P5NAw0e2Rf1FGvzDau1h54MKvx8G7w= github.com/cockroachdb/pebble v0.0.0-20230906160148-46873a6a7a06/go.mod h1:bynZ3gvVyhlvjLI7PT6dmZ7g76xzJ7HpxfjgkzCGz6s= -github.com/cockroachdb/redact v1.0.8 h1:8QG/764wK+vmEYoOlfobpe12EQcS81ukx/a4hdVMxNw= -github.com/cockroachdb/redact v1.0.8/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= -github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2 h1:IKgmqgMQlVJIZj19CdocBeSfSaiCbEBZGKODaixqtHM= -github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk0R8eg+OTkcqI6baNH4xAkpiYVvQ= +github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= +github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= -github.com/consensys/gnark-crypto v0.10.0 h1:zRh22SR7o4K35SoNqouS9J/TKHTyU2QWaj5ldehyXtA= -github.com/consensys/gnark-crypto v0.10.0/go.mod h1:Iq/P3HHl0ElSjsg2E1gsMwhAyxnxoKK5nVyZKd+/KhU= +github.com/consensys/gnark-crypto v0.11.2 h1:GJjjtWJ+db1xGao7vTsOgAOGgjfPe7eRGPL+xxMX0qE= +github.com/consensys/gnark-crypto v0.11.2/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -170,20 +123,21 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/ethereum/c-kzg-4844 v0.3.1 h1:sR65+68+WdnMKxseNWxSJuAv2tsUrihTpVBTfM/U5Zg= github.com/ethereum/c-kzg-4844 v0.3.1/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= -github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e h1:bBLctRc7kr01YGvaDfgLbTwjFNW5jdp5y5rj8XXBHfY= github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e/go.mod h1:AzA8Lj6YtixmJWL+wkKoBGsLWy9gFrAzi4g+5bCKwpY= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= -github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= +github.com/flashbots/go-boost-utils v1.7.1 h1:JN0JFOCuuQoPhyZEaFxFHC2dWVScixItJ2nijzfE6IQ= +github.com/flashbots/go-boost-utils v1.7.1/go.mod h1:O2LUD1QAqi1oMzU1mtj7f1NMunNySJizQGrw7xujSe8= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= @@ -196,22 +150,16 @@ github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x github.com/gballet/go-verkle v0.0.0-20230607174250-df487255f46b h1:vMT47RYsrftsHSTQhqXwC3BYflo38OLC3Y4LtXtLyU0= github.com/gballet/go-verkle v0.0.0-20230607174250-df487255f46b/go.mod h1:CDncRYVRSDqwakm282WEkjfaAj1hxU/v5RXxk5nXOiI= github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= +github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= +github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= +github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= -github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY= github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= @@ -219,7 +167,6 @@ github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34 github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= @@ -228,30 +175,19 @@ github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/E github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.3.0 h1:kHL1vqdqWNfATmA0FNMdmZNMyZI1U6O31X4rlIPoBog= github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -260,53 +196,38 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa h1:Q75Upo5UN4JbPFURXZ8nLKYUvF85dyFRop/vQ0Rv+64= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= @@ -314,7 +235,7 @@ github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLt github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 h1:3JQNjnMRil1yD0IfZKHF9GxxWKDJGj8I0IqOUol//sw= @@ -326,8 +247,7 @@ github.com/holiman/uint256 v1.2.3/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZm github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= -github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -339,7 +259,8 @@ github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 h1:W9WBk7 github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= +github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= +github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= @@ -347,52 +268,41 @@ github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 h1:TMtDYDHKYY github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267/go.mod h1:h1nSAbGFqGVzn6Jyl1R/iCcBUHN4g+gW1u9CoBTrb9E= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= -github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= -github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/karalabe/usb v0.0.3-0.20230711191512-61db3e06439c h1:AqsttAyEyIEsNz5WLRwuRwjiT5CMDUfLk6cFJDVPebs= github.com/karalabe/usb v0.0.3-0.20230711191512-61db3e06439c/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= -github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= -github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= -github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= -github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= +github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= +github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= +github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= +github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= +github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= github.com/kilic/bls12-381 v0.1.0 h1:encrdjqKMEvabVQ7qYOKu1OvhqpK4s47wDYtNiPtlp4= github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= +github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= @@ -403,28 +313,30 @@ github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIG github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= -github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= -github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= @@ -434,25 +346,23 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/naoina/go-stringutil v0.1.0 h1:rCUeRUHjBjGTSHl0VC00jUPLz8/F9dDzYI70Hzifhks= github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 h1:shk/vn9oCoOTmwcouEdwIeOtOGA/ELRUw/GwvxwfT+0= github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= -github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= -github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= @@ -465,41 +375,29 @@ github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQm github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.0 h1:C+UIj/QWtmqY13Arb8kwMt5j34/0Z2iKamrJ+ryC0Gg= -github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= +github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a h1:CmF68hwI0XsOQ5UwlBopMi2Ow4Pbg32akc4KIVCOm+Y= -github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= +github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7 h1:cZC+usqsYgHtlBaGulVnZ1hfKAi8iWtujBnRLQE698c= github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7/go.mod h1:IToEjHuttnUzwZI5KBSM/LOOW3qLbbrHOEfp3SbECGY= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= @@ -507,14 +405,11 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= @@ -526,18 +421,13 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= @@ -549,7 +439,9 @@ github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9f github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= @@ -569,98 +461,52 @@ github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmv github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.uber.org/automaxprocs v1.5.2 h1:2LxUOGiR3O6tw8ui5sZa2LAaHnsviZdVOUZw4fvbnME= go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20230810033253-352e893a4cad h1:g0bG7Z4uG+OgH2QDODnjp6ggkk1bJDsINcuWmJN1iJU= golang.org/x/exp v0.0.0-20230810033253-352e893a4cad/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -668,76 +514,43 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -745,11 +558,16 @@ golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -761,9 +579,7 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -773,132 +589,45 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -907,13 +636,11 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -923,6 +650,7 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= +gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= @@ -932,11 +660,11 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= @@ -944,14 +672,6 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= From bddc6376cb2ac27291275c694af130b2a544a72c Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Tue, 19 Sep 2023 22:02:58 -0400 Subject: [PATCH 19/40] fix,tests: Fix blocknative tracer tests. --- eth/tracers/internal/tracetest/txnOpCodeTracer_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eth/tracers/internal/tracetest/txnOpCodeTracer_test.go b/eth/tracers/internal/tracetest/txnOpCodeTracer_test.go index 1387d65d42cb..0b8849f604cd 100644 --- a/eth/tracers/internal/tracetest/txnOpCodeTracer_test.go +++ b/eth/tracers/internal/tracetest/txnOpCodeTracer_test.go @@ -88,7 +88,7 @@ func testTxnOpCodeTracer(tracerName string, dirPath string, t *testing.T) { BaseFee: baseFee, Random: test.Context.Random, } - _, statedb = tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false) + _, _, statedb = tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme) ) tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), test.TracerConfig) if err != nil { From 46932101cefb81b9a3cfdf795d6cec44e8d374bb Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Mon, 18 Sep 2023 12:51:17 -0400 Subject: [PATCH 20/40] tests: Make tracer tests work as benchmarks. --- .../blocknative/decoder/calldata_test.go | 2 +- .../tracetest/txnOpCodeTracer_test.go | 259 +++++++++++++----- 2 files changed, 190 insertions(+), 71 deletions(-) diff --git a/eth/tracers/blocknative/decoder/calldata_test.go b/eth/tracers/blocknative/decoder/calldata_test.go index f7aebe26d8e9..a32de115e0b4 100644 --- a/eth/tracers/blocknative/decoder/calldata_test.go +++ b/eth/tracers/blocknative/decoder/calldata_test.go @@ -146,7 +146,7 @@ func executeTests(t testing.TB, tt decodeCallDataTest) { gotJSON, _ := json.Marshal(got) wantJSON, _ := json.Marshal(tt.want) - require.Equal(t, string(gotJSON), string(wantJSON)) + require.Equal(t, string(wantJSON), string(gotJSON)) } func parseBigInt(s string) *big.Int { diff --git a/eth/tracers/internal/tracetest/txnOpCodeTracer_test.go b/eth/tracers/internal/tracetest/txnOpCodeTracer_test.go index 5860a2de1e65..d2bb2f7b3b9a 100644 --- a/eth/tracers/internal/tracetest/txnOpCodeTracer_test.go +++ b/eth/tracers/internal/tracetest/txnOpCodeTracer_test.go @@ -28,105 +28,224 @@ type txnOpCodeTracerTest struct { Input string `json:"input"` TracerConfig json.RawMessage `json:"tracerConfig"` Result *blocknative.Trace `json:"result"` + + name string + evm *vm.EVM + tx *types.Transaction + msg *core.Message + tracer tracers.Tracer + baseFee *big.Int + blockContext vm.BlockContext + signer types.Signer + origin common.Address + txContext vm.TxContext } func TestTxnOpCodeTracer(t *testing.T) { log.Root().SetHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(true))) + testTxnOpCodeTracer("txnOpCode_tracer", t) + testTxnOpCodeTracer("txnOpCode_tracer_with_netbalchanges", t) +} - testTxnOpCodeTracer("txnOpCodeTracer", "txnOpCode_tracer", t) - testTxnOpCodeTracer("txnOpCodeTracer", "txnOpCode_tracer_with_netbalchanges", t) +func BenchmarkTxnOpCodeTracerWithoutDecoding(b *testing.B) { + benchmarkTxnOpCodeTracer(b, false, "txnOpCode_tracer", "txnOpCode_tracer_with_netbalchanges") +} +func BenchmarkTxnOpCodeTracerWithDecoding(b *testing.B) { + benchmarkTxnOpCodeTracer(b, true, "txnOpCode_tracer", "txnOpCode_tracer_with_netbalchanges") } -func testTxnOpCodeTracer(tracerName string, dirPath string, t *testing.T) { - files, err := os.ReadDir(filepath.Join("testdata", dirPath)) - if err != nil { - t.Fatalf("failed to retrieve tracer tgest suite: %v", err) - } - for _, file := range files { - if !strings.HasSuffix(file.Name(), ".json") { - continue +func benchmarkTxnOpCodeTracer(b *testing.B, decode bool, dirPaths ...string) { + testCases := []*txnOpCodeTracerTest{} + + for _, dirPath := range dirPaths { + files, err := os.ReadDir(filepath.Join("testdata", dirPath)) + if err != nil { + b.Fatal(err) } - file := file - t.Run(camel(strings.TrimSuffix(file.Name(), ".json")), func(t *testing.T) { - //t.Parallel() + for _, file := range files { var ( test = new(txnOpCodeTracerTest) tx = new(types.Transaction) ) - // Call tracer test found, read if from disk if blob, err := os.ReadFile(filepath.Join("testdata", dirPath, file.Name())); err != nil { - t.Fatalf("failed to read testcase: %v", err) + b.Fatal(err) } else if err := json.Unmarshal(blob, test); err != nil { - t.Fatalf("failed to parse testcase: %v", err) + b.Fatal(err) } - // Here we use unmarshalBinary as it can account for EIP2718 typed transactions in the tests if err := tx.UnmarshalBinary(common.FromHex(test.Input)); err != nil { - t.Fatalf("failed to parse testcase input: %v", err) + b.Fatal(err) } - baseFee := big.NewInt(0xFF0000) + baseFee := big.NewInt(0x0) if test.Context.BaseFee != 0 { baseFee = new(big.Int).SetUint64(uint64(test.Context.BaseFee)) } - // Configure a blockchain with the given prestate - var ( - signer = types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time)) - origin, _ = signer.Sender(tx) - txContext = vm.TxContext{ - Origin: origin, - GasPrice: tx.GasPrice(), - } - context = vm.BlockContext{ - CanTransfer: core.CanTransfer, - Transfer: core.Transfer, - Coinbase: test.Context.Miner, - BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)), - Time: uint64(test.Context.Time), - Difficulty: (*big.Int)(test.Context.Difficulty), - GasLimit: uint64(test.Context.GasLimit), - BaseFee: baseFee, - Random: test.Context.Random, - } - _, _, statedb = tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme) - ) - tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), test.TracerConfig) - if err != nil { - t.Fatalf("failed to create call tracer: %v", err) - } - evm := vm.NewEVM(context, txContext, statedb, test.Genesis.Config, vm.Config{Tracer: tracer}) - msg, err := core.TransactionToMessage(tx, signer, context.BaseFee) - if err != nil { - t.Fatalf("failed to prepare transaction for tracing: %v", err) + test.name = camel(strings.TrimSuffix(file.Name(), ".json")) + test.tx = tx + test.baseFee = baseFee + + test.signer = types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time)) + test.blockContext = vm.BlockContext{ + CanTransfer: core.CanTransfer, + Transfer: core.Transfer, + Coinbase: test.Context.Miner, + BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)), + Time: uint64(test.Context.Time), + Difficulty: (*big.Int)(test.Context.Difficulty), + GasLimit: uint64(test.Context.GasLimit), + BaseFee: test.baseFee, + Random: test.Context.Random, } - st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas())) - if _, err = st.TransitionDb(); err != nil { - t.Fatalf("failed to execute transaction: %v", err) + + test.origin, _ = test.signer.Sender(tx) + test.txContext = vm.TxContext{ + Origin: test.origin, + GasPrice: tx.GasPrice(), } - res, err := tracer.GetResult() - if err != nil { - t.Fatalf("failed to retrieve trace result: %v", err) + testCases = append(testCases, test) + } + } + + for i := 0; i < b.N; i++ { + test := testCases[i%len(testCases)] + tx := test.tx + + _, _, statedb := tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme) + opts := blocknative.TracerOpts{Decode: decode} + tracer, err := blocknative.NewTxnOpCodeTracerWithOpts(opts) + if err != nil { + b.Fatal(err) + } + + evm := vm.NewEVM(test.blockContext, test.txContext, statedb, test.Genesis.Config, vm.Config{Tracer: tracer}) + msg, err := core.TransactionToMessage(tx, test.signer, test.blockContext.BaseFee) + if err != nil { + b.Fatal(err) + } + + test.evm = evm + test.msg = msg + test.tracer = tracer + + executeTestCase(test, b, false) + + } +} + +func testTxnOpCodeTracer(dirPath string, t *testing.T) { + testsCases, err := loadTestTxs(dirPath) + if err != nil { + t.Fatal(err) + } + + for _, test := range testsCases { + t.Run(test.name, func(t *testing.T) { + executeTestCase(test, t, true) + }) + } +} + +func loadTestTxs(dirPath string) ([]*txnOpCodeTracerTest, error) { + files, err := os.ReadDir(filepath.Join("testdata", dirPath)) + if err != nil { + return nil, err + } + + testCases := make([]*txnOpCodeTracerTest, 0, len(files)) + for _, file := range files { + if !strings.HasSuffix(file.Name(), ".json") { + continue + } + + var ( + test = new(txnOpCodeTracerTest) + tx = new(types.Transaction) + ) + if blob, err := os.ReadFile(filepath.Join("testdata", dirPath, file.Name())); err != nil { + return nil, err + } else if err := json.Unmarshal(blob, test); err != nil { + return nil, err + } + if err := tx.UnmarshalBinary(common.FromHex(test.Input)); err != nil { + return nil, err + } + + baseFee := big.NewInt(0xFF0000) + if test.Context.BaseFee != 0 { + baseFee = new(big.Int).SetUint64(uint64(test.Context.BaseFee)) + } + + // Configure a blockchain with the given prestate + var ( + signer = types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time)) + origin, _ = signer.Sender(tx) + txContext = vm.TxContext{ + Origin: origin, + GasPrice: tx.GasPrice(), } - ret := new(blocknative.Trace) - if err := json.Unmarshal(res, ret); err != nil { - t.Fatalf("failed to unmarshal trace result: %v", err) + context = vm.BlockContext{ + CanTransfer: core.CanTransfer, + Transfer: core.Transfer, + Coinbase: test.Context.Miner, + BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)), + Time: uint64(test.Context.Time), + Difficulty: (*big.Int)(test.Context.Difficulty), + GasLimit: uint64(test.Context.GasLimit), + BaseFee: baseFee, + Random: test.Context.Random, } + _, _, statedb = tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme) + ) + tracer, err := blocknative.NewTxnOpCodeTracer(test.TracerConfig) + if err != nil { + return nil, err + } + evm := vm.NewEVM(context, txContext, statedb, test.Genesis.Config, vm.Config{Tracer: tracer}) + msg, err := core.TransactionToMessage(tx, signer, context.BaseFee) + if err != nil { + return nil, err + } - if !tracesEqual(ret, test.Result) { - // Below are prints to show differences if we fail, can always just check against the specific test json files too! - //fmt.Println("Trace return: ") - //x, _ := json.Marshal(ret) - ////x, _ := json.MarshalIndent(ret, "", " ") - //y, _ := json.Marshal(test.Result) - //fmt.Println(string(x)) - //fmt.Println("test.Result") - //fmt.Println(string(y)) - t.Fatal("traces mismatch") - //t.Fatalf("trace mismatch: \nhave %+v\nwant %+v", ret, test.Result) - } - }) + test.name = camel(strings.TrimSuffix(file.Name(), ".json")) + test.evm = evm + test.tx = tx + test.msg = msg + test.tracer = tracer + testCases = append(testCases, test) + } + + return testCases, nil +} + +func executeTestCase(test *txnOpCodeTracerTest, t testing.TB, checkResult bool) { + st := core.NewStateTransition(test.evm, test.msg, new(core.GasPool).AddGas(test.tx.Gas())) + if _, err := st.TransitionDb(); err != nil { + t.Fatalf("failed to execute transaction: %v", err) + } + + res, err := test.tracer.GetResult() + if err != nil { + t.Fatalf("failed to retrieve trace result: %v", err) + } + ret := new(blocknative.Trace) + if err := json.Unmarshal(res, ret); err != nil { + t.Fatalf("failed to unmarshal trace result: %v", err) + } + + if checkResult && !tracesEqual(ret, test.Result) { + // Below are prints to show differences if we fail, can always just check against the specific test json files too! + //fmt.Println("Trace return: ") + //x, _ := json.Marshal(ret) + ////x, _ := json.MarshalIndent(ret, "", " ") + //y, _ := json.Marshal(test.Result) + //fmt.Println(string(x)) + //fmt.Println("test.Result") + //fmt.Println(string(y)) + t.Fatal("traces mismatch") + //t.Fatalf("trace mismatch: \nhave %+v\nwant %+v", ret, test.Result) } } From 22652ad54c14ad111b13ae5c55f99869eb216423 Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Tue, 19 Sep 2023 19:13:48 -0400 Subject: [PATCH 21/40] fix: Fix out of bounds read. --- eth/tracers/blocknative/decoder/calldata.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/eth/tracers/blocknative/decoder/calldata.go b/eth/tracers/blocknative/decoder/calldata.go index dbe89b6a9293..b5756b47f0ba 100644 --- a/eth/tracers/blocknative/decoder/calldata.go +++ b/eth/tracers/blocknative/decoder/calldata.go @@ -33,8 +33,12 @@ func decodeCallData(sender common.Address, contract *Contract, input []byte) (*C // scanWord gets the next 32 bytes and advances the index scanWord := func() []byte { - word := input[idx : idx+32] - idx += 32 + endIdx := idx + 32 + if endIdx > inputLen { + endIdx = inputLen + } + word := input[idx:endIdx] + idx = endIdx return word } From e16640dbe89676ed5b025cfbace4f2462a083d64 Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Tue, 19 Sep 2023 19:19:21 -0400 Subject: [PATCH 22/40] tweak: Cache traces in trace stream. --- eth/filters/trace_api.go | 54 ++++++++++++++++++-- eth/tracers/blocknative/cache/trace_cache.go | 27 ++++++++++ 2 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 eth/tracers/blocknative/cache/trace_cache.go diff --git a/eth/filters/trace_api.go b/eth/filters/trace_api.go index 878bc7ced1d7..898bcb4cbc6a 100644 --- a/eth/filters/trace_api.go +++ b/eth/filters/trace_api.go @@ -5,6 +5,10 @@ import ( "encoding/json" "errors" "fmt" + "math/big" + "sync" + "time" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus/misc/eip1559" @@ -14,10 +18,10 @@ import ( "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/eth/tracers/blocknative" + "github.com/ethereum/go-ethereum/eth/tracers/blocknative/cache" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" - "math/big" ) var defaultTxTraceOpts = blocknative.TracerOpts{ @@ -227,13 +231,45 @@ func (api *FilterAPI) NewFullBlocksWithTrace(ctx context.Context, tracerOptsJSON return rpcSub, nil } +var ( + txTraceLocksMu sync.RWMutex + txTraceLocks = make(map[common.Hash]chan struct{}) + txTraceLocksTimeout = 1 * time.Second +) + // traceTx traces a transaction with the given contexts. func traceTx(message *core.Message, txCtx *tracers.Context, vmctx vm.BlockContext, chainConfig *params.ChainConfig, statedb *state.StateDB, tracerOpts blocknative.TracerOpts) (*blocknative.Trace, error) { + // Check cached trace or an in-progress trace before executing. + trace, ok := cache.GetTrace(txCtx.TxHash, txCtx.BlockHash) + if ok { + return trace, nil + } + + // Check if there is an in-progress trace for this transaction. + // If there is then wait for it to finish and return it. + // If there is not then lock the trace and create a new one. + // Don't wait longer than a second for the cache to finish. + txTraceLocksMu.Lock() + if unlockCh, ok := txTraceLocks[txCtx.TxHash]; ok { + timeOut := time.NewTimer(txTraceLocksTimeout) + select { + case <-unlockCh: + if trace, ok := cache.GetTrace(txCtx.TxHash, txCtx.BlockHash); ok { + txTraceLocksMu.Unlock() + return trace, nil + } + case <-timeOut.C: + } + } + unlockCh := make(chan struct{}) + txTraceLocks[txCtx.TxHash] = unlockCh + txTraceLocksMu.Unlock() + + // No trace in cache or in-progress so create a new one. tracer, err := blocknative.NewTxnOpCodeTracerWithOpts(tracerOpts) if err != nil { return nil, err } - txContext := core.NewEVMTxContext(message) vmenv := vm.NewEVM(vmctx, txContext, statedb, chainConfig, vm.Config{Tracer: tracer}) statedb.SetTxContext(txCtx.TxHash, txCtx.TxIndex) @@ -241,7 +277,19 @@ func traceTx(message *core.Message, txCtx *tracers.Context, vmctx vm.BlockContex if _, err = core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.GasLimit)); err != nil { return nil, fmt.Errorf("tracing failed: %w", err) } - return tracer.GetTrace() + trace, err = tracer.GetTrace() + if err != nil { + return nil, err + } + + // Cache the result and unlock/delete the trace lock. + cache.PutTrace(txCtx.TxHash, txCtx.BlockHash, trace) + close(unlockCh) + txTraceLocksMu.Lock() + delete(txTraceLocks, txCtx.TxHash) + txTraceLocksMu.Unlock() + + return trace, err } // traceBlock traces all transactions in a block. diff --git a/eth/tracers/blocknative/cache/trace_cache.go b/eth/tracers/blocknative/cache/trace_cache.go new file mode 100644 index 000000000000..afdc4f0cbedc --- /dev/null +++ b/eth/tracers/blocknative/cache/trace_cache.go @@ -0,0 +1,27 @@ +package cache + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/lru" + "github.com/ethereum/go-ethereum/eth/tracers/blocknative" +) + +var ( + traceCacheSize = 10_000 + traceCache = lru.NewCache[[64]byte, *blocknative.Trace](traceCacheSize) +) + +func PutTrace(blockHash, txHash common.Hash, trace *blocknative.Trace) bool { + return traceCache.Add(traceCacheKey(blockHash, txHash), trace) +} + +func GetTrace(blockHash, txHash common.Hash) (*blocknative.Trace, bool) { + return traceCache.Get(traceCacheKey(blockHash, txHash)) +} + +func traceCacheKey(blockHash, txHash common.Hash) [64]byte { + key := [64]byte{} + copy(key[:32], blockHash[:]) + copy(key[32:], txHash[:]) + return key +} From 8060e523cbc0e7767141deb62649548c209e52d4 Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Wed, 20 Sep 2023 00:21:02 -0400 Subject: [PATCH 23/40] tweak: Use a much more performant addrToHex method. --- eth/tracers/blocknative/utils.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/eth/tracers/blocknative/utils.go b/eth/tracers/blocknative/utils.go index a45c7d0bdb1d..96d9262d4c72 100644 --- a/eth/tracers/blocknative/utils.go +++ b/eth/tracers/blocknative/utils.go @@ -1,9 +1,9 @@ package blocknative import ( + "encoding/hex" "math/big" "strconv" - "strings" "github.com/ethereum/go-ethereum/common" ) @@ -24,5 +24,8 @@ func uintToHex(n uint64) string { } func addrToHex(a common.Address) string { - return strings.ToLower(a.Hex()) + var buf [len(a)*2 + 2]byte + copy(buf[:2], "0x") + hex.Encode(buf[2:], a[:]) + return string(buf[:]) } From 969f969ebad220d289832dce1833b44b2e64167d Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Wed, 20 Sep 2023 18:42:18 -0400 Subject: [PATCH 24/40] refactor: Move decoderEVM to its own file. --- eth/tracers/blocknative/decoder_evm.go | 26 ++++++++++++++++++++++ eth/tracers/blocknative/txnOpCodeTracer.go | 20 ----------------- 2 files changed, 26 insertions(+), 20 deletions(-) create mode 100644 eth/tracers/blocknative/decoder_evm.go diff --git a/eth/tracers/blocknative/decoder_evm.go b/eth/tracers/blocknative/decoder_evm.go new file mode 100644 index 000000000000..75f762a95a51 --- /dev/null +++ b/eth/tracers/blocknative/decoder_evm.go @@ -0,0 +1,26 @@ +package blocknative + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" + "math" +) + +// decoderEVM contains the functionality required by the decoder from the EVM. +type decoderEVM struct { + *vm.EVM +} + +// GetCode returns the bytecode of the account with the given address, or nil +// if the account is not a contract. +func (d decoderEVM) GetCode(addr common.Address) []byte { + return d.StateDB.GetCode(addr) +} + +// CallCode executes the given method on the code at the given address. +func (d decoderEVM) CallCode(addr common.Address, method []byte) ([]byte, error) { + code := d.StateDB.GetCode(addr) + contract := vm.NewContract(vm.AccountRef(common.Address{}), vm.AccountRef(addr), common.Big0, math.MaxUint64) + contract.SetCallCode(&addr, d.StateDB.GetCodeHash(addr), code) + return d.Interpreter().Run(contract, method, false) +} diff --git a/eth/tracers/blocknative/txnOpCodeTracer.go b/eth/tracers/blocknative/txnOpCodeTracer.go index 7c89c050d980..19ebc35f16ac 100644 --- a/eth/tracers/blocknative/txnOpCodeTracer.go +++ b/eth/tracers/blocknative/txnOpCodeTracer.go @@ -3,7 +3,6 @@ package blocknative import ( "encoding/json" "fmt" - "math" "math/big" "sync/atomic" "time" @@ -261,22 +260,3 @@ func finalizeCallFrame(call *CallFrame, output []byte, gasUsed uint64, err error // The call was successful so decode the output. call.Output = bytesToHex(output) } - -type decoderEVM struct { - *vm.EVM -} - -func (d decoderEVM) GetCode(addr common.Address) []byte { - return d.StateDB.GetCode(addr) -} - -func (d decoderEVM) CallCode(addr common.Address, method []byte) ([]byte, error) { - code := d.StateDB.GetCode(addr) - contract := vm.NewContract(vm.AccountRef(common.Address{}), vm.AccountRef(addr), common.Big0, math.MaxUint64) - contract.SetCallCode(&addr, d.StateDB.GetCodeHash(addr), code) - ret, err := d.Interpreter().Run(contract, method, false) - if err != nil { - return nil, err - } - return ret, nil -} From bfc267e423a269681a3012b696da3e30ef66dc43 Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Thu, 21 Sep 2023 04:52:31 -0400 Subject: [PATCH 25/40] tests: Add micro-benchmark for decodeCallData. --- .../blocknative/decoder/calldata_test.go | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/eth/tracers/blocknative/decoder/calldata_test.go b/eth/tracers/blocknative/decoder/calldata_test.go index a32de115e0b4..d4599c84b26d 100644 --- a/eth/tracers/blocknative/decoder/calldata_test.go +++ b/eth/tracers/blocknative/decoder/calldata_test.go @@ -4,6 +4,8 @@ import ( "encoding/hex" "encoding/json" "math/big" + "os" + "path/filepath" "testing" "github.com/ethereum/go-ethereum/common" @@ -37,6 +39,85 @@ func BenchmarkDecodeCalldata(B *testing.B) { executeTests(B, tests[i%len(tests)]) } } +func BenchmarkDecodeCalldataWithStandardVectors(b *testing.B) { + testVectors, err := loadTestVectors() + require.NoError(b, err) + + calls := []*testCall{} + var addAllCalls func(calls []*testVector) + addAllCalls = func(tests []*testVector) { + for _, test := range tests { + input, err := hex.DecodeString(test.Input[2:]) + require.NoError(b, err) + value, _ := new(big.Int).SetString(test.Value, 10) + contract := &Contract{Type: contractTypesByName[test.Type]} + calls = append(calls, &testCall{ + contract: contract, + from: common.HexToAddress(test.From), + to: common.HexToAddress(test.To), + value: NewAmount(value), + input: input, + }) + addAllCalls(test.Calls) + } + } + for _, v := range testVectors { + addAllCalls(v.Calls) + } + + // Run the benchmark, decoding each call in turn. + var call testCall + for i := 0; i < b.N; i++ { + call = *calls[i%len(calls)] + _, _ = decodeCallData(call.from, call.contract, call.input) + } +} + +type testVector struct { + Type string `json:"type"` + From string `json:"from"` + To string `json:"to,omitempty"` + Value string `json:"value,omitempty"` + Input string `json:"input"` + Calls []*testVector `json:"calls,omitempty"` +} + +type testCall struct { + contract *Contract + from common.Address + to common.Address + value *Amount + input []byte +} + +func loadTestVectors() ([]*testVector, error) { + testVectorDirs := []string{ + "../../internal/tracetest/testdata/txnOpCode_tracer", + "../../internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges", + } + + var testVectors []*testVector + for _, dirPath := range testVectorDirs { + files, err := os.ReadDir(dirPath) + if err != nil { + return nil, err + } + + for _, file := range files { + test := new(struct { + Result *testVector `json:"result"` + }) + if blob, err := os.ReadFile(filepath.Join(dirPath, file.Name())); err != nil { + return nil, err + } else if err := json.Unmarshal(blob, test); err != nil { + return nil, err + } + + testVectors = append(testVectors, test.Result.Calls...) + } + } + return testVectors, nil +} func getTestCases() []decodeCallDataTest { return []decodeCallDataTest{ From efecb5a4101b52a3d7bbfdb3da1b210987deb319 Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Thu, 21 Sep 2023 05:25:28 -0400 Subject: [PATCH 26/40] tweak: Use int nanoseconds instead of string for duration. --- eth/tracers/blocknative/blocknative.go | 2 +- eth/tracers/blocknative/txnOpCodeTracer.go | 4 +--- eth/tracers/internal/tracetest/txnOpCodeTracer_test.go | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/eth/tracers/blocknative/blocknative.go b/eth/tracers/blocknative/blocknative.go index cdfaf685fcc2..5f3abff0dd63 100644 --- a/eth/tracers/blocknative/blocknative.go +++ b/eth/tracers/blocknative/blocknative.go @@ -30,7 +30,7 @@ type Trace struct { CallFrame BlockContext *BlockContext `json:"blockContext,omitempty"` Logs []CallLog `json:"logs,omitempty"` - Time string `json:"time,omitempty"` + Time int64 `json:"time,omitempty"` BalanceChanges decoder.NetBalanceChanges `json:"balanceChanges"` } diff --git a/eth/tracers/blocknative/txnOpCodeTracer.go b/eth/tracers/blocknative/txnOpCodeTracer.go index 19ebc35f16ac..eca7f8622805 100644 --- a/eth/tracers/blocknative/txnOpCodeTracer.go +++ b/eth/tracers/blocknative/txnOpCodeTracer.go @@ -2,7 +2,6 @@ package blocknative import ( "encoding/json" - "fmt" "math/big" "sync/atomic" "time" @@ -154,8 +153,7 @@ func (t *txnOpCodeTracer) CaptureEnd(output []byte, gasUsed uint64, err error) { } // Add total time duration for this trace request - elapsedTime := time.Now().Sub(t.startTime) - t.trace.Time = fmt.Sprintf("%v", elapsedTime) + t.trace.Time = time.Now().Sub(t.startTime).Nanoseconds() } // CaptureState implements the EVMLogger interface to trace a single step of VM execution. diff --git a/eth/tracers/internal/tracetest/txnOpCodeTracer_test.go b/eth/tracers/internal/tracetest/txnOpCodeTracer_test.go index d2bb2f7b3b9a..73ec2b770b98 100644 --- a/eth/tracers/internal/tracetest/txnOpCodeTracer_test.go +++ b/eth/tracers/internal/tracetest/txnOpCodeTracer_test.go @@ -265,8 +265,8 @@ func (a BalanceChangesByAssetAddress) Less(i, j int) bool { func tracesEqual(x, y *blocknative.Trace) bool { // Clear out non-deterministic time - x.Time = "" - y.Time = "" + x.Time = 0 + y.Time = 0 // Sort the balance changes because we don't care about the order of the // breakdown. From 856d7245f2bb2b5341b2d29e562a783b1ac2d835 Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Thu, 21 Sep 2023 07:39:29 -0400 Subject: [PATCH 27/40] refactor: Rename blocknative.txnOpCodeTracer -> blocknative.tracer. --- core/state_processor.go | 2 +- eth/filters/trace_api.go | 2 +- .../{txnopcodetracer_readme.md => README.md} | 2 +- eth/tracers/blocknative/blocknative.go | 4 + .../blocknative/decoder/calldata_test.go | 7 +- eth/tracers/blocknative/tracer.go | 261 ++++++++++++++++++ eth/tracers/blocknative/txnOpCodeTracer.go | 260 ----------------- ...CodeTracer_test.go => blocknative_test.go} | 53 ++-- .../block_random.json | 0 .../create.json | 0 .../deep_calls.json | 0 .../delegatecall.json | 0 .../inner_create_oog_outer_throw.json | 0 .../inner_instafail.json | 0 .../inner_revert_reason.json | 0 .../inner_throw_outer_revert.json | 0 .../logs.json | 0 .../oog.json | 0 .../revert.json | 0 .../revert_reason.json | 0 .../selfdestruct.json | 0 .../simple.json | 0 .../simple_onlytop.json | 0 .../throw.json | 0 .../with_decoding}/delegatecall.json | 0 .../with_decoding}/erc20_transfer.json | 0 .../with_decoding}/erc20_transfer2.json | 0 .../with_decoding}/inner_create.json | 0 .../multi_contracts_transfers.json | 0 eth/tracers/register_blocknative.go | 6 +- 30 files changed, 304 insertions(+), 293 deletions(-) rename eth/tracers/blocknative/{txnopcodetracer_readme.md => README.md} (99%) create mode 100644 eth/tracers/blocknative/tracer.go delete mode 100644 eth/tracers/blocknative/txnOpCodeTracer.go rename eth/tracers/internal/tracetest/{txnOpCodeTracer_test.go => blocknative_test.go} (84%) rename eth/tracers/internal/tracetest/testdata/{txnOpCode_tracer => blocknative}/block_random.json (100%) rename eth/tracers/internal/tracetest/testdata/{txnOpCode_tracer => blocknative}/create.json (100%) rename eth/tracers/internal/tracetest/testdata/{txnOpCode_tracer => blocknative}/deep_calls.json (100%) rename eth/tracers/internal/tracetest/testdata/{txnOpCode_tracer => blocknative}/delegatecall.json (100%) rename eth/tracers/internal/tracetest/testdata/{txnOpCode_tracer => blocknative}/inner_create_oog_outer_throw.json (100%) rename eth/tracers/internal/tracetest/testdata/{txnOpCode_tracer => blocknative}/inner_instafail.json (100%) rename eth/tracers/internal/tracetest/testdata/{txnOpCode_tracer => blocknative}/inner_revert_reason.json (100%) rename eth/tracers/internal/tracetest/testdata/{txnOpCode_tracer => blocknative}/inner_throw_outer_revert.json (100%) rename eth/tracers/internal/tracetest/testdata/{txnOpCode_tracer => blocknative}/logs.json (100%) rename eth/tracers/internal/tracetest/testdata/{txnOpCode_tracer => blocknative}/oog.json (100%) rename eth/tracers/internal/tracetest/testdata/{txnOpCode_tracer => blocknative}/revert.json (100%) rename eth/tracers/internal/tracetest/testdata/{txnOpCode_tracer => blocknative}/revert_reason.json (100%) rename eth/tracers/internal/tracetest/testdata/{txnOpCode_tracer => blocknative}/selfdestruct.json (100%) rename eth/tracers/internal/tracetest/testdata/{txnOpCode_tracer => blocknative}/simple.json (100%) rename eth/tracers/internal/tracetest/testdata/{txnOpCode_tracer => blocknative}/simple_onlytop.json (100%) rename eth/tracers/internal/tracetest/testdata/{txnOpCode_tracer => blocknative}/throw.json (100%) rename eth/tracers/internal/tracetest/testdata/{txnOpCode_tracer_with_netbalchanges => blocknative/with_decoding}/delegatecall.json (100%) rename eth/tracers/internal/tracetest/testdata/{txnOpCode_tracer_with_netbalchanges => blocknative/with_decoding}/erc20_transfer.json (100%) rename eth/tracers/internal/tracetest/testdata/{txnOpCode_tracer_with_netbalchanges => blocknative/with_decoding}/erc20_transfer2.json (100%) rename eth/tracers/internal/tracetest/testdata/{txnOpCode_tracer_with_netbalchanges => blocknative/with_decoding}/inner_create.json (100%) rename eth/tracers/internal/tracetest/testdata/{txnOpCode_tracer_with_netbalchanges => blocknative/with_decoding}/multi_contracts_transfers.json (100%) diff --git a/core/state_processor.go b/core/state_processor.go index 17555f62d7ac..bf3707f828d6 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -250,7 +250,7 @@ func ApplyTransactionWithResult(config *params.ChainConfig, bc ChainContext, aut func ApplyUnsignedTransactionWithResult(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, msg *Message, usedGas *uint64, cfg vm.Config) (*types.Receipt, *ExecutionResult, interface{}, error) { // Create a blocknative tracer to get execution traces. - tracer, err := blocknative.NewTxnOpCodeTracer(nil) + tracer, err := blocknative.NewTracer(nil) if err != nil { return nil, nil, nil, err } diff --git a/eth/filters/trace_api.go b/eth/filters/trace_api.go index 898bcb4cbc6a..f5e7bb750cb4 100644 --- a/eth/filters/trace_api.go +++ b/eth/filters/trace_api.go @@ -266,7 +266,7 @@ func traceTx(message *core.Message, txCtx *tracers.Context, vmctx vm.BlockContex txTraceLocksMu.Unlock() // No trace in cache or in-progress so create a new one. - tracer, err := blocknative.NewTxnOpCodeTracerWithOpts(tracerOpts) + tracer, err := blocknative.NewTracerWithOpts(tracerOpts) if err != nil { return nil, err } diff --git a/eth/tracers/blocknative/txnopcodetracer_readme.md b/eth/tracers/blocknative/README.md similarity index 99% rename from eth/tracers/blocknative/txnopcodetracer_readme.md rename to eth/tracers/blocknative/README.md index 8b6a6114083e..6f926f824f5f 100644 --- a/eth/tracers/blocknative/txnopcodetracer_readme.md +++ b/eth/tracers/blocknative/README.md @@ -1,4 +1,4 @@ -# txnOpCodeTracer +# Blocknative Tracer ## Options diff --git a/eth/tracers/blocknative/blocknative.go b/eth/tracers/blocknative/blocknative.go index 5f3abff0dd63..fd1517a8672d 100644 --- a/eth/tracers/blocknative/blocknative.go +++ b/eth/tracers/blocknative/blocknative.go @@ -2,11 +2,15 @@ package blocknative import ( "encoding/json" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/tracers/blocknative/decoder" ) +// Tracer is the interface for the Blocknative tracer. +// It implements the standard EVMLogger tracer interface, but also exposes the +// resulting Trace object directly. type Tracer interface { vm.EVMLogger GetTrace() (*Trace, error) diff --git a/eth/tracers/blocknative/decoder/calldata_test.go b/eth/tracers/blocknative/decoder/calldata_test.go index d4599c84b26d..baa30881beb1 100644 --- a/eth/tracers/blocknative/decoder/calldata_test.go +++ b/eth/tracers/blocknative/decoder/calldata_test.go @@ -8,8 +8,9 @@ import ( "path/filepath" "testing" - "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/common" ) type decodeCallDataTest struct { @@ -92,8 +93,8 @@ type testCall struct { func loadTestVectors() ([]*testVector, error) { testVectorDirs := []string{ - "../../internal/tracetest/testdata/txnOpCode_tracer", - "../../internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges", + "../../internal/tracetest/testdata/blocknative", + "../../internal/tracetest/testdata/blocknative/with_decoding", } var testVectors []*testVector diff --git a/eth/tracers/blocknative/tracer.go b/eth/tracers/blocknative/tracer.go new file mode 100644 index 000000000000..c407548b309d --- /dev/null +++ b/eth/tracers/blocknative/tracer.go @@ -0,0 +1,261 @@ +package blocknative + +import ( + "encoding/json" + "math/big" + "sync/atomic" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/eth/tracers/blocknative/decoder" +) + +var ( + // decoderCache is a global cache for the decoder, shared across traces. + decoderCache = decoder.NewCaches() +) + +// tracer is Blocknative's transaction tracer. It decodes messages into +// call-frames and decodes them into higher-level abstractions. It returns all +// the information required to reconstruct a transaction's execution while +// decoding inputs, outputs, logs, and environmental effects. +type tracer struct { + opts TracerOpts + evm *vm.EVM + decoder *decoder.Decoder + + trace Trace + startTime time.Time + callStack []CallFrame + + interrupt *atomic.Bool + interruptReason error +} + +// NewTracer returns a new tracer with the given json decoded as TracerOpts. +// This allows us to easily construct a tracer from the standard tracer API +// which receives options as json. +func NewTracer(cfg json.RawMessage) (Tracer, error) { + var opts TracerOpts + if cfg != nil { + if err := json.Unmarshal(cfg, &opts); err != nil { + return nil, err + } + } + return NewTracerWithOpts(opts) +} + +// NewTracerWithOpts is the primary constructor for the tracer. +func NewTracerWithOpts(opts TracerOpts) (Tracer, error) { + opts.Decode = opts.Decode || opts.BalanceChanges + + var t = tracer{ + opts: opts, + callStack: make([]CallFrame, 1, 4), + interrupt: new(atomic.Bool), + } + + if !opts.DisableBlockContext { + t.trace.BlockContext = &BlockContext{} + } + + return &t, nil + +} + +// SetStateRoot implements core.stateRootSetter and stores the given root in the +// trace's BlockContext. It's called between the constructor and the first +// call-frame. +func (t *tracer) SetStateRoot(root common.Hash) { + if t.trace.BlockContext != nil { + t.trace.BlockContext.StateRoot = bytesToHex(root.Bytes()) + } +} + +// CaptureStart is called before the top-level call starts. +// This is also where we get the EVM instance, so we initialize the things that +// need it here instead of the constructor. +func (t *tracer) CaptureStart(evm *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { + t.startTime = time.Now() + t.evm = evm + + if t.opts.Decode { + t.decoder = decoder.New(decoderCache, decoderEVM{evm}) + } + + if !t.opts.DisableBlockContext { + t.trace.BlockContext.Number = evm.Context.BlockNumber.Uint64() + t.trace.BlockContext.BaseFee = evm.Context.BaseFee.Uint64() + t.trace.BlockContext.Time = evm.Context.Time + t.trace.BlockContext.Coinbase = addrToHex(evm.Context.Coinbase) + t.trace.BlockContext.GasLimit = evm.Context.GasLimit + if evm.Context.Random != nil { + t.trace.BlockContext.Random = bytesToHex(evm.Context.Random.Bytes()) + } + } + + // Create a call-frame for the top-level call. + t.callStack[0] = CallFrame{ + Type: "CALL", + From: addrToHex(from), + To: addrToHex(to), + Input: bytesToHex(input), + Gas: uintToHex(gas), + Value: bigToHex(value), + } + if create { + t.callStack[0].Type = "CREATE" + } + + // Try adding decode information, but don't fail if we can't. + if t.opts.Decode { + if decoded, err := t.decoder.DecodeCallFrame(from, to, value, input); err == nil { + t.callStack[0].Decoded = decoded + } + } +} + +// CaptureEnd is called after the top-level call finishes to finalize tracing. +func (t *tracer) CaptureEnd(output []byte, gasUsed uint64, err error) { + finalizeCallFrame(&t.callStack[0], output, gasUsed, err) + + // If the user wants the logs, grab them from the state + if t.opts.Logs { + for _, stateLog := range t.evm.StateDB.Logs() { + t.trace.Logs = append(t.trace.Logs, CallLog{ + Address: stateLog.Address, + Data: bytesToHex(stateLog.Data), + Topics: stateLog.Topics, + }) + } + } + + // Add gas payments to balance changes + if t.opts.Decode { + t.decoder.CaptureGas(t.evm.TxContext.Origin, t.evm.Context.Coinbase, gasUsed, t.evm.TxContext.GasPrice, t.evm.Context.BaseFee) + } + + // Add total time duration for this trace request + t.trace.Time = time.Now().Sub(t.startTime).Nanoseconds() +} + +// CaptureEnter is called before any new sub-call starts. +// (via call, create or selfdestruct). +func (t *tracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { + if t.interrupt.Load() { + return + } + + // Create CallFrame, decode it, and all it to the end of the callstack. + call := CallFrame{ + Type: typ.String(), + From: addrToHex(from), + To: addrToHex(to), + Input: bytesToHex(input), + Gas: uintToHex(gas), + Value: bigToHex(value), + } + if t.opts.Decode { + if decoded, err := t.decoder.DecodeCallFrame(from, to, value, input); err == nil { + call.Decoded = decoded + } + } + + t.callStack = append(t.callStack, call) +} + +// CaptureExit is called after any sub call ends. +func (t *tracer) CaptureExit(output []byte, gasUsed uint64, err error) { + // Skip if we have no call-frames. + size := len(t.callStack) + if size == 0 { + return + } + + // We have a call-frame, so finalize it. + finalizeCallFrame(&t.callStack[size-1], output, gasUsed, err) + + // We have a parent call-frame, so nest this one under it. + if size <= 1 { + return + } + end := size - 1 + call := t.callStack[end] + t.callStack = t.callStack[:end] + end -= 1 + t.callStack[end].Calls = append(t.callStack[end].Calls, call) +} + +// Stop terminates execution of the tracer at the first opportune moment. +func (t *tracer) Stop(err error) { + t.interrupt.Store(true) + t.interruptReason = err + t.evm.Cancel() +} + +// GetTrace returns a Trace from the current state. +func (t *tracer) GetTrace() (*Trace, error) { + if t.interrupt.Load() { + return nil, t.interruptReason + } + + t.trace.CallFrame = t.callStack[0] + + if t.opts.Decode { + t.trace.BalanceChanges = t.decoder.GetBalanceChanges() + } + + return &t.trace, nil +} + +// GetResult returns a JSON encoded Trace from the current state. +func (t *tracer) GetResult() (json.RawMessage, error) { + trace, err := t.GetTrace() + if err != nil { + return nil, err + } + + return json.Marshal(trace) +} + +func finalizeCallFrame(call *CallFrame, output []byte, gasUsed uint64, err error) { + call.GasUsed = uintToHex(gasUsed) + + // If there was an error then try decoding it and stop. + if err != nil { + call.Error = err.Error() + if err.Error() == "execution reverted" && len(output) > 0 { + call.Output = bytesToHex(output) + revertReason, _ := abi.UnpackRevert(output) + call.ErrorReason = revertReason + } + + if call.Type == "CREATE" || call.Type == "CREATE2" { + call.To = "" + } + return + } + + // The call was successful so decode the output. + call.Output = bytesToHex(output) +} + +// +// Unused interface methods. +// + +// CaptureState implements the tracer interface, but is unused. +func (t *tracer) CaptureState(_ uint64, _ vm.OpCode, _, _ uint64, _ *vm.ScopeContext, _ []byte, _ int, _ error) { +} + +// CaptureFault implements the tracer interface, but is unused. +func (t *tracer) CaptureFault(_ uint64, _ vm.OpCode, _, _ uint64, _ *vm.ScopeContext, _ int, _ error) { +} + +// CaptureTxStart implements the tracer interface, but is unused. +func (t *tracer) CaptureTxStart(_ uint64) {} + +// CaptureTxEnd implements the tracer interface, but is unused. +func (t *tracer) CaptureTxEnd(_ uint64) {} diff --git a/eth/tracers/blocknative/txnOpCodeTracer.go b/eth/tracers/blocknative/txnOpCodeTracer.go deleted file mode 100644 index eca7f8622805..000000000000 --- a/eth/tracers/blocknative/txnOpCodeTracer.go +++ /dev/null @@ -1,260 +0,0 @@ -package blocknative - -import ( - "encoding/json" - "math/big" - "sync/atomic" - "time" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/eth/tracers/blocknative/decoder" - "github.com/ethereum/go-ethereum/log" -) - -var ( - decoderCache = decoder.NewCaches() -) - -// txnOpCodeTracer is a go implementation of the Tracer interface which -// only returns a restricted trace of a transaction consisting of transaction -// op codes and relevant gas data. -// This is intended for Blocknative usage. -type txnOpCodeTracer struct { - opts TracerOpts - env *vm.EVM - decoder *decoder.Decoder - - trace Trace - startTime time.Time - callStack []CallFrame - interrupt uint32 - reason error -} - -// NewTxnOpCodeTracer returns a new txnOpCodeTracer tracer with the given -// options applied. -func NewTxnOpCodeTracer(cfg json.RawMessage) (Tracer, error) { - var opts TracerOpts - - if cfg != nil { - if err := json.Unmarshal(cfg, &opts); err != nil { - return nil, err - } - } - - return NewTxnOpCodeTracerWithOpts(opts) -} - -func NewTxnOpCodeTracerWithOpts(opts TracerOpts) (Tracer, error) { - opts.Decode = opts.Decode || opts.BalanceChanges - - var t = txnOpCodeTracer{ - opts: opts, - callStack: make([]CallFrame, 1), - } - - if !t.opts.DisableBlockContext { - t.trace.BlockContext = &BlockContext{} - } - - return &t, nil - -} - -// GetTrace returns the resulting Trace object. -func (t *txnOpCodeTracer) GetTrace() (*Trace, error) { - if t.opts.Decode { - t.trace.BalanceChanges = t.decoder.GetBalanceChanges() - } - - t.trace.CallFrame = t.callStack[0] - return &t.trace, nil -} - -// GetResult returns an empty json object. -func (t *txnOpCodeTracer) GetResult() (json.RawMessage, error) { - trace, err := t.GetTrace() - if err != nil { - return nil, err - } - - res, err := json.Marshal(trace) - if err != nil { - return nil, err - } - return res, t.reason -} - -// CaptureStart implements the EVMLogger interface to initialize the tracing operation. -func (t *txnOpCodeTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { - t.startTime = time.Now() - t.env = env - - if t.opts.Decode { - t.decoder = decoder.New(decoderCache, decoderEVM{env}) - } - - if !t.opts.DisableBlockContext { - // Blocks only contain `Random` post-merge, but we still have pre-merge tests. - random := "" - if env.Context.Random != nil { - random = bytesToHex(env.Context.Random.Bytes()) - } - - t.trace.BlockContext.Number = env.Context.BlockNumber.Uint64() - t.trace.BlockContext.BaseFee = env.Context.BaseFee.Uint64() - t.trace.BlockContext.Time = env.Context.Time - t.trace.BlockContext.Coinbase = addrToHex(env.Context.Coinbase) - t.trace.BlockContext.GasLimit = env.Context.GasLimit - t.trace.BlockContext.Random = random - } - - // Create a call-frame for the top level call. - t.callStack[0] = CallFrame{ - Type: "CALL", - From: addrToHex(from), - To: addrToHex(to), - Input: bytesToHex(input), - Gas: uintToHex(gas), - Value: bigToHex(value), - } - if create { - t.callStack[0].Type = "CREATE" - } - - // Try adding decode information but don't fail if we can't. - if t.opts.Decode { - if decoded, err := t.decoder.DecodeCallFrame(from, to, value, input); err == nil { - t.callStack[0].Decoded = decoded - } - } -} - -// CaptureEnd is called after the call finishes to finalize the tracing. -func (t *txnOpCodeTracer) CaptureEnd(output []byte, gasUsed uint64, err error) { - finalizeCallFrame(&t.callStack[0], output, gasUsed, err) - - // If the user wants the logs, grab them from the state - if t.opts.Logs { - for _, stateLog := range t.env.StateDB.Logs() { - t.trace.Logs = append(t.trace.Logs, CallLog{ - Address: stateLog.Address, - Data: bytesToHex(stateLog.Data), - Topics: stateLog.Topics, - }) - } - } - - // Add gas payments to balance changes - if t.opts.Decode { - t.decoder.CaptureGas(t.env.TxContext.Origin, t.env.Context.Coinbase, gasUsed, t.env.TxContext.GasPrice, t.env.Context.BaseFee) - } - - // Add total time duration for this trace request - t.trace.Time = time.Now().Sub(t.startTime).Nanoseconds() -} - -// CaptureState implements the EVMLogger interface to trace a single step of VM execution. -func (t *txnOpCodeTracer) CaptureState(_ uint64, _ vm.OpCode, _, _ uint64, _ *vm.ScopeContext, _ []byte, depth int, _ error) { - defer func() { - if r := recover(); r != nil { - t.callStack[depth].Error = "internal failure" - log.Warn("Panic during trace. Recovered.", "err", r) - } - }() -} - -// CaptureFault implements the EVMLogger interface to trace an execution fault. -func (t *txnOpCodeTracer) CaptureFault(_ uint64, _ vm.OpCode, _, _ uint64, _ *vm.ScopeContext, _ int, _ error) { -} - -// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct). -func (t *txnOpCodeTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { - // Skip if tracing was interrupted - if atomic.LoadUint32(&t.interrupt) > 0 { - t.env.Cancel() - return - } - - // Create CallFrame, decode it, and all it to the end of the callstack. - call := CallFrame{ - Type: typ.String(), - From: addrToHex(from), - To: addrToHex(to), - Input: bytesToHex(input), - Gas: uintToHex(gas), - Value: bigToHex(value), - } - if t.opts.Decode { - if decoded, err := t.decoder.DecodeCallFrame(from, to, value, input); err == nil { - call.Decoded = decoded - } - } - - t.callStack = append(t.callStack, call) -} - -// CaptureExit is called when EVM exits a scope, even if the scope didn't execute any code. -func (t *txnOpCodeTracer) CaptureExit(output []byte, gasUsed uint64, err error) { - // Skip if we have no call frames. - size := len(t.callStack) - if size == 0 { - return - } - - // We have a call frame, so finalize it. - finalizeCallFrame(&t.callStack[size-1], output, gasUsed, err) - - // If we have a parent call frame nest this one into it. - if size <= 1 { - return - } - end := size - 1 - call := t.callStack[end] - t.callStack = t.callStack[:end] - end -= 1 - t.callStack[end].Calls = append(t.callStack[end].Calls, call) -} - -// CaptureTxStart fulfils the standard Tracer interface, but we don't use it. -func (t *txnOpCodeTracer) CaptureTxStart(_ uint64) {} - -// CaptureTxEnd fulfils the standard Tracer interface, but we don't use it. -func (t *txnOpCodeTracer) CaptureTxEnd(_ uint64) {} - -// Stop terminates execution of the tracer at the first opportune moment. -func (t *txnOpCodeTracer) Stop(err error) { - t.reason = err - atomic.StoreUint32(&t.interrupt, 1) -} - -// SetStateRoot implements core.stateRootSetter and stores the given root in the trace's BlockContext. -func (t *txnOpCodeTracer) SetStateRoot(root common.Hash) { - if !t.opts.DisableBlockContext { - t.trace.BlockContext.StateRoot = bytesToHex(root.Bytes()) - } -} - -func finalizeCallFrame(call *CallFrame, output []byte, gasUsed uint64, err error) { - call.GasUsed = uintToHex(gasUsed) - - // If there was an error then try decoding it and stop. - if err != nil { - call.Error = err.Error() - if err.Error() == "execution reverted" && len(output) > 0 { - call.Output = bytesToHex(output) - revertReason, _ := abi.UnpackRevert(output) - call.ErrorReason = revertReason - } - - if call.Type == "CREATE" || call.Type == "CREATE2" { - call.To = "" - } - return - } - - // The call was successful so decode the output. - call.Output = bytesToHex(output) -} diff --git a/eth/tracers/internal/tracetest/txnOpCodeTracer_test.go b/eth/tracers/internal/tracetest/blocknative_test.go similarity index 84% rename from eth/tracers/internal/tracetest/txnOpCodeTracer_test.go rename to eth/tracers/internal/tracetest/blocknative_test.go index 73ec2b770b98..c40e242d0d6a 100644 --- a/eth/tracers/internal/tracetest/txnOpCodeTracer_test.go +++ b/eth/tracers/internal/tracetest/blocknative_test.go @@ -2,6 +2,7 @@ package tracetest import ( "encoding/json" + "fmt" "math/big" "os" "path/filepath" @@ -22,7 +23,7 @@ import ( "github.com/ethereum/go-ethereum/tests" ) -type txnOpCodeTracerTest struct { +type blocknativeTracerTest struct { Genesis *core.Genesis `json:"genesis"` Context *callContext `json:"context"` Input string `json:"input"` @@ -41,21 +42,21 @@ type txnOpCodeTracerTest struct { txContext vm.TxContext } -func TestTxnOpCodeTracer(t *testing.T) { +func TestBlocknativeTracer(t *testing.T) { log.Root().SetHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(true))) - testTxnOpCodeTracer("txnOpCode_tracer", t) - testTxnOpCodeTracer("txnOpCode_tracer_with_netbalchanges", t) + testBlocknativeTracer("blocknative", t) + testBlocknativeTracer("blocknative/with_decoding", t) } -func BenchmarkTxnOpCodeTracerWithoutDecoding(b *testing.B) { - benchmarkTxnOpCodeTracer(b, false, "txnOpCode_tracer", "txnOpCode_tracer_with_netbalchanges") +func BenchmarkBlocknativeTracerWithoutDecoding(b *testing.B) { + benchmarkBlocknativeTracer(b, false, "blocknative", "blocknative/with_decoding") } -func BenchmarkTxnOpCodeTracerWithDecoding(b *testing.B) { - benchmarkTxnOpCodeTracer(b, true, "txnOpCode_tracer", "txnOpCode_tracer_with_netbalchanges") +func BenchmarkBlocknativeTracerWithDecoding(b *testing.B) { + benchmarkBlocknativeTracer(b, true, "blocknative", "blocknative/with_decoding") } -func benchmarkTxnOpCodeTracer(b *testing.B, decode bool, dirPaths ...string) { - testCases := []*txnOpCodeTracerTest{} +func benchmarkBlocknativeTracer(b *testing.B, decode bool, dirPaths ...string) { + testCases := []*blocknativeTracerTest{} for _, dirPath := range dirPaths { files, err := os.ReadDir(filepath.Join("testdata", dirPath)) @@ -65,7 +66,7 @@ func benchmarkTxnOpCodeTracer(b *testing.B, decode bool, dirPaths ...string) { for _, file := range files { var ( - test = new(txnOpCodeTracerTest) + test = new(blocknativeTracerTest) tx = new(types.Transaction) ) if blob, err := os.ReadFile(filepath.Join("testdata", dirPath, file.Name())); err != nil { @@ -115,7 +116,7 @@ func benchmarkTxnOpCodeTracer(b *testing.B, decode bool, dirPaths ...string) { _, _, statedb := tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme) opts := blocknative.TracerOpts{Decode: decode} - tracer, err := blocknative.NewTxnOpCodeTracerWithOpts(opts) + tracer, err := blocknative.NewTracerWithOpts(opts) if err != nil { b.Fatal(err) } @@ -135,7 +136,7 @@ func benchmarkTxnOpCodeTracer(b *testing.B, decode bool, dirPaths ...string) { } } -func testTxnOpCodeTracer(dirPath string, t *testing.T) { +func testBlocknativeTracer(dirPath string, t *testing.T) { testsCases, err := loadTestTxs(dirPath) if err != nil { t.Fatal(err) @@ -148,20 +149,20 @@ func testTxnOpCodeTracer(dirPath string, t *testing.T) { } } -func loadTestTxs(dirPath string) ([]*txnOpCodeTracerTest, error) { +func loadTestTxs(dirPath string) ([]*blocknativeTracerTest, error) { files, err := os.ReadDir(filepath.Join("testdata", dirPath)) if err != nil { return nil, err } - testCases := make([]*txnOpCodeTracerTest, 0, len(files)) + testCases := make([]*blocknativeTracerTest, 0, len(files)) for _, file := range files { if !strings.HasSuffix(file.Name(), ".json") { continue } var ( - test = new(txnOpCodeTracerTest) + test = new(blocknativeTracerTest) tx = new(types.Transaction) ) if blob, err := os.ReadFile(filepath.Join("testdata", dirPath, file.Name())); err != nil { @@ -199,7 +200,7 @@ func loadTestTxs(dirPath string) ([]*txnOpCodeTracerTest, error) { } _, _, statedb = tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme) ) - tracer, err := blocknative.NewTxnOpCodeTracer(test.TracerConfig) + tracer, err := blocknative.NewTracer(test.TracerConfig) if err != nil { return nil, err } @@ -220,7 +221,7 @@ func loadTestTxs(dirPath string) ([]*txnOpCodeTracerTest, error) { return testCases, nil } -func executeTestCase(test *txnOpCodeTracerTest, t testing.TB, checkResult bool) { +func executeTestCase(test *blocknativeTracerTest, t testing.TB, checkResult bool) { st := core.NewStateTransition(test.evm, test.msg, new(core.GasPool).AddGas(test.tx.Gas())) if _, err := st.TransitionDb(); err != nil { t.Fatalf("failed to execute transaction: %v", err) @@ -237,15 +238,15 @@ func executeTestCase(test *txnOpCodeTracerTest, t testing.TB, checkResult bool) if checkResult && !tracesEqual(ret, test.Result) { // Below are prints to show differences if we fail, can always just check against the specific test json files too! - //fmt.Println("Trace return: ") - //x, _ := json.Marshal(ret) - ////x, _ := json.MarshalIndent(ret, "", " ") - //y, _ := json.Marshal(test.Result) - //fmt.Println(string(x)) - //fmt.Println("test.Result") - //fmt.Println(string(y)) + fmt.Println("Trace return: ") + x, _ := json.Marshal(ret) + // //x, _ := json.MarshalIndent(ret, "", " ") + y, _ := json.Marshal(test.Result) + fmt.Println(string(x)) + fmt.Println("test.Result") + fmt.Println(string(y)) t.Fatal("traces mismatch") - //t.Fatalf("trace mismatch: \nhave %+v\nwant %+v", ret, test.Result) + // t.Fatalf("trace mismatch: \nhave %+v\nwant %+v", ret, test.Result) } } diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/block_random.json b/eth/tracers/internal/tracetest/testdata/blocknative/block_random.json similarity index 100% rename from eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/block_random.json rename to eth/tracers/internal/tracetest/testdata/blocknative/block_random.json diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/create.json b/eth/tracers/internal/tracetest/testdata/blocknative/create.json similarity index 100% rename from eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/create.json rename to eth/tracers/internal/tracetest/testdata/blocknative/create.json diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/deep_calls.json b/eth/tracers/internal/tracetest/testdata/blocknative/deep_calls.json similarity index 100% rename from eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/deep_calls.json rename to eth/tracers/internal/tracetest/testdata/blocknative/deep_calls.json diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/delegatecall.json b/eth/tracers/internal/tracetest/testdata/blocknative/delegatecall.json similarity index 100% rename from eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/delegatecall.json rename to eth/tracers/internal/tracetest/testdata/blocknative/delegatecall.json diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/inner_create_oog_outer_throw.json b/eth/tracers/internal/tracetest/testdata/blocknative/inner_create_oog_outer_throw.json similarity index 100% rename from eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/inner_create_oog_outer_throw.json rename to eth/tracers/internal/tracetest/testdata/blocknative/inner_create_oog_outer_throw.json diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/inner_instafail.json b/eth/tracers/internal/tracetest/testdata/blocknative/inner_instafail.json similarity index 100% rename from eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/inner_instafail.json rename to eth/tracers/internal/tracetest/testdata/blocknative/inner_instafail.json diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/inner_revert_reason.json b/eth/tracers/internal/tracetest/testdata/blocknative/inner_revert_reason.json similarity index 100% rename from eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/inner_revert_reason.json rename to eth/tracers/internal/tracetest/testdata/blocknative/inner_revert_reason.json diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/inner_throw_outer_revert.json b/eth/tracers/internal/tracetest/testdata/blocknative/inner_throw_outer_revert.json similarity index 100% rename from eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/inner_throw_outer_revert.json rename to eth/tracers/internal/tracetest/testdata/blocknative/inner_throw_outer_revert.json diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/logs.json b/eth/tracers/internal/tracetest/testdata/blocknative/logs.json similarity index 100% rename from eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/logs.json rename to eth/tracers/internal/tracetest/testdata/blocknative/logs.json diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/oog.json b/eth/tracers/internal/tracetest/testdata/blocknative/oog.json similarity index 100% rename from eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/oog.json rename to eth/tracers/internal/tracetest/testdata/blocknative/oog.json diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/revert.json b/eth/tracers/internal/tracetest/testdata/blocknative/revert.json similarity index 100% rename from eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/revert.json rename to eth/tracers/internal/tracetest/testdata/blocknative/revert.json diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/revert_reason.json b/eth/tracers/internal/tracetest/testdata/blocknative/revert_reason.json similarity index 100% rename from eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/revert_reason.json rename to eth/tracers/internal/tracetest/testdata/blocknative/revert_reason.json diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/selfdestruct.json b/eth/tracers/internal/tracetest/testdata/blocknative/selfdestruct.json similarity index 100% rename from eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/selfdestruct.json rename to eth/tracers/internal/tracetest/testdata/blocknative/selfdestruct.json diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/simple.json b/eth/tracers/internal/tracetest/testdata/blocknative/simple.json similarity index 100% rename from eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/simple.json rename to eth/tracers/internal/tracetest/testdata/blocknative/simple.json diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/simple_onlytop.json b/eth/tracers/internal/tracetest/testdata/blocknative/simple_onlytop.json similarity index 100% rename from eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/simple_onlytop.json rename to eth/tracers/internal/tracetest/testdata/blocknative/simple_onlytop.json diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/throw.json b/eth/tracers/internal/tracetest/testdata/blocknative/throw.json similarity index 100% rename from eth/tracers/internal/tracetest/testdata/txnOpCode_tracer/throw.json rename to eth/tracers/internal/tracetest/testdata/blocknative/throw.json diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/delegatecall.json b/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/delegatecall.json similarity index 100% rename from eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/delegatecall.json rename to eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/delegatecall.json diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/erc20_transfer.json b/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/erc20_transfer.json similarity index 100% rename from eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/erc20_transfer.json rename to eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/erc20_transfer.json diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/erc20_transfer2.json b/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/erc20_transfer2.json similarity index 100% rename from eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/erc20_transfer2.json rename to eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/erc20_transfer2.json diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/inner_create.json b/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/inner_create.json similarity index 100% rename from eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/inner_create.json rename to eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/inner_create.json diff --git a/eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/multi_contracts_transfers.json b/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/multi_contracts_transfers.json similarity index 100% rename from eth/tracers/internal/tracetest/testdata/txnOpCode_tracer_with_netbalchanges/multi_contracts_transfers.json rename to eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/multi_contracts_transfers.json diff --git a/eth/tracers/register_blocknative.go b/eth/tracers/register_blocknative.go index f6b67c913619..900ea9872ca2 100644 --- a/eth/tracers/register_blocknative.go +++ b/eth/tracers/register_blocknative.go @@ -2,6 +2,7 @@ package tracers import ( "encoding/json" + "github.com/ethereum/go-ethereum/eth/tracers/blocknative" ) @@ -11,9 +12,12 @@ import ( // in turn allows us to use the blocknative tracers from inside the geth/core // package without causing circular dependency issues. func init() { + DefaultDirectory.Register("blocknative", blocknativeTracerCtor, false) + + // Also register the tracer under the old name for backwards compatibility. DefaultDirectory.Register("txnOpCodeTracer", blocknativeTracerCtor, false) } func blocknativeTracerCtor(_ *Context, cfg json.RawMessage) (Tracer, error) { - return blocknative.NewTxnOpCodeTracer(cfg) + return blocknative.NewTracer(cfg) } From e59f4f89a59bd3c924de8bb43c8e57410d3de11f Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Fri, 22 Sep 2023 21:49:29 -0400 Subject: [PATCH 28/40] tests,fix: Fix tracer test output and file handling. --- eth/tracers/internal/tracetest/blocknative_test.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/eth/tracers/internal/tracetest/blocknative_test.go b/eth/tracers/internal/tracetest/blocknative_test.go index c40e242d0d6a..be0652f07f5b 100644 --- a/eth/tracers/internal/tracetest/blocknative_test.go +++ b/eth/tracers/internal/tracetest/blocknative_test.go @@ -65,6 +65,9 @@ func benchmarkBlocknativeTracer(b *testing.B, decode bool, dirPaths ...string) { } for _, file := range files { + if file.IsDir() { + continue + } var ( test = new(blocknativeTracerTest) tx = new(types.Transaction) @@ -241,10 +244,10 @@ func executeTestCase(test *blocknativeTracerTest, t testing.TB, checkResult bool fmt.Println("Trace return: ") x, _ := json.Marshal(ret) // //x, _ := json.MarshalIndent(ret, "", " ") - y, _ := json.Marshal(test.Result) + // y, _ := json.Marshal(test.Result) fmt.Println(string(x)) fmt.Println("test.Result") - fmt.Println(string(y)) + // fmt.Println(string(y)) t.Fatal("traces mismatch") // t.Fatalf("trace mismatch: \nhave %+v\nwant %+v", ret, test.Result) } From 148094c3bc3e950636e84179c2ce702b98064e90 Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Sat, 23 Sep 2023 15:46:35 -0400 Subject: [PATCH 29/40] tests: Allow specifying a tracer test with -file. --- .../internal/tracetest/blocknative_test.go | 55 +++++++++++++------ 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/eth/tracers/internal/tracetest/blocknative_test.go b/eth/tracers/internal/tracetest/blocknative_test.go index be0652f07f5b..533e67ab103a 100644 --- a/eth/tracers/internal/tracetest/blocknative_test.go +++ b/eth/tracers/internal/tracetest/blocknative_test.go @@ -2,6 +2,7 @@ package tracetest import ( "encoding/json" + "flag" "fmt" "math/big" "os" @@ -23,6 +24,13 @@ import ( "github.com/ethereum/go-ethereum/tests" ) +var testFileFlag = flag.String("file", "", "Name of the file to run the test for") + +func TestMain(m *testing.M) { + flag.Parse() + os.Exit(m.Run()) +} + type blocknativeTracerTest struct { Genesis *core.Genesis `json:"genesis"` Context *callContext `json:"context"` @@ -44,8 +52,29 @@ type blocknativeTracerTest struct { func TestBlocknativeTracer(t *testing.T) { log.Root().SetHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(true))) - testBlocknativeTracer("blocknative", t) - testBlocknativeTracer("blocknative/with_decoding", t) + + testsCases, err := loadTestTxs("blocknative") + if err != nil { + t.Fatal(err) + } + decodingTestsCases, err := loadTestTxs("blocknative/with_decoding") + if err != nil { + t.Fatal(err) + } + testsCases = append(testsCases, decodingTestsCases...) + + for _, test := range testsCases { + if *testFileFlag != "" { + a := strings.ToLower(*testFileFlag) + b := strings.ToLower(test.name) + if a != b { + continue + } + } + t.Run(test.name, func(t *testing.T) { + executeTestCase(test, t, true) + }) + } } func BenchmarkBlocknativeTracerWithoutDecoding(b *testing.B) { @@ -139,19 +168,6 @@ func benchmarkBlocknativeTracer(b *testing.B, decode bool, dirPaths ...string) { } } -func testBlocknativeTracer(dirPath string, t *testing.T) { - testsCases, err := loadTestTxs(dirPath) - if err != nil { - t.Fatal(err) - } - - for _, test := range testsCases { - t.Run(test.name, func(t *testing.T) { - executeTestCase(test, t, true) - }) - } -} - func loadTestTxs(dirPath string) ([]*blocknativeTracerTest, error) { files, err := os.ReadDir(filepath.Join("testdata", dirPath)) if err != nil { @@ -213,7 +229,14 @@ func loadTestTxs(dirPath string) ([]*blocknativeTracerTest, error) { return nil, err } - test.name = camel(strings.TrimSuffix(file.Name(), ".json")) + name := strings.TrimPrefix(dirPath, "blocknative") + name = strings.TrimPrefix(name, "/") + if name != "" { + name = name + "/" + } + name = name + camel(strings.TrimSuffix(file.Name(), ".json")) + + test.name = name test.evm = evm test.tx = tx test.msg = msg From ed335484d5f58ffde1921573cc92565bbba38e42 Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Sat, 23 Sep 2023 15:59:19 -0400 Subject: [PATCH 30/40] tests: Allow setting log level in tracer tests. --- .../internal/tracetest/blocknative_test.go | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/eth/tracers/internal/tracetest/blocknative_test.go b/eth/tracers/internal/tracetest/blocknative_test.go index 533e67ab103a..70025ee28916 100644 --- a/eth/tracers/internal/tracetest/blocknative_test.go +++ b/eth/tracers/internal/tracetest/blocknative_test.go @@ -24,7 +24,10 @@ import ( "github.com/ethereum/go-ethereum/tests" ) -var testFileFlag = flag.String("file", "", "Name of the file to run the test for") +var ( + testFlagLogLevl = flag.String("loglevel", "info", "Log level to use") + testFlagFile = flag.String("file", "", "Name of the file to run the test for") +) func TestMain(m *testing.M) { flag.Parse() @@ -51,7 +54,7 @@ type blocknativeTracerTest struct { } func TestBlocknativeTracer(t *testing.T) { - log.Root().SetHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(true))) + setLogging(t) testsCases, err := loadTestTxs("blocknative") if err != nil { @@ -64,8 +67,8 @@ func TestBlocknativeTracer(t *testing.T) { testsCases = append(testsCases, decodingTestsCases...) for _, test := range testsCases { - if *testFileFlag != "" { - a := strings.ToLower(*testFileFlag) + if *testFlagFile != "" { + a := strings.ToLower(*testFlagFile) b := strings.ToLower(test.name) if a != b { continue @@ -168,6 +171,19 @@ func benchmarkBlocknativeTracer(b *testing.B, decode bool, dirPaths ...string) { } } +func setLogging(t testing.TB) { + logHandler := log.StreamHandler(os.Stdout, log.TerminalFormat(true)) + level := log.LvlDebug + if *testFlagLogLevl != "" { + var err error + level, err = log.LvlFromString(*testFlagLogLevl) + if err != nil { + t.Fatal(err) + } + } + log.Root().SetHandler(log.LvlFilterHandler(level, logHandler)) +} + func loadTestTxs(dirPath string) ([]*blocknativeTracerTest, error) { files, err := os.ReadDir(filepath.Join("testdata", dirPath)) if err != nil { From 1fd5854d568d21e6b1cc1463c54a7b3a8bd3bb07 Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Sat, 23 Sep 2023 15:59:57 -0400 Subject: [PATCH 31/40] tests: Cleanup tracer test failure output. --- eth/tracers/internal/tracetest/blocknative_test.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/eth/tracers/internal/tracetest/blocknative_test.go b/eth/tracers/internal/tracetest/blocknative_test.go index 70025ee28916..c09d29ebdb6b 100644 --- a/eth/tracers/internal/tracetest/blocknative_test.go +++ b/eth/tracers/internal/tracetest/blocknative_test.go @@ -280,15 +280,14 @@ func executeTestCase(test *blocknativeTracerTest, t testing.TB, checkResult bool if checkResult && !tracesEqual(ret, test.Result) { // Below are prints to show differences if we fail, can always just check against the specific test json files too! - fmt.Println("Trace return: ") + fmt.Println("Got Trace:") x, _ := json.Marshal(ret) - // //x, _ := json.MarshalIndent(ret, "", " ") - // y, _ := json.Marshal(test.Result) fmt.Println(string(x)) - fmt.Println("test.Result") + + // fmt.Println("Expected Trace:") + // y, _ := json.Marshal(test.Result) // fmt.Println(string(y)) t.Fatal("traces mismatch") - // t.Fatalf("trace mismatch: \nhave %+v\nwant %+v", ret, test.Result) } } From 17941a579a34921f1df8fdd75448722268b563b8 Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Sat, 23 Sep 2023 16:18:27 -0400 Subject: [PATCH 32/40] tests,fix: Clear decoder cache between tests. --- eth/tracers/blocknative/tracer.go | 6 ++++++ eth/tracers/internal/tracetest/blocknative_test.go | 2 ++ 2 files changed, 8 insertions(+) diff --git a/eth/tracers/blocknative/tracer.go b/eth/tracers/blocknative/tracer.go index c407548b309d..7fa4841a7b35 100644 --- a/eth/tracers/blocknative/tracer.go +++ b/eth/tracers/blocknative/tracer.go @@ -242,6 +242,12 @@ func finalizeCallFrame(call *CallFrame, output []byte, gasUsed uint64, err error call.Output = bytesToHex(output) } +// EmptyCache is for testing purposes. It clears the global cache so tests don't +// interfere with each other. +func EmptyCache() { + decoderCache = decoder.NewCaches() +} + // // Unused interface methods. // diff --git a/eth/tracers/internal/tracetest/blocknative_test.go b/eth/tracers/internal/tracetest/blocknative_test.go index c09d29ebdb6b..cb5f9c07d1e7 100644 --- a/eth/tracers/internal/tracetest/blocknative_test.go +++ b/eth/tracers/internal/tracetest/blocknative_test.go @@ -264,6 +264,8 @@ func loadTestTxs(dirPath string) ([]*blocknativeTracerTest, error) { } func executeTestCase(test *blocknativeTracerTest, t testing.TB, checkResult bool) { + blocknative.EmptyCache() + st := core.NewStateTransition(test.evm, test.msg, new(core.GasPool).AddGas(test.tx.Gas())) if _, err := st.TransitionDb(); err != nil { t.Fatalf("failed to execute transaction: %v", err) From 0236ae680497dd8030a55ad2cbc57464c4d820a3 Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Fri, 22 Sep 2023 22:19:43 -0400 Subject: [PATCH 33/40] refactor: Defer CallFrame serialization to the end. --- eth/tracers/blocknative/blocknative.go | 31 ++++++++-------- eth/tracers/blocknative/tracer.go | 51 ++++++++++++++++---------- eth/tracers/blocknative/utils.go | 36 ++++++++++-------- 3 files changed, 68 insertions(+), 50 deletions(-) diff --git a/eth/tracers/blocknative/blocknative.go b/eth/tracers/blocknative/blocknative.go index fd1517a8672d..c67fe0ba8894 100644 --- a/eth/tracers/blocknative/blocknative.go +++ b/eth/tracers/blocknative/blocknative.go @@ -4,6 +4,7 @@ import ( "encoding/json" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/tracers/blocknative/decoder" ) @@ -40,24 +41,24 @@ type Trace struct { // BlockContext contains information about the block we simulate transactions in. type BlockContext struct { - Number uint64 `json:"number"` - StateRoot string `json:"stateRoot,omitempty"` - BaseFee uint64 `json:"baseFee"` - Time uint64 `json:"time"` - Coinbase string `json:"coinbase"` - GasLimit uint64 `json:"gasLimit"` - Random string `json:"random,omitempty"` + Number uint64 `json:"number"` + BaseFee uint64 `json:"baseFee"` + Time uint64 `json:"time"` + GasLimit uint64 `json:"gasLimit"` + Coinbase common.Address `json:"coinbase"` + StateRoot hexutil.Bytes `json:"stateRoot,omitempty"` + Random common.Hash `json:"random,omitempty"` } type CallFrame struct { Type string `json:"type"` - From string `json:"from"` - To string `json:"to,omitempty"` - Value string `json:"value,omitempty"` - Gas string `json:"gas"` - GasUsed string `json:"gasUsed"` - Input string `json:"input"` - Output string `json:"output,omitempty"` + From common.Address `json:"from"` + To common.Address `json:"to,omitempty"` + Value Big `json:"value,omitempty"` + Gas Uint64 `json:"gas"` + GasUsed Uint64 `json:"gasUsed"` + Input hexutil.Bytes `json:"input"` + Output hexutil.Bytes `json:"output,omitempty"` Error string `json:"error,omitempty"` ErrorReason string `json:"errorReason,omitempty"` Calls []CallFrame `json:"calls,omitempty"` @@ -70,7 +71,7 @@ type CallLog struct { Address common.Address `json:"address"` // Data is the encoded memory provided with the log. - Data string `json:"data"` + Data hexutil.Bytes `json:"data"` // Topics is a slice of up to 4 32byte words provided with the log. Topics []common.Hash `json:"topics"` diff --git a/eth/tracers/blocknative/tracer.go b/eth/tracers/blocknative/tracer.go index 7fa4841a7b35..2b7d839044d4 100644 --- a/eth/tracers/blocknative/tracer.go +++ b/eth/tracers/blocknative/tracer.go @@ -70,7 +70,7 @@ func NewTracerWithOpts(opts TracerOpts) (Tracer, error) { // call-frame. func (t *tracer) SetStateRoot(root common.Hash) { if t.trace.BlockContext != nil { - t.trace.BlockContext.StateRoot = bytesToHex(root.Bytes()) + t.trace.BlockContext.StateRoot = root.Bytes() } } @@ -89,21 +89,25 @@ func (t *tracer) CaptureStart(evm *vm.EVM, from common.Address, to common.Addres t.trace.BlockContext.Number = evm.Context.BlockNumber.Uint64() t.trace.BlockContext.BaseFee = evm.Context.BaseFee.Uint64() t.trace.BlockContext.Time = evm.Context.Time - t.trace.BlockContext.Coinbase = addrToHex(evm.Context.Coinbase) + t.trace.BlockContext.Coinbase = evm.Context.Coinbase t.trace.BlockContext.GasLimit = evm.Context.GasLimit if evm.Context.Random != nil { - t.trace.BlockContext.Random = bytesToHex(evm.Context.Random.Bytes()) + copy(t.trace.BlockContext.Random[:], evm.Context.Random[:]) } } // Create a call-frame for the top-level call. + var bigValue Big + if value != nil { + bigValue = Big(*value) + } t.callStack[0] = CallFrame{ Type: "CALL", - From: addrToHex(from), - To: addrToHex(to), - Input: bytesToHex(input), - Gas: uintToHex(gas), - Value: bigToHex(value), + From: from, + To: to, + Input: cloneBytes(input), + Gas: Uint64(gas), + Value: bigValue, } if create { t.callStack[0].Type = "CREATE" @@ -126,7 +130,7 @@ func (t *tracer) CaptureEnd(output []byte, gasUsed uint64, err error) { for _, stateLog := range t.evm.StateDB.Logs() { t.trace.Logs = append(t.trace.Logs, CallLog{ Address: stateLog.Address, - Data: bytesToHex(stateLog.Data), + Data: stateLog.Data, Topics: stateLog.Topics, }) } @@ -149,13 +153,17 @@ func (t *tracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Addr } // Create CallFrame, decode it, and all it to the end of the callstack. + var bigValue Big + if value != nil { + bigValue = Big(*value) + } call := CallFrame{ Type: typ.String(), - From: addrToHex(from), - To: addrToHex(to), - Input: bytesToHex(input), - Gas: uintToHex(gas), - Value: bigToHex(value), + From: from, + To: to, + Input: cloneBytes(input), + Gas: Uint64(gas), + Value: bigValue, } if t.opts.Decode { if decoded, err := t.decoder.DecodeCallFrame(from, to, value, input); err == nil { @@ -221,25 +229,30 @@ func (t *tracer) GetResult() (json.RawMessage, error) { } func finalizeCallFrame(call *CallFrame, output []byte, gasUsed uint64, err error) { - call.GasUsed = uintToHex(gasUsed) + call.GasUsed = Uint64(gasUsed) // If there was an error then try decoding it and stop. if err != nil { call.Error = err.Error() if err.Error() == "execution reverted" && len(output) > 0 { - call.Output = bytesToHex(output) + call.Output = output revertReason, _ := abi.UnpackRevert(output) call.ErrorReason = revertReason } if call.Type == "CREATE" || call.Type == "CREATE2" { - call.To = "" + call.To = common.Address{} } return } - // The call was successful so decode the output. - call.Output = bytesToHex(output) + call.Output = output +} + +func cloneBytes(src []byte) []byte { + dst := make([]byte, len(src)) + copy(dst, src) + return dst } // EmptyCache is for testing purposes. It clears the global cache so tests don't diff --git a/eth/tracers/blocknative/utils.go b/eth/tracers/blocknative/utils.go index 96d9262d4c72..ec53adad97f3 100644 --- a/eth/tracers/blocknative/utils.go +++ b/eth/tracers/blocknative/utils.go @@ -1,31 +1,35 @@ package blocknative import ( - "encoding/hex" "math/big" "strconv" - "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" ) -func bytesToHex(s []byte) string { - return "0x" + common.Bytes2Hex(s) +// Big overrides hexutil.Big to to use a faster serialization method. +type Big hexutil.Big + +// MarshalText implements encoding.TextMarshaler +func (b Big) MarshalText() ([]byte, error) { + b2 := big.Int(b) + return []byte("0x" + b2.Text(16)), nil } -func bigToHex(n *big.Int) string { - if n == nil { - return "" - } - return "0x" + n.Text(16) +func (b Big) UnmarshalJSON(input []byte) error { + b2 := hexutil.Big(b) + return b2.UnmarshalJSON(input) } -func uintToHex(n uint64) string { - return "0x" + strconv.FormatUint(n, 16) +// Uint64 overrides hexutil.Uint64 to to use a faster serialization method. +type Uint64 hexutil.Uint64 + +// MarshalText implements encoding.TextMarshaler. +func (b Uint64) MarshalText() ([]byte, error) { + return []byte("0x" + strconv.FormatUint(uint64(b), 16)), nil } -func addrToHex(a common.Address) string { - var buf [len(a)*2 + 2]byte - copy(buf[:2], "0x") - hex.Encode(buf[2:], a[:]) - return string(buf[:]) +func (b Uint64) UnmarshalJSON(input []byte) error { + u := hexutil.Uint64(b) + return u.UnmarshalJSON(input) } From a527547f5f1872fb7ba2582a8f24f777aeefecea Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Fri, 22 Sep 2023 22:33:12 -0400 Subject: [PATCH 34/40] refactor: Move decoder evm calls to their own file. --- eth/tracers/blocknative/decoder/asset.go | 93 ++----------------- eth/tracers/blocknative/decoder/evm_caller.go | 92 ++++++++++++++++++ 2 files changed, 101 insertions(+), 84 deletions(-) create mode 100644 eth/tracers/blocknative/decoder/evm_caller.go diff --git a/eth/tracers/blocknative/decoder/asset.go b/eth/tracers/blocknative/decoder/asset.go index c797752b8a0b..8f9f043ea427 100644 --- a/eth/tracers/blocknative/decoder/asset.go +++ b/eth/tracers/blocknative/decoder/asset.go @@ -2,9 +2,10 @@ package decoder import ( "fmt" + "math/big" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" - "math/big" ) var ( @@ -45,13 +46,13 @@ func decodeERC20Metadata(evmCall evmCallFn, addr common.Address) AssetMetadata { var err error metadata := AssetMetadata{Type: AssetTypeERC20} - if metadata.Name, err = decodeMetadataName(evmCall, addr); err != nil { + if metadata.Name, err = evmCallMethodName(evmCall, addr); err != nil { log.Trace("failed to decode ERC20 name", "err", err) } - if metadata.Symbol, err = decodeMetadataSymbol(evmCall, addr); err != nil { + if metadata.Symbol, err = evmCallMethodSymbol(evmCall, addr); err != nil { log.Trace("failed to decode ERC20 symbol", "err", err) } - if metadata.Decimals, err = decodeMetadataDecimals(evmCall, addr); err != nil { + if metadata.Decimals, err = evmCallMethodDecimals(evmCall, addr); err != nil { log.Trace("failed to decode ERC20 decimals", "err", err) } @@ -63,13 +64,13 @@ func decodeERC721Metadata(evmCall evmCallFn, addr common.Address, tokenID *big.I var err error metadata := AssetMetadata{Type: AssetTypeERC721} - if metadata.Name, err = decodeMetadataName(evmCall, addr); err != nil { + if metadata.Name, err = evmCallMethodName(evmCall, addr); err != nil { log.Trace("failed to decode ERC721 name", "err", err) } - if metadata.Symbol, err = decodeMetadataSymbol(evmCall, addr); err != nil { + if metadata.Symbol, err = evmCallMethodSymbol(evmCall, addr); err != nil { log.Trace("failed to decode ERC721 symbol", "err", err) } - if metadata.URI, err = decodeMetadataTokenURI(evmCall, addr, tokenID); err != nil { + if metadata.URI, err = evmCallMethodTokenURI(evmCall, addr, tokenID); err != nil { log.Trace("failed to decode ERC721 tokenURI", "err", err) } @@ -81,89 +82,13 @@ func decodeERC1155Metadata(evmCall evmCallFn, addr common.Address, tokenID *big. var err error metadata := AssetMetadata{Type: AssetTypeERC1155} - if metadata.URI, err = decodeMetadataURI(evmCall, addr, tokenID); err != nil { + if metadata.URI, err = evmCallMethodURI(evmCall, addr, tokenID); err != nil { log.Trace("failed to decode ERC1155 URI", "err", err) } return metadata } -// decodeMetadataName decodes the name of an asset from the EVM. -func decodeMetadataName(evmCall evmCallFn, addr common.Address) (string, error) { - return callAndDecodeString(evmCall, addr, methodIDName) -} - -// decodeMetadataSymbol decodes the symbol of an asset from the EVM. -func decodeMetadataSymbol(evmCall evmCallFn, addr common.Address) (string, error) { - return callAndDecodeString(evmCall, addr, methodIDSymbol) -} - -// decodeMetadataDecimals decodes the decimals of an asset from the EVM. -func decodeMetadataDecimals(evmCall evmCallFn, addr common.Address) (uint8, error) { - return callAndDecodeUint8(evmCall, addr, methodIDDecimals) -} - -// decodeMetadataTokenURI decodes the tokenURI of an asset from the EVM. -func decodeMetadataTokenURI(evmCall evmCallFn, addr common.Address, tokenID *big.Int) (string, error) { - tokenIDBytes := tokenID.Bytes() - if len(tokenIDBytes) > 32 { - return "", fmt.Errorf("tokenID is too large") - } - common.LeftPadBytes(tokenIDBytes, 32) - input := append(methodIDTokenURI, tokenIDBytes...) - return callAndDecodeString(evmCall, addr, input) -} - -// decodeMetadataURI decodes the URI of an asset from the EVM. -func decodeMetadataURI(evmCall evmCallFn, addr common.Address, tokenID *big.Int) (string, error) { - tokenIDBytes := tokenID.Bytes() - if len(tokenIDBytes) > 32 { - return "", fmt.Errorf("tokenID is too large") - } - common.LeftPadBytes(tokenIDBytes, 32) - input := append(methodIDURI, tokenIDBytes...) - return callAndDecodeString(evmCall, addr, input) -} - -// callAndDecodeString calls a method and decodes the result as a string. -func callAndDecodeString(evmCall evmCallFn, addr common.Address, method []byte) (string, error) { - // Load bytes from the EVM. - stringBytes, err := evmCall(addr, method) - if err != nil { - return "", err - } - - // Parse into a string. - stringInterface, err := abiArgs.singleString.Unpack(stringBytes) - if err != nil { - return "", err - } - if len(stringInterface) < len(abiArgs.singleString) { - return "", fmt.Errorf("unexpected decoded size") - } - str, ok := stringInterface[0].(string) - if !ok { - return "", fmt.Errorf("unexpected type for decoded string") - } - - return str, nil -} - -// callAndDecodeUint8 calls a method and decodes the result as a uint8. -func callAndDecodeUint8(evmCall evmCallFn, addr common.Address, method []byte) (uint8, error) { - // Load bytes from the EVM. - uint8Bytes, err := evmCall(addr, method) - if err != nil { - return 0, err - } - - // Parse into a uint8. - if len(uint8Bytes) < 1 { - return 0, fmt.Errorf("unexpected decoded size") - } - return uint8Bytes[len(uint8Bytes)-1], nil -} - // decodeArgsSafeBatchTransferFrom calls a method and decodes the result as a uint256[]. func decodeArgsSafeBatchTransferFrom(bytes []byte) ([]*Transfer, error) { args, err := abiArgs.batchTransfer.UnpackValues(bytes) diff --git a/eth/tracers/blocknative/decoder/evm_caller.go b/eth/tracers/blocknative/decoder/evm_caller.go new file mode 100644 index 000000000000..693761ef0c86 --- /dev/null +++ b/eth/tracers/blocknative/decoder/evm_caller.go @@ -0,0 +1,92 @@ +package decoder + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" +) + +// +// General callers +// + +// callAndDecodeString calls a method and decodes the result as a string. +func callAndDecodeString(evmCall evmCallFn, addr common.Address, method []byte) (string, error) { + // Load bytes from the EVM. + stringBytes, err := evmCall(addr, method) + if err != nil { + return "", err + } + + // Parse into a string. + stringInterface, err := abiArgs.singleString.Unpack(stringBytes) + if err != nil { + return "", err + } + if len(stringInterface) < len(abiArgs.singleString) { + return "", fmt.Errorf("unexpected decoded size") + } + str, ok := stringInterface[0].(string) + if !ok { + return "", fmt.Errorf("unexpected type for decoded string") + } + + return str, nil +} + +// callAndDecodeUint8 calls a method and decodes the result as a uint8. +func callAndDecodeUint8(evmCall evmCallFn, addr common.Address, method []byte) (uint8, error) { + // Load bytes from the EVM. + uint8Bytes, err := evmCall(addr, method) + if err != nil { + return 0, err + } + + // Parse into a uint8. + if len(uint8Bytes) < 1 { + return 0, fmt.Errorf("unexpected decoded size") + } + return uint8Bytes[len(uint8Bytes)-1], nil +} + +// +// Specific method callers +// + +// evmCallMethodName decodes the name of an asset from the EVM. +func evmCallMethodName(evmCall evmCallFn, addr common.Address) (string, error) { + return callAndDecodeString(evmCall, addr, methodIDName) +} + +// evmCallMethodSymbol decodes the symbol of an asset from the EVM. +func evmCallMethodSymbol(evmCall evmCallFn, addr common.Address) (string, error) { + return callAndDecodeString(evmCall, addr, methodIDSymbol) +} + +// evmCallMethodDecimals decodes the decimals of an asset from the EVM. +func evmCallMethodDecimals(evmCall evmCallFn, addr common.Address) (uint8, error) { + return callAndDecodeUint8(evmCall, addr, methodIDDecimals) +} + +// evmCallMethodTokenURI decodes the tokenURI of an asset from the EVM. +func evmCallMethodTokenURI(evmCall evmCallFn, addr common.Address, tokenID *big.Int) (string, error) { + tokenIDBytes := tokenID.Bytes() + if len(tokenIDBytes) > 32 { + return "", fmt.Errorf("tokenID is too large") + } + common.LeftPadBytes(tokenIDBytes, 32) + input := append(methodIDTokenURI, tokenIDBytes...) + return callAndDecodeString(evmCall, addr, input) +} + +// evmCallMethodURI decodes the URI of an asset from the EVM. +func evmCallMethodURI(evmCall evmCallFn, addr common.Address, tokenID *big.Int) (string, error) { + tokenIDBytes := tokenID.Bytes() + if len(tokenIDBytes) > 32 { + return "", fmt.Errorf("tokenID is too large") + } + common.LeftPadBytes(tokenIDBytes, 32) + input := append(methodIDURI, tokenIDBytes...) + return callAndDecodeString(evmCall, addr, input) +} From 3b21854410f1ef1d4e2d35b5d982b4e78c253579 Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Fri, 22 Sep 2023 23:27:53 -0400 Subject: [PATCH 35/40] feature: Capture token transfer taxes. --- eth/tracers/blocknative/decoder/balances.go | 6 +- eth/tracers/blocknative/decoder/contract.go | 12 +- eth/tracers/blocknative/decoder/decoder.go | 127 +++++++++++- eth/tracers/blocknative/decoder/evm_caller.go | 39 +++- eth/tracers/blocknative/decoder/types.go | 7 +- eth/tracers/blocknative/tracer.go | 30 ++- .../erc20_transfer_with_tax.json | 189 ++++++++++++++++++ 7 files changed, 373 insertions(+), 37 deletions(-) create mode 100644 eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/erc20_transfer_with_tax.json diff --git a/eth/tracers/blocknative/decoder/balances.go b/eth/tracers/blocknative/decoder/balances.go index e3e16e60c03e..a153487e3527 100644 --- a/eth/tracers/blocknative/decoder/balances.go +++ b/eth/tracers/blocknative/decoder/balances.go @@ -18,13 +18,15 @@ func newBalances() *balances { } } -// captureCall decodes potential balance change data out of calldata. -func (bt *balances) captureCall(sender common.Address, receiver common.Address, value *Amount, decoded *CallFrame) { +// captureCallFrameStart decodes potential balance change data out of calldata. +func (bt *balances) captureCallFrameStart(sender common.Address, receiver common.Address, value *Amount, decoded *CallFrame) { // Add the native transfer. if value != nil && value.ToInt().Sign() > 0 { bt.balanceChanges.addAssetTransfer(EthAsset, sender, receiver, value) } +} +func (bt *balances) captureCallFrameEnd(decoded *CallFrame) { if decoded == nil { return } diff --git a/eth/tracers/blocknative/decoder/contract.go b/eth/tracers/blocknative/decoder/contract.go index cd967c5a45df..195a31b4cdb3 100644 --- a/eth/tracers/blocknative/decoder/contract.go +++ b/eth/tracers/blocknative/decoder/contract.go @@ -2,18 +2,14 @@ package decoder import ( "bytes" + "golang.org/x/exp/slices" ) // decodeContract decodes the contract bytecode and determines all interfaces -func decodeContract(bytecode ByteCode) (*Contract, error) { - - interfaces := bytecode.DecodeInterfaces() - - return &Contract{ - interfaces: interfaces, - Type: contractTypeForInterfaces(interfaces), - }, nil +func decodeContract(c *Contract, bytecode ByteCode) { + c.interfaces = bytecode.DecodeInterfaces() + c.Type = contractTypeForInterfaces(c.interfaces) } // IsERC20 returns true iff the contract interfaces contains ERC-20. diff --git a/eth/tracers/blocknative/decoder/decoder.go b/eth/tracers/blocknative/decoder/decoder.go index c0f0e26488dd..084b9b6c937d 100644 --- a/eth/tracers/blocknative/decoder/decoder.go +++ b/eth/tracers/blocknative/decoder/decoder.go @@ -2,9 +2,10 @@ package decoder import ( "errors" + "math/big" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" - "math/big" ) var ( @@ -30,7 +31,7 @@ func New(caches *Caches, evm evm) *Decoder { // DecodeCallFrame decodes the given call frame into its method and arguments. // If the call frame is determined to represent one or more Asset transfers we // add those too. -func (d *Decoder) DecodeCallFrame(sender common.Address, receiver common.Address, value *big.Int, input []byte) (*CallFrame, error) { +func (d *Decoder) DecodeCallFrameStart(sender common.Address, receiver common.Address, value *big.Int, input []byte) (*CallFrame, error) { contract, err := d.DecodeContract(receiver) if err != nil { return nil, err @@ -54,15 +55,126 @@ func (d *Decoder) DecodeCallFrame(sender common.Address, receiver common.Address continue } transfer.Asset.AssetMetadata = assetMetadata + + // If the transfer is taxable, get balances for the sender, receiver, and contract. + switch contract.Type { + case ContractTypeERC20: + if transfer.balanceBeforeTo, err = evmCallMethodBalanceOf(d.evm.CallCode, receiver, transfer.To); err != nil { + log.Trace("failed to get balance before", "err", err) + continue + } + if transfer.balanceBeforeContract, err = evmCallMethodBalanceOf(d.evm.CallCode, receiver, receiver); err != nil { + log.Trace("failed to get balance before", "err", err) + continue + } + case ContractTypeERC1155: + if transfer.balanceBeforeTo, err = evmCallMethodBalanceOf2(d.evm.CallCode, receiver, transfer.To, transfer.TokenID); err != nil { + log.Trace("failed to get balance before", "err", err) + return nil, err + } + if transfer.balanceBeforeContract, err = evmCallMethodBalanceOf2(d.evm.CallCode, receiver, receiver, transfer.TokenID); err != nil { + log.Trace("failed to get balance before", "err", err) + return nil, err + } + } } cf := &CallFrame{Contract: contract, CallData: callData} - d.balances.captureCall(sender, receiver, NewAmount(value), cf) + d.balances.captureCallFrameStart(sender, receiver, NewAmount(value), cf) return cf, nil } +func (d *Decoder) DecodeCallFrameEnd(cf *CallFrame) error { + if cf == nil || cf.Contract == nil || cf.CallData == nil { + return nil + } + + // Check updated balances for taxable transfers and look for active taxes. + // If we find them, add them as new transfers. + transfers := cf.CallData.Transfers + for _, transfer := range transfers { + // First check if we set a balanceBeforeTo. If we didn't then we can't + // utilize this inference. + if transfer.balanceBeforeTo == nil { + continue + } + + // Get the balance after the transfer. At this point balanceOf worked + // once so we don't expect it to fail. If it does then we report it as + // an error so we can inspect later, and then we continue to the next + // transfer. + var ( + err error + balanceAfterTo *big.Int + ) + switch cf.Contract.Type { + case ContractTypeERC20: + if balanceAfterTo, err = evmCallMethodBalanceOf(d.evm.CallCode, cf.Contract.address, transfer.To); err != nil { + log.Error("failed to get balance after for receiver", "err", err) + continue + } + case ContractTypeERC1155: + if balanceAfterTo, err = evmCallMethodBalanceOf2(d.evm.CallCode, cf.Contract.address, transfer.To, transfer.TokenID); err != nil { + log.Error("failed to get balance after for receiver", "err", err) + continue + } + default: + continue + } + + // If the increase in balance of the transfer recipient is less than we + // decoded it to be, then we know that the transfer was taxed. + // + // We don't know where the tax went but it will often go to the contract + // itself so we check the contract balance to see if that's the case. + decodedValue := transfer.Value.ToInt() + deltaTo := balanceAfterTo.Sub(balanceAfterTo, transfer.balanceBeforeTo) + if deltaTo.Cmp(decodedValue) < 0 { + // First, update the transfer value to the actual delta. + transfer.Value = NewAmount(deltaTo) + + // Now let's see if the contract was the tax recipient. + balanceAfterContract, err := evmCallMethodBalanceOf(d.evm.CallCode, cf.Contract.address, cf.Contract.address) + if err != nil { + log.Error("failed to get balance after for contract", "err", err) + continue + } + deltaContract := balanceAfterContract.Sub(balanceAfterContract, transfer.balanceBeforeContract) + if deltaContract.Sign() == 1 { + // The contract balance increased so we know at least some of + // the tax went there. Add a tax transfer. + cf.Transfers = append(cf.Transfers, &Transfer{ + Asset: transfer.Asset, + From: transfer.From, + + To: cf.Contract.address, + Value: NewAmount(deltaContract), + }) + } + + // Check to see if there was a tax amount not accounted for by + // subtracting the known deltas from the decoded value. + unaccountedTax := new(big.Int).Add(deltaTo, deltaContract) + unaccountedTax.Sub(decodedValue, unaccountedTax) + if unaccountedTax.Sign() == 1 { + cf.Transfers = append(cf.Transfers, &Transfer{ + Asset: transfer.Asset, + From: transfer.From, + + To: common.Address{}, + Value: NewAmount(unaccountedTax), + }) + } + } + } + + d.balances.captureCallFrameEnd(cf) + + return nil +} + // DecodeContract decodes the contract at the given address. func (d *Decoder) DecodeContract(addr common.Address) (*Contract, error) { // Check the cache for an existing entry. @@ -84,10 +196,8 @@ func (d *Decoder) DecodeContract(addr common.Address) (*Contract, error) { } // We have an unknown contract; decode itm, add it to the cache, and return it. - contract, err := decodeContract(bytecode) - if err != nil { - return nil, err - } + contract = &Contract{address: addr} + decodeContract(contract, bytecode) d.caches.contracts.Add(addr, contract) return contract, nil } @@ -121,14 +231,11 @@ func (d *Decoder) decodeAsset(contract *Contract, assetID AssetID) (*AssetMetada } // Cache miss; decode and add to the cache. - asset, err := DecodeAsset(d.evm.CallCode, contract, assetID) if err != nil { return nil, err } - d.caches.assets.Add(assetID, asset) - return asset, nil } diff --git a/eth/tracers/blocknative/decoder/evm_caller.go b/eth/tracers/blocknative/decoder/evm_caller.go index 693761ef0c86..4fb0773fc3c9 100644 --- a/eth/tracers/blocknative/decoder/evm_caller.go +++ b/eth/tracers/blocknative/decoder/evm_caller.go @@ -12,9 +12,9 @@ import ( // // callAndDecodeString calls a method and decodes the result as a string. -func callAndDecodeString(evmCall evmCallFn, addr common.Address, method []byte) (string, error) { +func callAndDecodeString(evmCall evmCallFn, addr common.Address, msg []byte) (string, error) { // Load bytes from the EVM. - stringBytes, err := evmCall(addr, method) + stringBytes, err := evmCall(addr, msg) if err != nil { return "", err } @@ -36,9 +36,9 @@ func callAndDecodeString(evmCall evmCallFn, addr common.Address, method []byte) } // callAndDecodeUint8 calls a method and decodes the result as a uint8. -func callAndDecodeUint8(evmCall evmCallFn, addr common.Address, method []byte) (uint8, error) { +func callAndDecodeUint8(evmCall evmCallFn, addr common.Address, msg []byte) (uint8, error) { // Load bytes from the EVM. - uint8Bytes, err := evmCall(addr, method) + uint8Bytes, err := evmCall(addr, msg) if err != nil { return 0, err } @@ -50,6 +50,15 @@ func callAndDecodeUint8(evmCall evmCallFn, addr common.Address, method []byte) ( return uint8Bytes[len(uint8Bytes)-1], nil } +// callAndDecodeBigInt calls a method and decodes the result as a *big.Int. +func callAndDecodeBigInt(evmCall evmCallFn, addr common.Address, msg []byte) (*big.Int, error) { + bigIntBytes, err := evmCall(addr, msg) + if err != nil { + return nil, err + } + return new(big.Int).SetBytes(bigIntBytes), nil +} + // // Specific method callers // @@ -82,11 +91,23 @@ func evmCallMethodTokenURI(evmCall evmCallFn, addr common.Address, tokenID *big. // evmCallMethodURI decodes the URI of an asset from the EVM. func evmCallMethodURI(evmCall evmCallFn, addr common.Address, tokenID *big.Int) (string, error) { - tokenIDBytes := tokenID.Bytes() - if len(tokenIDBytes) > 32 { - return "", fmt.Errorf("tokenID is too large") - } - common.LeftPadBytes(tokenIDBytes, 32) + tokenIDBytes := common.LeftPadBytes(tokenID.Bytes(), 32) input := append(methodIDURI, tokenIDBytes...) return callAndDecodeString(evmCall, addr, input) } + +// evmCallMethodBalanceOf decodes the balance of an asset from the EVM. +func evmCallMethodBalanceOf(evmCall evmCallFn, addr common.Address, owner common.Address) (*big.Int, error) { + ownerBytes := common.LeftPadBytes(owner.Bytes(), 32) + input := append(methodIDBalanceOf, ownerBytes...) + return callAndDecodeBigInt(evmCall, addr, input) +} + +// evmCallMethodBalanceOf2 decodes the balance of an asset from the EVM. +func evmCallMethodBalanceOf2(evmCall evmCallFn, addr common.Address, owner common.Address, tokenID *big.Int) (*big.Int, error) { + tokenIDBytes := common.LeftPadBytes(tokenID.Bytes(), 32) + ownerBytes := common.LeftPadBytes(owner.Bytes(), 32) + input := append(methodIDBalanceOf2, ownerBytes...) + input = append(input, tokenIDBytes...) + return callAndDecodeBigInt(evmCall, addr, input) +} diff --git a/eth/tracers/blocknative/decoder/types.go b/eth/tracers/blocknative/decoder/types.go index 251470e80268..34194f491e59 100644 --- a/eth/tracers/blocknative/decoder/types.go +++ b/eth/tracers/blocknative/decoder/types.go @@ -3,8 +3,9 @@ package decoder import ( "encoding/json" "fmt" - "github.com/ethereum/go-ethereum/common" "math/big" + + "github.com/ethereum/go-ethereum/common" ) type CallFrame struct { @@ -14,6 +15,7 @@ type CallFrame struct { type Contract struct { Type ContractType `json:"type,omitempty"` + address common.Address interfaces []Interface } @@ -30,6 +32,9 @@ type Transfer struct { To common.Address `json:"to"` Value *Amount `json:"value"` TokenID *big.Int `json:"tokenID,omitempty"` + + balanceBeforeTo *big.Int + balanceBeforeContract *big.Int } type Asset struct { diff --git a/eth/tracers/blocknative/tracer.go b/eth/tracers/blocknative/tracer.go index 2b7d839044d4..6e4658d8b184 100644 --- a/eth/tracers/blocknative/tracer.go +++ b/eth/tracers/blocknative/tracer.go @@ -10,6 +10,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/tracers/blocknative/decoder" + "github.com/ethereum/go-ethereum/log" ) var ( @@ -115,7 +116,7 @@ func (t *tracer) CaptureStart(evm *vm.EVM, from common.Address, to common.Addres // Try adding decode information, but don't fail if we can't. if t.opts.Decode { - if decoded, err := t.decoder.DecodeCallFrame(from, to, value, input); err == nil { + if decoded, err := t.decoder.DecodeCallFrameStart(from, to, value, input); err == nil { t.callStack[0].Decoded = decoded } } @@ -123,7 +124,9 @@ func (t *tracer) CaptureStart(evm *vm.EVM, from common.Address, to common.Addres // CaptureEnd is called after the top-level call finishes to finalize tracing. func (t *tracer) CaptureEnd(output []byte, gasUsed uint64, err error) { - finalizeCallFrame(&t.callStack[0], output, gasUsed, err) + if err := t.finalizeCallFrame(&t.callStack[0], output, gasUsed, err); err != nil { + log.Error("failed to finalize call frame", "err", err) + } // If the user wants the logs, grab them from the state if t.opts.Logs { @@ -166,7 +169,7 @@ func (t *tracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Addr Value: bigValue, } if t.opts.Decode { - if decoded, err := t.decoder.DecodeCallFrame(from, to, value, input); err == nil { + if decoded, err := t.decoder.DecodeCallFrameStart(from, to, value, input); err == nil { call.Decoded = decoded } } @@ -183,15 +186,20 @@ func (t *tracer) CaptureExit(output []byte, gasUsed uint64, err error) { } // We have a call-frame, so finalize it. - finalizeCallFrame(&t.callStack[size-1], output, gasUsed, err) + call := t.callStack[size-1] + if err := t.finalizeCallFrame(&call, output, gasUsed, err); err != nil { + log.Error("failed to finalize call frame", "err", err) + return + } // We have a parent call-frame, so nest this one under it. if size <= 1 { return } + // Pop our call of the stack. end := size - 1 - call := t.callStack[end] t.callStack = t.callStack[:end] + // Append this call to the parent's calls. end -= 1 t.callStack[end].Calls = append(t.callStack[end].Calls, call) } @@ -228,9 +236,16 @@ func (t *tracer) GetResult() (json.RawMessage, error) { return json.Marshal(trace) } -func finalizeCallFrame(call *CallFrame, output []byte, gasUsed uint64, err error) { +func (t *tracer) finalizeCallFrame(call *CallFrame, output []byte, gasUsed uint64, err error) error { call.GasUsed = Uint64(gasUsed) + // Finalize the decoding. + if t.opts.Decode && call.Decoded != nil { + if err := t.decoder.DecodeCallFrameEnd(call.Decoded); err != nil { + return err + } + } + // If there was an error then try decoding it and stop. if err != nil { call.Error = err.Error() @@ -243,10 +258,11 @@ func finalizeCallFrame(call *CallFrame, output []byte, gasUsed uint64, err error if call.Type == "CREATE" || call.Type == "CREATE2" { call.To = common.Address{} } - return + return nil } call.Output = output + return nil } func cloneBytes(src []byte) []byte { diff --git a/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/erc20_transfer_with_tax.json b/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/erc20_transfer_with_tax.json new file mode 100644 index 000000000000..1ee6ea8ab952 --- /dev/null +++ b/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/erc20_transfer_with_tax.json @@ -0,0 +1,189 @@ +{ + "genesis": { + "baseFeePerGas": "15276637384", + "difficulty": "0", + "extraData": "0x6275696c64657230783639", + "gasLimit": "30000000", + "hash": "0x8d67e46fc4bb9facbaeb26627d30e2567db96e66eb22c9f811a6f44e277b5ebf", + "miner": "0x4675C7e5BaAFBFFbca748158bEcBA61ef3b0a263", + "mixHash": "0x572668f17a2e0a384117e5ae5f062b1ab2bbb25213e509d1f95dce2f6f90c0f9", + "nonce": "0x0000000000000000", + "number": "16967879", + "stateRoot": "0xb0fe203965f60ee45cf6686f06e2f9b0fe228446b668b3a5c1466b4eabca1dca", + "timestamp": "1674198911", + "totalDifficulty": "5.8750003716598352816469e+22", + "alloc": { + "0xf527A5Ee2155fAD99A5bBB23c9e52B0a11b99dD4": { + "balance": "0x3C3A38E5AB72FC0000", + "nonce": "3" + }, + "0xc3761EB917CD790B30dAD99f6Cc5b4Ff93C4F9eA": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106100b45760003560e01c8063313ce56711610071578063313ce5671461015f57806370a082311461016e57806395d89b4114610197578063a9059cbb146101b6578063b632612b146101c9578063dd62ed3e146101d157600080fd5b806306fdde03146100b9578063095ea7b3146100f057806318160ddd1461011357806323b872dd1461012457806327e235e314610137578063300126ff14610157575b600080fd5b6040805180820190915260098152682a30bc102a37b5b2b760b91b60208201525b6040516100e791906102a1565b60405180910390f35b6101036100fe36600461030b565b6101df565b60405190151581526020016100e7565b60005b6040519081526020016100e7565b610103610132366004610335565b6101e8565b610116610145366004610371565b60006020819052908152604090205481565b610116600181565b604051600281526020016100e7565b61011661017c366004610371565b6001600160a01b031660009081526020819052604090205490565b6040805180820190915260038152620a882b60eb1b60208201526100da565b6101036101c436600461030b565b6101fc565b610116606481565b6101166100fe36600461038c565b60005b92915050565b60006101f4838361020f565b949350505050565b6000610208838361020f565b9392505050565b600080606461021f6001856103d5565b61022991906103ec565b90506000610237828561040e565b905080600080876001600160a01b03166001600160a01b03168152602001908152602001600020600082825461026d9190610421565b90915550503060009081526020819052604081208054849290610291908490610421565b9091555060019695505050505050565b600060208083528351808285015260005b818110156102ce578581018301518582016040015282016102b2565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b038116811461030657600080fd5b919050565b6000806040838503121561031e57600080fd5b610327836102ef565b946020939093013593505050565b60008060006060848603121561034a57600080fd5b610353846102ef565b9250610361602085016102ef565b9150604084013590509250925092565b60006020828403121561038357600080fd5b610208826102ef565b6000806040838503121561039f57600080fd5b6103a8836102ef565b91506103b6602084016102ef565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176101e2576101e26103bf565b60008261040957634e487b7160e01b600052601260045260246000fd5b500490565b818103818111156101e2576101e26103bf565b808201808211156101e2576101e26103bf56fea2646970667358221220cefe50dd4d581917165a9a4385cdd9446091c1e068ff1a11713ca3ceed8e7ad064736f6c63430008150033" + } + }, + "config": { + "chainId": 1, + "homesteadBlock": 10, + "eip150Block": 10, + "eip155Block": 10, + "eip158Block": 10, + "byzantiumBlock": 10, + "constantinopleBlock": 10, + "petersburgBlock": 10, + "istanbulBlock": 10, + "berlinBlock": 10, + "londonBlock": 10 + } + }, + "tracerConfig": { + "decode": true + }, + "context": { + "number": "16967879", + "difficulty": "58750003716598352816469", + "timestamp": "1674198923", + "gasLimit": "30000000", + "miner": "0x4675C7e5BaAFBFFbca748158bEcBA61ef3b0a263" + }, + "input": "0x02f8b301038505b3524e108505b3524e108405f5e10094c3761eb917cd790b30dad99f6cc5b4ff93c4f9ea80b844a9059cbb000000000000000000000000fba9f22d040e53e5fac36698080cee3dd3792262000000000000000000000000000000000000000000000207b733832c88c007cac080a07371e0060c5a04e594e52bc949f0155ef29c9205cfce0dffebe6cef23a68c8eba00ff5c780cf75d1e6eeb9d08719e2988bb09e1f4bd18af3ee357dd47186265160", + "result": { + "type": "CALL", + "from": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", + "to": "0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea", + "value": "0x0", + "gas": "0x0", + "gasUsed": "0x0", + "input": "0xa9059cbb000000000000000000000000fba9f22d040e53e5fac36698080cee3dd3792262000000000000000000000000000000000000000000000207b733832c88c007ca", + "output": "0x0000000000000000000000000000000000000000000000000000000000000001", + "decoded": { + "type": "erc20", + "method": "0xa9059cbb", + "signature": "transfer(address,uint256)", + "args": [ + "0xFbA9F22D040e53e5FAc36698080cee3dD3792262", + "9587061213415306430410" + ] + }, + "blockContext": { + "number": 16967879, + "baseFee": 16711680, + "time": 1674198923, + "gasLimit": 30000000, + "coinbase": "0x4675c7e5baafbffbca748158becba61ef3b0a263", + "stateRoot": "0x4b7559defbb79e8de7975492f30fb5f6fae2d5afc06ef5e4905d97e346355265", + "random": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "balanceChanges": [ + { + "address": "0xfba9f22d040e53e5fac36698080cee3dd3792262", + "balanceChanges": [ + { + "delta": "9491190601281153366106", + "asset": { + "address": "0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea", + "type": "erc20", + "name": "Tax Token", + "symbol": "TAX", + "decimals": 2 + }, + "breakdown": [ + { + "counterparty": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", + "amount": "9491190601281153366106" + } + ] + } + ] + }, + { + "address": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", + "balanceChanges": [ + { + "delta": "-9587061213415306430410", + "asset": { + "address": "0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea", + "type": "erc20", + "name": "Tax Token", + "symbol": "TAX", + "decimals": 2 + }, + "breakdown": [ + { + "counterparty": "0xfba9f22d040e53e5fac36698080cee3dd3792262", + "amount": "-9491190601281153366106" + }, + { + "counterparty": "0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea", + "amount": "-95870612134153064304" + } + ] + }, + { + "delta": "-1012435575212160", + "asset": { + "address": "0x0000000000000000000000000000000000000000", + "type": "eth", + "name": "Ether", + "symbol": "ETH", + "decimals": 18 + }, + "breakdown": [ + { + "counterparty": "0x0000000000000000000000000000000000000000", + "amount": "-691061391360" + }, + { + "counterparty": "0x4675c7e5baafbffbca748158becba61ef3b0a263", + "amount": "-1011744513820800" + } + ] + } + ] + }, + { + "address": "0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea", + "balanceChanges": [ + { + "delta": "95870612134153064304", + "asset": { + "address": "0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea", + "type": "erc20", + "name": "Tax Token", + "symbol": "TAX", + "decimals": 2 + }, + "breakdown": [ + { + "counterparty": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", + "amount": "95870612134153064304" + } + ] + } + ] + }, + { + "address": "0x4675c7e5baafbffbca748158becba61ef3b0a263", + "balanceChanges": [ + { + "delta": "1011744513820800", + "asset": { + "address": "0x0000000000000000000000000000000000000000", + "type": "eth", + "name": "Ether", + "symbol": "ETH", + "decimals": 18 + }, + "breakdown": [ + { + "counterparty": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", + "amount": "1011744513820800" + } + ] + } + ] + } + ] + } +} + \ No newline at end of file From a8dc05779581f6addbd6334f0a07d508b7d9d36d Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Sat, 23 Sep 2023 15:45:20 -0400 Subject: [PATCH 36/40] refactor: Use better errors in evm_caller. --- eth/tracers/blocknative/decoder/evm_caller.go | 42 +++++++++++-------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/eth/tracers/blocknative/decoder/evm_caller.go b/eth/tracers/blocknative/decoder/evm_caller.go index 4fb0773fc3c9..5e5bdd9b1fd0 100644 --- a/eth/tracers/blocknative/decoder/evm_caller.go +++ b/eth/tracers/blocknative/decoder/evm_caller.go @@ -7,6 +7,11 @@ import ( "github.com/ethereum/go-ethereum/common" ) +var ( + ErrUnexpectedDecodedSize = fmt.Errorf("unexpected decoded size") + ErrUnexpectedType = fmt.Errorf("unexpected type") +) + // // General callers // @@ -14,22 +19,22 @@ import ( // callAndDecodeString calls a method and decodes the result as a string. func callAndDecodeString(evmCall evmCallFn, addr common.Address, msg []byte) (string, error) { // Load bytes from the EVM. - stringBytes, err := evmCall(addr, msg) + ret, err := evmCall(addr, msg) if err != nil { return "", err } // Parse into a string. - stringInterface, err := abiArgs.singleString.Unpack(stringBytes) + stringIntf, err := abiArgs.singleString.Unpack(ret) if err != nil { - return "", err + return "", fmt.Errorf("decoding string: %w", err) } - if len(stringInterface) < len(abiArgs.singleString) { - return "", fmt.Errorf("unexpected decoded size") + if len(stringIntf) < len(abiArgs.singleString) { + return "", fmt.Errorf("decoding string: %w", ErrUnexpectedDecodedSize) } - str, ok := stringInterface[0].(string) + str, ok := stringIntf[0].(string) if !ok { - return "", fmt.Errorf("unexpected type for decoded string") + return "", fmt.Errorf("decoding string: %w", ErrUnexpectedType) } return str, nil @@ -38,25 +43,28 @@ func callAndDecodeString(evmCall evmCallFn, addr common.Address, msg []byte) (st // callAndDecodeUint8 calls a method and decodes the result as a uint8. func callAndDecodeUint8(evmCall evmCallFn, addr common.Address, msg []byte) (uint8, error) { // Load bytes from the EVM. - uint8Bytes, err := evmCall(addr, msg) + ret, err := evmCall(addr, msg) if err != nil { return 0, err } // Parse into a uint8. - if len(uint8Bytes) < 1 { - return 0, fmt.Errorf("unexpected decoded size") + if len(ret) < 1 { + return 0, fmt.Errorf("decoding uint8: %w", ErrUnexpectedDecodedSize) } - return uint8Bytes[len(uint8Bytes)-1], nil + return ret[len(ret)-1], nil } -// callAndDecodeBigInt calls a method and decodes the result as a *big.Int. -func callAndDecodeBigInt(evmCall evmCallFn, addr common.Address, msg []byte) (*big.Int, error) { - bigIntBytes, err := evmCall(addr, msg) +// callAndDecodeUint256 calls a method and decodes the result as a *big.Int. +func callAndDecodeUint256(evmCall evmCallFn, addr common.Address, msg []byte) (*big.Int, error) { + ret, err := evmCall(addr, msg) if err != nil { return nil, err } - return new(big.Int).SetBytes(bigIntBytes), nil + if len(ret) > 32 { + return nil, fmt.Errorf("decoding uint256: %w", ErrUnexpectedDecodedSize) + } + return new(big.Int).SetBytes(ret), nil } // @@ -100,7 +108,7 @@ func evmCallMethodURI(evmCall evmCallFn, addr common.Address, tokenID *big.Int) func evmCallMethodBalanceOf(evmCall evmCallFn, addr common.Address, owner common.Address) (*big.Int, error) { ownerBytes := common.LeftPadBytes(owner.Bytes(), 32) input := append(methodIDBalanceOf, ownerBytes...) - return callAndDecodeBigInt(evmCall, addr, input) + return callAndDecodeUint256(evmCall, addr, input) } // evmCallMethodBalanceOf2 decodes the balance of an asset from the EVM. @@ -109,5 +117,5 @@ func evmCallMethodBalanceOf2(evmCall evmCallFn, addr common.Address, owner commo ownerBytes := common.LeftPadBytes(owner.Bytes(), 32) input := append(methodIDBalanceOf2, ownerBytes...) input = append(input, tokenIDBytes...) - return callAndDecodeBigInt(evmCall, addr, input) + return callAndDecodeUint256(evmCall, addr, input) } From 07024f878d2391d7ff96bcf73d8f21678ee70a05 Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Sat, 23 Sep 2023 21:42:19 -0400 Subject: [PATCH 37/40] tweak: Completely disable tracer during internal evm calls. --- eth/tracers/blocknative/decoder_evm.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/eth/tracers/blocknative/decoder_evm.go b/eth/tracers/blocknative/decoder_evm.go index 75f762a95a51..8bbab0038d2b 100644 --- a/eth/tracers/blocknative/decoder_evm.go +++ b/eth/tracers/blocknative/decoder_evm.go @@ -1,9 +1,10 @@ package blocknative import ( + "math" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/vm" - "math" ) // decoderEVM contains the functionality required by the decoder from the EVM. @@ -22,5 +23,11 @@ func (d decoderEVM) CallCode(addr common.Address, method []byte) ([]byte, error) code := d.StateDB.GetCode(addr) contract := vm.NewContract(vm.AccountRef(common.Address{}), vm.AccountRef(addr), common.Big0, math.MaxUint64) contract.SetCallCode(&addr, d.StateDB.GetCodeHash(addr), code) - return d.Interpreter().Run(contract, method, false) + + t := d.EVM.Config.Tracer + d.EVM.Config.Tracer = nil + ret, err := d.Interpreter().Run(contract, method, false) + d.EVM.Config.Tracer = t + + return ret, err } From 8cb9b84cb912e3c6630807effea51872e831d9ce Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Sat, 23 Sep 2023 22:26:45 -0400 Subject: [PATCH 38/40] fix: Don't invoke tracer during internal evm calls. --- eth/tracers/blocknative/decoder_evm.go | 6 +- .../with_decoding/delegatecall.json | 129 ++++++------------ 2 files changed, 50 insertions(+), 85 deletions(-) diff --git a/eth/tracers/blocknative/decoder_evm.go b/eth/tracers/blocknative/decoder_evm.go index 8bbab0038d2b..bca14175f72a 100644 --- a/eth/tracers/blocknative/decoder_evm.go +++ b/eth/tracers/blocknative/decoder_evm.go @@ -19,11 +19,15 @@ func (d decoderEVM) GetCode(addr common.Address) []byte { } // CallCode executes the given method on the code at the given address. +var callCodeCallerAddr = vm.AccountRef(common.HexToAddress("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")) + func (d decoderEVM) CallCode(addr common.Address, method []byte) ([]byte, error) { code := d.StateDB.GetCode(addr) - contract := vm.NewContract(vm.AccountRef(common.Address{}), vm.AccountRef(addr), common.Big0, math.MaxUint64) + contract := vm.NewContract(callCodeCallerAddr, vm.AccountRef(addr), common.Big0, math.MaxUint64) contract.SetCallCode(&addr, d.StateDB.GetCodeHash(addr), code) + // Stash the tracer and disable tracing for the call, then replace it. + // Otherwise the call will be traced as part of the current trace. t := d.EVM.Config.Tracer d.EVM.Config.Tracer = nil ret, err := d.Interpreter().Run(contract, method, false) diff --git a/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/delegatecall.json b/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/delegatecall.json index 151c773bfb9b..280ed407b21c 100644 --- a/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/delegatecall.json +++ b/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/delegatecall.json @@ -137,8 +137,8 @@ "from": "0x3de712784baf97260455ae25fb74f574ec9c1add", "to": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", "value": "0x0", - "gas": "0x7e2c0", - "gasUsed": "0x25883", + "gas": "0x0", + "gasUsed": "0x0", "input": "0xbbd4f854e9efd3ab89acad6a3edf9828c3b00ed1c4a74e974d05d32d3b2fb15aa16fc3770000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000080d29fa5cccfadac", "output": "0x00000000000000000000000000000000000000000000000080d29fa5cccfadac", "calls": [ @@ -147,8 +147,8 @@ "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", "to": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", "value": "0x0", - "gas": "0x77e82", - "gasUsed": "0x54c", + "gas": "0x0", + "gasUsed": "0x0", "input": "0x8c172fa2d9a4ffe21d19763887176173d08241e8393c1dfd208f29193dfecdf854b664ac", "output": "0x446374989d279847d0dbc6708a9c76a419fe9831d42c78bc89473f559a00d91500000000000000000000000061d76c05cd2aa9ed5135e21e52fff188b02089d4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000092f1dbea03ce08225e31e95cc926ddbe0198e6f2000000000000000000000000529c4cb814029b8bb32acb516ea3a4b07fdae350846fd373887ade3ab7703750294876afa61cf56303f5f014a4d80d04f508a1f100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "decoded": { @@ -164,8 +164,8 @@ "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", "to": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0", "value": "0x0", - "gas": "0x7737b", - "gasUsed": "0x3fe1", + "gas": "0x0", + "gasUsed": "0x0", "input": "0x0439978de9efd3ab89acad6a3edf9828c3b00ed1c4a74e974d05d32d3b2fb15aa16fc3770000000000000000000000000000000000000000000000004563918244f4000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000026566ea1ec2f6a9b00000000000000000000000000000000000000000000000072aa5b7e04d56a9b", "output": "0x0000000000000000000000000000000000000000000000008060b57e2e0c99aa", "calls": [ @@ -174,8 +174,8 @@ "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0", "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae", "value": "0x0", - "gas": "0x770ef", - "gasUsed": "0xc24", + "gas": "0x0", + "gasUsed": "0x0", "input": "0x24d4e90a0000000000000000000000000000000000000000000000020000000000000000", "output": "0x000000000000000000000000000000000000000000000000b17217f7d1cf79ab", "decoded": { @@ -190,8 +190,8 @@ "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0", "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae", "value": "0x0", - "gas": "0x75eb2", - "gasUsed": "0x265", + "gas": "0x0", + "gasUsed": "0x0", "input": "0x872fb2b5000000000000000000000000000000000000000000000000c330b3f7006420b8", "output": "0x00000000000000000000000000000000000000000000000224bf7df2c80f0878", "decoded": { @@ -206,8 +206,8 @@ "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0", "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae", "value": "0x0", - "gas": "0x75aad", - "gasUsed": "0x25b", + "gas": "0x0", + "gasUsed": "0x0", "input": "0x872fb2b50000000000000000000000000000000000000000000000000000000000000000", "output": "0x00000000000000000000000000000000000000000000000100000016aee6e8ef", "decoded": { @@ -222,8 +222,8 @@ "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0", "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae", "value": "0x0", - "gas": "0x75737", - "gasUsed": "0xc24", + "gas": "0x0", + "gasUsed": "0x0", "input": "0x24d4e90a00000000000000000000000000000000000000000000000324bf7e0976f5f167", "output": "0x0000000000000000000000000000000000000000000000012535c5e5f87ee0d2", "decoded": { @@ -238,8 +238,8 @@ "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0", "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae", "value": "0x0", - "gas": "0x748c7", - "gasUsed": "0x265", + "gas": "0x0", + "gasUsed": "0x0", "input": "0x872fb2b5000000000000000000000000000000000000000000000000c330b3f7006420b8", "output": "0x00000000000000000000000000000000000000000000000224bf7df2c80f0878", "decoded": { @@ -254,8 +254,8 @@ "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0", "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae", "value": "0x0", - "gas": "0x744c2", - "gasUsed": "0x265", + "gas": "0x0", + "gasUsed": "0x0", "input": "0x872fb2b500000000000000000000000000000000000000000000000237d37fe5d297a500", "output": "0x0000000000000000000000000000000000000000000000093088c407fcbbce38", "decoded": { @@ -270,8 +270,8 @@ "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0", "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae", "value": "0x0", - "gas": "0x74142", - "gasUsed": "0xc99", + "gas": "0x0", + "gasUsed": "0x0", "input": "0x24d4e90a00000000000000000000000000000000000000000000000b554841fac4cad6b0", "output": "0x0000000000000000000000000000000000000000000000026d7fc130d6a74cbe", "decoded": { @@ -301,8 +301,8 @@ "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", "to": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", "value": "0x0", - "gas": "0x731be", - "gasUsed": "0x241", + "gas": "0x0", + "gasUsed": "0x0", "input": "0xc51cf179000000000000000000000000000000000000000000000000de0b6b3a76400000", "output": "0x0000000000000000000000000000000000000000000000000071ea279ec31402", "decoded": { @@ -313,33 +313,13 @@ ] } }, - { - "type": "CALL", - "from": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0", - "gas": "0xf", - "gasUsed": "0xf", - "input": "0x", - "output": "0x" - }, - { - "type": "CALL", - "from": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0", - "gas": "0xf", - "gasUsed": "0xf", - "input": "0x", - "output": "0x" - }, { "type": "CALL", "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", "to": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", "value": "0x0", - "gas": "0x72df4", - "gasUsed": "0x468b", + "gas": "0x0", + "gasUsed": "0x0", "input": "0x23b872dd0000000000000000000000003de712784baf97260455ae25fb74f574ec9c1add0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba500000000000000000000000000000000000000000000000080d29fa5cccfadac", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { @@ -358,8 +338,8 @@ "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", "to": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", "value": "0x0", - "gas": "0x6e627", - "gasUsed": "0x56d6", + "gas": "0x0", + "gasUsed": "0x0", "input": "0x095ea7b30000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd00000000000000000000000000000000000000000000000080d29fa5cccfadac", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { @@ -377,8 +357,8 @@ "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", "to": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", "value": "0x0", - "gas": "0x68dae", - "gasUsed": "0xd6f0", + "gas": "0x0", + "gasUsed": "0x0", "input": "0x07d5b826d9a4ffe21d19763887176173d08241e8393c1dfd208f29193dfecdf854b664ac00000000000000000000000000000000000000000000000080d29fa5cccfadac", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "calls": [ @@ -387,8 +367,8 @@ "from": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", "to": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", "value": "0x0", - "gas": "0x629ff", - "gasUsed": "0x468b", + "gas": "0x0", + "gasUsed": "0x0", "input": "0x23b872dd0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba50000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd00000000000000000000000000000000000000000000000080d29fa5cccfadac", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { @@ -407,8 +387,8 @@ "from": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", "to": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", "value": "0x0", - "gas": "0x5e0df", - "gasUsed": "0x31af", + "gas": "0x0", + "gasUsed": "0x0", "input": "0xa9059cbb000000000000000000000000950ca4a06c78934a148b7a3ff3ea8fc366f77a060000000000000000000000000000000000000000000000000041f50e27d56848", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { @@ -426,8 +406,8 @@ "from": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", "to": "0x01e60b511fced1eb2b5b40991eb1dfd171a6df42", "value": "0x0", - "gas": "0x5ac6b", - "gasUsed": "0x29ae", + "gas": "0x0", + "gasUsed": "0x0", "input": "0x475a9fa90000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba50000000000000000000000000000000000000000000000008090aa97a4fa4564", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { @@ -444,8 +424,8 @@ "from": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", "to": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", "value": "0x0", - "gas": "0x57fed", - "gasUsed": "0x29ae", + "gas": "0x0", + "gasUsed": "0x0", "input": "0x475a9fa90000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba50000000000000000000000000000000000000000000000008090aa97a4fa4564", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { @@ -472,8 +452,8 @@ "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", "to": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", "value": "0x0", - "gas": "0x56030", - "gasUsed": "0x265", + "gas": "0x0", + "gasUsed": "0x0", "input": "0x1f0c1e0cd9a4ffe21d19763887176173d08241e8393c1dfd208f29193dfecdf854b664ac0000000000000000000000000000000000000000000000000000000000000001", "output": "0x000000000000000000000000f4cbd7e037b80c2e67b80512d482685f15b1fb28", "decoded": { @@ -485,33 +465,13 @@ ] } }, - { - "type": "CALL", - "from": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0", - "gas": "0xf", - "gasUsed": "0xf", - "input": "0x", - "output": "0x" - }, - { - "type": "CALL", - "from": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0", - "gas": "0xf", - "gasUsed": "0xf", - "input": "0x", - "output": "0x" - }, { "type": "CALL", "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", "to": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", "value": "0x0", - "gas": "0x55cc3", - "gasUsed": "0x339f", + "gas": "0x0", + "gasUsed": "0x0", "input": "0xa9059cbb0000000000000000000000003de712784baf97260455ae25fb74f574ec9c1add000000000000000000000000000000000000000000000000de0b6b3a76400000", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "calls": [ @@ -520,8 +480,8 @@ "from": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", "to": "0x19ee743d2e356d5f0e4d97cc09b96d06e933d0db", "value": "0x0", - "gas": "0x55a8a", - "gasUsed": "0x30f7", + "gas": "0x0", + "gasUsed": "0x0", "input": "0x88d5fecb00000000000000000000000000000000000000000000000000000000000000010000000000000000000000003de712784baf97260455ae25fb74f574ec9c1add000000000000000000000000000000000000000000000000de0b6b3a76400000", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { @@ -556,11 +516,12 @@ }, "blockContext": { "number": 2340153, - "stateRoot": "0xfd6b6b8e67375609b44379ad18b293b1d6369d8e93e17f8240600a3f990caeae", "baseFee": 16711680, "time": 1475034716, + "gasLimit": 1500062, "coinbase": "0x61c808d82a3ac53231750dadc13c777b59310bd9", - "gasLimit": 1500062 + "stateRoot": "0xfd6b6b8e67375609b44379ad18b293b1d6369d8e93e17f8240600a3f990caeae", + "random": "0x0000000000000000000000000000000000000000000000000000000000000000" }, "balanceChanges": [ { From a67d095a546adfdef897adf2088f93dcc740fa8c Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Sat, 23 Sep 2023 22:28:43 -0400 Subject: [PATCH 39/40] fix: Fix Uint64 deserialization in tests. --- eth/tracers/blocknative/utils.go | 10 ++- .../with_decoding/delegatecall.json | 84 +++++++++---------- .../erc20_transfer_with_tax.json | 80 +++++++++--------- 3 files changed, 89 insertions(+), 85 deletions(-) diff --git a/eth/tracers/blocknative/utils.go b/eth/tracers/blocknative/utils.go index ec53adad97f3..d0a18b032c99 100644 --- a/eth/tracers/blocknative/utils.go +++ b/eth/tracers/blocknative/utils.go @@ -29,7 +29,11 @@ func (b Uint64) MarshalText() ([]byte, error) { return []byte("0x" + strconv.FormatUint(uint64(b), 16)), nil } -func (b Uint64) UnmarshalJSON(input []byte) error { - u := hexutil.Uint64(b) - return u.UnmarshalJSON(input) +func (b *Uint64) UnmarshalJSON(input []byte) error { + u := hexutil.Uint64(*b) + if err := u.UnmarshalJSON(input); err != nil { + return err + } + *b = Uint64(u) + return nil } diff --git a/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/delegatecall.json b/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/delegatecall.json index 280ed407b21c..9514fecaa656 100644 --- a/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/delegatecall.json +++ b/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/delegatecall.json @@ -137,8 +137,8 @@ "from": "0x3de712784baf97260455ae25fb74f574ec9c1add", "to": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", "value": "0x0", - "gas": "0x0", - "gasUsed": "0x0", + "gas": "0x7e2c0", + "gasUsed": "0x25883", "input": "0xbbd4f854e9efd3ab89acad6a3edf9828c3b00ed1c4a74e974d05d32d3b2fb15aa16fc3770000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000080d29fa5cccfadac", "output": "0x00000000000000000000000000000000000000000000000080d29fa5cccfadac", "calls": [ @@ -147,8 +147,8 @@ "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", "to": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", "value": "0x0", - "gas": "0x0", - "gasUsed": "0x0", + "gas": "0x77e82", + "gasUsed": "0x54c", "input": "0x8c172fa2d9a4ffe21d19763887176173d08241e8393c1dfd208f29193dfecdf854b664ac", "output": "0x446374989d279847d0dbc6708a9c76a419fe9831d42c78bc89473f559a00d91500000000000000000000000061d76c05cd2aa9ed5135e21e52fff188b02089d4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000092f1dbea03ce08225e31e95cc926ddbe0198e6f2000000000000000000000000529c4cb814029b8bb32acb516ea3a4b07fdae350846fd373887ade3ab7703750294876afa61cf56303f5f014a4d80d04f508a1f100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "decoded": { @@ -164,8 +164,8 @@ "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", "to": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0", "value": "0x0", - "gas": "0x0", - "gasUsed": "0x0", + "gas": "0x7737b", + "gasUsed": "0x3fe1", "input": "0x0439978de9efd3ab89acad6a3edf9828c3b00ed1c4a74e974d05d32d3b2fb15aa16fc3770000000000000000000000000000000000000000000000004563918244f4000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000026566ea1ec2f6a9b00000000000000000000000000000000000000000000000072aa5b7e04d56a9b", "output": "0x0000000000000000000000000000000000000000000000008060b57e2e0c99aa", "calls": [ @@ -174,8 +174,8 @@ "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0", "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae", "value": "0x0", - "gas": "0x0", - "gasUsed": "0x0", + "gas": "0x770ef", + "gasUsed": "0xc24", "input": "0x24d4e90a0000000000000000000000000000000000000000000000020000000000000000", "output": "0x000000000000000000000000000000000000000000000000b17217f7d1cf79ab", "decoded": { @@ -190,8 +190,8 @@ "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0", "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae", "value": "0x0", - "gas": "0x0", - "gasUsed": "0x0", + "gas": "0x75eb2", + "gasUsed": "0x265", "input": "0x872fb2b5000000000000000000000000000000000000000000000000c330b3f7006420b8", "output": "0x00000000000000000000000000000000000000000000000224bf7df2c80f0878", "decoded": { @@ -206,8 +206,8 @@ "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0", "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae", "value": "0x0", - "gas": "0x0", - "gasUsed": "0x0", + "gas": "0x75aad", + "gasUsed": "0x25b", "input": "0x872fb2b50000000000000000000000000000000000000000000000000000000000000000", "output": "0x00000000000000000000000000000000000000000000000100000016aee6e8ef", "decoded": { @@ -222,8 +222,8 @@ "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0", "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae", "value": "0x0", - "gas": "0x0", - "gasUsed": "0x0", + "gas": "0x75737", + "gasUsed": "0xc24", "input": "0x24d4e90a00000000000000000000000000000000000000000000000324bf7e0976f5f167", "output": "0x0000000000000000000000000000000000000000000000012535c5e5f87ee0d2", "decoded": { @@ -238,8 +238,8 @@ "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0", "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae", "value": "0x0", - "gas": "0x0", - "gasUsed": "0x0", + "gas": "0x748c7", + "gasUsed": "0x265", "input": "0x872fb2b5000000000000000000000000000000000000000000000000c330b3f7006420b8", "output": "0x00000000000000000000000000000000000000000000000224bf7df2c80f0878", "decoded": { @@ -254,8 +254,8 @@ "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0", "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae", "value": "0x0", - "gas": "0x0", - "gasUsed": "0x0", + "gas": "0x744c2", + "gasUsed": "0x265", "input": "0x872fb2b500000000000000000000000000000000000000000000000237d37fe5d297a500", "output": "0x0000000000000000000000000000000000000000000000093088c407fcbbce38", "decoded": { @@ -270,8 +270,8 @@ "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0", "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae", "value": "0x0", - "gas": "0x0", - "gasUsed": "0x0", + "gas": "0x74142", + "gasUsed": "0xc99", "input": "0x24d4e90a00000000000000000000000000000000000000000000000b554841fac4cad6b0", "output": "0x0000000000000000000000000000000000000000000000026d7fc130d6a74cbe", "decoded": { @@ -301,8 +301,8 @@ "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", "to": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", "value": "0x0", - "gas": "0x0", - "gasUsed": "0x0", + "gas": "0x731be", + "gasUsed": "0x241", "input": "0xc51cf179000000000000000000000000000000000000000000000000de0b6b3a76400000", "output": "0x0000000000000000000000000000000000000000000000000071ea279ec31402", "decoded": { @@ -318,8 +318,8 @@ "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", "to": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", "value": "0x0", - "gas": "0x0", - "gasUsed": "0x0", + "gas": "0x72df4", + "gasUsed": "0x468b", "input": "0x23b872dd0000000000000000000000003de712784baf97260455ae25fb74f574ec9c1add0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba500000000000000000000000000000000000000000000000080d29fa5cccfadac", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { @@ -338,8 +338,8 @@ "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", "to": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", "value": "0x0", - "gas": "0x0", - "gasUsed": "0x0", + "gas": "0x6e627", + "gasUsed": "0x56d6", "input": "0x095ea7b30000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd00000000000000000000000000000000000000000000000080d29fa5cccfadac", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { @@ -357,8 +357,8 @@ "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", "to": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", "value": "0x0", - "gas": "0x0", - "gasUsed": "0x0", + "gas": "0x68dae", + "gasUsed": "0xd6f0", "input": "0x07d5b826d9a4ffe21d19763887176173d08241e8393c1dfd208f29193dfecdf854b664ac00000000000000000000000000000000000000000000000080d29fa5cccfadac", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "calls": [ @@ -367,8 +367,8 @@ "from": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", "to": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", "value": "0x0", - "gas": "0x0", - "gasUsed": "0x0", + "gas": "0x629ff", + "gasUsed": "0x468b", "input": "0x23b872dd0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba50000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd00000000000000000000000000000000000000000000000080d29fa5cccfadac", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { @@ -387,8 +387,8 @@ "from": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", "to": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", "value": "0x0", - "gas": "0x0", - "gasUsed": "0x0", + "gas": "0x5e0df", + "gasUsed": "0x31af", "input": "0xa9059cbb000000000000000000000000950ca4a06c78934a148b7a3ff3ea8fc366f77a060000000000000000000000000000000000000000000000000041f50e27d56848", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { @@ -406,8 +406,8 @@ "from": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", "to": "0x01e60b511fced1eb2b5b40991eb1dfd171a6df42", "value": "0x0", - "gas": "0x0", - "gasUsed": "0x0", + "gas": "0x5ac6b", + "gasUsed": "0x29ae", "input": "0x475a9fa90000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba50000000000000000000000000000000000000000000000008090aa97a4fa4564", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { @@ -424,8 +424,8 @@ "from": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", "to": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", "value": "0x0", - "gas": "0x0", - "gasUsed": "0x0", + "gas": "0x57fed", + "gasUsed": "0x29ae", "input": "0x475a9fa90000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba50000000000000000000000000000000000000000000000008090aa97a4fa4564", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { @@ -452,8 +452,8 @@ "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", "to": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", "value": "0x0", - "gas": "0x0", - "gasUsed": "0x0", + "gas": "0x56030", + "gasUsed": "0x265", "input": "0x1f0c1e0cd9a4ffe21d19763887176173d08241e8393c1dfd208f29193dfecdf854b664ac0000000000000000000000000000000000000000000000000000000000000001", "output": "0x000000000000000000000000f4cbd7e037b80c2e67b80512d482685f15b1fb28", "decoded": { @@ -470,8 +470,8 @@ "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", "to": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", "value": "0x0", - "gas": "0x0", - "gasUsed": "0x0", + "gas": "0x55cc3", + "gasUsed": "0x339f", "input": "0xa9059cbb0000000000000000000000003de712784baf97260455ae25fb74f574ec9c1add000000000000000000000000000000000000000000000000de0b6b3a76400000", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "calls": [ @@ -480,8 +480,8 @@ "from": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", "to": "0x19ee743d2e356d5f0e4d97cc09b96d06e933d0db", "value": "0x0", - "gas": "0x0", - "gasUsed": "0x0", + "gas": "0x55a8a", + "gasUsed": "0x30f7", "input": "0x88d5fecb00000000000000000000000000000000000000000000000000000000000000010000000000000000000000003de712784baf97260455ae25fb74f574ec9c1add000000000000000000000000000000000000000000000000de0b6b3a76400000", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { diff --git a/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/erc20_transfer_with_tax.json b/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/erc20_transfer_with_tax.json index 1ee6ea8ab952..7a3cf2e5da56 100644 --- a/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/erc20_transfer_with_tax.json +++ b/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/erc20_transfer_with_tax.json @@ -52,8 +52,8 @@ "from": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", "to": "0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea", "value": "0x0", - "gas": "0x0", - "gasUsed": "0x0", + "gas": "0x5f58c50", + "gasUsed": "0xa188", "input": "0xa9059cbb000000000000000000000000fba9f22d040e53e5fac36698080cee3dd3792262000000000000000000000000000000000000000000000207b733832c88c007ca", "output": "0x0000000000000000000000000000000000000000000000000000000000000001", "decoded": { @@ -75,6 +75,27 @@ "random": "0x0000000000000000000000000000000000000000000000000000000000000000" }, "balanceChanges": [ + { + "address": "0x4675c7e5baafbffbca748158becba61ef3b0a263", + "balanceChanges": [ + { + "delta": "1011744513820800", + "asset": { + "address": "0x0000000000000000000000000000000000000000", + "type": "eth", + "name": "Ether", + "symbol": "ETH", + "decimals": 18 + }, + "breakdown": [ + { + "counterparty": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", + "amount": "1011744513820800" + } + ] + } + ] + }, { "address": "0xfba9f22d040e53e5fac36698080cee3dd3792262", "balanceChanges": [ @@ -97,10 +118,10 @@ ] }, { - "address": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", + "address": "0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea", "balanceChanges": [ { - "delta": "-9587061213415306430410", + "delta": "95870612134153064304", "asset": { "address": "0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea", "type": "erc20", @@ -110,15 +131,16 @@ }, "breakdown": [ { - "counterparty": "0xfba9f22d040e53e5fac36698080cee3dd3792262", - "amount": "-9491190601281153366106" - }, - { - "counterparty": "0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea", - "amount": "-95870612134153064304" + "counterparty": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", + "amount": "95870612134153064304" } ] - }, + } + ] + }, + { + "address": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", + "balanceChanges": [ { "delta": "-1012435575212160", "asset": { @@ -138,14 +160,9 @@ "amount": "-1011744513820800" } ] - } - ] - }, - { - "address": "0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea", - "balanceChanges": [ + }, { - "delta": "95870612134153064304", + "delta": "-9587061213415306430410", "asset": { "address": "0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea", "type": "erc20", @@ -155,29 +172,12 @@ }, "breakdown": [ { - "counterparty": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", - "amount": "95870612134153064304" - } - ] - } - ] - }, - { - "address": "0x4675c7e5baafbffbca748158becba61ef3b0a263", - "balanceChanges": [ - { - "delta": "1011744513820800", - "asset": { - "address": "0x0000000000000000000000000000000000000000", - "type": "eth", - "name": "Ether", - "symbol": "ETH", - "decimals": 18 - }, - "breakdown": [ + "counterparty": "0xfba9f22d040e53e5fac36698080cee3dd3792262", + "amount": "-9491190601281153366106" + }, { - "counterparty": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", - "amount": "1011744513820800" + "counterparty": "0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea", + "amount": "-95870612134153064304" } ] } From 5e69d8002caf0061281600470773ed16f6fc5de9 Mon Sep 17 00:00:00 2001 From: hsouf Date: Sat, 30 Sep 2023 00:06:25 +0100 Subject: [PATCH 40/40] add accountTouchTracer --- eth/tracers/native/accountTouchTracer.go | 100 +++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 eth/tracers/native/accountTouchTracer.go diff --git a/eth/tracers/native/accountTouchTracer.go b/eth/tracers/native/accountTouchTracer.go new file mode 100644 index 000000000000..b8c4be66dddc --- /dev/null +++ b/eth/tracers/native/accountTouchTracer.go @@ -0,0 +1,100 @@ +// Copyright 2022 flashbots +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package native + +import ( + "encoding/json" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/eth/tracers" +) + +func init() { + tracers.DefaultDirectory.Register("accountTouchTracer", newAccountTouchTracer, false) +} + +type accountTouchTracer struct { + touched map[common.Address]struct{} +} + +// newAccountTouchTracer creates new AccountTouchTracer +// that collect all addresses touched in the given tx +// including tx sender and tx.to from the top level call +func newAccountTouchTracer(ctx *tracers.Context, _ json.RawMessage) (tracers.Tracer, error) { + t := &accountTouchTracer{ + touched: make(map[common.Address]struct{}), + } + return t, nil +} + +func (t *accountTouchTracer) TouchedAddressesSet() map[common.Address]struct{} { + return t.touched +} + +func (t *accountTouchTracer) TouchedAddresses() []common.Address { + result := make([]common.Address, 0, len(t.touched)) + + for address := range t.touched { + result = append(result, address) + } + return result +} + +func (t *accountTouchTracer) CaptureTxStart(uint64) {} + +func (t *accountTouchTracer) CaptureTxEnd(uint64) {} + +func (t *accountTouchTracer) CaptureStart(_ *vm.EVM, from common.Address, to common.Address, _ bool, _ []byte, _ uint64, _ *big.Int) { + t.touched[from] = struct{}{} + t.touched[to] = struct{}{} +} + +func (t *accountTouchTracer) CaptureEnd([]byte, uint64, error) {} + +func (t *accountTouchTracer) CaptureEnter(_ vm.OpCode, _ common.Address, to common.Address, _ []byte, _ uint64, _ *big.Int) { + t.touched[to] = struct{}{} +} + +func (t *accountTouchTracer) CaptureExit([]byte, uint64, error) {} + +func (t *accountTouchTracer) CaptureState(_ uint64, op vm.OpCode, _, _ uint64, scope *vm.ScopeContext, _ []byte, _ int, _ error) { + stack := scope.Stack + stackData := stack.Data() + stackLen := len(stackData) + if (op == vm.EXTCODECOPY || op == vm.EXTCODEHASH || op == vm.EXTCODESIZE || op == vm.BALANCE || op == vm.SELFDESTRUCT) && stackLen >= 1 { + addr := common.Address(stackData[stackLen-1].Bytes20()) + t.touched[addr] = struct{}{} + } +} + +func (t *accountTouchTracer) CaptureFault(uint64, vm.OpCode, uint64, uint64, *vm.ScopeContext, int, error) { +} + +// GetResult returns an empty json object. +func (t *accountTouchTracer) GetResult() (json.RawMessage, error) { + res, err := json.Marshal(t.TouchedAddresses()) + if err != nil { + return nil, err + } + return json.RawMessage(res), nil +} + +// Stop terminates execution of the tracer at the first opportune moment. +func (t *accountTouchTracer) Stop(err error) { +}