github.com/0xsequence/ethkit@v1.25.0/ethcoder/abi_test.go (about) 1 package ethcoder 2 3 import ( 4 "math/big" 5 "reflect" 6 "testing" 7 8 "github.com/0xsequence/ethkit/go-ethereum/common" 9 "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" 10 "github.com/stretchr/testify/assert" 11 ) 12 13 func TestAbiEncoding(t *testing.T) { 14 cases := []struct { 15 argTypes []string 16 expected string 17 input []interface{} 18 }{ 19 { 20 argTypes: []string{ 21 "uint256[]", 22 "uint256[]", 23 }, 24 expected: `0x000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000016`, 25 input: []interface{}{ 26 []*big.Int{big.NewInt(44)}, 27 []*big.Int{big.NewInt(22)}, 28 }, 29 }, 30 } 31 32 for _, i := range cases { 33 packed, err := AbiCoder(i.argTypes, i.input) 34 assert.NoError(t, err) 35 36 // the expected value is the same 37 assert.Equal(t, i.expected, hexutil.Encode(packed)) 38 39 // decode the value 40 output := make([]interface{}, len(i.argTypes)) 41 err = AbiDecoder(i.argTypes, packed, output) 42 assert.NoError(t, err) 43 44 if !reflect.DeepEqual(output, i.input) { 45 t.Fatal("encode/decode do not match") 46 } 47 } 48 } 49 50 func TestAbiDecoder(t *testing.T) { 51 { 52 input, err := HexDecode("0x000000000000000000000000000000000000000000007998f984c2040a5a9e01000000000000000000000000000000000000000000007998f984c2040a5a9e01") 53 assert.NoError(t, err) 54 var num, num2 *big.Int 55 err = AbiDecoder([]string{"uint256", "uint256"}, input, []interface{}{&num, &num2}) 56 assert.NoError(t, err) 57 } 58 59 { 60 input, err := HexDecode("0x000000000000000000000000000000000000000000007998f984c2040a5a9e01") 61 assert.NoError(t, err) 62 var num *big.Int 63 err = AbiDecoder([]string{"uint256"}, input, []interface{}{&num}) 64 assert.NoError(t, err) 65 } 66 67 { 68 input, err := HexDecode("0x000000000000000000000000000000000000000000007998f984c2040a5a9e01") 69 assert.NoError(t, err) 70 71 values, err := AbiDecoderWithReturnedValues([]string{"uint256"}, input) 72 assert.NoError(t, err) 73 assert.Len(t, values, 1) 74 75 num, ok := values[0].(*big.Int) 76 assert.True(t, ok) 77 assert.Equal(t, "574228229235365901934081", num.String()) 78 } 79 } 80 81 func TestParseMethodABI(t *testing.T) { 82 // correct usage 83 { 84 mabi, methodName, err := ParseMethodABI("balanceOf(address,uint256)", "uint256") 85 assert.NoError(t, err) 86 assert.Equal(t, "balanceOf", methodName) 87 88 ownerAddress := common.HexToAddress("0x6615e4e985bf0d137196897dfa182dbd7127f54f") 89 data, err := mabi.Pack("balanceOf", ownerAddress, big.NewInt(2)) 90 assert.NoError(t, err) 91 92 assert.Equal(t, "0x00fdd58e0000000000000000000000006615e4e985bf0d137196897dfa182dbd7127f54f0000000000000000000000000000000000000000000000000000000000000002", HexEncode(data)) 93 } 94 95 // correct usage 96 { 97 _, _, err := ParseMethodABI("someMethod(address)", "(uint256, bytes)") 98 assert.NoError(t, err) 99 100 // we also allow names for input/output arguments 101 _, _, err = ParseMethodABI("someMethod(address owner)", "(uint256 count, bytes value)") 102 assert.NoError(t, err) 103 104 // no args 105 _, _, err = ParseMethodABI("read()", "uint256") 106 assert.NoError(t, err) 107 } 108 109 // invalid usage 110 { 111 _, _, err := ParseMethodABI("balanceOf address, uint256)", "uint256") 112 assert.Error(t, err) 113 114 _, _, err = ParseMethodABI("balanceOf(address, uint256)", "blah") 115 assert.Contains(t, "unsupported arg type: blah", err.Error()) 116 } 117 } 118 119 func TestAbiEncodeMethodCalldata(t *testing.T) { 120 ownerAddress := common.HexToAddress("0x6615e4e985bf0d137196897dfa182dbd7127f54f") 121 122 { 123 calldata, err := AbiEncodeMethodCalldata("balanceOf(address,uint256)", []interface{}{ownerAddress, big.NewInt(2)}) 124 assert.NoError(t, err) 125 assert.Equal(t, "0x00fdd58e0000000000000000000000006615e4e985bf0d137196897dfa182dbd7127f54f0000000000000000000000000000000000000000000000000000000000000002", HexEncode(calldata)) 126 127 // arrays 128 calldata, err = AbiEncodeMethodCalldata("getCurrencyReserves(uint256[])", []interface{}{[]*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)}}) 129 assert.NoError(t, err) 130 assert.Equal(t, "0x209b96c500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", HexEncode(calldata)) 131 } 132 133 { 134 calldata, err := AbiEncodeMethodCalldataFromStringValues("balanceOf(address,uint256)", []string{"0x6615e4e985bf0d137196897dfa182dbd7127f54f", "2"}) 135 assert.NoError(t, err) 136 assert.Equal(t, "0x00fdd58e0000000000000000000000006615e4e985bf0d137196897dfa182dbd7127f54f0000000000000000000000000000000000000000000000000000000000000002", HexEncode(calldata)) // same as above 137 138 // arrays 139 calldata, err = AbiEncodeMethodCalldataFromStringValues("getCurrencyReserves(uint256[])", []string{`["1","2","3"]`}) 140 assert.NoError(t, err) 141 assert.Equal(t, "0x209b96c500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", HexEncode(calldata)) // same as above 142 } 143 } 144 145 func TestAbiDecodeExpr(t *testing.T) { 146 ret := "0x000000000000000000000000000000000000000000007998f984c2040a5a9e01" 147 148 { 149 retTrimmed, err := HexTrimLeadingZeros(ret) 150 assert.NoError(t, err) 151 assert.Equal(t, "0x7998f984c2040a5a9e01", retTrimmed) 152 153 val, err := hexutil.DecodeBig(retTrimmed) 154 assert.NoError(t, err) 155 assert.Equal(t, "574228229235365901934081", val.String()) 156 } 157 158 { 159 input, err := HexDecode(ret) 160 assert.NoError(t, err) 161 162 var num *big.Int 163 output := []interface{}{&num} 164 165 err = AbiDecodeExpr("uint256", input, output) 166 assert.NoError(t, err) 167 assert.Equal(t, "574228229235365901934081", num.String()) 168 } 169 } 170 171 func TestAbiDecodeExprAndStringify(t *testing.T) { 172 { 173 values, err := AbiDecodeExprAndStringify("uint256", MustHexDecode("0x000000000000000000000000000000000000000000007998f984c2040a5a9e01")) 174 assert.NoError(t, err) 175 assert.Len(t, values, 1) 176 assert.Equal(t, "574228229235365901934081", values[0]) 177 } 178 179 { 180 data, err := AbiCoder([]string{"uint256", "address"}, []interface{}{big.NewInt(1337), common.HexToAddress("0x6615e4e985bf0d137196897dfa182dbd7127f54f")}) 181 assert.NoError(t, err) 182 183 values, err := AbiDecodeExprAndStringify("(uint256,address)", data) 184 assert.NoError(t, err) 185 assert.Len(t, values, 2) 186 assert.Equal(t, "1337", values[0]) 187 assert.Equal(t, "0x6615e4e985BF0D137196897Dfa182dBD7127f54f", values[1]) 188 } 189 190 { 191 data, err := AbiCoder([]string{"bool", "bool"}, []interface{}{true, false}) 192 assert.NoError(t, err) 193 194 values, err := AbiDecodeExprAndStringify("(bool,bool)", data) 195 assert.NoError(t, err) 196 assert.Len(t, values, 2) 197 assert.Equal(t, "true", values[0]) 198 assert.Equal(t, "false", values[1]) 199 } 200 201 { 202 data, err := AbiCoder([]string{"bytes"}, []interface{}{[]byte{1, 2, 3, 4}}) 203 assert.NoError(t, err) 204 205 values, err := AbiDecodeExprAndStringify("(bytes)", data) 206 assert.NoError(t, err) 207 assert.Len(t, values, 1) 208 assert.Equal(t, "[1 2 3 4]", values[0]) 209 } 210 } 211 212 func TestAbiUnmarshalStringValues(t *testing.T) { 213 { 214 values, err := AbiUnmarshalStringValues([]string{"address", "uint256"}, []string{"0x6615e4e985bf0d137196897dfa182dbd7127f54f", "2"}) 215 assert.NoError(t, err) 216 assert.Len(t, values, 2) 217 218 v1, ok := values[0].(common.Address) 219 assert.True(t, ok) 220 assert.Equal(t, "0x6615e4e985BF0D137196897Dfa182dBD7127f54f", v1.String()) 221 222 v2, ok := values[1].(*big.Int) 223 assert.True(t, ok) 224 assert.Equal(t, int64(2), v2.Int64()) 225 } 226 227 { 228 values, err := AbiUnmarshalStringValues([]string{"address", "bytes8"}, []string{"0x6615e4e985bf0d137196897dfa182dbd7127f54f", "0xaabbccddaabbccdd"}) 229 assert.NoError(t, err) 230 231 v1, ok := values[0].(common.Address) 232 assert.True(t, ok) 233 assert.Equal(t, "0x6615e4e985BF0D137196897Dfa182dBD7127f54f", v1.String()) 234 235 v2, ok := values[1].([]uint8) 236 assert.True(t, ok) 237 assert.Equal(t, []uint8{170, 187, 204, 221, 170, 187, 204, 221}, v2) 238 } 239 240 { 241 values, err := AbiUnmarshalStringValues([]string{"address", "bytes7"}, []string{"0x6615e4e985bf0d137196897dfa182dbd7127f54f", "0xaabbccddaabbcc"}) 242 assert.NoError(t, err) 243 244 v1, ok := values[0].(common.Address) 245 assert.True(t, ok) 246 assert.Equal(t, "0x6615e4e985BF0D137196897Dfa182dBD7127f54f", v1.String()) 247 248 v2, ok := values[1].([]uint8) 249 assert.True(t, ok) 250 assert.Equal(t, []uint8{170, 187, 204, 221, 170, 187, 204}, v2) 251 } 252 253 { 254 values, err := AbiUnmarshalStringValues([]string{"address", "uint256"}, []string{"", "2"}) 255 assert.Error(t, err) 256 assert.Len(t, values, 0) 257 } 258 259 { 260 values, err := AbiUnmarshalStringValues([]string{"bytes", "uint256"}, []string{"0", "2"}) 261 assert.Error(t, err) 262 assert.Len(t, values, 0) 263 } 264 265 { 266 values, err := AbiUnmarshalStringValues([]string{"bytes", "uint256"}, []string{"0z", "2"}) 267 assert.Error(t, err) 268 assert.Len(t, values, 0) 269 } 270 } 271 272 // func TestAbiContractCall1(t *testing.T) { 273 // calldata, err := AbiEncodeMethodCalldata("getCurrencyReserves(uint256[])", []interface{}{[]*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)}}) 274 // assert.NoError(t, err) 275 // assert.Equal(t, "0x209b96c500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", HexEncode(calldata)) 276 277 // ca := common.HexToAddress("0xa519711c25a631e55a6eac19d1f2858c97a86a95") 278 // txMsg := ethereum.CallMsg{ 279 // To: &ca, 280 // Data: calldata, 281 // } 282 283 // p, _ := ethrpc.NewProvider("https://rinkeby.infura.io/v3/xxxx") 284 // contractCallOutput, err := p.CallContract(context.Background(), txMsg, nil) 285 // assert.NoError(t, err) 286 287 // spew.Dump(contractCallOutput) 288 289 // var values []*big.Int 290 // err = AbiDecodeExpr("uint256[]", contractCallOutput, []interface{}{&values}) 291 // assert.NoError(t, err) 292 293 // // spew.Dump(values) 294 // } 295 296 // func TestAbiContractCall2(t *testing.T) { 297 // calldata, err := AbiEncodeMethodCalldataFromStringValues("getCurrencyReserves(uint256[])", []string{`["1","2","3"]`}) 298 // assert.NoError(t, err) 299 // assert.Equal(t, "0x209b96c500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", HexEncode(calldata)) 300 301 // ca := common.HexToAddress("0xa519711c25a631e55a6eac19d1f2858c97a86a95") 302 // txMsg := ethereum.CallMsg{ 303 // To: &ca, 304 // Data: calldata, 305 // } 306 307 // p, _ := ethrpc.NewProvider("https://rinkeby.infura.io/v3/xxxx") 308 // contractCallOutput, err := p.CallContract(context.Background(), txMsg, nil) 309 // assert.NoError(t, err) 310 311 // spew.Dump(contractCallOutput) 312 313 // values, err := AbiDecodeExprAndStringify("uint256[]", contractCallOutput) 314 // assert.NoError(t, err) 315 316 // spew.Dump(values) 317 // }