mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
review fixes/changes
This commit is contained in:
parent
5452945641
commit
8b3364a234
6 changed files with 435 additions and 68 deletions
|
|
@ -72,37 +72,39 @@ func (abi ABI) Pack(name string, args ...interface{}) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unpack output in v according to the abi specification
|
// Unpack output in v according to the abi specification
|
||||||
func (abi ABI) Unpack(v interface{}, name string, output []byte) (err error) {
|
func (abi ABI) Unpack(v interface{}, name string, data []byte) (err error) {
|
||||||
if len(output) == 0 {
|
if len(data) == 0 {
|
||||||
return fmt.Errorf("abi: unmarshalling empty output")
|
return fmt.Errorf("abi: unmarshalling empty output")
|
||||||
}
|
}
|
||||||
// since there can't be naming collisions with contracts and events,
|
// since there can't be naming collisions with contracts and events,
|
||||||
// we need to decide whether we're calling a method or an event
|
// we need to decide whether we're calling a method or an event
|
||||||
if method, ok := abi.Methods[name]; ok {
|
if method, ok := abi.Methods[name]; ok {
|
||||||
if len(output)%32 != 0 {
|
if len(data)%32 != 0 {
|
||||||
return fmt.Errorf("abi: improperly formatted output: %s - Bytes: [%+v]", string(output), output)
|
return fmt.Errorf("abi: improperly formatted output: %s - Bytes: [%+v]", string(data), data)
|
||||||
}
|
}
|
||||||
return method.Outputs.Unpack(v, output)
|
return method.Outputs.Unpack(v, data)
|
||||||
} else if event, ok := abi.Events[name]; ok {
|
}
|
||||||
return event.Inputs.Unpack(v, output)
|
if event, ok := abi.Events[name]; ok {
|
||||||
|
return event.Inputs.Unpack(v, data)
|
||||||
}
|
}
|
||||||
return fmt.Errorf("abi: could not locate named method or event")
|
return fmt.Errorf("abi: could not locate named method or event")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unpack output into a map according to the abi specification
|
// UnpackIntoMap unpacks a log into the provided map[string]interface{}
|
||||||
func (abi ABI) UnpackIntoMap(v map[string]interface{}, name string, output []byte) (err error) {
|
func (abi ABI) UnpackIntoMap(v map[string]interface{}, name string, data []byte) (err error) {
|
||||||
if len(output) == 0 {
|
if len(data) == 0 {
|
||||||
return fmt.Errorf("abi: unmarshalling empty output")
|
return fmt.Errorf("abi: unmarshalling empty output")
|
||||||
}
|
}
|
||||||
// since there can't be naming collisions with contracts and events,
|
// since there can't be naming collisions with contracts and events,
|
||||||
// we need to decide whether we're calling a method or an event
|
// we need to decide whether we're calling a method or an event
|
||||||
if method, ok := abi.Methods[name]; ok {
|
if method, ok := abi.Methods[name]; ok {
|
||||||
if len(output)%32 != 0 {
|
if len(data)%32 != 0 {
|
||||||
return fmt.Errorf("abi: improperly formatted output")
|
return fmt.Errorf("abi: improperly formatted output")
|
||||||
}
|
}
|
||||||
return method.Outputs.UnpackIntoMap(v, output)
|
return method.Outputs.UnpackIntoMap(v, data)
|
||||||
} else if event, ok := abi.Events[name]; ok {
|
}
|
||||||
return event.Inputs.UnpackIntoMap(v, output)
|
if event, ok := abi.Events[name]; ok {
|
||||||
|
return event.Inputs.UnpackIntoMap(v, data)
|
||||||
}
|
}
|
||||||
return fmt.Errorf("abi: could not locate named method or event")
|
return fmt.Errorf("abi: could not locate named method or event")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -714,39 +714,169 @@ func TestUnpackEventIntoMap(t *testing.T) {
|
||||||
expectedReceivedMap := map[string]interface{}{
|
expectedReceivedMap := map[string]interface{}{
|
||||||
"sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"),
|
"sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"),
|
||||||
"amount": big.NewInt(1),
|
"amount": big.NewInt(1),
|
||||||
"memo": []uint8{88},
|
"memo": []byte{88},
|
||||||
}
|
}
|
||||||
if err := abi.UnpackIntoMap(receivedMap, "received", data); err != nil {
|
if err := abi.UnpackIntoMap(receivedMap, "received", data); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(receivedMap) != 3 {
|
if len(receivedMap) != 3 {
|
||||||
t.Error("unpacked map expected to have length 3")
|
t.Error("unpacked `received` map expected to have length 3")
|
||||||
}
|
}
|
||||||
if receivedMap["sender"] != expectedReceivedMap["sender"] {
|
if receivedMap["sender"] != expectedReceivedMap["sender"] {
|
||||||
t.Error("unpacked map does not match expected map")
|
t.Error("unpacked `received` map does not match expected map")
|
||||||
}
|
}
|
||||||
if receivedMap["amount"].(*big.Int).String() != expectedReceivedMap["amount"].(*big.Int).String() {
|
if receivedMap["amount"].(*big.Int).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 {
|
||||||
t.Error("unpacked map does not match expected map")
|
t.Error("unpacked `received` 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")
|
|
||||||
}
|
}
|
||||||
|
if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) {
|
||||||
|
t.Error("unpacked `received` map does not match expected map")
|
||||||
}
|
}
|
||||||
|
|
||||||
receivedAddrMap := map[string]interface{}{}
|
receivedAddrMap := map[string]interface{}{}
|
||||||
if err = abi.UnpackIntoMap(receivedAddrMap, "receivedAddr", data); err != nil {
|
if err = abi.UnpackIntoMap(receivedAddrMap, "receivedAddr", data); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(receivedAddrMap) != 1 {
|
if len(receivedAddrMap) != 1 {
|
||||||
t.Error("unpacked map expected to have length 1")
|
t.Error("unpacked `receivedAddr` map expected to have length 1")
|
||||||
}
|
}
|
||||||
if receivedAddrMap["sender"] != expectedReceivedMap["sender"] {
|
if receivedAddrMap["sender"] != expectedReceivedMap["sender"] {
|
||||||
t.Error("unpacked map does not match expected map")
|
t.Error("unpacked `receivedAddr` map does not match expected map")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnpackMethodIntoMap(t *testing.T) {
|
||||||
|
const abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"send","outputs":[{"name":"amount","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"}],"name":"get","outputs":[{"name":"hash","type":"bytes"}],"payable":true,"stateMutability":"payable","type":"function"}]`
|
||||||
|
abi, err := JSON(strings.NewReader(abiJSON))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
const hexdata = `00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000015800000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000158000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001580000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000015800000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000158`
|
||||||
|
data, err := hex.DecodeString(hexdata)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(data)%32 != 0 {
|
||||||
|
t.Errorf("len(data) is %d, want a multiple of 32", len(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests a method with no outputs
|
||||||
|
receiveMap := map[string]interface{}{}
|
||||||
|
if err = abi.UnpackIntoMap(receiveMap, "receive", data); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if len(receiveMap) > 0 {
|
||||||
|
t.Error("unpacked `receive` map expected to have length 0")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests a method with only outputs
|
||||||
|
sendMap := map[string]interface{}{}
|
||||||
|
if err = abi.UnpackIntoMap(sendMap, "send", data); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if len(sendMap) != 1 {
|
||||||
|
t.Error("unpacked `send` map expected to have length 1")
|
||||||
|
}
|
||||||
|
if sendMap["amount"].(*big.Int).Cmp(big.NewInt(1)) != 0 {
|
||||||
|
t.Error("unpacked `send` map expected `amount` value of 1")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests a method with outputs and inputs
|
||||||
|
getMap := map[string]interface{}{}
|
||||||
|
if err = abi.UnpackIntoMap(getMap, "get", data); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if len(sendMap) != 1 {
|
||||||
|
t.Error("unpacked `get` map expected to have length 1")
|
||||||
|
}
|
||||||
|
expectedBytes := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 88, 0}
|
||||||
|
if !bytes.Equal(getMap["hash"].([]byte), expectedBytes) {
|
||||||
|
t.Errorf("unpacked `get` map expected `hash` value of %v", expectedBytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnpackIntoMapNamingConflict(t *testing.T) {
|
||||||
|
// Two methods have the same name
|
||||||
|
var abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"get","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"send","outputs":[{"name":"amount","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"}],"name":"get","outputs":[{"name":"hash","type":"bytes"}],"payable":true,"stateMutability":"payable","type":"function"}]`
|
||||||
|
abi, err := JSON(strings.NewReader(abiJSON))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
var hexdata = `00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158`
|
||||||
|
data, err := hex.DecodeString(hexdata)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(data)%32 == 0 {
|
||||||
|
t.Errorf("len(data) is %d, want a non-multiple of 32", len(data))
|
||||||
|
}
|
||||||
|
getMap := map[string]interface{}{}
|
||||||
|
if err = abi.UnpackIntoMap(getMap, "get", data); err == nil {
|
||||||
|
t.Error("naming conflict between two methods; error expected")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Two events have the same name
|
||||||
|
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":"received","type":"event"}]`
|
||||||
|
abi, err = JSON(strings.NewReader(abiJSON))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
hexdata = `000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158`
|
||||||
|
data, err = hex.DecodeString(hexdata)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(data)%32 == 0 {
|
||||||
|
t.Errorf("len(data) is %d, want a non-multiple of 32", len(data))
|
||||||
|
}
|
||||||
|
receivedMap := map[string]interface{}{}
|
||||||
|
if err = abi.UnpackIntoMap(receivedMap, "received", data); err != nil {
|
||||||
|
t.Error("naming conflict between two events; no error expected")
|
||||||
|
}
|
||||||
|
if len(receivedMap) != 1 {
|
||||||
|
t.Error("naming conflict between two events; event defined latest in the abi expected to be used")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method and event have the same name
|
||||||
|
abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"received","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 {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(data)%32 == 0 {
|
||||||
|
t.Errorf("len(data) is %d, want a non-multiple of 32", len(data))
|
||||||
|
}
|
||||||
|
if err = abi.UnpackIntoMap(receivedMap, "received", data); err == nil {
|
||||||
|
t.Error("naming conflict between an event and a method; error expected")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Conflict is case sensitive
|
||||||
|
abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"received","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 {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(data)%32 == 0 {
|
||||||
|
t.Errorf("len(data) is %d, want a non-multiple of 32", len(data))
|
||||||
|
}
|
||||||
|
expectedReceivedMap := map[string]interface{}{
|
||||||
|
"sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"),
|
||||||
|
"amount": big.NewInt(1),
|
||||||
|
"memo": []byte{88},
|
||||||
|
}
|
||||||
|
if err = abi.UnpackIntoMap(receivedMap, "Received", data); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if len(receivedMap) != 3 {
|
||||||
|
t.Error("unpacked `received` map expected to have length 3")
|
||||||
|
}
|
||||||
|
if receivedMap["sender"] != expectedReceivedMap["sender"] {
|
||||||
|
t.Error("unpacked `received` map does not match expected map")
|
||||||
|
}
|
||||||
|
if receivedMap["amount"].(*big.Int).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 {
|
||||||
|
t.Error("unpacked `received` map does not match expected map")
|
||||||
|
}
|
||||||
|
if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) {
|
||||||
|
t.Error("unpacked `received` map does not match expected map")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ func (arguments Arguments) Unpack(v interface{}, data []byte) error {
|
||||||
return arguments.unpackAtomic(v, marshalledValues[0])
|
return arguments.unpackAtomic(v, marshalledValues[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unpack performs the operation hexdata -> mapping of argument name to argument value
|
// UnpackIntoMap performs the operation hexdata -> mapping of argument name to argument value
|
||||||
func (arguments Arguments) UnpackIntoMap(v map[string]interface{}, data []byte) error {
|
func (arguments Arguments) UnpackIntoMap(v map[string]interface{}, data []byte) error {
|
||||||
marshalledValues, err := arguments.UnpackValues(data)
|
marshalledValues, err := arguments.UnpackValues(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -170,7 +170,7 @@ func unpack(t *Type, dst interface{}, src interface{}) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unpack arguments into map
|
// unpackIntoMap unpacks marshalledValues into the provided map[string]interface{}
|
||||||
func (arguments Arguments) unpackIntoMap(v map[string]interface{}, marshalledValues []interface{}) error {
|
func (arguments Arguments) unpackIntoMap(v map[string]interface{}, marshalledValues []interface{}) error {
|
||||||
// Make sure map is not nil
|
// Make sure map is not nil
|
||||||
if v == nil {
|
if v == nil {
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,8 @@
|
||||||
package bind_test
|
package bind_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
@ -28,6 +27,10 @@ import (
|
||||||
"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"
|
||||||
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
|
|
||||||
type mockCaller struct {
|
type mockCaller struct {
|
||||||
|
|
@ -44,7 +47,6 @@ func (mc *mockCaller) CallContract(ctx context.Context, call ethereum.CallMsg, b
|
||||||
mc.callContractBlockNumber = blockNumber
|
mc.callContractBlockNumber = blockNumber
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPassingBlockNumber(t *testing.T) {
|
func TestPassingBlockNumber(t *testing.T) {
|
||||||
|
|
||||||
mc := &mockCaller{}
|
mc := &mockCaller{}
|
||||||
|
|
@ -82,34 +84,35 @@ func TestPassingBlockNumber(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUnpackIntoMap(t *testing.T) {
|
const hexData = "0x000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158"
|
||||||
hexData := "0x000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158"
|
|
||||||
|
func TestUnpackIndexedStringTyLogIntoMap(t *testing.T) {
|
||||||
|
hash := crypto.Keccak256Hash([]byte("testName"))
|
||||||
mockLog := types.Log{
|
mockLog := types.Log{
|
||||||
Address: common.HexToAddress("0x0"),
|
Address: common.HexToAddress("0x0"),
|
||||||
Topics: []common.Hash{
|
Topics: []common.Hash{
|
||||||
common.HexToHash("0x99b5620489b6ef926d4518936cfec15d305452712b88bd59da2d9c10fb0953e8"),
|
common.HexToHash("0x0"),
|
||||||
common.BytesToHash([]byte("testName")),
|
hash,
|
||||||
},
|
},
|
||||||
Data: hexutil.MustDecode(hexData),
|
Data: hexutil.MustDecode(hexData),
|
||||||
BlockNumber: uint64(26),
|
BlockNumber: uint64(26),
|
||||||
TxHash: common.HexToHash("0x5c698f13940a2153440c6d19660878bc90219d9298fdcf37365aa8d88d40fc42"),
|
TxHash: common.HexToHash("0x0"),
|
||||||
TxIndex: 111,
|
TxIndex: 111,
|
||||||
BlockHash: common.BytesToHash([]byte{1, 2, 3, 4, 5}),
|
BlockHash: common.BytesToHash([]byte{1, 2, 3, 4, 5}),
|
||||||
Index: 7,
|
Index: 7,
|
||||||
Removed: false,
|
Removed: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
// This event has an indexed string, which cannot be handled by the normal Unpack method
|
abiString := `[{"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"}]`
|
||||||
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))
|
parsedAbi, _ := abi.JSON(strings.NewReader(abiString))
|
||||||
bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil)
|
bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil)
|
||||||
|
|
||||||
receivedMap := make(map[string]interface{})
|
receivedMap := make(map[string]interface{})
|
||||||
expectedReceivedMap := map[string]interface{}{
|
expectedReceivedMap := map[string]interface{}{
|
||||||
"name": "testName",
|
"name": hash,
|
||||||
"sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"),
|
"sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"),
|
||||||
"amount": big.NewInt(1),
|
"amount": big.NewInt(1),
|
||||||
"memo": []uint8{88},
|
"memo": []byte{88},
|
||||||
}
|
}
|
||||||
if err := bc.UnpackLogIntoMap(receivedMap, "received", mockLog); err != nil {
|
if err := bc.UnpackLogIntoMap(receivedMap, "received", mockLog); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
|
|
@ -124,14 +127,247 @@ func TestUnpackIntoMap(t *testing.T) {
|
||||||
if receivedMap["sender"] != expectedReceivedMap["sender"] {
|
if receivedMap["sender"] != expectedReceivedMap["sender"] {
|
||||||
t.Error("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).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 {
|
||||||
t.Error("unpacked map does not match expected map")
|
t.Error("unpacked map does not match expected map")
|
||||||
}
|
}
|
||||||
u8 := receivedMap["memo"].([]uint8)
|
if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) {
|
||||||
expectedU8 := expectedReceivedMap["memo"].([]uint8)
|
|
||||||
for i, v := range expectedU8 {
|
|
||||||
if u8[i] != v {
|
|
||||||
t.Error("unpacked map does not match expected map")
|
t.Error("unpacked map does not match expected map")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUnpackIndexedSliceTyLogIntoMap(t *testing.T) {
|
||||||
|
sliceBytes, err := rlp.EncodeToBytes([]string{"name1", "name2", "name3", "name4"})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
hash := crypto.Keccak256Hash(sliceBytes)
|
||||||
|
mockLog := types.Log{
|
||||||
|
Address: common.HexToAddress("0x0"),
|
||||||
|
Topics: []common.Hash{
|
||||||
|
common.HexToHash("0x0"),
|
||||||
|
hash,
|
||||||
|
},
|
||||||
|
Data: hexutil.MustDecode(hexData),
|
||||||
|
BlockNumber: uint64(26),
|
||||||
|
TxHash: common.HexToHash("0x0"),
|
||||||
|
TxIndex: 111,
|
||||||
|
BlockHash: common.BytesToHash([]byte{1, 2, 3, 4, 5}),
|
||||||
|
Index: 7,
|
||||||
|
Removed: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"names","type":"string[]"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","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{}{
|
||||||
|
"names": hash,
|
||||||
|
"sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"),
|
||||||
|
"amount": big.NewInt(1),
|
||||||
|
"memo": []byte{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["names"] != expectedReceivedMap["names"] {
|
||||||
|
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).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 {
|
||||||
|
t.Error("unpacked map does not match expected map")
|
||||||
|
}
|
||||||
|
if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) {
|
||||||
|
t.Error("unpacked map does not match expected map")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnpackIndexedArrayTyLogIntoMap(t *testing.T) {
|
||||||
|
arrBytes, err := rlp.EncodeToBytes([2]common.Address{common.HexToAddress("0x0"), common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2")})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
hash := crypto.Keccak256Hash(arrBytes)
|
||||||
|
mockLog := types.Log{
|
||||||
|
Address: common.HexToAddress("0x0"),
|
||||||
|
Topics: []common.Hash{
|
||||||
|
common.HexToHash("0x0"),
|
||||||
|
hash,
|
||||||
|
},
|
||||||
|
Data: hexutil.MustDecode(hexData),
|
||||||
|
BlockNumber: uint64(26),
|
||||||
|
TxHash: common.HexToHash("0x0"),
|
||||||
|
TxIndex: 111,
|
||||||
|
BlockHash: common.BytesToHash([]byte{1, 2, 3, 4, 5}),
|
||||||
|
Index: 7,
|
||||||
|
Removed: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"addresses","type":"address[2]"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","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{}{
|
||||||
|
"addresses": hash,
|
||||||
|
"sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"),
|
||||||
|
"amount": big.NewInt(1),
|
||||||
|
"memo": []byte{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["addresses"] != expectedReceivedMap["addresses"] {
|
||||||
|
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).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 {
|
||||||
|
t.Error("unpacked map does not match expected map")
|
||||||
|
}
|
||||||
|
if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) {
|
||||||
|
t.Error("unpacked map does not match expected map")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnpackIndexedFuncTyLogIntoMap(t *testing.T) {
|
||||||
|
mockAddress := common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2")
|
||||||
|
addrBytes := mockAddress.Bytes()
|
||||||
|
hash := crypto.Keccak256Hash([]byte("mockFunction(address,uint)"))
|
||||||
|
functionSelector := hash[:4]
|
||||||
|
functionTyBytes := append(addrBytes, functionSelector...)
|
||||||
|
var functionTy [24]byte
|
||||||
|
copy(functionTy[:], functionTyBytes[0:24])
|
||||||
|
mockLog := types.Log{
|
||||||
|
Address: common.HexToAddress("0x0"),
|
||||||
|
Topics: []common.Hash{
|
||||||
|
common.HexToHash("0x99b5620489b6ef926d4518936cfec15d305452712b88bd59da2d9c10fb0953e8"),
|
||||||
|
common.BytesToHash(functionTyBytes),
|
||||||
|
},
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
|
||||||
|
abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"function","type":"function"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","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{}{
|
||||||
|
"function": functionTy,
|
||||||
|
"sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"),
|
||||||
|
"amount": big.NewInt(1),
|
||||||
|
"memo": []byte{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["function"] != expectedReceivedMap["function"] {
|
||||||
|
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).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 {
|
||||||
|
t.Error("unpacked map does not match expected map")
|
||||||
|
}
|
||||||
|
if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) {
|
||||||
|
t.Error("unpacked map does not match expected map")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnpackIndexedBytesTyLogIntoMap(t *testing.T) {
|
||||||
|
byts := []byte{1, 2, 3, 4, 5}
|
||||||
|
hash := crypto.Keccak256Hash(byts)
|
||||||
|
mockLog := types.Log{
|
||||||
|
Address: common.HexToAddress("0x0"),
|
||||||
|
Topics: []common.Hash{
|
||||||
|
common.HexToHash("0x99b5620489b6ef926d4518936cfec15d305452712b88bd59da2d9c10fb0953e8"),
|
||||||
|
hash,
|
||||||
|
},
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
|
||||||
|
abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"content","type":"bytes"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","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{}{
|
||||||
|
"content": hash,
|
||||||
|
"sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"),
|
||||||
|
"amount": big.NewInt(1),
|
||||||
|
"memo": []byte{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["content"] != expectedReceivedMap["content"] {
|
||||||
|
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).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 {
|
||||||
|
t.Error("unpacked map does not match expected map")
|
||||||
|
}
|
||||||
|
if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) {
|
||||||
|
t.Error("unpacked map does not match expected map")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnpackIntoMapNamingConflict(t *testing.T) {
|
||||||
|
hash := crypto.Keccak256Hash([]byte("testName"))
|
||||||
|
mockLog := types.Log{
|
||||||
|
Address: common.HexToAddress("0x0"),
|
||||||
|
Topics: []common.Hash{
|
||||||
|
common.HexToHash("0x0"),
|
||||||
|
hash,
|
||||||
|
},
|
||||||
|
Data: hexutil.MustDecode(hexData),
|
||||||
|
BlockNumber: uint64(26),
|
||||||
|
TxHash: common.HexToHash("0x0"),
|
||||||
|
TxIndex: 111,
|
||||||
|
BlockHash: common.BytesToHash([]byte{1, 2, 3, 4, 5}),
|
||||||
|
Index: 7,
|
||||||
|
Removed: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
abiString := `[{"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":"received","type":"event"}]`
|
||||||
|
parsedAbi, _ := abi.JSON(strings.NewReader(abiString))
|
||||||
|
bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil)
|
||||||
|
receivedMap := make(map[string]interface{})
|
||||||
|
if err := bc.UnpackLogIntoMap(receivedMap, "received", mockLog); err == nil {
|
||||||
|
t.Error("naming conflict between two events; error expected")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
package bind
|
package bind
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
@ -188,7 +189,7 @@ func parseTopics(out interface{}, fields abi.Arguments, topics []common.Hash) er
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseTopics converts the indexed topic field-value pairs into map key-value pairs
|
// parseTopicsIntoMap converts the indexed topic field-value pairs into map key-value pairs
|
||||||
func parseTopicsIntoMap(out map[string]interface{}, fields abi.Arguments, topics []common.Hash) error {
|
func parseTopicsIntoMap(out map[string]interface{}, fields abi.Arguments, topics []common.Hash) error {
|
||||||
// Sanity check that the fields and topics match up
|
// Sanity check that the fields and topics match up
|
||||||
if len(fields) != len(topics) {
|
if len(fields) != len(topics) {
|
||||||
|
|
@ -202,11 +203,7 @@ func parseTopicsIntoMap(out map[string]interface{}, fields abi.Arguments, topics
|
||||||
|
|
||||||
switch arg.Type.T {
|
switch arg.Type.T {
|
||||||
case abi.BoolTy:
|
case abi.BoolTy:
|
||||||
if topics[0][common.HashLength-1] == 1 {
|
out[arg.Name] = topics[0][common.HashLength-1] == 1
|
||||||
out[arg.Name] = true
|
|
||||||
} else {
|
|
||||||
out[arg.Name] = false
|
|
||||||
}
|
|
||||||
case abi.IntTy, abi.UintTy:
|
case abi.IntTy, abi.UintTy:
|
||||||
num := new(big.Int).SetBytes(topics[0][:])
|
num := new(big.Int).SetBytes(topics[0][:])
|
||||||
out[arg.Name] = num
|
out[arg.Name] = num
|
||||||
|
|
@ -216,19 +213,21 @@ func parseTopicsIntoMap(out map[string]interface{}, fields abi.Arguments, topics
|
||||||
out[arg.Name] = addr
|
out[arg.Name] = addr
|
||||||
case abi.HashTy:
|
case abi.HashTy:
|
||||||
out[arg.Name] = topics[0]
|
out[arg.Name] = topics[0]
|
||||||
case abi.BytesTy, abi.FixedBytesTy:
|
case abi.FixedBytesTy:
|
||||||
out[arg.Name] = topics[0][:]
|
out[arg.Name] = topics[0][:]
|
||||||
case abi.StringTy:
|
case abi.StringTy, abi.BytesTy, abi.SliceTy, abi.ArrayTy:
|
||||||
bytes := topics[0].Bytes()
|
// Array types (including strings and bytes) have their keccak256 hashes stored in the topic- not a hash
|
||||||
var trimmedBytes []byte
|
// whose bytes can be decoded to the actual value- so the best we can do is retrieve that hash
|
||||||
for i, by := range bytes {
|
out[arg.Name] = topics[0]
|
||||||
if by != 0 {
|
case abi.FunctionTy:
|
||||||
trimmedBytes = bytes[i:]
|
if garbage := binary.BigEndian.Uint64(topics[0][0:8]); garbage != 0 {
|
||||||
break
|
return fmt.Errorf("bind: got improperly encoded function type, got %v", topics[0].Bytes())
|
||||||
}
|
}
|
||||||
}
|
var tmp [24]byte
|
||||||
out[arg.Name] = string(trimmedBytes)
|
copy(tmp[:], topics[0][8:32])
|
||||||
default:
|
out[arg.Name] = tmp
|
||||||
|
default: // Not handling tuples
|
||||||
|
return fmt.Errorf("unsupported indexed type: %v", arg.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
topics = topics[1:]
|
topics = topics[1:]
|
||||||
|
|
|
||||||
|
|
@ -269,7 +269,7 @@ func lengthPrefixPointsTo(index int, output []byte) (start int, length int, err
|
||||||
totalSize.Add(totalSize, bigOffsetEnd)
|
totalSize.Add(totalSize, bigOffsetEnd)
|
||||||
totalSize.Add(totalSize, lengthBig)
|
totalSize.Add(totalSize, lengthBig)
|
||||||
if totalSize.BitLen() > 63 {
|
if totalSize.BitLen() > 63 {
|
||||||
return 0, 0, fmt.Errorf("abi length larger than int64: %v", totalSize)
|
return 0, 0, fmt.Errorf("abi: length larger than int64: %v", totalSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
if totalSize.Cmp(outputLength) > 0 {
|
if totalSize.Cmp(outputLength) > 0 {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue