diff --git a/cmd/ethkit/block.go b/cmd/ethkit/block.go index e5ffdc15..5fe0b9a9 100644 --- a/cmd/ethkit/block.go +++ b/cmd/ethkit/block.go @@ -172,7 +172,7 @@ func NewHeader(b *types.Block) *Header { WithdrawalsHash: b.Header().WithdrawalsHash, Size: b.Header().Size(), // TotalDifficulty: b.Difficulty(), - TransactionsHash: TransactionsHash(*b), + TransactionsHash: TransactionsHash(b), } } @@ -188,7 +188,7 @@ func (h *Header) String() string { } // TransactionsHash returns a list of transaction hash starting from a list of transactions contained in a block. -func TransactionsHash(block types.Block) []common.Hash { +func TransactionsHash(block *types.Block) []common.Hash { txsh := make([]common.Hash, len(block.Transactions())) for i, tx := range block.Transactions() { diff --git a/cmd/ethkit/wallet.go b/cmd/ethkit/wallet.go index 967396e4..a2099e7d 100644 --- a/cmd/ethkit/wallet.go +++ b/cmd/ethkit/wallet.go @@ -13,8 +13,9 @@ import ( "github.com/0xsequence/ethkit/ethwallet" "github.com/0xsequence/ethkit/go-ethereum/accounts/keystore" "github.com/0xsequence/ethkit/go-ethereum/common" + "github.com/spf13/cobra" - "golang.org/x/crypto/ssh/terminal" + "golang.org/x/term" ) func init() { @@ -261,7 +262,7 @@ func fileExists(filename string) bool { func readSecretInput(prompt string) ([]byte, error) { fmt.Print(prompt) - password, err := terminal.ReadPassword(int(syscall.Stdin)) + password, err := term.ReadPassword(int(syscall.Stdin)) if err != nil { return nil, err } diff --git a/ethcoder/ethcoder.go b/ethcoder/ethcoder.go index 0487449f..dad89634 100644 --- a/ethcoder/ethcoder.go +++ b/ethcoder/ethcoder.go @@ -12,9 +12,7 @@ func BytesToBytes32(slice []byte) [32]byte { } func PaddedAddress(address string) string { - if strings.HasPrefix(address, "0x") { - address = address[2:] - } + address = strings.TrimPrefix(address, "0x") if len(address) < 64 { address = strings.Repeat("0", 64-len(address)) + address } diff --git a/ethcoder/solidity_pack.go b/ethcoder/solidity_pack.go index 500ae866..cd2f561f 100644 --- a/ethcoder/solidity_pack.go +++ b/ethcoder/solidity_pack.go @@ -163,7 +163,7 @@ func solidityArgumentPack(typ string, val interface{}, isArray bool) ([]byte, er return nil, fmt.Errorf("not a [%d]byte", size) } - v := make([]byte, size, size) + v := make([]byte, size) var ok bool for i := 0; i < int(size); i++ { v[i], ok = rv.Index(i).Interface().(byte) diff --git a/ethreceipts/ethreceipts.go b/ethreceipts/ethreceipts.go index 95121edd..a1b4df70 100644 --- a/ethreceipts/ethreceipts.go +++ b/ethreceipts/ethreceipts.go @@ -942,12 +942,11 @@ func groupLogsByTransaction(logs []types.Log) map[string][]*types.Log { return out } -func blockLogsCount(numTxns int, logs []types.Log) uint { - var max uint = uint(numTxns) +// this is unused +func blockLogsCount(numTxns int, logs []*types.Log) uint { + blockCount := uint(numTxns) for _, log := range logs { - if log.TxIndex+1 > max { - max = log.TxIndex + 1 - } + blockCount = max(blockCount, log.TxIndex+1) } - return max + return blockCount } diff --git a/go-ethereum/common/hexutil/json.go b/go-ethereum/common/hexutil/json.go index ce2d8cc6..27d11316 100644 --- a/go-ethereum/common/hexutil/json.go +++ b/go-ethereum/common/hexutil/json.go @@ -24,6 +24,7 @@ import ( "reflect" "strconv" + "github.com/0xsequence/ethkit/util" "github.com/holiman/uint256" ) @@ -47,6 +48,11 @@ func (b Bytes) MarshalText() ([]byte, error) { return result, nil } +// MarshalJSON implements json.Marshaler. +func (b Bytes) MarshalJSON() ([]byte, error) { + return util.QuoteString(b) +} + // UnmarshalJSON implements json.Unmarshaler. func (b *Bytes) UnmarshalJSON(input []byte) error { if !isString(input) { @@ -159,6 +165,11 @@ func (b Big) MarshalText() ([]byte, error) { return []byte(EncodeBig((*big.Int)(&b))), nil } +// MarshalJSON implements json.Marshaler. +func (b Big) MarshalJSON() ([]byte, error) { + return util.QuoteString(b) +} + // UnmarshalJSON implements json.Unmarshaler. func (b *Big) UnmarshalJSON(input []byte) error { if !isString(input) { @@ -238,6 +249,11 @@ func (b U256) MarshalText() ([]byte, error) { return []byte(u256.Hex()), nil } +// MarshalJSON implements json.Marshaler. +func (b U256) MarshalJSON() ([]byte, error) { + return util.QuoteString(b) +} + // UnmarshalJSON implements json.Unmarshaler. func (b *U256) UnmarshalJSON(input []byte) error { // The uint256.Int.UnmarshalJSON method accepts "dec", "0xhex"; we must be @@ -282,6 +298,11 @@ func (b Uint64) MarshalText() ([]byte, error) { return buf, nil } +// MarshalJSON implements json.Marshaler. +func (b Uint64) MarshalJSON() ([]byte, error) { + return util.QuoteString(b) +} + // UnmarshalJSON implements json.Unmarshaler. func (b *Uint64) UnmarshalJSON(input []byte) error { if !isString(input) { @@ -343,6 +364,11 @@ func (b Uint) MarshalText() ([]byte, error) { return Uint64(b).MarshalText() } +// MarshalJSON implements json.Marshaler. +func (b Uint) MarshalJSON() ([]byte, error) { + return util.QuoteString(b) +} + // UnmarshalJSON implements json.Unmarshaler. func (b *Uint) UnmarshalJSON(input []byte) error { if !isString(input) { diff --git a/go-ethereum/common/math/big.go b/go-ethereum/common/math/big.go index d9748d01..77fa9349 100644 --- a/go-ethereum/common/math/big.go +++ b/go-ethereum/common/math/big.go @@ -20,6 +20,8 @@ package math import ( "fmt" "math/big" + + "github.com/0xsequence/ethkit/util" ) // Various big integer limit values. @@ -78,6 +80,11 @@ func (i *HexOrDecimal256) MarshalText() ([]byte, error) { return []byte(fmt.Sprintf("%#x", (*big.Int)(i))), nil } +// MarshalJSON implements json.Marshaler. +func (i HexOrDecimal256) MarshalJSON() ([]byte, error) { + return util.QuoteString(&i) +} + // Decimal256 unmarshals big.Int as a decimal string. When unmarshalling, // it however accepts either "0x"-prefixed (hex encoded) or non-prefixed (decimal) type Decimal256 big.Int @@ -104,6 +111,11 @@ func (i *Decimal256) MarshalText() ([]byte, error) { return []byte(i.String()), nil } +// MarshalJSON implements json.Marshaler. +func (i Decimal256) MarshalJSON() ([]byte, error) { + return util.QuoteString(&i) +} + // String implements Stringer. func (i *Decimal256) String() string { if i == nil { diff --git a/go-ethereum/common/math/integer.go b/go-ethereum/common/math/integer.go index 82de96f9..3d62027f 100644 --- a/go-ethereum/common/math/integer.go +++ b/go-ethereum/common/math/integer.go @@ -20,6 +20,8 @@ import ( "fmt" "math/bits" "strconv" + + "github.com/0xsequence/ethkit/util" ) // Integer limit values. @@ -67,6 +69,11 @@ func (i HexOrDecimal64) MarshalText() ([]byte, error) { return []byte(fmt.Sprintf("%#x", uint64(i))), nil } +// MarshalJSON implements json.Marshaler. +func (i HexOrDecimal64) MarshalJSON() ([]byte, error) { + return util.QuoteString(i) +} + // ParseUint64 parses s as an integer in decimal or hexadecimal syntax. // Leading zeros are accepted. The empty string parses as zero. func ParseUint64(s string) (uint64, bool) { diff --git a/go-ethereum/common/types.go b/go-ethereum/common/types.go index 1416884e..9d632f9e 100644 --- a/go-ethereum/common/types.go +++ b/go-ethereum/common/types.go @@ -30,6 +30,8 @@ import ( "strings" "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" + "github.com/0xsequence/ethkit/util" + "golang.org/x/crypto/sha3" ) @@ -142,6 +144,11 @@ func (h Hash) MarshalText() ([]byte, error) { return hexutil.Bytes(h[:]).MarshalText() } +// MarshalJSON implements json.Marshaler. +func (h Hash) MarshalJSON() ([]byte, error) { + return util.QuoteString(h) +} + // SetBytes sets the hash to the value of b. // If b is larger than len(h), b will be cropped from the left. func (h *Hash) SetBytes(b []byte) { @@ -204,7 +211,14 @@ func (h *UnprefixedHash) UnmarshalText(input []byte) error { // MarshalText encodes the hash as hex. func (h UnprefixedHash) MarshalText() ([]byte, error) { - return []byte(hex.EncodeToString(h[:])), nil + b := make([]byte, hex.EncodedLen(len(h))) + hex.Encode(b, h[:]) + return b, nil +} + +// MarshalJSON implements json.Marshaler. +func (h UnprefixedHash) MarshalJSON() ([]byte, error) { + return util.QuoteString(h) } /////////// Address @@ -323,11 +337,16 @@ func (a *Address) SetBytes(b []byte) { copy(a[AddressLength-len(b):], b) } -// MarshalText returns the hex representation of a. +// MarshalText returns the hex representation of the address. func (a Address) MarshalText() ([]byte, error) { return hexutil.Bytes(a[:]).MarshalText() } +// MarshalJSON implements json.Marshaler. +func (a Address) MarshalJSON() ([]byte, error) { + return util.QuoteString(a) +} + // UnmarshalText parses a hash in hex syntax. func (a *Address) UnmarshalText(input []byte) error { return hexutil.UnmarshalFixedText("Address", input, a[:]) @@ -381,7 +400,14 @@ func (a *UnprefixedAddress) UnmarshalText(input []byte) error { // MarshalText encodes the address as hex. func (a UnprefixedAddress) MarshalText() ([]byte, error) { - return []byte(hex.EncodeToString(a[:])), nil + b := make([]byte, hex.EncodedLen(len(a))) + hex.Encode(b, a[:]) + return b, nil +} + +// MarshalJSON implements json.Marshaler. +func (a UnprefixedAddress) MarshalJSON() ([]byte, error) { + return util.QuoteString(a) } // MixedcaseAddress retains the original string, which may or may not be diff --git a/go-ethereum/core/types/account.go b/go-ethereum/core/types/account.go index 283a0363..535f6be2 100644 --- a/go-ethereum/core/types/account.go +++ b/go-ethereum/core/types/account.go @@ -26,6 +26,8 @@ import ( "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" "github.com/0xsequence/ethkit/go-ethereum/common/math" + + "github.com/0xsequence/ethkit/util" ) //go:generate go run github.com/fjl/gencodec -type Account -field-override accountMarshaling -out gen_account.go @@ -71,6 +73,11 @@ func (h storageJSON) MarshalText() ([]byte, error) { return hexutil.Bytes(h[:]).MarshalText() } +// MarshalJSON implements json.Marshaler. +func (h storageJSON) MarshalJSON() ([]byte, error) { + return util.QuoteString(h) +} + // GenesisAlloc specifies the initial state of a genesis block. type GenesisAlloc map[common.Address]Account diff --git a/go-ethereum/core/types/block.go b/go-ethereum/core/types/block.go index c0acc267..4bfa6ca4 100644 --- a/go-ethereum/core/types/block.go +++ b/go-ethereum/core/types/block.go @@ -31,6 +31,8 @@ import ( "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" "github.com/0xsequence/ethkit/go-ethereum/rlp" + + "github.com/0xsequence/ethkit/util" ) // A BlockNonce is a 64-bit hash which proves (combined with the @@ -55,6 +57,11 @@ func (n BlockNonce) MarshalText() ([]byte, error) { return hexutil.Bytes(n[:]).MarshalText() } +// MarshalJSON implements json.Marshaler. +func (b BlockNonce) MarshalJSON() ([]byte, error) { + return util.QuoteString(b) +} + // UnmarshalText implements encoding.TextUnmarshaler. func (n *BlockNonce) UnmarshalText(input []byte) error { return hexutil.UnmarshalFixedText("BlockNonce", input, n[:]) diff --git a/go-ethereum/core/types/bloom9.go b/go-ethereum/core/types/bloom9.go index 87ba2e6b..b7200600 100644 --- a/go-ethereum/core/types/bloom9.go +++ b/go-ethereum/core/types/bloom9.go @@ -23,6 +23,7 @@ import ( "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" "github.com/0xsequence/ethkit/go-ethereum/crypto" + "github.com/0xsequence/ethkit/util" ) type bytesBacked interface { @@ -95,6 +96,11 @@ func (b Bloom) MarshalText() ([]byte, error) { return hexutil.Bytes(b[:]).MarshalText() } +// MarshalJSON implements json.Marshaler. +func (b Bloom) MarshalJSON() ([]byte, error) { + return util.QuoteString(b) +} + // UnmarshalText b as a hex string with 0x prefix. func (b *Bloom) UnmarshalText(input []byte) error { return hexutil.UnmarshalFixedText("Bloom", input, b[:]) diff --git a/go-ethereum/crypto/crypto.go b/go-ethereum/crypto/crypto.go index 3bfa1a56..0c4a68f5 100644 --- a/go-ethereum/crypto/crypto.go +++ b/go-ethereum/crypto/crypto.go @@ -257,8 +257,10 @@ func checkKeyFileEnd(r *bufio.Reader) error { // SaveECDSA saves a secp256k1 private key to the given file with // restrictive permissions. The key data is saved hex-encoded. func SaveECDSA(file string, key *ecdsa.PrivateKey) error { - k := hex.EncodeToString(FromECDSA(key)) - return os.WriteFile(file, []byte(k), 0600) + raw := FromECDSA(key) + k := make([]byte, hex.EncodedLen(len(raw))) + hex.Encode(k, raw) + return os.WriteFile(file, k, 0600) } // GenerateKey generates a new private key. diff --git a/go-ethereum/crypto/kzg4844/kzg4844.go b/go-ethereum/crypto/kzg4844/kzg4844.go index b5f26eb4..f1c81e5a 100644 --- a/go-ethereum/crypto/kzg4844/kzg4844.go +++ b/go-ethereum/crypto/kzg4844/kzg4844.go @@ -25,6 +25,7 @@ import ( "sync/atomic" "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" + "github.com/0xsequence/ethkit/util" ) //go:embed trusted_setup.json @@ -49,6 +50,11 @@ func (b Blob) MarshalText() ([]byte, error) { return hexutil.Bytes(b[:]).MarshalText() } +// MarshalJSON implements json.Marshaler. +func (b Blob) MarshalJSON() ([]byte, error) { + return util.QuoteString(b) +} + // Commitment is a serialized commitment to a polynomial. type Commitment [48]byte @@ -62,6 +68,11 @@ func (c Commitment) MarshalText() ([]byte, error) { return hexutil.Bytes(c[:]).MarshalText() } +// MarshalJSON implements json.Marshaler. +func (c Commitment) MarshalJSON() ([]byte, error) { + return util.QuoteString(c) +} + // Proof is a serialized commitment to the quotient polynomial. type Proof [48]byte @@ -75,6 +86,11 @@ func (p Proof) MarshalText() ([]byte, error) { return hexutil.Bytes(p[:]).MarshalText() } +// MarshalJSON implements json.Marshaler. +func (p Proof) MarshalJSON() ([]byte, error) { + return util.QuoteString(p) +} + // Point is a BLS field element. type Point [32]byte diff --git a/go-ethereum/rpc/types.go b/go-ethereum/rpc/types.go index de10a20a..6b692cab 100644 --- a/go-ethereum/rpc/types.go +++ b/go-ethereum/rpc/types.go @@ -26,6 +26,8 @@ import ( "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" + + "github.com/0xsequence/ethkit/util" ) // API describes the set of methods offered over the RPC interface @@ -123,6 +125,11 @@ func (bn BlockNumber) MarshalText() ([]byte, error) { return []byte(bn.String()), nil } +// MarshalJSON implements json.Marshaler. +func (bn BlockNumber) MarshalJSON() ([]byte, error) { + return util.QuoteString(bn) +} + func (bn BlockNumber) String() string { switch bn { case EarliestBlockNumber: diff --git a/go.mod b/go.mod index d32c006a..1ec6671b 100644 --- a/go.mod +++ b/go.mod @@ -39,6 +39,7 @@ require ( golang.org/x/net v0.39.0 golang.org/x/sync v0.13.0 golang.org/x/sys v0.32.0 + golang.org/x/term v0.31.0 golang.org/x/tools v0.31.0 ) @@ -64,7 +65,6 @@ require ( github.com/redis/go-redis/v9 v9.7.3 // indirect github.com/spf13/pflag v1.0.6 // indirect github.com/supranational/blst v0.3.14 // indirect - golang.org/x/term v0.31.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect rsc.io/tmplfunc v0.0.3 // indirect ) diff --git a/util/quote.go b/util/quote.go new file mode 100644 index 00000000..432cf450 --- /dev/null +++ b/util/quote.go @@ -0,0 +1,14 @@ +package util + +import "encoding" + +// QuoteString adds quotes to the byte slice returned by the TextMarshaler. +func QuoteString(b encoding.TextMarshaler) ([]byte, error) { + raw, err := b.MarshalText() + if err != nil { + return nil, err + } + raw = append([]byte{'"'}, raw...) + raw = append(raw, '"') + return raw, nil +}