Skip to content

Commit aeb8a3f

Browse files
fix: display transaction input data as hex instead of base64 in monitorv2
Addresses: #620 (comment) Transaction input data and other byte fields in the human-readable JSON views were being displayed as base64-encoded strings, making them difficult to read. This change introduces a custom HexBytes type that marshals byte data as hex strings with 0x prefix for better readability. Updated fields: - Transaction input data (PrettyTransaction.Input) - Event log data (PrettyTxLogs.Data) - Block logs bloom filter (PrettyBlock.LogsBloom) - Block extra data (PrettyBlock.ExtraData) - Receipt logs bloom filter (PrettyReceipt.LogsBloom) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 04e922e commit aeb8a3f

File tree

1 file changed

+54
-11
lines changed

1 file changed

+54
-11
lines changed

rpctypes/pretty.go

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,27 +18,70 @@
1818
package rpctypes
1919

2020
import (
21+
"encoding/hex"
2122
"encoding/json"
23+
"fmt"
2224
"math/big"
25+
"strings"
2326

2427
ethcommon "github.com/ethereum/go-ethereum/common"
2528
)
2629

30+
// HexBytes represents byte data that should be JSON-marshaled as hex strings
31+
type HexBytes []byte
32+
33+
// MarshalJSON implements the json.Marshaler interface for HexBytes
34+
func (h HexBytes) MarshalJSON() ([]byte, error) {
35+
if h == nil {
36+
return []byte("null"), nil
37+
}
38+
if len(h) == 0 {
39+
return []byte(`"0x"`), nil
40+
}
41+
hexStr := "0x" + hex.EncodeToString(h)
42+
return json.Marshal(hexStr)
43+
}
44+
45+
// UnmarshalJSON implements the json.Unmarshaler interface for HexBytes
46+
func (h *HexBytes) UnmarshalJSON(data []byte) error {
47+
var s string
48+
if err := json.Unmarshal(data, &s); err != nil {
49+
return err
50+
}
51+
52+
if s == "" || s == "0x" {
53+
*h = HexBytes{}
54+
return nil
55+
}
56+
57+
if !strings.HasPrefix(s, "0x") {
58+
return fmt.Errorf("hex string must start with 0x")
59+
}
60+
61+
decoded, err := hex.DecodeString(s[2:])
62+
if err != nil {
63+
return err
64+
}
65+
66+
*h = HexBytes(decoded)
67+
return nil
68+
}
69+
2770
// PrettyBlock represents a human-readable block structure
2871
type PrettyBlock struct {
2972
Number *big.Int `json:"number"`
3073
Hash ethcommon.Hash `json:"hash"`
3174
ParentHash ethcommon.Hash `json:"parentHash"`
3275
Nonce uint64 `json:"nonce"`
3376
SHA3Uncles ethcommon.Hash `json:"sha3Uncles"`
34-
LogsBloom []byte `json:"logsBloom"`
77+
LogsBloom HexBytes `json:"logsBloom"`
3578
TransactionsRoot ethcommon.Hash `json:"transactionsRoot"`
3679
StateRoot ethcommon.Hash `json:"stateRoot"`
3780
ReceiptsRoot ethcommon.Hash `json:"receiptsRoot"`
3881
Miner ethcommon.Address `json:"miner"`
3982
Difficulty *big.Int `json:"difficulty"`
4083
TotalDifficulty *big.Int `json:"totalDifficulty,omitempty"`
41-
ExtraData []byte `json:"extraData"`
84+
ExtraData HexBytes `json:"extraData"`
4285
Size uint64 `json:"size"`
4386
GasLimit uint64 `json:"gasLimit"`
4487
GasUsed uint64 `json:"gasUsed"`
@@ -59,7 +102,7 @@ type PrettyTransaction struct {
59102
MaxPriorityFeePerGas uint64 `json:"maxPriorityFeePerGas"`
60103
MaxFeePerGas uint64 `json:"maxFeePerGas"`
61104
Hash ethcommon.Hash `json:"hash"`
62-
Input []byte `json:"input"`
105+
Input HexBytes `json:"input"`
63106
Nonce uint64 `json:"nonce"`
64107
To ethcommon.Address `json:"to"`
65108
TransactionIndex uint64 `json:"transactionIndex"`
@@ -79,7 +122,7 @@ type PrettyTxLogs struct {
79122
TransactionIndex uint64 `json:"transactionIndex"`
80123
Address ethcommon.Address `json:"address"`
81124
LogIndex uint64 `json:"logIndex"`
82-
Data []byte `json:"data"`
125+
Data HexBytes `json:"data"`
83126
Removed bool `json:"removed"`
84127
Topics []ethcommon.Hash `json:"topics"`
85128
TransactionHash ethcommon.Hash `json:"transactionHash"`
@@ -98,7 +141,7 @@ type PrettyReceipt struct {
98141
GasUsed *big.Int `json:"gasUsed"`
99142
ContractAddress ethcommon.Address `json:"contractAddress"`
100143
Logs []PrettyTxLogs `json:"logs"`
101-
LogsBloom []byte `json:"logsBloom"`
144+
LogsBloom HexBytes `json:"logsBloom"`
102145
Root ethcommon.Hash `json:"root"`
103146
Status uint64 `json:"status"`
104147
BlobGasPrice *big.Int `json:"blobGasPrice"`
@@ -119,7 +162,7 @@ func (i *implPolyBlock) MarshalJSONPretty() ([]byte, error) {
119162
MaxPriorityFeePerGas: tx.MaxPriorityFeePerGas.ToUint64(),
120163
MaxFeePerGas: tx.MaxFeePerGas.ToUint64(),
121164
Hash: tx.Hash.ToHash(),
122-
Input: tx.Input.ToBytes(),
165+
Input: HexBytes(tx.Input.ToBytes()),
123166
Nonce: tx.Nonce.ToUint64(),
124167
To: tx.To.ToAddress(),
125168
TransactionIndex: tx.TransactionIndex.ToUint64(),
@@ -145,13 +188,13 @@ func (i *implPolyBlock) MarshalJSONPretty() ([]byte, error) {
145188
ParentHash: i.inner.ParentHash.ToHash(),
146189
Nonce: i.inner.Nonce.ToUint64(),
147190
SHA3Uncles: i.inner.SHA3Uncles.ToHash(),
148-
LogsBloom: i.inner.LogsBloom.ToBytes(),
191+
LogsBloom: HexBytes(i.inner.LogsBloom.ToBytes()),
149192
TransactionsRoot: i.inner.TransactionsRoot.ToHash(),
150193
StateRoot: i.inner.StateRoot.ToHash(),
151194
ReceiptsRoot: i.inner.ReceiptsRoot.ToHash(),
152195
Miner: i.inner.Miner.ToAddress(),
153196
Difficulty: i.inner.Difficulty.ToBigInt(),
154-
ExtraData: i.inner.ExtraData.ToBytes(),
197+
ExtraData: HexBytes(i.inner.ExtraData.ToBytes()),
155198
Size: i.inner.Size.ToUint64(),
156199
GasLimit: i.inner.GasLimit.ToUint64(),
157200
GasUsed: i.inner.GasUsed.ToUint64(),
@@ -176,7 +219,7 @@ func (i *implPolyTransaction) MarshalJSONPretty() ([]byte, error) {
176219
MaxPriorityFeePerGas: i.inner.MaxPriorityFeePerGas.ToUint64(),
177220
MaxFeePerGas: i.inner.MaxFeePerGas.ToUint64(),
178221
Hash: i.inner.Hash.ToHash(),
179-
Input: i.inner.Input.ToBytes(),
222+
Input: HexBytes(i.inner.Input.ToBytes()),
180223
Nonce: i.inner.Nonce.ToUint64(),
181224
To: i.inner.To.ToAddress(),
182225
TransactionIndex: i.inner.TransactionIndex.ToUint64(),
@@ -209,7 +252,7 @@ func (i *implPolyReceipt) MarshalJSONPretty() ([]byte, error) {
209252
TransactionIndex: log.TransactionIndex.ToUint64(),
210253
Address: log.Address.ToAddress(),
211254
LogIndex: log.LogIndex.ToUint64(),
212-
Data: log.Data.ToBytes(),
255+
Data: HexBytes(log.Data.ToBytes()),
213256
Removed: log.Removed,
214257
Topics: prettyTopics,
215258
TransactionHash: log.TransactionHash.ToHash(),
@@ -228,7 +271,7 @@ func (i *implPolyReceipt) MarshalJSONPretty() ([]byte, error) {
228271
GasUsed: i.inner.GasUsed.ToBigInt(),
229272
ContractAddress: i.inner.ContractAddress.ToAddress(),
230273
Logs: prettyLogs,
231-
LogsBloom: i.inner.LogsBloom.ToBytes(),
274+
LogsBloom: HexBytes(i.inner.LogsBloom.ToBytes()),
232275
Root: i.inner.Root.ToHash(),
233276
Status: i.inner.Status.ToUint64(),
234277
BlobGasPrice: i.inner.BlobGasPrice.ToBigInt(),

0 commit comments

Comments
 (0)