abi_test.go 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. // Copyright 2019 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. package fourbyte
  17. import (
  18. "math/big"
  19. "reflect"
  20. "strings"
  21. "testing"
  22. "github.com/ethereum/go-ethereum/accounts/abi"
  23. "github.com/ethereum/go-ethereum/common"
  24. )
  25. func verify(t *testing.T, jsondata, calldata string, exp []interface{}) {
  26. abispec, err := abi.JSON(strings.NewReader(jsondata))
  27. if err != nil {
  28. t.Fatal(err)
  29. }
  30. cd := common.Hex2Bytes(calldata)
  31. sigdata, argdata := cd[:4], cd[4:]
  32. method, err := abispec.MethodById(sigdata)
  33. if err != nil {
  34. t.Fatal(err)
  35. }
  36. data, err := method.Inputs.UnpackValues(argdata)
  37. if err != nil {
  38. t.Fatal(err)
  39. }
  40. if len(data) != len(exp) {
  41. t.Fatalf("Mismatched length, expected %d, got %d", len(exp), len(data))
  42. }
  43. for i, elem := range data {
  44. if !reflect.DeepEqual(elem, exp[i]) {
  45. t.Fatalf("Unpack error, arg %d, got %v, want %v", i, elem, exp[i])
  46. }
  47. }
  48. }
  49. func TestNewUnpacker(t *testing.T) {
  50. type unpackTest struct {
  51. jsondata string
  52. calldata string
  53. exp []interface{}
  54. }
  55. testcases := []unpackTest{
  56. { // https://solidity.readthedocs.io/en/develop/abi-spec.html#use-of-dynamic-types
  57. `[{"type":"function","name":"f", "inputs":[{"type":"uint256"},{"type":"uint32[]"},{"type":"bytes10"},{"type":"bytes"}]}]`,
  58. // 0x123, [0x456, 0x789], "1234567890", "Hello, world!"
  59. "8be65246" + "00000000000000000000000000000000000000000000000000000000000001230000000000000000000000000000000000000000000000000000000000000080313233343536373839300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004560000000000000000000000000000000000000000000000000000000000000789000000000000000000000000000000000000000000000000000000000000000d48656c6c6f2c20776f726c642100000000000000000000000000000000000000",
  60. []interface{}{
  61. big.NewInt(0x123),
  62. []uint32{0x456, 0x789},
  63. [10]byte{49, 50, 51, 52, 53, 54, 55, 56, 57, 48},
  64. common.Hex2Bytes("48656c6c6f2c20776f726c6421"),
  65. },
  66. }, { // https://docs.soliditylang.org/en/develop/abi-spec.html#examples
  67. `[{"type":"function","name":"sam","inputs":[{"type":"bytes"},{"type":"bool"},{"type":"uint256[]"}]}]`,
  68. // "dave", true and [1,2,3]
  69. "a5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003",
  70. []interface{}{
  71. []byte{0x64, 0x61, 0x76, 0x65},
  72. true,
  73. []*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)},
  74. },
  75. }, {
  76. `[{"type":"function","name":"send","inputs":[{"type":"uint256"}]}]`,
  77. "a52c101e0000000000000000000000000000000000000000000000000000000000000012",
  78. []interface{}{big.NewInt(0x12)},
  79. }, {
  80. `[{"type":"function","name":"compareAndApprove","inputs":[{"type":"address"},{"type":"uint256"},{"type":"uint256"}]}]`,
  81. "751e107900000000000000000000000000000133700000deadbeef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
  82. []interface{}{
  83. common.HexToAddress("0x00000133700000deadbeef000000000000000000"),
  84. new(big.Int).SetBytes([]byte{0x00}),
  85. big.NewInt(0x1),
  86. },
  87. },
  88. }
  89. for _, c := range testcases {
  90. verify(t, c.jsondata, c.calldata, c.exp)
  91. }
  92. }
  93. func TestCalldataDecoding(t *testing.T) {
  94. // send(uint256) : a52c101e
  95. // compareAndApprove(address,uint256,uint256) : 751e1079
  96. // issue(address[],uint256) : 42958b54
  97. jsondata := `
  98. [
  99. {"type":"function","name":"send","inputs":[{"name":"a","type":"uint256"}]},
  100. {"type":"function","name":"compareAndApprove","inputs":[{"name":"a","type":"address"},{"name":"a","type":"uint256"},{"name":"a","type":"uint256"}]},
  101. {"type":"function","name":"issue","inputs":[{"name":"a","type":"address[]"},{"name":"a","type":"uint256"}]},
  102. {"type":"function","name":"sam","inputs":[{"name":"a","type":"bytes"},{"name":"a","type":"bool"},{"name":"a","type":"uint256[]"}]}
  103. ]`
  104. // Expected failures
  105. for i, hexdata := range []string{
  106. "a52c101e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042",
  107. "a52c101e000000000000000000000000000000000000000000000000000000000000001200",
  108. "a52c101e00000000000000000000000000000000000000000000000000000000000000",
  109. "a52c101e",
  110. "a52c10",
  111. "",
  112. // Too short
  113. "751e10790000000000000000000000000000000000000000000000000000000000000012",
  114. "751e1079FFffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
  115. // Not valid multiple of 32
  116. "deadbeef00000000000000000000000000000000000000000000000000000000000000",
  117. // Too short 'issue'
  118. "42958b5400000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042",
  119. // Too short compareAndApprove
  120. "a52c101e00ff0000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042",
  121. // From https://docs.soliditylang.org/en/develop/abi-spec.html
  122. // contains a bool with illegal values
  123. "a5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003",
  124. } {
  125. _, err := parseCallData(common.Hex2Bytes(hexdata), jsondata)
  126. if err == nil {
  127. t.Errorf("test %d: expected decoding to fail: %s", i, hexdata)
  128. }
  129. }
  130. // Expected success
  131. for i, hexdata := range []string{
  132. // From https://docs.soliditylang.org/en/develop/abi-spec.html
  133. "a5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003",
  134. "a52c101e0000000000000000000000000000000000000000000000000000000000000012",
  135. "a52c101eFFffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
  136. "751e1079000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  137. "42958b54" +
  138. // start of dynamic type
  139. "0000000000000000000000000000000000000000000000000000000000000040" +
  140. // uint256
  141. "0000000000000000000000000000000000000000000000000000000000000001" +
  142. // length of array
  143. "0000000000000000000000000000000000000000000000000000000000000002" +
  144. // array values
  145. "000000000000000000000000000000000000000000000000000000000000dead" +
  146. "000000000000000000000000000000000000000000000000000000000000beef",
  147. } {
  148. _, err := parseCallData(common.Hex2Bytes(hexdata), jsondata)
  149. if err != nil {
  150. t.Errorf("test %d: unexpected failure on input %s:\n %v (%d bytes) ", i, hexdata, err, len(common.Hex2Bytes(hexdata)))
  151. }
  152. }
  153. }
  154. func TestMaliciousABIStrings(t *testing.T) {
  155. tests := []string{
  156. "func(uint256,uint256,[]uint256)",
  157. "func(uint256,uint256,uint256,)",
  158. "func(,uint256,uint256,uint256)",
  159. }
  160. data := common.Hex2Bytes("4401a6e40000000000000000000000000000000000000000000000000000000000000012")
  161. for i, tt := range tests {
  162. _, err := verifySelector(tt, data)
  163. if err == nil {
  164. t.Errorf("test %d: expected error for selector '%v'", i, tt)
  165. }
  166. }
  167. }