From 0e2c43273ad4ea0bc20f7f0b3bb0ae4a17651d3d Mon Sep 17 00:00:00 2001 From: Chen Chen <34592639+envestcc@users.noreply.github.com> Date: Tue, 26 Sep 2023 12:41:42 +0800 Subject: [PATCH] [api] fix json unmarshal error when calling TransactionByHash via ethclient (#3933) --- api/web3server_marshal.go | 13 ++++++---- api/web3server_marshal_test.go | 43 ++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/api/web3server_marshal.go b/api/web3server_marshal.go index cbd16a7f7b..a3e0ffd78e 100644 --- a/api/web3server_marshal.go +++ b/api/web3server_marshal.go @@ -3,15 +3,17 @@ package api import ( "encoding/hex" "encoding/json" + "math/big" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" + "github.com/iotexproject/go-pkgs/crypto" + "github.com/iotexproject/go-pkgs/hash" + "github.com/iotexproject/iotex-address/address" "github.com/pkg/errors" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/timestamppb" - "github.com/iotexproject/go-pkgs/crypto" - "github.com/iotexproject/go-pkgs/hash" - "github.com/iotexproject/iotex-address/address" "github.com/iotexproject/iotex-core/action" apitypes "github.com/iotexproject/iotex-core/api/types" "github.com/iotexproject/iotex-core/blockchain/block" @@ -228,6 +230,7 @@ func (obj *getTransactionResult) MarshalJSON() ([]byte, error) { value, _ := intStrToHex(obj.ethTx.Value().String()) gasPrice, _ := intStrToHex(obj.ethTx.GasPrice().String()) + // TODO: if transaction is support EIP-155, we need to add chainID to v vVal := uint64(obj.signature[64]) if vVal < 27 { vVal += 27 @@ -260,8 +263,8 @@ func (obj *getTransactionResult) MarshalJSON() ([]byte, error) { GasPrice: gasPrice, Gas: uint64ToHex(obj.ethTx.Gas()), Input: byteToHex(obj.ethTx.Data()), - R: byteToHex(obj.signature[:32]), - S: byteToHex(obj.signature[32:64]), + R: hexutil.EncodeBig(new(big.Int).SetBytes(obj.signature[:32])), + S: hexutil.EncodeBig(new(big.Int).SetBytes(obj.signature[32:64])), V: uint64ToHex(vVal), }) } diff --git a/api/web3server_marshal_test.go b/api/web3server_marshal_test.go index 025aa58f39..562dc96719 100644 --- a/api/web3server_marshal_test.go +++ b/api/web3server_marshal_test.go @@ -232,6 +232,7 @@ func TestTransactionObjectMarshal(t *testing.T) { ethTx: types.NewContractCreation(1, big.NewInt(10), 21000, big.NewInt(0), []byte{}), receipt: receipt, pubkey: _testPubKey, + // TODO: should decode signature from hex string signature: []byte("69d89a0af27dcaa67f1b62a383594d97599aadd2b7b164cb4112aa8ddfd42f895649075cae1b7216c43a491c5e9be68d1d9a27b863d71155ecdd7c95dab5394f01"), }) require.NoError(err) @@ -254,6 +255,48 @@ func TestTransactionObjectMarshal(t *testing.T) { } `, string(res)) }) + t.Run("ISSUE3932", func(t *testing.T) { + sig, _ := hex.DecodeString("00d50c3169003e7c9c9392069a1c9e5251c8f558120cceb9aa312f0fa46247701f4cad47a5540cdda5459f7a46c62df752ca588e0b73722ec767ff08994134a41b") + blkHash, _ := hash.HexStringToHash256("bdcf722cbc0dc9b9eb5b46ad4af9e15944a886310b1cb2227129070c0e4b7de5") + contract := "0xc3527348de07d591c9d567ce1998efa2031b8675" + data, _ := hex.DecodeString("1fad948c0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000ec4daee51c4bf81bd00af165f8ca66823ee3b12a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000003e24491a4f2a946e30baf624fda6b4484d106c12000000000000000000000000000000000000000000000000000000000000005b000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000009fd90000000000000000000000000000000000000000000000000000000000011da4000000000000000000000000000000000000000000000000000000000000db26000000000000000000000000000000000000000000000000000000e8d4a51000000000000000000000000000000000000000000000000000000000e8d4a510000000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084b61d27f6000000000000000000000000065e1164818487818e6ba714e8d80b91718ad75800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000095ccc7012efb2e65aa31752f3ac01e23817c08a47500000000000000000000000000000000000000000000000000000000650af9f8000000000000000000000000000000000000000000000000000000006509a878b5acba7277159ae6fa661ed1988cc10ac2c96c58dc332bde2a6dc0d8531ea3924d9d04cda681c271411250ae7d9e9aea47661dba67a66f08d19804a255e45c561b0000000000000000000000000000000000000000000000000000000000000000000000000000000000004160daa88165299ca7e585d5d286cee98b54397b57ac704b74331a48d67651195322ef3884c7d60023333f2542a07936f34edc9efa3cbd19e8cd0f8972c54171a21b00000000000000000000000000000000000000000000000000000000000000") + pubkey, _ := crypto.HexStringToPublicKey("04806b217cb0b6a675974689fd99549e525d967287eee9a62dc4e598eea981b8158acfe026da7bf58397108abd0607672832c28ef3bc7b5855077f6e67ab5fc096") + actHash, _ := hash.HexStringToHash256("cbc2560d986d79a46bfd96a08d18c6045b29f97352c1360289e371d9cffd6b6a") + res, err := json.Marshal(&getTransactionResult{ + blockHash: blkHash, + to: &contract, + ethTx: types.NewContractCreation(305, big.NewInt(0), 297131, big.NewInt(1000000000000), data), + receipt: &action.Receipt{ + Status: 1, + BlockHeight: 22354907, + ActionHash: actHash, + GasConsumed: 196223, + ContractAddress: "", + TxIndex: 0, + }, + pubkey: pubkey, + signature: sig, + }) + require.NoError(err) + require.JSONEq(` + { + "hash": "0xcbc2560d986d79a46bfd96a08d18c6045b29f97352c1360289e371d9cffd6b6a", + "nonce": "0x131", + "blockHash": "0xbdcf722cbc0dc9b9eb5b46ad4af9e15944a886310b1cb2227129070c0e4b7de5", + "blockNumber": "0x1551bdb", + "transactionIndex": "0x0", + "from": "0xec4daee51c4bf81bd00af165f8ca66823ee3b12a", + "to": "0xc3527348de07d591c9d567ce1998efa2031b8675", + "value": "0x0", + "gasPrice": "0xe8d4a51000", + "gas": "0x488ab", + "input": "0x1fad948c0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000ec4daee51c4bf81bd00af165f8ca66823ee3b12a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000003e24491a4f2a946e30baf624fda6b4484d106c12000000000000000000000000000000000000000000000000000000000000005b000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000009fd90000000000000000000000000000000000000000000000000000000000011da4000000000000000000000000000000000000000000000000000000000000db26000000000000000000000000000000000000000000000000000000e8d4a51000000000000000000000000000000000000000000000000000000000e8d4a510000000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084b61d27f6000000000000000000000000065e1164818487818e6ba714e8d80b91718ad75800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000095ccc7012efb2e65aa31752f3ac01e23817c08a47500000000000000000000000000000000000000000000000000000000650af9f8000000000000000000000000000000000000000000000000000000006509a878b5acba7277159ae6fa661ed1988cc10ac2c96c58dc332bde2a6dc0d8531ea3924d9d04cda681c271411250ae7d9e9aea47661dba67a66f08d19804a255e45c561b0000000000000000000000000000000000000000000000000000000000000000000000000000000000004160daa88165299ca7e585d5d286cee98b54397b57ac704b74331a48d67651195322ef3884c7d60023333f2542a07936f34edc9efa3cbd19e8cd0f8972c54171a21b00000000000000000000000000000000000000000000000000000000000000", + "r": "0xd50c3169003e7c9c9392069a1c9e5251c8f558120cceb9aa312f0fa4624770", + "s": "0x1f4cad47a5540cdda5459f7a46c62df752ca588e0b73722ec767ff08994134a4", + "v": "0x1b" + } + `, string(res)) + }) } func TestReceiptObjectMarshal(t *testing.T) {