github.com/ontio/ontology@v1.14.4/vm/evm/logger_json.go (about) 1 // Copyright (C) 2021 The Ontology Authors 2 // Copyright 2017 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 18 package evm 19 20 import ( 21 "encoding/json" 22 "io" 23 "math/big" 24 "time" 25 26 "github.com/ethereum/go-ethereum/common" 27 "github.com/ethereum/go-ethereum/common/math" 28 ) 29 30 type JSONLogger struct { 31 encoder *json.Encoder 32 cfg *LogConfig 33 } 34 35 // NewJSONLogger creates a new EVM tracer that prints execution steps as JSON objects 36 // into the provided stream. 37 func NewJSONLogger(cfg *LogConfig, writer io.Writer) *JSONLogger { 38 l := &JSONLogger{json.NewEncoder(writer), cfg} 39 if l.cfg == nil { 40 l.cfg = &LogConfig{} 41 } 42 return l 43 } 44 45 func (l *JSONLogger) CaptureStart(from common.Address, to common.Address, create bool, input []byte, 46 gas uint64, value *big.Int) { 47 } 48 49 // CaptureState outputs state information on the logger. 50 func (l *JSONLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, 51 stack *Stack, rStack *ReturnStack, rData []byte, contract *Contract, depth int, err error) { 52 log := StructLog{ 53 Pc: pc, 54 Op: op, 55 Gas: gas, 56 GasCost: cost, 57 MemorySize: memory.Len(), 58 Storage: nil, 59 Depth: depth, 60 RefundCounter: env.StateDB.GetRefund(), 61 Err: err, 62 } 63 if !l.cfg.DisableMemory { 64 log.Memory = memory.Data() 65 } 66 if !l.cfg.DisableStack { 67 //TODO(@holiman) improve this 68 logstack := make([]*big.Int, len(stack.Data())) 69 for i, item := range stack.Data() { 70 logstack[i] = item.ToBig() 71 } 72 log.Stack = logstack 73 log.ReturnStack = rStack.data 74 } 75 if !l.cfg.DisableReturnData { 76 log.ReturnData = rData 77 } 78 79 _ = l.encoder.Encode(log) 80 } 81 82 // CaptureFault outputs state information on the logger. 83 func (l *JSONLogger) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, 84 stack *Stack, rStack *ReturnStack, contract *Contract, depth int, err error) { 85 } 86 87 // CaptureEnd is triggered at end of execution. 88 func (l *JSONLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) { 89 type endLog struct { 90 Output string `json:"output"` 91 GasUsed math.HexOrDecimal64 `json:"gasUsed"` 92 Time time.Duration `json:"time"` 93 Err string `json:"error,omitempty"` 94 } 95 if err != nil { 96 _ = l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), t, err.Error()}) 97 return 98 } 99 _ = l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), t, ""}) 100 return 101 }