github.com/klaytn/klaytn@v1.12.1/blockchain/vm/internaltx_trace_json.go (about)

     1  // Modifications Copyright 2020 The klaytn 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  // InternalTxTracer is a full blown transaction tracer that extracts and reports all
    19  // the internal calls made by a transaction, along with any useful information.
    20  //
    21  // This file is derived from eth/tracers/internal/tracers/call_tracer.js (2018/06/04).
    22  // Modified and improved for the klaytn development.
    23  
    24  package vm
    25  
    26  import (
    27  	"encoding/json"
    28  	"errors"
    29  	"time"
    30  
    31  	"github.com/klaytn/klaytn/common"
    32  	"github.com/klaytn/klaytn/common/hexutil"
    33  )
    34  
    35  func (i InternalTxTrace) MarshalJSON() ([]byte, error) {
    36  	type internalTxTrace struct {
    37  		Type  string          `json:"type"`
    38  		From  *common.Address `json:"from,omitempty"`
    39  		To    *common.Address `json:"to,omitempty"`
    40  		Value *string         `json:"value,omitempty"`
    41  
    42  		Gas     *hexutil.Uint64 `json:"gas,omitempty"`
    43  		GasUsed *hexutil.Uint64 `json:"gasUsed,omitempty"`
    44  
    45  		Input  *string `json:"input,omitempty"`  // hex string
    46  		Output *string `json:"output,omitempty"` // hex string
    47  		Error  *string `json:"error,omitempty"`
    48  
    49  		Time  *string            `json:"time,omitempty"`
    50  		Calls []*InternalTxTrace `json:"calls,omitempty"`
    51  
    52  		Reverted *RevertedInfo `json:"reverted,omitempty"`
    53  	}
    54  
    55  	var enc internalTxTrace
    56  	enc.Type = i.Type
    57  	enc.From = i.From
    58  	enc.To = i.To
    59  	if i.Value != "" {
    60  		enc.Value = &i.Value
    61  	}
    62  	if i.Gas != 0 {
    63  		gas := hexutil.Uint64(i.Gas)
    64  		enc.Gas = &gas
    65  	}
    66  	if i.GasUsed != 0 {
    67  		gasUsed := hexutil.Uint64(i.GasUsed)
    68  		enc.GasUsed = &gasUsed
    69  	}
    70  	if i.Input != "" {
    71  		enc.Input = &i.Input
    72  	}
    73  	if i.Output != "" {
    74  		enc.Output = &i.Output
    75  	}
    76  	if i.Error != nil {
    77  		errStr := i.Error.Error()
    78  		enc.Error = &errStr
    79  	}
    80  	if i.Time != time.Duration(0) {
    81  		timeStr := i.Time.String()
    82  		enc.Time = &timeStr
    83  	}
    84  	enc.Calls = i.Calls
    85  	enc.Reverted = i.Reverted
    86  
    87  	return json.Marshal(&enc)
    88  }
    89  
    90  func (i *InternalTxTrace) UnmarshalJSON(input []byte) error {
    91  	type internalTxTrace struct {
    92  		Type  string          `json:"type"`
    93  		From  *common.Address `json:"from,omitempty"`
    94  		To    *common.Address `json:"to,omitempty"`
    95  		Value *string         `json:"value,omitempty"`
    96  
    97  		Gas     *hexutil.Uint64 `json:"gas,omitempty"`
    98  		GasUsed *hexutil.Uint64 `json:"gasUsed,omitempty"`
    99  
   100  		Input  *string `json:"input,omitempty"`  // hex string
   101  		Output *string `json:"output,omitempty"` // hex string
   102  		Error  *string `json:"error,omitempty"`
   103  
   104  		Time  *string            `json:"time,omitempty"`
   105  		Calls []*InternalTxTrace `json:"calls,omitempty"`
   106  
   107  		Reverted *RevertedInfo `json:"reverted,omitempty"`
   108  	}
   109  	var dec internalTxTrace
   110  	if err := json.Unmarshal(input, &dec); err != nil {
   111  		return err
   112  	}
   113  	i.Type = dec.Type
   114  	if dec.From != nil {
   115  		i.From = dec.From
   116  	}
   117  	if dec.To != nil {
   118  		i.To = dec.To
   119  	}
   120  	if dec.Value != nil {
   121  		i.Value = *dec.Value
   122  	}
   123  	if dec.Gas != nil {
   124  		i.Gas = uint64(*dec.Gas)
   125  	}
   126  	if dec.GasUsed != nil {
   127  		i.GasUsed = uint64(*dec.GasUsed)
   128  	}
   129  	if dec.Input != nil {
   130  		i.Input = *dec.Input
   131  	}
   132  	if dec.Output != nil {
   133  		i.Output = *dec.Output
   134  	}
   135  	if dec.Error != nil {
   136  		i.Error = errors.New(*dec.Error)
   137  	}
   138  	if dec.Time != nil {
   139  		t, err := time.ParseDuration(*dec.Time)
   140  		if err != nil {
   141  			return err
   142  		}
   143  		i.Time = t
   144  	}
   145  	i.Calls = dec.Calls
   146  	i.Reverted = dec.Reverted
   147  	return nil
   148  }
   149  
   150  func (r RevertedInfo) MarshalJSON() ([]byte, error) {
   151  	type RevertedInfo struct {
   152  		Contract *common.Address `json:"contract,omitempty"`
   153  		Message  *string         `json:"message,omitempty"`
   154  	}
   155  	var enc RevertedInfo
   156  	enc.Contract = r.Contract
   157  	if r.Message != "" {
   158  		enc.Message = &r.Message
   159  	}
   160  	return json.Marshal(&enc)
   161  }
   162  
   163  func (r *RevertedInfo) UnmarshalJSON(data []byte) error {
   164  	type RevertedInfo struct {
   165  		Contract *common.Address `json:"contract,omitempty"`
   166  		Message  *string         `json:"message,omitempty"`
   167  	}
   168  	var dec RevertedInfo
   169  	if err := json.Unmarshal(data, &dec); err != nil {
   170  		return err
   171  	}
   172  	if dec.Message != nil {
   173  		r.Message = *dec.Message
   174  	}
   175  	r.Contract = dec.Contract
   176  	return nil
   177  }