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  }