|
|
|
@ -19,14 +19,51 @@ package abi |
|
|
|
|
import ( |
|
|
|
|
"bytes" |
|
|
|
|
"reflect" |
|
|
|
|
"encoding/hex" |
|
|
|
|
"encoding/json" |
|
|
|
|
"math/big" |
|
|
|
|
"strings" |
|
|
|
|
"testing" |
|
|
|
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/common" |
|
|
|
|
"github.com/ethereum/go-ethereum/crypto" |
|
|
|
|
"github.com/stretchr/testify/assert" |
|
|
|
|
"github.com/stretchr/testify/require" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
var jsonEventTransfer = []byte(`{ |
|
|
|
|
"anonymous": false, |
|
|
|
|
"inputs": [ |
|
|
|
|
{ |
|
|
|
|
"indexed": true, "name": "from", "type": "address" |
|
|
|
|
}, { |
|
|
|
|
"indexed": true, "name": "to", "type": "address" |
|
|
|
|
}, { |
|
|
|
|
"indexed": false, "name": "value", "type": "uint256" |
|
|
|
|
}], |
|
|
|
|
"name": "Transfer", |
|
|
|
|
"type": "event" |
|
|
|
|
}`) |
|
|
|
|
|
|
|
|
|
var jsonEventPledge = []byte(`{ |
|
|
|
|
"anonymous": false, |
|
|
|
|
"inputs": [{ |
|
|
|
|
"indexed": false, "name": "who", "type": "address" |
|
|
|
|
}, { |
|
|
|
|
"indexed": false, "name": "wad", "type": "uint128" |
|
|
|
|
}, { |
|
|
|
|
"indexed": false, "name": "currency", "type": "bytes3" |
|
|
|
|
}], |
|
|
|
|
"name": "Pledge", |
|
|
|
|
"type": "event" |
|
|
|
|
}`) |
|
|
|
|
|
|
|
|
|
// 1000000
|
|
|
|
|
var transferData1 = "00000000000000000000000000000000000000000000000000000000000f4240" |
|
|
|
|
|
|
|
|
|
// "0x00Ce0d46d924CC8437c806721496599FC3FFA268", 2218516807680, "usd"
|
|
|
|
|
var pledgeData1 = "00000000000000000000000000ce0d46d924cc8437c806721496599fc3ffa2680000000000000000000000000000000000000000000000000000020489e800007573640000000000000000000000000000000000000000000000000000000000" |
|
|
|
|
|
|
|
|
|
func TestEventId(t *testing.T) { |
|
|
|
|
var table = []struct { |
|
|
|
|
definition string |
|
|
|
@ -77,3 +114,120 @@ func TestEventMultiValueWithArrayUnpack(t *testing.T) { |
|
|
|
|
require.Equal(t, [2]uint8{1, 2}, rst.Value1) |
|
|
|
|
require.Equal(t, uint8(3), rst.Value2) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func TestEventTupleUnpack(t *testing.T) { |
|
|
|
|
|
|
|
|
|
type EventTransfer struct { |
|
|
|
|
Value *big.Int |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type EventPledge struct { |
|
|
|
|
Who common.Address |
|
|
|
|
Wad *big.Int |
|
|
|
|
Currency [3]byte |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type BadEventPledge struct { |
|
|
|
|
Who string |
|
|
|
|
Wad int |
|
|
|
|
Currency [3]byte |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bigint := new(big.Int) |
|
|
|
|
bigintExpected := big.NewInt(1000000) |
|
|
|
|
bigintExpected2 := big.NewInt(2218516807680) |
|
|
|
|
addr := common.HexToAddress("0x00Ce0d46d924CC8437c806721496599FC3FFA268") |
|
|
|
|
var testCases = []struct { |
|
|
|
|
data string |
|
|
|
|
dest interface{} |
|
|
|
|
expected interface{} |
|
|
|
|
jsonLog []byte |
|
|
|
|
error string |
|
|
|
|
name string |
|
|
|
|
}{{ |
|
|
|
|
transferData1, |
|
|
|
|
&EventTransfer{}, |
|
|
|
|
&EventTransfer{Value: bigintExpected}, |
|
|
|
|
jsonEventTransfer, |
|
|
|
|
"", |
|
|
|
|
"Can unpack ERC20 Transfer event into structure", |
|
|
|
|
}, { |
|
|
|
|
transferData1, |
|
|
|
|
&[]interface{}{&bigint}, |
|
|
|
|
&[]interface{}{&bigintExpected}, |
|
|
|
|
jsonEventTransfer, |
|
|
|
|
"", |
|
|
|
|
"Can unpack ERC20 Transfer event into slice", |
|
|
|
|
}, { |
|
|
|
|
pledgeData1, |
|
|
|
|
&EventPledge{}, |
|
|
|
|
&EventPledge{ |
|
|
|
|
addr, |
|
|
|
|
bigintExpected2, |
|
|
|
|
[3]byte{'u', 's', 'd'}}, |
|
|
|
|
jsonEventPledge, |
|
|
|
|
"", |
|
|
|
|
"Can unpack Pledge event into structure", |
|
|
|
|
}, { |
|
|
|
|
pledgeData1, |
|
|
|
|
&[]interface{}{&common.Address{}, &bigint, &[3]byte{}}, |
|
|
|
|
&[]interface{}{ |
|
|
|
|
&addr, |
|
|
|
|
&bigintExpected2, |
|
|
|
|
&[3]byte{'u', 's', 'd'}}, |
|
|
|
|
jsonEventPledge, |
|
|
|
|
"", |
|
|
|
|
"Can unpack Pledge event into slice", |
|
|
|
|
}, { |
|
|
|
|
pledgeData1, |
|
|
|
|
&[]interface{}{new(int), 0, 0}, |
|
|
|
|
&[]interface{}{}, |
|
|
|
|
jsonEventPledge, |
|
|
|
|
"abi: cannot unmarshal common.Address in to int", |
|
|
|
|
"Can not unpack Pledge event into slice with wrong types", |
|
|
|
|
}, { |
|
|
|
|
pledgeData1, |
|
|
|
|
&BadEventPledge{}, |
|
|
|
|
&BadEventPledge{}, |
|
|
|
|
jsonEventPledge, |
|
|
|
|
"abi: cannot unmarshal common.Address in to string", |
|
|
|
|
"Can not unpack Pledge event into struct with wrong filed types", |
|
|
|
|
}, { |
|
|
|
|
pledgeData1, |
|
|
|
|
&[]interface{}{common.Address{}, new(big.Int)}, |
|
|
|
|
&[]interface{}{}, |
|
|
|
|
jsonEventPledge, |
|
|
|
|
"abi: insufficient number of elements in the list/array for unpack, want 3, got 2", |
|
|
|
|
"Can not unpack Pledge event into too short slice", |
|
|
|
|
}, { |
|
|
|
|
pledgeData1, |
|
|
|
|
new(map[string]interface{}), |
|
|
|
|
&[]interface{}{}, |
|
|
|
|
jsonEventPledge, |
|
|
|
|
"abi: cannot unmarshal tuple into map[string]interface {}", |
|
|
|
|
"Can not unpack Pledge event into map", |
|
|
|
|
}} |
|
|
|
|
|
|
|
|
|
for _, tc := range testCases { |
|
|
|
|
assert := assert.New(t) |
|
|
|
|
tc := tc |
|
|
|
|
t.Run(tc.name, func(t *testing.T) { |
|
|
|
|
err := unpackTestEventData(tc.dest, tc.data, tc.jsonLog, assert) |
|
|
|
|
if tc.error == "" { |
|
|
|
|
assert.Nil(err, "Should be able to unpack event data.") |
|
|
|
|
assert.Equal(tc.expected, tc.dest) |
|
|
|
|
} else { |
|
|
|
|
assert.EqualError(err, tc.error) |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func unpackTestEventData(dest interface{}, hexData string, jsonEvent []byte, assert *assert.Assertions) error { |
|
|
|
|
data, err := hex.DecodeString(hexData) |
|
|
|
|
assert.NoError(err, "Hex data should be a correct hex-string") |
|
|
|
|
var e Event |
|
|
|
|
assert.NoError(json.Unmarshal(jsonEvent, &e), "Should be able to unmarshal event ABI") |
|
|
|
|
a := ABI{Events: map[string]Event{"e": e}} |
|
|
|
|
return a.Unpack(dest, "e", data) |
|
|
|
|
} |
|
|
|
|