add missing support for string and a base_test that demonstrates unpacking event with indexed string

This commit is contained in:
Ian Norden 2019-03-08 12:39:23 -06:00
parent 8be278dda8
commit 5452945641
3 changed files with 81 additions and 14 deletions

View file

@ -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"}]` 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)) abi, err := JSON(strings.NewReader(abiJSON))
if err != nil { if err != nil {
@ -716,37 +716,37 @@ func TestUnpackIntoMapEvent(t *testing.T) {
"amount": big.NewInt(1), "amount": big.NewInt(1),
"memo": []uint8{88}, "memo": []uint8{88},
} }
if err := abi.UnpackIntoMap(receivedMap, "received", data); err != nil {
err = abi.UnpackIntoMap(receivedMap, "received", data)
if err != nil {
t.Error(err) t.Error(err)
} }
if len(receivedMap) != 3 {
t.Error("unpacked map expected to have length 3")
}
if receivedMap["sender"] != expectedReceivedMap["sender"] { 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() { 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) u8 := receivedMap["memo"].([]uint8)
expectedU8 := expectedReceivedMap["memo"].([]uint8) expectedU8 := expectedReceivedMap["memo"].([]uint8)
for i, v := range expectedU8 { for i, v := range expectedU8 {
if u8[i] != v { 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{}{} receivedAddrMap := map[string]interface{}{}
if err = abi.UnpackIntoMap(receivedAddrMap, "receivedAddr", data); err != nil {
err = abi.UnpackIntoMap(receivedAddrMap, "receivedAddr", data)
if err != nil {
t.Error(err) t.Error(err)
} }
if len(receivedAddrMap) != 1 {
t.Error("unpacked map expected to have length 1")
}
if receivedAddrMap["sender"] != expectedReceivedMap["sender"] { if receivedAddrMap["sender"] != expectedReceivedMap["sender"] {
t.Errorf("unpacked map does not match expected map") t.Error("unpacked map does not match expected map")
} }
} }

View file

@ -18,10 +18,13 @@ package bind_test
import ( import (
"context" "context"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"math/big" "math/big"
"strings"
"testing" "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"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common" "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") 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")
}
}
}

View file

@ -218,6 +218,16 @@ func parseTopicsIntoMap(out map[string]interface{}, fields abi.Arguments, topics
out[arg.Name] = topics[0] out[arg.Name] = topics[0]
case abi.BytesTy, abi.FixedBytesTy: case abi.BytesTy, abi.FixedBytesTy:
out[arg.Name] = topics[0][:] 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: default:
} }