github.com/jeffallen/go-ethereum@v1.1.4-0.20150910155051-571d3236c49c/accounts/abi/abi_test.go (about) 1 // Copyright 2015 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 17 package abi 18 19 import ( 20 "bytes" 21 "math/big" 22 "reflect" 23 "strings" 24 "testing" 25 26 "github.com/ethereum/go-ethereum/crypto" 27 ) 28 29 const jsondata = ` 30 [ 31 { "name" : "balance", "const" : true }, 32 { "name" : "send", "const" : false, "input" : [ { "name" : "amount", "type" : "uint256" } ] } 33 ]` 34 35 const jsondata2 = ` 36 [ 37 { "name" : "balance", "const" : true }, 38 { "name" : "send", "const" : false, "input" : [ { "name" : "amount", "type" : "uint256" } ] }, 39 { "name" : "test", "const" : false, "input" : [ { "name" : "number", "type" : "uint32" } ] }, 40 { "name" : "string", "const" : false, "input" : [ { "name" : "input", "type" : "string" } ] }, 41 { "name" : "bool", "const" : false, "input" : [ { "name" : "input", "type" : "bool" } ] }, 42 { "name" : "address", "const" : false, "input" : [ { "name" : "input", "type" : "address" } ] }, 43 { "name" : "string32", "const" : false, "input" : [ { "name" : "input", "type" : "string32" } ] }, 44 { "name" : "uint64[2]", "const" : false, "input" : [ { "name" : "input", "type" : "uint64[2]" } ] }, 45 { "name" : "uint64[]", "const" : false, "input" : [ { "name" : "input", "type" : "uint64[]" } ] }, 46 { "name" : "foo", "const" : false, "input" : [ { "name" : "input", "type" : "uint32" } ] }, 47 { "name" : "bar", "const" : false, "input" : [ { "name" : "input", "type" : "uint32" }, { "name" : "string", "type" : "uint16" } ] }, 48 { "name" : "slice", "const" : false, "input" : [ { "name" : "input", "type" : "uint32[2]" } ] }, 49 { "name" : "slice256", "const" : false, "input" : [ { "name" : "input", "type" : "uint256[2]" } ] } 50 ]` 51 52 func TestType(t *testing.T) { 53 typ, err := NewType("uint32") 54 if err != nil { 55 t.Error(err) 56 } 57 if typ.Kind != reflect.Ptr { 58 t.Error("expected uint32 to have kind Ptr") 59 } 60 61 typ, err = NewType("uint32[]") 62 if err != nil { 63 t.Error(err) 64 } 65 if typ.Kind != reflect.Slice { 66 t.Error("expected uint32[] to have type slice") 67 } 68 if typ.Type != ubig_ts { 69 t.Error("expcted uith32[] to have type uint64") 70 } 71 72 typ, err = NewType("uint32[2]") 73 if err != nil { 74 t.Error(err) 75 } 76 if typ.Kind != reflect.Slice { 77 t.Error("expected uint32[2] to have kind slice") 78 } 79 if typ.Type != ubig_ts { 80 t.Error("expcted uith32[2] to have type uint64") 81 } 82 if typ.Size != 2 { 83 t.Error("expected uint32[2] to have a size of 2") 84 } 85 } 86 87 func TestReader(t *testing.T) { 88 Uint256, _ := NewType("uint256") 89 exp := ABI{ 90 Methods: map[string]Method{ 91 "balance": Method{ 92 "balance", true, nil, Type{}, 93 }, 94 "send": Method{ 95 "send", false, []Argument{ 96 Argument{"amount", Uint256}, 97 }, Type{}, 98 }, 99 }, 100 } 101 102 abi, err := JSON(strings.NewReader(jsondata)) 103 if err != nil { 104 t.Error(err) 105 } 106 107 // deep equal fails for some reason 108 t.Skip() 109 if !reflect.DeepEqual(abi, exp) { 110 t.Errorf("\nabi: %v\ndoes not match exp: %v", abi, exp) 111 } 112 } 113 114 func TestTestNumbers(t *testing.T) { 115 abi, err := JSON(strings.NewReader(jsondata2)) 116 if err != nil { 117 t.Error(err) 118 t.FailNow() 119 } 120 121 if _, err := abi.Pack("balance"); err != nil { 122 t.Error(err) 123 } 124 125 if _, err := abi.Pack("balance", 1); err == nil { 126 t.Error("expected error for balance(1)") 127 } 128 129 if _, err := abi.Pack("doesntexist", nil); err == nil { 130 t.Errorf("doesntexist shouldn't exist") 131 } 132 133 if _, err := abi.Pack("doesntexist", 1); err == nil { 134 t.Errorf("doesntexist(1) shouldn't exist") 135 } 136 137 if _, err := abi.Pack("send", big.NewInt(1000)); err != nil { 138 t.Error(err) 139 } 140 141 i := new(int) 142 *i = 1000 143 if _, err := abi.Pack("send", i); err == nil { 144 t.Errorf("expected send( ptr ) to throw, requires *big.Int instead of *int") 145 } 146 147 if _, err := abi.Pack("send", 1000); err != nil { 148 t.Error("expected send(1000) to cast to big") 149 } 150 151 if _, err := abi.Pack("test", uint32(1000)); err != nil { 152 t.Error(err) 153 } 154 } 155 156 func TestTestString(t *testing.T) { 157 abi, err := JSON(strings.NewReader(jsondata2)) 158 if err != nil { 159 t.Error(err) 160 t.FailNow() 161 } 162 163 if _, err := abi.Pack("string", "hello world"); err != nil { 164 t.Error(err) 165 } 166 167 str10 := string(make([]byte, 10)) 168 if _, err := abi.Pack("string32", str10); err != nil { 169 t.Error(err) 170 } 171 172 str32 := string(make([]byte, 32)) 173 if _, err := abi.Pack("string32", str32); err != nil { 174 t.Error(err) 175 } 176 177 str33 := string(make([]byte, 33)) 178 if _, err := abi.Pack("string32", str33); err == nil { 179 t.Error("expected str33 to throw out of bound error") 180 } 181 } 182 183 func TestTestBool(t *testing.T) { 184 abi, err := JSON(strings.NewReader(jsondata2)) 185 if err != nil { 186 t.Error(err) 187 t.FailNow() 188 } 189 190 if _, err := abi.Pack("bool", true); err != nil { 191 t.Error(err) 192 } 193 } 194 195 func TestTestSlice(t *testing.T) { 196 abi, err := JSON(strings.NewReader(jsondata2)) 197 if err != nil { 198 t.Error(err) 199 t.FailNow() 200 } 201 202 addr := make([]byte, 20) 203 if _, err := abi.Pack("address", addr); err != nil { 204 t.Error(err) 205 } 206 207 addr = make([]byte, 21) 208 if _, err := abi.Pack("address", addr); err == nil { 209 t.Error("expected address of 21 width to throw") 210 } 211 212 slice := make([]byte, 2) 213 if _, err := abi.Pack("uint64[2]", slice); err != nil { 214 t.Error(err) 215 } 216 217 if _, err := abi.Pack("uint64[]", slice); err != nil { 218 t.Error(err) 219 } 220 } 221 222 func TestTestAddress(t *testing.T) { 223 abi, err := JSON(strings.NewReader(jsondata2)) 224 if err != nil { 225 t.Error(err) 226 t.FailNow() 227 } 228 229 addr := make([]byte, 20) 230 if _, err := abi.Pack("address", addr); err != nil { 231 t.Error(err) 232 } 233 } 234 235 func TestMethodSignature(t *testing.T) { 236 String, _ := NewType("string") 237 String32, _ := NewType("string32") 238 m := Method{"foo", false, []Argument{Argument{"bar", String32}, Argument{"baz", String}}, Type{}} 239 exp := "foo(string32,string)" 240 if m.String() != exp { 241 t.Error("signature mismatch", exp, "!=", m.String()) 242 } 243 244 idexp := crypto.Sha3([]byte(exp))[:4] 245 if !bytes.Equal(m.Id(), idexp) { 246 t.Errorf("expected ids to match %x != %x", m.Id(), idexp) 247 } 248 249 uintt, _ := NewType("uint") 250 m = Method{"foo", false, []Argument{Argument{"bar", uintt}}, Type{}} 251 exp = "foo(uint256)" 252 if m.String() != exp { 253 t.Error("signature mismatch", exp, "!=", m.String()) 254 } 255 } 256 257 func TestPack(t *testing.T) { 258 abi, err := JSON(strings.NewReader(jsondata2)) 259 if err != nil { 260 t.Error(err) 261 t.FailNow() 262 } 263 264 sig := crypto.Sha3([]byte("foo(uint32)"))[:4] 265 sig = append(sig, make([]byte, 32)...) 266 sig[35] = 10 267 268 packed, err := abi.Pack("foo", uint32(10)) 269 if err != nil { 270 t.Error(err) 271 t.FailNow() 272 } 273 274 if !bytes.Equal(packed, sig) { 275 t.Errorf("expected %x got %x", sig, packed) 276 } 277 } 278 279 func TestMultiPack(t *testing.T) { 280 abi, err := JSON(strings.NewReader(jsondata2)) 281 if err != nil { 282 t.Error(err) 283 t.FailNow() 284 } 285 286 sig := crypto.Sha3([]byte("bar(uint32,uint16)"))[:4] 287 sig = append(sig, make([]byte, 64)...) 288 sig[35] = 10 289 sig[67] = 11 290 291 packed, err := abi.Pack("bar", uint32(10), uint16(11)) 292 if err != nil { 293 t.Error(err) 294 t.FailNow() 295 } 296 297 if !bytes.Equal(packed, sig) { 298 t.Errorf("expected %x got %x", sig, packed) 299 } 300 } 301 302 func TestPackSlice(t *testing.T) { 303 abi, err := JSON(strings.NewReader(jsondata2)) 304 if err != nil { 305 t.Error(err) 306 t.FailNow() 307 } 308 309 sig := crypto.Sha3([]byte("slice(uint32[2])"))[:4] 310 sig = append(sig, make([]byte, 64)...) 311 sig[35] = 1 312 sig[67] = 2 313 314 packed, err := abi.Pack("slice", []uint32{1, 2}) 315 if err != nil { 316 t.Error(err) 317 t.FailNow() 318 } 319 320 if !bytes.Equal(packed, sig) { 321 t.Errorf("expected %x got %x", sig, packed) 322 } 323 } 324 325 func TestPackSliceBig(t *testing.T) { 326 abi, err := JSON(strings.NewReader(jsondata2)) 327 if err != nil { 328 t.Error(err) 329 t.FailNow() 330 } 331 332 sig := crypto.Sha3([]byte("slice256(uint256[2])"))[:4] 333 sig = append(sig, make([]byte, 64)...) 334 sig[35] = 1 335 sig[67] = 2 336 337 packed, err := abi.Pack("slice256", []*big.Int{big.NewInt(1), big.NewInt(2)}) 338 if err != nil { 339 t.Error(err) 340 t.FailNow() 341 } 342 343 if !bytes.Equal(packed, sig) { 344 t.Errorf("expected %x got %x", sig, packed) 345 } 346 }