From 545294564198add052d38f869cc15403d6caadbc Mon Sep 17 00:00:00 2001 From: Ian Norden Date: Fri, 8 Mar 2019 12:39:23 -0600 Subject: [PATCH] add missing support for string and a base_test that demonstrates unpacking event with indexed string --- accounts/abi/abi_test.go | 26 +++++++-------- accounts/abi/bind/base_test.go | 59 +++++++++++++++++++++++++++++++++- accounts/abi/bind/topics.go | 10 ++++++ 3 files changed, 81 insertions(+), 14 deletions(-) diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index 6c2b7c2f56..f033c0e8ba 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -694,7 +694,7 @@ func TestUnpackEvent(t *testing.T) { } } -func TestUnpackIntoMapEvent(t *testing.T) { +func TestUnpackEventIntoMap(t *testing.T) { const abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"receivedAddr","type":"event"}]` abi, err := JSON(strings.NewReader(abiJSON)) if err != nil { @@ -716,37 +716,37 @@ func TestUnpackIntoMapEvent(t *testing.T) { "amount": big.NewInt(1), "memo": []uint8{88}, } - - err = abi.UnpackIntoMap(receivedMap, "received", data) - if err != nil { + if err := abi.UnpackIntoMap(receivedMap, "received", data); err != nil { t.Error(err) } + if len(receivedMap) != 3 { + t.Error("unpacked map expected to have length 3") + } if receivedMap["sender"] != expectedReceivedMap["sender"] { - t.Errorf("unpacked map does not match expected map") + t.Error("unpacked map does not match expected map") } - if receivedMap["amount"].(*big.Int).String() != expectedReceivedMap["amount"].(*big.Int).String() { - t.Errorf("unpacked map does not match expected map") + t.Error("unpacked map does not match expected map") } - u8 := receivedMap["memo"].([]uint8) expectedU8 := expectedReceivedMap["memo"].([]uint8) for i, v := range expectedU8 { if u8[i] != v { - t.Errorf("unpacked map does not match expected map") + t.Error("unpacked map does not match expected map") } } receivedAddrMap := map[string]interface{}{} - - err = abi.UnpackIntoMap(receivedAddrMap, "receivedAddr", data) - if err != nil { + if err = abi.UnpackIntoMap(receivedAddrMap, "receivedAddr", data); err != nil { t.Error(err) } + if len(receivedAddrMap) != 1 { + t.Error("unpacked map expected to have length 1") + } if receivedAddrMap["sender"] != expectedReceivedMap["sender"] { - t.Errorf("unpacked map does not match expected map") + t.Error("unpacked map does not match expected map") } } diff --git a/accounts/abi/bind/base_test.go b/accounts/abi/bind/base_test.go index 02caf457a4..1e47ae285e 100644 --- a/accounts/abi/bind/base_test.go +++ b/accounts/abi/bind/base_test.go @@ -18,10 +18,13 @@ package bind_test import ( "context" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" "math/big" + "strings" "testing" - ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" @@ -78,3 +81,57 @@ func TestPassingBlockNumber(t *testing.T) { t.Fatalf("CodeAt() was passed a block number when it should not have been") } } + +func TestUnpackIntoMap(t *testing.T) { + hexData := "0x000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158" + mockLog := types.Log{ + Address: common.HexToAddress("0x0"), + Topics: []common.Hash{ + common.HexToHash("0x99b5620489b6ef926d4518936cfec15d305452712b88bd59da2d9c10fb0953e8"), + common.BytesToHash([]byte("testName")), + }, + Data: hexutil.MustDecode(hexData), + BlockNumber: uint64(26), + TxHash: common.HexToHash("0x5c698f13940a2153440c6d19660878bc90219d9298fdcf37365aa8d88d40fc42"), + TxIndex: 111, + BlockHash: common.BytesToHash([]byte{1, 2, 3, 4, 5}), + Index: 7, + Removed: false, + } + + // This event has an indexed string, which cannot be handled by the normal Unpack method + abiString := `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"string"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"receivedAddr","type":"event"}]` + parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) + bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) + + receivedMap := make(map[string]interface{}) + expectedReceivedMap := map[string]interface{}{ + "name": "testName", + "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), + "amount": big.NewInt(1), + "memo": []uint8{88}, + } + if err := bc.UnpackLogIntoMap(receivedMap, "received", mockLog); err != nil { + t.Error(err) + } + + if len(receivedMap) != 4 { + t.Fatal("unpacked map expected to have length 4") + } + if receivedMap["name"] != expectedReceivedMap["name"] { + t.Error("unpacked map does not match expected map") + } + if receivedMap["sender"] != expectedReceivedMap["sender"] { + t.Error("unpacked map does not match expected map") + } + if receivedMap["amount"].(*big.Int).String() != expectedReceivedMap["amount"].(*big.Int).String() { + t.Error("unpacked map does not match expected map") + } + u8 := receivedMap["memo"].([]uint8) + expectedU8 := expectedReceivedMap["memo"].([]uint8) + for i, v := range expectedU8 { + if u8[i] != v { + t.Error("unpacked map does not match expected map") + } + } +} diff --git a/accounts/abi/bind/topics.go b/accounts/abi/bind/topics.go index cd84fb164c..1569fae549 100644 --- a/accounts/abi/bind/topics.go +++ b/accounts/abi/bind/topics.go @@ -218,6 +218,16 @@ func parseTopicsIntoMap(out map[string]interface{}, fields abi.Arguments, topics out[arg.Name] = topics[0] case abi.BytesTy, abi.FixedBytesTy: out[arg.Name] = topics[0][:] + case abi.StringTy: + bytes := topics[0].Bytes() + var trimmedBytes []byte + for i, by := range bytes { + if by != 0 { + trimmedBytes = bytes[i:] + break + } + } + out[arg.Name] = string(trimmedBytes) default: }