mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-14 16:03:45 +00:00
Merge branch 'extended-tracer' into feature/firehose-extended-tracer
# Conflicts: # core/vm/evm.go
This commit is contained in:
commit
09df0e0c95
10 changed files with 125 additions and 53 deletions
|
|
@ -256,7 +256,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
|
||||||
if vmConfig.Tracer != nil {
|
if vmConfig.Tracer != nil {
|
||||||
l, ok := vmConfig.Tracer.(BlockchainLogger)
|
l, ok := vmConfig.Tracer.(BlockchainLogger)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("only extended tracers are supported for live mode")
|
return nil, errors.New("only extended tracers are supported for live mode")
|
||||||
}
|
}
|
||||||
logger = l
|
logger = l
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,7 @@
|
||||||
package vm
|
package vm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
|
@ -181,24 +179,24 @@ func (evm *EVM) SetBlockContext(blockCtx BlockContext) {
|
||||||
// the necessary steps to create accounts and reverses the state in case of an
|
// the necessary steps to create accounts and reverses the state in case of an
|
||||||
// execution error or failed value transfer.
|
// execution error or failed value transfer.
|
||||||
func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) {
|
func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) {
|
||||||
if tracer := evm.Config.Tracer; tracer != nil {
|
// Capture the tracer start/end events in debug mode
|
||||||
|
if evm.Config.Tracer != nil {
|
||||||
if evm.depth == 0 {
|
if evm.depth == 0 {
|
||||||
tracer.CaptureStart(caller.Address(), addr, false, input, gas, value)
|
evm.Config.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value)
|
||||||
defer func(startGas uint64) { // Lazy evaluation of the parameters
|
defer func(startGas uint64) { // Lazy evaluation of the parameters
|
||||||
tracer.CaptureEnd(ret, startGas-leftOverGas, err)
|
evm.Config.Tracer.CaptureEnd(ret, startGas-gas, err)
|
||||||
}(gas)
|
}(gas)
|
||||||
} else {
|
} else {
|
||||||
// Handle tracer events for entering and exiting a call frame
|
// Handle tracer events for entering and exiting a call frame
|
||||||
tracer.CaptureEnter(CALL, caller.Address(), addr, input, gas, value)
|
evm.Config.Tracer.CaptureEnter(CALL, caller.Address(), addr, input, gas, value)
|
||||||
tracer.OnGasConsumed(0, -gas, GasInitialBalance)
|
evm.Config.Tracer.OnGasConsumed(0, -gas, GasInitialBalance)
|
||||||
|
|
||||||
defer func(startGas uint64) {
|
defer func(startGas uint64) {
|
||||||
tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
|
evm.Config.Tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
|
||||||
tracer.CaptureExit(ret, startGas-leftOverGas, err)
|
evm.Config.Tracer.CaptureExit(ret, startGas-gas, err)
|
||||||
}(gas)
|
}(gas)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fail if we're trying to execute above the call depth limit
|
// Fail if we're trying to execute above the call depth limit
|
||||||
if evm.depth > int(params.CallCreateDepth) {
|
if evm.depth > int(params.CallCreateDepth) {
|
||||||
return nil, gas, ErrDepth
|
return nil, gas, ErrDepth
|
||||||
|
|
@ -212,6 +210,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
||||||
|
|
||||||
if !evm.StateDB.Exist(addr) {
|
if !evm.StateDB.Exist(addr) {
|
||||||
if !isPrecompile && evm.chainRules.IsEIP158 && value.Sign() == 0 {
|
if !isPrecompile && evm.chainRules.IsEIP158 && value.Sign() == 0 {
|
||||||
|
// Calling a non-existing account, don't do anything.
|
||||||
return nil, gas, nil
|
return nil, gas, nil
|
||||||
}
|
}
|
||||||
evm.StateDB.CreateAccount(addr)
|
evm.StateDB.CreateAccount(addr)
|
||||||
|
|
@ -237,7 +236,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// When an error was returned by the EVM or when setting the creation code
|
// When an error was returned by the EVM or when setting the creation code
|
||||||
// above we revert to the snapshot and consume any gas remaining. Additionally
|
// above we revert to the snapshot and consume any gas remaining. Additionally,
|
||||||
// when we're in homestead this also counts for code storage gas errors.
|
// when we're in homestead this also counts for code storage gas errors.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
evm.StateDB.RevertToSnapshot(snapshot)
|
evm.StateDB.RevertToSnapshot(snapshot)
|
||||||
|
|
@ -264,16 +263,15 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
||||||
// code with the caller as context.
|
// code with the caller as context.
|
||||||
func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) {
|
func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) {
|
||||||
// Invoke tracer hooks that signal entering/exiting a call frame
|
// Invoke tracer hooks that signal entering/exiting a call frame
|
||||||
if tracer := evm.Config.Tracer; tracer != nil {
|
if evm.Config.Tracer != nil {
|
||||||
tracer.CaptureEnter(CALLCODE, caller.Address(), addr, input, gas, value)
|
evm.Config.Tracer.CaptureEnter(CALLCODE, caller.Address(), addr, input, gas, value)
|
||||||
tracer.OnGasConsumed(0, -gas, GasInitialBalance)
|
evm.Config.Tracer.OnGasConsumed(0, -gas, GasInitialBalance)
|
||||||
|
|
||||||
defer func(startGas uint64) {
|
defer func(startGas uint64) {
|
||||||
tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
|
evm.Config.Tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
|
||||||
tracer.CaptureExit(ret, startGas-leftOverGas, err)
|
evm.Config.Tracer.CaptureExit(ret, startGas-gas, err)
|
||||||
}(gas)
|
}(gas)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fail if we're trying to execute above the call depth limit
|
// Fail if we're trying to execute above the call depth limit
|
||||||
if evm.depth > int(params.CallCreateDepth) {
|
if evm.depth > int(params.CallCreateDepth) {
|
||||||
return nil, gas, ErrDepth
|
return nil, gas, ErrDepth
|
||||||
|
|
@ -319,20 +317,19 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
|
||||||
// code with the caller as context and the caller is set to the caller of the caller.
|
// code with the caller as context and the caller is set to the caller of the caller.
|
||||||
func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) {
|
func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) {
|
||||||
// Invoke tracer hooks that signal entering/exiting a call frame
|
// Invoke tracer hooks that signal entering/exiting a call frame
|
||||||
if tracer := evm.Config.Tracer; tracer != nil {
|
if evm.Config.Tracer != nil {
|
||||||
// NOTE: caller must, at all times be a contract. It should never happen
|
// NOTE: caller must, at all times be a contract. It should never happen
|
||||||
// that caller is something other than a Contract.
|
// that caller is something other than a Contract.
|
||||||
parent := caller.(*Contract)
|
parent := caller.(*Contract)
|
||||||
// DELEGATECALL inherits value from parent call
|
// DELEGATECALL inherits value from parent call
|
||||||
tracer.CaptureEnter(DELEGATECALL, caller.Address(), addr, input, gas, parent.value)
|
evm.Config.Tracer.CaptureEnter(DELEGATECALL, caller.Address(), addr, input, gas, parent.value)
|
||||||
tracer.OnGasConsumed(0, -gas, GasInitialBalance)
|
evm.Config.Tracer.OnGasConsumed(0, -gas, GasInitialBalance)
|
||||||
|
|
||||||
defer func(startGas uint64) {
|
defer func(startGas uint64) {
|
||||||
tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
|
evm.Config.Tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
|
||||||
tracer.CaptureExit(ret, startGas-leftOverGas, err)
|
evm.Config.Tracer.CaptureExit(ret, startGas-gas, err)
|
||||||
}(gas)
|
}(gas)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fail if we're trying to execute above the call depth limit
|
// Fail if we're trying to execute above the call depth limit
|
||||||
if evm.depth > int(params.CallCreateDepth) {
|
if evm.depth > int(params.CallCreateDepth) {
|
||||||
return nil, gas, ErrDepth
|
return nil, gas, ErrDepth
|
||||||
|
|
@ -369,16 +366,15 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
|
||||||
// instead of performing the modifications.
|
// instead of performing the modifications.
|
||||||
func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) {
|
func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) {
|
||||||
// Invoke tracer hooks that signal entering/exiting a call frame
|
// Invoke tracer hooks that signal entering/exiting a call frame
|
||||||
if tracer := evm.Config.Tracer; tracer != nil {
|
if evm.Config.Tracer != nil {
|
||||||
tracer.CaptureEnter(STATICCALL, caller.Address(), addr, input, gas, nil)
|
evm.Config.Tracer.CaptureEnter(STATICCALL, caller.Address(), addr, input, gas, nil)
|
||||||
tracer.OnGasConsumed(0, -gas, GasInitialBalance)
|
evm.Config.Tracer.OnGasConsumed(0, -gas, GasInitialBalance)
|
||||||
|
|
||||||
defer func(startGas uint64) {
|
defer func(startGas uint64) {
|
||||||
tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
|
evm.Config.Tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
|
||||||
tracer.CaptureExit(ret, startGas-leftOverGas, err)
|
evm.Config.Tracer.CaptureExit(ret, startGas-gas, err)
|
||||||
}(gas)
|
}(gas)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fail if we're trying to execute above the call depth limit
|
// Fail if we're trying to execute above the call depth limit
|
||||||
if evm.depth > int(params.CallCreateDepth) {
|
if evm.depth > int(params.CallCreateDepth) {
|
||||||
return nil, gas, ErrDepth
|
return nil, gas, ErrDepth
|
||||||
|
|
@ -439,24 +435,23 @@ func (c *codeAndHash) Hash() common.Hash {
|
||||||
}
|
}
|
||||||
|
|
||||||
// create creates a new contract using code as deployment code.
|
// create creates a new contract using code as deployment code.
|
||||||
func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, value *big.Int, address common.Address, typ OpCode) (ret []byte, created common.Address, leftOverGas uint64, err error) {
|
func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, value *big.Int, address common.Address, typ OpCode) (ret []byte, createAddress common.Address, leftoverGas uint64, err error) {
|
||||||
if tracer := evm.Config.Tracer; tracer != nil {
|
if evm.Config.Tracer != nil {
|
||||||
if evm.depth == 0 {
|
if evm.depth == 0 {
|
||||||
tracer.CaptureStart(caller.Address(), address, true, codeAndHash.code, gas, value)
|
evm.Config.Tracer.CaptureStart(caller.Address(), address, true, codeAndHash.code, gas, value)
|
||||||
defer func(startGas uint64) {
|
defer func() {
|
||||||
tracer.CaptureEnd(ret, startGas-leftOverGas, err)
|
evm.Config.Tracer.CaptureEnd(ret, gas-leftoverGas, err)
|
||||||
}(gas)
|
}()
|
||||||
} else {
|
} else {
|
||||||
tracer.CaptureEnter(typ, caller.Address(), address, codeAndHash.code, gas, value)
|
evm.Config.Tracer.CaptureEnter(typ, caller.Address(), address, codeAndHash.code, gas, value)
|
||||||
tracer.OnGasConsumed(0, -gas, GasInitialBalance)
|
evm.Config.Tracer.OnGasConsumed(0, -gas, GasInitialBalance)
|
||||||
|
|
||||||
defer func(startGas uint64) {
|
defer func() {
|
||||||
tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
|
evm.Config.Tracer.OnGasConsumed(leftoverGas, leftoverGas, GasBuyBack)
|
||||||
tracer.CaptureExit(ret, startGas-leftOverGas, err)
|
evm.Config.Tracer.CaptureExit(ret, gas-leftoverGas, err)
|
||||||
}(gas)
|
}()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Depth check execution. Fail if we're trying to execute above the
|
// Depth check execution. Fail if we're trying to execute above the
|
||||||
// limit.
|
// limit.
|
||||||
if evm.depth > int(params.CallCreateDepth) {
|
if evm.depth > int(params.CallCreateDepth) {
|
||||||
|
|
@ -523,7 +518,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
|
||||||
}
|
}
|
||||||
|
|
||||||
// When an error was returned by the EVM or when setting the creation code
|
// When an error was returned by the EVM or when setting the creation code
|
||||||
// above we revert to the snapshot and consume any gas remaining. Additionally
|
// above we revert to the snapshot and consume any gas remaining. Additionally,
|
||||||
// when we're in homestead this also counts for code storage gas errors.
|
// when we're in homestead this also counts for code storage gas errors.
|
||||||
if err != nil && (evm.chainRules.IsHomestead || err != ErrCodeStoreOutOfGas) {
|
if err != nil && (evm.chainRules.IsHomestead || err != ErrCodeStoreOutOfGas) {
|
||||||
evm.StateDB.RevertToSnapshot(snapshot)
|
evm.StateDB.RevertToSnapshot(snapshot)
|
||||||
|
|
|
||||||
|
|
@ -562,7 +562,6 @@ func TestTracingWithOverrides(t *testing.T) {
|
||||||
From: &accounts[0].addr,
|
From: &accounts[0].addr,
|
||||||
// BLOCKNUMBER PUSH1 MSTORE
|
// BLOCKNUMBER PUSH1 MSTORE
|
||||||
Input: newRPCBytes(common.Hex2Bytes("4360005260206000f3")),
|
Input: newRPCBytes(common.Hex2Bytes("4360005260206000f3")),
|
||||||
//&hexutil.Bytes{0x43}, // blocknumber
|
|
||||||
},
|
},
|
||||||
config: &TraceCallConfig{
|
config: &TraceCallConfig{
|
||||||
BlockOverrides: ðapi.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(0x1337))},
|
BlockOverrides: ðapi.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(0x1337))},
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ func flatCallTracerTestRunner(tracerName string, filename string, dirPath string
|
||||||
return fmt.Errorf("failed to unmarshal trace result: %v", err)
|
return fmt.Errorf("failed to unmarshal trace result: %v", err)
|
||||||
}
|
}
|
||||||
if !jsonEqualFlat(ret, test.Result) {
|
if !jsonEqualFlat(ret, test.Result) {
|
||||||
t.Logf("tracer name: %s", tracerName)
|
t.Logf("test %s failed", filename)
|
||||||
|
|
||||||
// uncomment this for easier debugging
|
// uncomment this for easier debugging
|
||||||
// have, _ := json.MarshalIndent(ret, "", " ")
|
// have, _ := json.MarshalIndent(ret, "", " ")
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,16 @@
|
||||||
"value": "0x0",
|
"value": "0x0",
|
||||||
"gas": "0x1f97e",
|
"gas": "0x1f97e",
|
||||||
"gasUsed": "0x72de",
|
"gasUsed": "0x72de",
|
||||||
"input": "0x2e1a7d4d00000000000000000000000000000000000000000000000014d1120d7b160000"
|
"input": "0x2e1a7d4d00000000000000000000000000000000000000000000000014d1120d7b160000",
|
||||||
|
"calls": [{
|
||||||
|
"from":"0x6c06b16512b332e6cd8293a2974872674716ce18",
|
||||||
|
"gas":"0x8fc",
|
||||||
|
"gasUsed":"0x0",
|
||||||
|
"to":"0x66fdfd05e46126a07465ad24e40cc0597bc1ef31",
|
||||||
|
"input":"0x",
|
||||||
|
"error":"insufficient balance for transfer",
|
||||||
|
"value":"0x14d1120d7b160000",
|
||||||
|
"type":"CALL"
|
||||||
|
}]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,12 +63,27 @@
|
||||||
"address": "0x5f8a7e007172ba80afbff1b15f800eb0b260f224"
|
"address": "0x5f8a7e007172ba80afbff1b15f800eb0b260f224"
|
||||||
},
|
},
|
||||||
"traceAddress": [],
|
"traceAddress": [],
|
||||||
"subtraces": 0,
|
"subtraces": 1,
|
||||||
"transactionPosition": 74,
|
"transactionPosition": 74,
|
||||||
"transactionHash": "0x5ef60b27ac971c22a7d484e546e50093ca62300c8986d165154e47773764b6a4",
|
"transactionHash": "0x5ef60b27ac971c22a7d484e546e50093ca62300c8986d165154e47773764b6a4",
|
||||||
"blockNumber": 1555279,
|
"blockNumber": 1555279,
|
||||||
"blockHash": "0xd6c98d1b87dfa92a210d99bad2873adaf0c9e51fe43addc63fd9cca03a5c6f46",
|
"blockHash": "0xd6c98d1b87dfa92a210d99bad2873adaf0c9e51fe43addc63fd9cca03a5c6f46",
|
||||||
"time": "209.346µs"
|
"time": "209.346µs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"balance": "0x0",
|
||||||
|
"callType": "callcode",
|
||||||
|
"from": "0x5f8a7e007172ba80afbff1b15f800eb0b260f224",
|
||||||
|
"gas": "0xaf64",
|
||||||
|
"to": "0x0000000000000000000000000000000000000004",
|
||||||
|
"value": "0x13"
|
||||||
|
},
|
||||||
|
"error": "insufficient balance for transfer",
|
||||||
|
"result": {},
|
||||||
|
"subtraces": 0,
|
||||||
|
"traceAddress": [0],
|
||||||
|
"type": "call"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,9 +64,23 @@
|
||||||
"gasUsed": "0x72de",
|
"gasUsed": "0x72de",
|
||||||
"output": "0x"
|
"output": "0x"
|
||||||
},
|
},
|
||||||
"subtraces": 0,
|
"subtraces": 1,
|
||||||
"traceAddress": [],
|
"traceAddress": [],
|
||||||
"type": "call"
|
"type": "call"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"callType": "call",
|
||||||
|
"from": "0x6c06b16512b332e6cd8293a2974872674716ce18",
|
||||||
|
"gas": "0x8fc",
|
||||||
|
"to": "0x66fdfd05e46126a07465ad24e40cc0597bc1ef31",
|
||||||
|
"value": "0x14d1120d7b160000"
|
||||||
|
},
|
||||||
|
"error": "insufficient balance for transfer",
|
||||||
|
"result": {},
|
||||||
|
"subtraces": 0,
|
||||||
|
"traceAddress": [0],
|
||||||
|
"type": "call"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,12 +70,25 @@
|
||||||
"output": "0x"
|
"output": "0x"
|
||||||
},
|
},
|
||||||
"traceAddress": [],
|
"traceAddress": [],
|
||||||
"subtraces": 0,
|
"subtraces": 1,
|
||||||
"transactionPosition": 26,
|
"transactionPosition": 26,
|
||||||
"transactionHash": "0xcb1090fa85d2a3da8326b75333e92b3dca89963c895d9c981bfdaa64643135e4",
|
"transactionHash": "0xcb1090fa85d2a3da8326b75333e92b3dca89963c895d9c981bfdaa64643135e4",
|
||||||
"blockNumber": 839247,
|
"blockNumber": 839247,
|
||||||
"blockHash": "0xce7ff7d84ca97f0f89d6065e2c12409a795c9f607cdb14aef0713cad5d7e311c",
|
"blockHash": "0xce7ff7d84ca97f0f89d6065e2c12409a795c9f607cdb14aef0713cad5d7e311c",
|
||||||
"time": "182.267µs"
|
"time": "182.267µs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"from": "0x76554b33410b6d90b7dc889bfed0451ad195f27e",
|
||||||
|
"gas": "0x25a18",
|
||||||
|
"init": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"value": "0xa"
|
||||||
|
},
|
||||||
|
"error": "insufficient balance for transfer",
|
||||||
|
"result": {},
|
||||||
|
"subtraces": 0,
|
||||||
|
"traceAddress": [0],
|
||||||
|
"type": "create"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -63,13 +63,26 @@
|
||||||
"address": "0x1d99a1a3efa9181f540f9e24fa6e4e08eb7844ca"
|
"address": "0x1d99a1a3efa9181f540f9e24fa6e4e08eb7844ca"
|
||||||
},
|
},
|
||||||
"traceAddress": [],
|
"traceAddress": [],
|
||||||
"subtraces": 1,
|
"subtraces": 2,
|
||||||
"transactionPosition": 14,
|
"transactionPosition": 14,
|
||||||
"transactionHash": "0xdd76f02407e2f8329303ba688e111cae4f7008ad0d14d6e42c5698424ea36d79",
|
"transactionHash": "0xdd76f02407e2f8329303ba688e111cae4f7008ad0d14d6e42c5698424ea36d79",
|
||||||
"blockNumber": 1555146,
|
"blockNumber": 1555146,
|
||||||
"blockHash": "0xafb4f1dd27b9054c805acb81a88ed04384788cb31d84164c21874935c81e5c7e",
|
"blockHash": "0xafb4f1dd27b9054c805acb81a88ed04384788cb31d84164c21874935c81e5c7e",
|
||||||
"time": "187.145µs"
|
"time": "187.145µs"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"from": "0x1d99a1a3efa9181f540f9e24fa6e4e08eb7844ca",
|
||||||
|
"gas": "0x50ac",
|
||||||
|
"init": "0x5a",
|
||||||
|
"value": "0x1"
|
||||||
|
},
|
||||||
|
"error": "insufficient balance for transfer",
|
||||||
|
"result": {},
|
||||||
|
"subtraces": 0,
|
||||||
|
"traceAddress": [0],
|
||||||
|
"type": "create"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "suicide",
|
"type": "suicide",
|
||||||
"action": {
|
"action": {
|
||||||
|
|
@ -79,7 +92,7 @@
|
||||||
},
|
},
|
||||||
"result": null,
|
"result": null,
|
||||||
"traceAddress": [
|
"traceAddress": [
|
||||||
0
|
1
|
||||||
],
|
],
|
||||||
"subtraces": 0,
|
"subtraces": 0,
|
||||||
"transactionPosition": 14,
|
"transactionPosition": 14,
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue