github.com/datachainlab/burrow@v0.25.0/execution/evm/abi/abi.go (about)

     1  package abi
     2  
     3  import (
     4  	"encoding/binary"
     5  	"encoding/json"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"math/big"
     9  	"reflect"
    10  	"regexp"
    11  	"strconv"
    12  	"strings"
    13  	"unsafe" // just for Sizeof
    14  
    15  	burrow_binary "github.com/hyperledger/burrow/binary"
    16  	"github.com/hyperledger/burrow/crypto"
    17  	"github.com/hyperledger/burrow/crypto/sha3"
    18  )
    19  
    20  // EVM Solidity calls and return values are packed into
    21  // pieces of 32 bytes, including a bool (wasting 255 out of 256 bits)
    22  const ElementSize = 32
    23  
    24  type EVMType interface {
    25  	GetSignature() string
    26  	getGoType() interface{}
    27  	pack(v interface{}) ([]byte, error)
    28  	unpack(data []byte, offset int, v interface{}) (int, error)
    29  	Dynamic() bool
    30  }
    31  
    32  var _ EVMType = (*EVMBool)(nil)
    33  
    34  type EVMBool struct {
    35  }
    36  
    37  func (e EVMBool) GetSignature() string {
    38  	return "bool"
    39  }
    40  
    41  func (e EVMBool) getGoType() interface{} {
    42  	return new(bool)
    43  }
    44  
    45  func (e EVMBool) pack(v interface{}) ([]byte, error) {
    46  	var b bool
    47  	arg := reflect.ValueOf(v)
    48  	if arg.Kind() == reflect.String {
    49  		val := arg.String()
    50  		if strings.EqualFold(val, "true") || val == "1" {
    51  			b = true
    52  		} else if strings.EqualFold(val, "false") || val == "0" {
    53  			b = false
    54  		} else {
    55  			return nil, fmt.Errorf("%s is not a valid value for EVM Bool type", val)
    56  		}
    57  	} else if arg.Kind() == reflect.Bool {
    58  		b = arg.Bool()
    59  	} else {
    60  		return nil, fmt.Errorf("%s cannot be converted to EVM Bool type", arg.Kind().String())
    61  	}
    62  	res := make([]byte, ElementSize)
    63  	if b {
    64  		res[ElementSize-1] = 1
    65  	}
    66  	return res, nil
    67  }
    68  
    69  func (e EVMBool) unpack(data []byte, offset int, v interface{}) (int, error) {
    70  	if len(data)-offset < 32 {
    71  		return 0, fmt.Errorf("not enough data")
    72  	}
    73  	data = data[offset:]
    74  	switch v := v.(type) {
    75  	case *string:
    76  		if data[ElementSize-1] == 1 {
    77  			*v = "true"
    78  		} else if data[ElementSize-1] == 0 {
    79  			*v = "false"
    80  		} else {
    81  			return 0, fmt.Errorf("unexpected value for EVM bool")
    82  		}
    83  	case *int8:
    84  		*v = int8(data[ElementSize-1])
    85  	case *int16:
    86  		*v = int16(data[ElementSize-1])
    87  	case *int32:
    88  		*v = int32(data[ElementSize-1])
    89  	case *int64:
    90  		*v = int64(data[ElementSize-1])
    91  	case *int:
    92  		*v = int(data[ElementSize-1])
    93  	case *uint8:
    94  		*v = uint8(data[ElementSize-1])
    95  	case *uint16:
    96  		*v = uint16(data[ElementSize-1])
    97  	case *uint32:
    98  		*v = uint32(data[ElementSize-1])
    99  	case *uint64:
   100  		*v = uint64(data[ElementSize-1])
   101  	case *uint:
   102  		*v = uint(data[ElementSize-1])
   103  	case *bool:
   104  		*v = data[ElementSize-1] == 1
   105  	default:
   106  		return 0, fmt.Errorf("cannot set type %s for EVM bool", reflect.ValueOf(v).Kind().String())
   107  	}
   108  	return 32, nil
   109  }
   110  
   111  func (e EVMBool) Dynamic() bool {
   112  	return false
   113  }
   114  
   115  var _ EVMType = (*EVMUint)(nil)
   116  
   117  type EVMUint struct {
   118  	M uint64
   119  }
   120  
   121  func (e EVMUint) GetSignature() string {
   122  	return fmt.Sprintf("uint%d", e.M)
   123  }
   124  
   125  func (e EVMUint) getGoType() interface{} {
   126  	switch e.M {
   127  	case 8:
   128  		return new(uint8)
   129  	case 16:
   130  		return new(uint16)
   131  	case 32:
   132  		return new(uint32)
   133  	case 64:
   134  		return new(uint64)
   135  	default:
   136  		return new(big.Int)
   137  	}
   138  }
   139  
   140  func (e EVMUint) pack(v interface{}) ([]byte, error) {
   141  	n := new(big.Int)
   142  
   143  	arg := reflect.ValueOf(v)
   144  	switch arg.Kind() {
   145  	case reflect.String:
   146  		_, ok := n.SetString(arg.String(), 0)
   147  		if !ok {
   148  			return nil, fmt.Errorf("Failed to parse `%s", arg.String())
   149  		}
   150  		if n.Sign() < 0 {
   151  			return nil, fmt.Errorf("negative value not allowed for uint%d", e.M)
   152  		}
   153  	case reflect.Uint8:
   154  		fallthrough
   155  	case reflect.Uint16:
   156  		fallthrough
   157  	case reflect.Uint32:
   158  		fallthrough
   159  	case reflect.Uint64:
   160  		fallthrough
   161  	case reflect.Uint:
   162  		n.SetUint64(arg.Uint())
   163  	case reflect.Int8:
   164  		fallthrough
   165  	case reflect.Int16:
   166  		fallthrough
   167  	case reflect.Int32:
   168  		fallthrough
   169  	case reflect.Int64:
   170  		fallthrough
   171  	case reflect.Int:
   172  		x := arg.Int()
   173  		if x < 0 {
   174  			return nil, fmt.Errorf("negative value not allowed for uint%d", e.M)
   175  		}
   176  		n.SetInt64(x)
   177  	default:
   178  		t := reflect.TypeOf(new(uint64))
   179  		if reflect.TypeOf(v).ConvertibleTo(t) {
   180  			n.SetUint64(reflect.ValueOf(v).Convert(t).Uint())
   181  		} else {
   182  			return nil, fmt.Errorf("cannot convert type %s to uint%d", arg.Kind().String(), e.M)
   183  		}
   184  	}
   185  
   186  	b := n.Bytes()
   187  	if uint64(len(b)) > e.M {
   188  		return nil, fmt.Errorf("value to large for int%d", e.M)
   189  	}
   190  	return pad(b, ElementSize, true), nil
   191  }
   192  
   193  func (e EVMUint) unpack(data []byte, offset int, v interface{}) (int, error) {
   194  	if len(data)-offset < ElementSize {
   195  		return 0, fmt.Errorf("not enough data")
   196  	}
   197  
   198  	data = data[offset:]
   199  	empty := 0
   200  	for empty = 0; empty < ElementSize; empty++ {
   201  		if data[empty] != 0 {
   202  			break
   203  		}
   204  	}
   205  
   206  	length := ElementSize - empty
   207  
   208  	switch v := v.(type) {
   209  	case *string:
   210  		b := new(big.Int)
   211  		b.SetBytes(data[empty:ElementSize])
   212  		*v = b.String()
   213  	case *big.Int:
   214  		b := new(big.Int)
   215  		*v = *b.SetBytes(data[0:ElementSize])
   216  	case *uint64:
   217  		maxLen := int(unsafe.Sizeof(*v))
   218  		if length > maxLen {
   219  			return 0, fmt.Errorf("value to large for uint64")
   220  		}
   221  		*v = binary.BigEndian.Uint64(data[ElementSize-maxLen : ElementSize])
   222  	case *uint32:
   223  		maxLen := int(unsafe.Sizeof(*v))
   224  		if length > maxLen {
   225  			return 0, fmt.Errorf("value to large for uint64")
   226  		}
   227  		*v = binary.BigEndian.Uint32(data[ElementSize-maxLen : ElementSize])
   228  	case *uint16:
   229  		maxLen := int(unsafe.Sizeof(*v))
   230  		if length > maxLen {
   231  			return 0, fmt.Errorf("value to large for uint16")
   232  		}
   233  		*v = binary.BigEndian.Uint16(data[ElementSize-maxLen : ElementSize])
   234  	case *uint8:
   235  		maxLen := 1
   236  		if length > maxLen {
   237  			return 0, fmt.Errorf("value to large for uint8")
   238  		}
   239  		*v = uint8(data[31])
   240  	case *int64:
   241  		maxLen := int(unsafe.Sizeof(*v))
   242  		if length > maxLen || (data[ElementSize-maxLen]&0x80) != 0 {
   243  			return 0, fmt.Errorf("value to large for int64")
   244  		}
   245  		*v = int64(binary.BigEndian.Uint64(data[ElementSize-maxLen : ElementSize]))
   246  	case *int32:
   247  		maxLen := int(unsafe.Sizeof(*v))
   248  		if length > maxLen || (data[ElementSize-maxLen]&0x80) != 0 {
   249  			return 0, fmt.Errorf("value to large for int64")
   250  		}
   251  		*v = int32(binary.BigEndian.Uint32(data[ElementSize-maxLen : ElementSize]))
   252  	case *int16:
   253  		maxLen := int(unsafe.Sizeof(*v))
   254  		if length > maxLen || (data[ElementSize-maxLen]&0x80) != 0 {
   255  			return 0, fmt.Errorf("value to large for int16")
   256  		}
   257  		*v = int16(binary.BigEndian.Uint16(data[ElementSize-maxLen : ElementSize]))
   258  	case *int8:
   259  		maxLen := 1
   260  		if length > maxLen || (data[ElementSize-maxLen]&0x80) != 0 {
   261  			return 0, fmt.Errorf("value to large for int8")
   262  		}
   263  		*v = int8(data[ElementSize-1])
   264  	default:
   265  		return 0, fmt.Errorf("unable to convert %s to %s", e.GetSignature(), reflect.ValueOf(v).Kind().String())
   266  	}
   267  
   268  	return 32, nil
   269  }
   270  
   271  func (e EVMUint) Dynamic() bool {
   272  	return false
   273  }
   274  
   275  var _ EVMType = (*EVMInt)(nil)
   276  
   277  type EVMInt struct {
   278  	M uint64
   279  }
   280  
   281  func (e EVMInt) getGoType() interface{} {
   282  	switch e.M {
   283  	case 8:
   284  		return new(int8)
   285  	case 16:
   286  		return new(int16)
   287  	case 32:
   288  		return new(int32)
   289  	case 64:
   290  		return new(int64)
   291  	default:
   292  		return new(big.Int)
   293  	}
   294  }
   295  
   296  func (e EVMInt) GetSignature() string {
   297  	return fmt.Sprintf("int%d", e.M)
   298  }
   299  
   300  func (e EVMInt) pack(v interface{}) ([]byte, error) {
   301  	n := new(big.Int)
   302  
   303  	arg := reflect.ValueOf(v)
   304  	switch arg.Kind() {
   305  	case reflect.String:
   306  		_, ok := n.SetString(arg.String(), 0)
   307  		if !ok {
   308  			return nil, fmt.Errorf("Failed to parse `%s", arg.String())
   309  		}
   310  	case reflect.Uint8:
   311  		fallthrough
   312  	case reflect.Uint16:
   313  		fallthrough
   314  	case reflect.Uint32:
   315  		fallthrough
   316  	case reflect.Uint64:
   317  		fallthrough
   318  	case reflect.Uint:
   319  		n.SetUint64(arg.Uint())
   320  	case reflect.Int8:
   321  		fallthrough
   322  	case reflect.Int16:
   323  		fallthrough
   324  	case reflect.Int32:
   325  		fallthrough
   326  	case reflect.Int64:
   327  		fallthrough
   328  	case reflect.Int:
   329  		n.SetInt64(arg.Int())
   330  	default:
   331  		t := reflect.TypeOf(new(int64))
   332  		if reflect.TypeOf(v).ConvertibleTo(t) {
   333  			n.SetInt64(reflect.ValueOf(v).Convert(t).Int())
   334  		} else {
   335  			return nil, fmt.Errorf("cannot convert type %s to int%d", arg.Kind().String(), e.M)
   336  		}
   337  	}
   338  
   339  	b := n.Bytes()
   340  	if uint64(len(b)) > e.M {
   341  		return nil, fmt.Errorf("value to large for int%d", e.M)
   342  	}
   343  	res := pad(b, ElementSize, true)
   344  	if (res[0] & 0x80) != 0 {
   345  		return nil, fmt.Errorf("value to large for int%d", e.M)
   346  	}
   347  	if n.Sign() < 0 {
   348  		// One's complement; i.e. 0xffff is -1, not 0.
   349  		n.Add(n, big.NewInt(1))
   350  		b := n.Bytes()
   351  		res = pad(b, ElementSize, true)
   352  		for i := 0; i < len(res); i++ {
   353  			res[i] = ^res[i]
   354  		}
   355  	}
   356  	return res, nil
   357  }
   358  
   359  func (e EVMInt) unpack(data []byte, offset int, v interface{}) (int, error) {
   360  	if len(data)-offset < ElementSize {
   361  		return 0, fmt.Errorf("not enough data")
   362  	}
   363  
   364  	data = data[offset:]
   365  	sign := (data[0] & 0x80) != 0
   366  
   367  	empty := 0
   368  	for empty = 0; empty < ElementSize; empty++ {
   369  		if (sign && data[empty] != 255) || (!sign && data[empty] != 0) {
   370  			break
   371  		}
   372  	}
   373  
   374  	length := ElementSize - empty
   375  	inv := make([]byte, ElementSize)
   376  	for i := 0; i < ElementSize; i++ {
   377  		if sign {
   378  			inv[i] = ^data[i]
   379  		} else {
   380  			inv[i] = data[i]
   381  		}
   382  	}
   383  	toType := reflect.ValueOf(v).Kind().String()
   384  
   385  	switch v := v.(type) {
   386  	case *string:
   387  		b := new(big.Int)
   388  		b.SetBytes(inv[empty:ElementSize])
   389  		if sign {
   390  			*v = b.Sub(big.NewInt(-1), b).String()
   391  		} else {
   392  			*v = b.String()
   393  		}
   394  	case *big.Int:
   395  		b := new(big.Int)
   396  		b.SetBytes(inv[0:ElementSize])
   397  		if sign {
   398  			*v = *b.Sub(big.NewInt(-1), b)
   399  		} else {
   400  			*v = *b
   401  		}
   402  	case *uint64:
   403  		if sign {
   404  			return 0, fmt.Errorf("cannot convert negative EVM int to %s", toType)
   405  		}
   406  		maxLen := int(unsafe.Sizeof(*v))
   407  		if length > maxLen {
   408  			return 0, fmt.Errorf("value to large for uint64")
   409  		}
   410  		*v = binary.BigEndian.Uint64(data[ElementSize-maxLen : ElementSize])
   411  	case *uint32:
   412  		if sign {
   413  			return 0, fmt.Errorf("cannot convert negative EVM int to %s", toType)
   414  		}
   415  		maxLen := int(unsafe.Sizeof(*v))
   416  		if length > maxLen {
   417  			return 0, fmt.Errorf("value to large for int32")
   418  		}
   419  		*v = binary.BigEndian.Uint32(data[ElementSize-maxLen : ElementSize])
   420  	case *uint16:
   421  		if sign {
   422  			return 0, fmt.Errorf("cannot convert negative EVM int to %s", toType)
   423  		}
   424  		maxLen := int(unsafe.Sizeof(*v))
   425  		if length > maxLen {
   426  			return 0, fmt.Errorf("value to large for uint16")
   427  		}
   428  		*v = binary.BigEndian.Uint16(data[ElementSize-maxLen : ElementSize])
   429  	case *int64:
   430  		maxLen := int(unsafe.Sizeof(*v))
   431  		if length > maxLen || (inv[ElementSize-maxLen]&0x80) != 0 {
   432  			return 0, fmt.Errorf("value to large for int64")
   433  		}
   434  		*v = int64(binary.BigEndian.Uint64(data[ElementSize-maxLen : ElementSize]))
   435  	case *int32:
   436  		maxLen := int(unsafe.Sizeof(*v))
   437  		if length > maxLen || (inv[ElementSize-maxLen]&0x80) != 0 {
   438  			return 0, fmt.Errorf("value to large for uint64")
   439  		}
   440  		*v = int32(binary.BigEndian.Uint32(data[ElementSize-maxLen : ElementSize]))
   441  	case *int16:
   442  		maxLen := int(unsafe.Sizeof(*v))
   443  		if length > maxLen || (inv[ElementSize-maxLen]&0x80) != 0 {
   444  			return 0, fmt.Errorf("value to large for uint16")
   445  		}
   446  		*v = int16(binary.BigEndian.Uint16(data[ElementSize-maxLen : ElementSize]))
   447  	default:
   448  		return 0, fmt.Errorf("unable to convert %s to %s", e.GetSignature(), toType)
   449  	}
   450  
   451  	return ElementSize, nil
   452  }
   453  
   454  func (e EVMInt) fixedSize() int {
   455  	return ElementSize
   456  }
   457  
   458  func (e EVMInt) Dynamic() bool {
   459  	return false
   460  }
   461  
   462  var _ EVMType = (*EVMAddress)(nil)
   463  
   464  type EVMAddress struct {
   465  }
   466  
   467  func (e EVMAddress) getGoType() interface{} {
   468  	return new(crypto.Address)
   469  }
   470  
   471  func (e EVMAddress) GetSignature() string {
   472  	return "address"
   473  }
   474  
   475  func (e EVMAddress) pack(v interface{}) ([]byte, error) {
   476  	var err error
   477  	a, ok := v.(crypto.Address)
   478  	if !ok {
   479  		s, ok := v.(string)
   480  		if ok {
   481  			a, err = crypto.AddressFromHexString(s)
   482  			if err != nil {
   483  				return nil, err
   484  			}
   485  		}
   486  	} else {
   487  		b, ok := v.([]byte)
   488  		if !ok {
   489  			return nil, fmt.Errorf("cannot map to %s to EVM address", reflect.ValueOf(v).Kind().String())
   490  		}
   491  
   492  		a, err = crypto.AddressFromBytes(b)
   493  		if err != nil {
   494  			return nil, err
   495  		}
   496  	}
   497  
   498  	return pad(a[:], ElementSize, true), nil
   499  }
   500  
   501  func (e EVMAddress) unpack(data []byte, offset int, v interface{}) (int, error) {
   502  	addr, err := crypto.AddressFromBytes(data[offset+ElementSize-crypto.AddressLength : offset+ElementSize])
   503  	if err != nil {
   504  		return 0, err
   505  	}
   506  	switch v := v.(type) {
   507  	case *string:
   508  		*v = addr.String()
   509  	case *crypto.Address:
   510  		*v = addr
   511  	case *([]byte):
   512  		*v = data[offset+ElementSize-crypto.AddressLength : offset+ElementSize]
   513  	default:
   514  		return 0, fmt.Errorf("cannot map EVM address to %s", reflect.ValueOf(v).Kind().String())
   515  	}
   516  
   517  	return ElementSize, nil
   518  }
   519  
   520  func (e EVMAddress) Dynamic() bool {
   521  	return false
   522  }
   523  
   524  var _ EVMType = (*EVMBytes)(nil)
   525  
   526  type EVMBytes struct {
   527  	M uint64
   528  }
   529  
   530  func (e EVMBytes) getGoType() interface{} {
   531  	v := make([]byte, e.M)
   532  	return &v
   533  }
   534  
   535  func (e EVMBytes) pack(v interface{}) ([]byte, error) {
   536  	b, ok := v.([]byte)
   537  	if !ok {
   538  		s, ok := v.(string)
   539  		if ok {
   540  			b = []byte(s)
   541  		} else {
   542  			return nil, fmt.Errorf("cannot map to %s to EVM bytes", reflect.ValueOf(v).Kind().String())
   543  		}
   544  	}
   545  
   546  	if e.M > 0 {
   547  		if uint64(len(b)) > e.M {
   548  			return nil, fmt.Errorf("[%d]byte to long for %s", len(b), e.GetSignature())
   549  		}
   550  		return pad(b, ElementSize, false), nil
   551  	} else {
   552  		length := EVMUint{M: 256}
   553  		p, err := length.pack(len(b))
   554  		if err != nil {
   555  			return nil, err
   556  		}
   557  		for i := 0; i < len(b); i += ElementSize {
   558  			a := b[i:]
   559  			if len(a) == 0 {
   560  				break
   561  			}
   562  			p = append(p, pad(a, ElementSize, false)...)
   563  		}
   564  
   565  		return p, nil
   566  	}
   567  }
   568  
   569  func (e EVMBytes) unpack(data []byte, offset int, v interface{}) (int, error) {
   570  	if e.M == 0 {
   571  		s := EVMString{}
   572  
   573  		return s.unpack(data, offset, v)
   574  	}
   575  
   576  	v2 := reflect.ValueOf(v).Elem()
   577  	switch v2.Type().Kind() {
   578  	case reflect.String:
   579  		start := 0
   580  		end := int(e.M)
   581  
   582  		for start < ElementSize-1 && data[offset+start] == 0 && start < end {
   583  			start++
   584  		}
   585  		for end > start && data[offset+end-1] == 0 {
   586  			end--
   587  		}
   588  		v2.SetString(string(data[offset+start : offset+end]))
   589  	case reflect.Array:
   590  		fallthrough
   591  	case reflect.Slice:
   592  		v2.SetBytes(data[offset : offset+int(e.M)])
   593  	default:
   594  		return 0, fmt.Errorf("cannot map EVM %s to %s", e.GetSignature(), reflect.ValueOf(v).Kind().String())
   595  	}
   596  
   597  	return ElementSize, nil
   598  }
   599  
   600  func (e EVMBytes) fixedSize() int {
   601  	return ElementSize
   602  }
   603  
   604  func (e EVMBytes) Dynamic() bool {
   605  	return e.M == 0
   606  }
   607  
   608  func (e EVMBytes) GetSignature() string {
   609  	if e.M > 0 {
   610  		return fmt.Sprintf("bytes%d", e.M)
   611  	} else {
   612  		return "bytes"
   613  	}
   614  }
   615  
   616  var _ EVMType = (*EVMString)(nil)
   617  
   618  type EVMString struct {
   619  }
   620  
   621  func (e EVMString) GetSignature() string {
   622  	return "string"
   623  }
   624  
   625  func (e EVMString) getGoType() interface{} {
   626  	return new(string)
   627  }
   628  
   629  func (e EVMString) pack(v interface{}) ([]byte, error) {
   630  	b := EVMBytes{M: 0}
   631  
   632  	return b.pack(v)
   633  }
   634  
   635  func (e EVMString) unpack(data []byte, offset int, v interface{}) (int, error) {
   636  	lenType := EVMInt{M: 64}
   637  	var len int64
   638  	l, err := lenType.unpack(data, offset, &len)
   639  	if err != nil {
   640  		return 0, err
   641  	}
   642  	offset += l
   643  
   644  	switch v := v.(type) {
   645  	case *string:
   646  		*v = string(data[offset : offset+int(len)])
   647  	case *[]byte:
   648  		*v = data[offset : offset+int(len)]
   649  	default:
   650  		return 0, fmt.Errorf("cannot map EVM string to %s", reflect.ValueOf(v).Kind().String())
   651  	}
   652  
   653  	return ElementSize, nil
   654  }
   655  
   656  func (e EVMString) Dynamic() bool {
   657  	return true
   658  }
   659  
   660  var _ EVMType = (*EVMFixed)(nil)
   661  
   662  type EVMFixed struct {
   663  	N, M   uint64
   664  	signed bool
   665  }
   666  
   667  func (e EVMFixed) getGoType() interface{} {
   668  	// This is not right, obviously
   669  	return new(big.Float)
   670  }
   671  
   672  func (e EVMFixed) GetSignature() string {
   673  	if e.signed {
   674  		return fmt.Sprintf("fixed%dx%d", e.M, e.N)
   675  	} else {
   676  		return fmt.Sprintf("ufixed%dx%d", e.M, e.N)
   677  	}
   678  }
   679  
   680  func (e EVMFixed) pack(v interface{}) ([]byte, error) {
   681  	// The ABI spec does not describe how this should be packed; go-ethereum abi does not implement this
   682  	// need to dig in solidity to find out how this is packed
   683  	return nil, fmt.Errorf("packing of %s not implemented, patches welcome", e.GetSignature())
   684  }
   685  
   686  func (e EVMFixed) unpack(data []byte, offset int, v interface{}) (int, error) {
   687  	// The ABI spec does not describe how this should be packed; go-ethereum abi does not implement this
   688  	// need to dig in solidity to find out how this is packed
   689  	return 0, fmt.Errorf("unpacking of %s not implemented, patches welcome", e.GetSignature())
   690  }
   691  
   692  func (e EVMFixed) fixedSize() int {
   693  	return ElementSize
   694  }
   695  
   696  func (e EVMFixed) Dynamic() bool {
   697  	return false
   698  }
   699  
   700  type Argument struct {
   701  	Name        string
   702  	EVM         EVMType
   703  	IsArray     bool
   704  	Indexed     bool
   705  	Hashed      bool
   706  	ArrayLength uint64
   707  }
   708  
   709  const FunctionIDSize = 4
   710  
   711  type FunctionID [FunctionIDSize]byte
   712  
   713  const EventIDSize = 32
   714  
   715  type EventID [EventIDSize]byte
   716  
   717  type FunctionSpec struct {
   718  	FunctionID FunctionID
   719  	Constant   bool
   720  	Inputs     []Argument
   721  	Outputs    []Argument
   722  }
   723  
   724  type EventSpec struct {
   725  	EventID   EventID
   726  	Inputs    []Argument
   727  	Name      string
   728  	Anonymous bool
   729  }
   730  
   731  type AbiSpec struct {
   732  	Constructor FunctionSpec
   733  	Fallback    FunctionSpec
   734  	Functions   map[string]FunctionSpec
   735  	Events      map[string]EventSpec
   736  	EventsById  map[EventID]EventSpec
   737  }
   738  
   739  type ArgumentJSON struct {
   740  	Name       string
   741  	Type       string
   742  	Components []ArgumentJSON
   743  	Indexed    bool
   744  }
   745  
   746  type AbiSpecJSON struct {
   747  	Name            string
   748  	Type            string
   749  	Inputs          []ArgumentJSON
   750  	Outputs         []ArgumentJSON
   751  	Constant        bool
   752  	Payable         bool
   753  	StateMutability string
   754  	Anonymous       bool
   755  }
   756  
   757  func readArgSpec(argsJ []ArgumentJSON) ([]Argument, error) {
   758  	args := make([]Argument, len(argsJ))
   759  	var err error
   760  
   761  	for i, a := range argsJ {
   762  		args[i].Name = a.Name
   763  		args[i].Indexed = a.Indexed
   764  
   765  		baseType := a.Type
   766  		isArray := regexp.MustCompile("(.*)\\[([0-9]+)\\]")
   767  		m := isArray.FindStringSubmatch(a.Type)
   768  		if m != nil {
   769  			args[i].IsArray = true
   770  			args[i].ArrayLength, err = strconv.ParseUint(m[2], 10, 32)
   771  			if err != nil {
   772  				return nil, err
   773  			}
   774  			baseType = m[1]
   775  		} else if strings.HasSuffix(a.Type, "[]") {
   776  			args[i].IsArray = true
   777  			baseType = strings.TrimSuffix(a.Type, "[]")
   778  		}
   779  
   780  		isM := regexp.MustCompile("(bytes|uint|int)([0-9]+)")
   781  		m = isM.FindStringSubmatch(baseType)
   782  		if m != nil {
   783  			M, err := strconv.ParseUint(m[2], 10, 32)
   784  			if err != nil {
   785  				return nil, err
   786  			}
   787  			switch m[1] {
   788  			case "bytes":
   789  				if M < 1 || M > 32 {
   790  					return nil, fmt.Errorf("bytes%d is not valid type", M)
   791  				}
   792  				args[i].EVM = EVMBytes{M}
   793  			case "uint":
   794  				if M < 8 || M > 256 || (M%8) != 0 {
   795  					return nil, fmt.Errorf("uint%d is not valid type", M)
   796  				}
   797  				args[i].EVM = EVMUint{M}
   798  			case "int":
   799  				if M < 8 || M > 256 || (M%8) != 0 {
   800  					return nil, fmt.Errorf("uint%d is not valid type", M)
   801  				}
   802  				args[i].EVM = EVMInt{M}
   803  			}
   804  			continue
   805  		}
   806  
   807  		isMxN := regexp.MustCompile("(fixed|ufixed)([0-9]+)x([0-9]+)")
   808  		m = isMxN.FindStringSubmatch(baseType)
   809  		if m != nil {
   810  			M, err := strconv.ParseUint(m[2], 10, 32)
   811  			if err != nil {
   812  				return nil, err
   813  			}
   814  			N, err := strconv.ParseUint(m[3], 10, 32)
   815  			if err != nil {
   816  				return nil, err
   817  			}
   818  			if M < 8 || M > 256 || (M%8) != 0 {
   819  				return nil, fmt.Errorf("%s is not valid type", baseType)
   820  			}
   821  			if N <= 0 || N > 80 {
   822  				return nil, fmt.Errorf("%s is not valid type", baseType)
   823  			}
   824  			if m[1] == "fixed" {
   825  				args[i].EVM = EVMFixed{N: N, M: M, signed: true}
   826  			} else if m[1] == "ufixed" {
   827  				args[i].EVM = EVMFixed{N: N, M: M, signed: false}
   828  			} else {
   829  				panic(m[1])
   830  			}
   831  			continue
   832  		}
   833  		switch baseType {
   834  		case "uint":
   835  			args[i].EVM = EVMUint{M: 256}
   836  		case "int":
   837  			args[i].EVM = EVMInt{M: 256}
   838  		case "address":
   839  			args[i].EVM = EVMAddress{}
   840  		case "bool":
   841  			args[i].EVM = EVMBool{}
   842  		case "fixed":
   843  			args[i].EVM = EVMFixed{M: 128, N: 8, signed: true}
   844  		case "ufixed":
   845  			args[i].EVM = EVMFixed{M: 128, N: 8, signed: false}
   846  		case "bytes":
   847  			args[i].EVM = EVMBytes{M: 0}
   848  		case "string":
   849  			args[i].EVM = EVMString{}
   850  		default:
   851  			// Assume it is a type of Contract
   852  			args[i].EVM = EVMAddress{}
   853  		}
   854  	}
   855  
   856  	return args, nil
   857  }
   858  
   859  func ReadAbiSpec(specBytes []byte) (*AbiSpec, error) {
   860  	var specJ []AbiSpecJSON
   861  	err := json.Unmarshal(specBytes, &specJ)
   862  	if err != nil {
   863  		// The abi spec file might a bin file, with the Abi under the Abi field in json
   864  		var binFile struct {
   865  			Abi []AbiSpecJSON
   866  		}
   867  		err = json.Unmarshal(specBytes, &binFile)
   868  		if err != nil {
   869  			return nil, err
   870  		}
   871  		specJ = binFile.Abi
   872  	}
   873  
   874  	abiSpec := AbiSpec{
   875  		Events:     make(map[string]EventSpec),
   876  		EventsById: make(map[EventID]EventSpec),
   877  		Functions:  make(map[string]FunctionSpec),
   878  	}
   879  
   880  	for _, s := range specJ {
   881  		switch s.Type {
   882  		case "constructor":
   883  			abiSpec.Constructor.Inputs, err = readArgSpec(s.Inputs)
   884  			if err != nil {
   885  				return nil, err
   886  			}
   887  		case "fallback":
   888  			abiSpec.Fallback.Inputs = make([]Argument, 0)
   889  			abiSpec.Fallback.Outputs = make([]Argument, 0)
   890  		case "event":
   891  			inputs, err := readArgSpec(s.Inputs)
   892  			if err != nil {
   893  				return nil, err
   894  			}
   895  			// Get signature before we deal with hashed types
   896  			sig := Signature(s.Name, inputs)
   897  			for i := range inputs {
   898  				if inputs[i].Indexed && inputs[i].EVM.Dynamic() {
   899  					// For Dynamic types, the hash is stored in stead
   900  					inputs[i].EVM = EVMBytes{M: 32}
   901  					inputs[i].Hashed = true
   902  				}
   903  			}
   904  			ev := EventSpec{Name: s.Name, EventID: GetEventID(sig), Inputs: inputs, Anonymous: s.Anonymous}
   905  			abiSpec.Events[ev.Name] = ev
   906  			abiSpec.EventsById[ev.EventID] = ev
   907  		case "function":
   908  			inputs, err := readArgSpec(s.Inputs)
   909  			if err != nil {
   910  				return nil, err
   911  			}
   912  			outputs, err := readArgSpec(s.Outputs)
   913  			if err != nil {
   914  				return nil, err
   915  			}
   916  			fs := FunctionSpec{Inputs: inputs, Outputs: outputs, Constant: s.Constant}
   917  			fs.SetFunctionID(s.Name)
   918  			abiSpec.Functions[s.Name] = fs
   919  		}
   920  	}
   921  
   922  	return &abiSpec, nil
   923  }
   924  
   925  func ReadAbiSpecFile(filename string) (*AbiSpec, error) {
   926  	specBytes, err := ioutil.ReadFile(filename)
   927  	if err != nil {
   928  		return nil, err
   929  	}
   930  
   931  	return ReadAbiSpec(specBytes)
   932  }
   933  
   934  // MergeAbiSpec takes multiple AbiSpecs and merges them into once structure. Note that
   935  // the same function name or event name can occur in different abis, so there might be
   936  // some information loss.
   937  func MergeAbiSpec(abiSpec []*AbiSpec) *AbiSpec {
   938  	newSpec := AbiSpec{
   939  		Events:     make(map[string]EventSpec),
   940  		EventsById: make(map[EventID]EventSpec),
   941  		Functions:  make(map[string]FunctionSpec),
   942  	}
   943  
   944  	for _, s := range abiSpec {
   945  		for n, f := range s.Functions {
   946  			newSpec.Functions[n] = f
   947  		}
   948  
   949  		// Different Abis can have the Event name, but with a different signature
   950  		// Loop over the signatures, as these are less likely to have collisions
   951  		for _, e := range s.EventsById {
   952  			newSpec.Events[e.Name] = e
   953  			newSpec.EventsById[e.EventID] = e
   954  		}
   955  	}
   956  
   957  	return &newSpec
   958  }
   959  
   960  func EVMTypeFromReflect(v reflect.Type) Argument {
   961  	arg := Argument{Name: v.Name()}
   962  
   963  	if v == reflect.TypeOf(crypto.Address{}) {
   964  		arg.EVM = EVMAddress{}
   965  	} else if v == reflect.TypeOf(big.Int{}) {
   966  		arg.EVM = EVMInt{M: 256}
   967  	} else {
   968  		if v.Kind() == reflect.Array {
   969  			arg.IsArray = true
   970  			arg.ArrayLength = uint64(v.Len())
   971  			v = v.Elem()
   972  		} else if v.Kind() == reflect.Slice {
   973  			arg.IsArray = true
   974  			v = v.Elem()
   975  		}
   976  
   977  		switch v.Kind() {
   978  		case reflect.Bool:
   979  			arg.EVM = EVMBool{}
   980  		case reflect.String:
   981  			arg.EVM = EVMString{}
   982  		case reflect.Uint64:
   983  			arg.EVM = EVMUint{M: 64}
   984  		case reflect.Int64:
   985  			arg.EVM = EVMInt{M: 64}
   986  		default:
   987  			panic(fmt.Sprintf("no mapping for type %v", v.Kind()))
   988  		}
   989  	}
   990  
   991  	return arg
   992  }
   993  
   994  // SpecFromStructReflect generates a FunctionSpec where the arguments and return values are
   995  // described a struct. Both args and rets should be set to the return value of reflect.TypeOf()
   996  // with the respective struct as an argument.
   997  func SpecFromStructReflect(fname string, args reflect.Type, rets reflect.Type) *FunctionSpec {
   998  	s := FunctionSpec{
   999  		Inputs:  make([]Argument, args.NumField()),
  1000  		Outputs: make([]Argument, rets.NumField()),
  1001  	}
  1002  	for i := 0; i < args.NumField(); i++ {
  1003  		f := args.Field(i)
  1004  		a := EVMTypeFromReflect(f.Type)
  1005  		a.Name = f.Name
  1006  		s.Inputs[i] = a
  1007  	}
  1008  	for i := 0; i < rets.NumField(); i++ {
  1009  		f := rets.Field(i)
  1010  		a := EVMTypeFromReflect(f.Type)
  1011  		a.Name = f.Name
  1012  		s.Outputs[i] = a
  1013  	}
  1014  	s.SetFunctionID(fname)
  1015  
  1016  	return &s
  1017  }
  1018  
  1019  func SpecFromFunctionReflect(fname string, v reflect.Value, skipIn, skipOut int) *FunctionSpec {
  1020  	t := v.Type()
  1021  
  1022  	if t.Kind() != reflect.Func {
  1023  		panic(fmt.Sprintf("%s is not a function", t.Name()))
  1024  	}
  1025  
  1026  	s := FunctionSpec{}
  1027  	s.Inputs = make([]Argument, t.NumIn()-skipIn)
  1028  	s.Outputs = make([]Argument, t.NumOut()-skipOut)
  1029  
  1030  	for i := range s.Inputs {
  1031  		s.Inputs[i] = EVMTypeFromReflect(t.In(i + skipIn))
  1032  	}
  1033  
  1034  	for i := range s.Outputs {
  1035  		s.Outputs[i] = EVMTypeFromReflect(t.Out(i))
  1036  	}
  1037  
  1038  	s.SetFunctionID(fname)
  1039  	return &s
  1040  }
  1041  
  1042  func Signature(name string, args []Argument) (sig string) {
  1043  	sig = name + "("
  1044  	for i, a := range args {
  1045  		if i > 0 {
  1046  			sig += ","
  1047  		}
  1048  		sig += a.EVM.GetSignature()
  1049  		if a.IsArray {
  1050  			if a.ArrayLength > 0 {
  1051  				sig += fmt.Sprintf("[%d]", a.ArrayLength)
  1052  			} else {
  1053  				sig += "[]"
  1054  			}
  1055  		}
  1056  	}
  1057  	sig += ")"
  1058  	return
  1059  }
  1060  
  1061  func (functionSpec *FunctionSpec) SetFunctionID(functionName string) {
  1062  	sig := Signature(functionName, functionSpec.Inputs)
  1063  	functionSpec.FunctionID = GetFunctionID(sig)
  1064  }
  1065  
  1066  func (fs FunctionID) Bytes() []byte {
  1067  	return fs[:]
  1068  }
  1069  
  1070  func GetFunctionID(signature string) (id FunctionID) {
  1071  	hash := sha3.NewKeccak256()
  1072  	hash.Write([]byte(signature))
  1073  	copy(id[:], hash.Sum(nil)[:4])
  1074  	return
  1075  }
  1076  
  1077  func (fs EventID) Bytes() []byte {
  1078  	return fs[:]
  1079  }
  1080  
  1081  func GetEventID(signature string) (id EventID) {
  1082  	hash := sha3.NewKeccak256()
  1083  	hash.Write([]byte(signature))
  1084  	copy(id[:], hash.Sum(nil))
  1085  	return
  1086  }
  1087  
  1088  // UnpackRevert decodes the revert reason if a contract called revert. If no
  1089  // reason was given, message will be nil else it will point to the string
  1090  func UnpackRevert(data []byte) (message *string, err error) {
  1091  	if len(data) > 0 {
  1092  		var msg string
  1093  		err = RevertAbi.UnpackWithID(data, &msg)
  1094  		message = &msg
  1095  	}
  1096  	return
  1097  }
  1098  
  1099  /*
  1100   * Given a eventSpec, get all the fields (topic fields or not)
  1101   */
  1102  func UnpackEvent(eventSpec *EventSpec, topics []burrow_binary.Word256, data []byte, args ...interface{}) error {
  1103  	// First unpack the topic fields
  1104  	topicIndex := 0
  1105  	if !eventSpec.Anonymous {
  1106  		topicIndex++
  1107  	}
  1108  
  1109  	for i, a := range eventSpec.Inputs {
  1110  		if a.Indexed {
  1111  			_, err := a.EVM.unpack(topics[topicIndex].Bytes(), 0, args[i])
  1112  			if err != nil {
  1113  				return err
  1114  			}
  1115  			topicIndex++
  1116  		}
  1117  	}
  1118  
  1119  	// Now unpack the other fields. unpack will step over any indexed fields
  1120  	return unpack(eventSpec.Inputs, data, func(i int) interface{} {
  1121  		return args[i]
  1122  	})
  1123  }
  1124  
  1125  func (abiSpec *AbiSpec) Unpack(data []byte, fname string, args ...interface{}) error {
  1126  	var funcSpec FunctionSpec
  1127  	var argSpec []Argument
  1128  	if fname != "" {
  1129  		if _, ok := abiSpec.Functions[fname]; ok {
  1130  			funcSpec = abiSpec.Functions[fname]
  1131  		} else {
  1132  			funcSpec = abiSpec.Fallback
  1133  		}
  1134  	} else {
  1135  		funcSpec = abiSpec.Constructor
  1136  	}
  1137  
  1138  	argSpec = funcSpec.Outputs
  1139  
  1140  	if argSpec == nil {
  1141  		return fmt.Errorf("Unknown function %s", fname)
  1142  	}
  1143  
  1144  	return unpack(argSpec, data, func(i int) interface{} {
  1145  		return args[i]
  1146  	})
  1147  }
  1148  
  1149  func (abiSpec *AbiSpec) UnpackWithID(data []byte, args ...interface{}) error {
  1150  	var argSpec []Argument
  1151  
  1152  	var id FunctionID
  1153  	copy(id[:], data)
  1154  	for _, fspec := range abiSpec.Functions {
  1155  		if id == fspec.FunctionID {
  1156  			argSpec = fspec.Outputs
  1157  		}
  1158  	}
  1159  
  1160  	if argSpec == nil {
  1161  		return fmt.Errorf("Unknown function %x", id)
  1162  	}
  1163  
  1164  	return unpack(argSpec, data[4:], func(i int) interface{} {
  1165  		return args[i]
  1166  	})
  1167  }
  1168  
  1169  // Pack ABI encodes a function call. The fname specifies which function should called, if
  1170  // it doesn't exist exist the fallback function will be called. If fname is the empty
  1171  // string, the constructor is called. The arguments must be specified in args. The count
  1172  // must match the function being called.
  1173  // Returns the ABI encoded function call, whether the function is constant according
  1174  // to the ABI (which means it does not modified contract state)
  1175  func (abiSpec *AbiSpec) Pack(fname string, args ...interface{}) ([]byte, *FunctionSpec, error) {
  1176  	var funcSpec FunctionSpec
  1177  	var argSpec []Argument
  1178  	if fname != "" {
  1179  		if _, ok := abiSpec.Functions[fname]; ok {
  1180  			funcSpec = abiSpec.Functions[fname]
  1181  		} else {
  1182  			funcSpec = abiSpec.Fallback
  1183  		}
  1184  	} else {
  1185  		funcSpec = abiSpec.Constructor
  1186  	}
  1187  
  1188  	argSpec = funcSpec.Inputs
  1189  
  1190  	if argSpec == nil {
  1191  		if fname == "" {
  1192  			return nil, nil, fmt.Errorf("Contract does not have a constructor")
  1193  		}
  1194  
  1195  		return nil, nil, fmt.Errorf("Unknown function %s", fname)
  1196  	}
  1197  
  1198  	packed := make([]byte, 0)
  1199  
  1200  	if fname != "" {
  1201  		packed = funcSpec.FunctionID[:]
  1202  	}
  1203  
  1204  	packedArgs, err := Pack(argSpec, args...)
  1205  	if err != nil {
  1206  		return nil, nil, err
  1207  	}
  1208  
  1209  	return append(packed, packedArgs...), &funcSpec, nil
  1210  }
  1211  
  1212  func PackIntoStruct(argSpec []Argument, st interface{}) ([]byte, error) {
  1213  	v := reflect.ValueOf(st)
  1214  
  1215  	fields := v.NumField()
  1216  	if fields != len(argSpec) {
  1217  		return nil, fmt.Errorf("%d arguments expected, %d received", len(argSpec), fields)
  1218  	}
  1219  
  1220  	return pack(argSpec, func(i int) interface{} {
  1221  		return v.Field(i).Interface()
  1222  	})
  1223  }
  1224  
  1225  func Pack(argSpec []Argument, args ...interface{}) ([]byte, error) {
  1226  	if len(args) != len(argSpec) {
  1227  		return nil, fmt.Errorf("%d arguments expected, %d received", len(argSpec), len(args))
  1228  	}
  1229  
  1230  	return pack(argSpec, func(i int) interface{} {
  1231  		return args[i]
  1232  	})
  1233  }
  1234  
  1235  func pack(argSpec []Argument, getArg func(int) interface{}) ([]byte, error) {
  1236  	packed := make([]byte, 0)
  1237  	packedDynamic := []byte{}
  1238  	fixedSize := 0
  1239  	// Anything dynamic is stored after the "fixed" block. For the dynamic types, the fixed
  1240  	// block contains byte offsets to the data. We need to know the length of the fixed
  1241  	// block, so we can calcute the offsets
  1242  	for _, a := range argSpec {
  1243  		if a.IsArray {
  1244  			if a.ArrayLength > 0 {
  1245  				fixedSize += ElementSize * int(a.ArrayLength)
  1246  			} else {
  1247  				fixedSize += ElementSize
  1248  			}
  1249  		} else {
  1250  			fixedSize += ElementSize
  1251  		}
  1252  	}
  1253  
  1254  	addArg := func(v interface{}, a Argument) error {
  1255  		var b []byte
  1256  		var err error
  1257  		if a.EVM.Dynamic() {
  1258  			offset := EVMUint{M: 256}
  1259  			b, _ = offset.pack(fixedSize)
  1260  			d, err := a.EVM.pack(v)
  1261  			if err != nil {
  1262  				return err
  1263  			}
  1264  			fixedSize += len(d)
  1265  			packedDynamic = append(packedDynamic, d...)
  1266  		} else {
  1267  			b, err = a.EVM.pack(v)
  1268  			if err != nil {
  1269  				return err
  1270  			}
  1271  		}
  1272  		packed = append(packed, b...)
  1273  		return nil
  1274  	}
  1275  
  1276  	for i, as := range argSpec {
  1277  		a := getArg(i)
  1278  		if as.IsArray {
  1279  			s, ok := a.(string)
  1280  			if ok && s[0:1] == "[" && s[len(s)-1:] == "]" {
  1281  				a = strings.Split(s[1:len(s)-1], ",")
  1282  			}
  1283  
  1284  			val := reflect.ValueOf(a)
  1285  			if val.Kind() != reflect.Slice && val.Kind() != reflect.Array {
  1286  				return nil, fmt.Errorf("argument %d should be array or slice, not %s", i, val.Kind().String())
  1287  			}
  1288  
  1289  			if as.ArrayLength > 0 {
  1290  				if as.ArrayLength != uint64(val.Len()) {
  1291  					return nil, fmt.Errorf("argumment %d should be array of %d, not %d", i, as.ArrayLength, val.Len())
  1292  				}
  1293  
  1294  				for n := 0; n < val.Len(); n++ {
  1295  					err := addArg(val.Index(n).Interface(), as)
  1296  					if err != nil {
  1297  						return nil, err
  1298  					}
  1299  				}
  1300  			} else {
  1301  				// dynamic array
  1302  				offset := EVMUint{M: 256}
  1303  				b, _ := offset.pack(fixedSize)
  1304  				packed = append(packed, b...)
  1305  				fixedSize += len(b)
  1306  
  1307  				// store length
  1308  				b, _ = offset.pack(val.Len())
  1309  				packedDynamic = append(packedDynamic, b...)
  1310  				for n := 0; n < val.Len(); n++ {
  1311  					d, err := as.EVM.pack(val.Index(n).Interface())
  1312  					if err != nil {
  1313  						return nil, err
  1314  					}
  1315  					packedDynamic = append(packedDynamic, d...)
  1316  				}
  1317  			}
  1318  		} else {
  1319  			err := addArg(a, as)
  1320  			if err != nil {
  1321  				return nil, err
  1322  			}
  1323  		}
  1324  	}
  1325  
  1326  	return append(packed, packedDynamic...), nil
  1327  }
  1328  
  1329  func GetPackingTypes(args []Argument) []interface{} {
  1330  	res := make([]interface{}, len(args))
  1331  
  1332  	for i, a := range args {
  1333  		if a.IsArray {
  1334  			t := reflect.TypeOf(a.EVM.getGoType())
  1335  			res[i] = reflect.MakeSlice(reflect.SliceOf(t), int(a.ArrayLength), 0).Interface()
  1336  		} else {
  1337  			res[i] = a.EVM.getGoType()
  1338  		}
  1339  	}
  1340  
  1341  	return res
  1342  }
  1343  
  1344  func UnpackIntoStruct(argSpec []Argument, data []byte, st interface{}) error {
  1345  	v := reflect.ValueOf(st).Elem()
  1346  	return unpack(argSpec, data, func(i int) interface{} {
  1347  		return v.Field(i).Addr().Interface()
  1348  	})
  1349  }
  1350  
  1351  func Unpack(argSpec []Argument, data []byte, args ...interface{}) error {
  1352  	return unpack(argSpec, data, func(i int) interface{} {
  1353  		return args[i]
  1354  	})
  1355  }
  1356  
  1357  func unpack(argSpec []Argument, data []byte, getArg func(int) interface{}) error {
  1358  	offset := 0
  1359  	offType := EVMInt{M: 64}
  1360  
  1361  	getPrimitive := func(e interface{}, a Argument) error {
  1362  		if a.EVM.Dynamic() {
  1363  			var o int64
  1364  			l, err := offType.unpack(data, offset, &o)
  1365  			if err != nil {
  1366  				return err
  1367  			}
  1368  			offset += l
  1369  			l, err = a.EVM.unpack(data, int(o), e)
  1370  			if err != nil {
  1371  				return err
  1372  			}
  1373  		} else {
  1374  			l, err := a.EVM.unpack(data, offset, e)
  1375  			if err != nil {
  1376  				return err
  1377  			}
  1378  			offset += l
  1379  		}
  1380  
  1381  		return nil
  1382  	}
  1383  
  1384  	for i, a := range argSpec {
  1385  		if a.Indexed {
  1386  			continue
  1387  		}
  1388  
  1389  		arg := getArg(i)
  1390  		if a.IsArray {
  1391  			var array *[]interface{}
  1392  
  1393  			array, ok := arg.(*[]interface{})
  1394  			if !ok {
  1395  				if _, ok := arg.(*string); ok {
  1396  					// We have been asked to return the value as a string; make intermediate
  1397  					// array of strings; we will concatenate after
  1398  					intermediate := make([]interface{}, a.ArrayLength)
  1399  					for i, _ := range intermediate {
  1400  						intermediate[i] = new(string)
  1401  					}
  1402  					array = &intermediate
  1403  				} else {
  1404  					return fmt.Errorf("argument %d should be array, slice or string", i)
  1405  				}
  1406  			}
  1407  
  1408  			if a.ArrayLength > 0 {
  1409  				if int(a.ArrayLength) != len(*array) {
  1410  					return fmt.Errorf("argument %d should be array or slice of %d elements", i, a.ArrayLength)
  1411  				}
  1412  
  1413  				for n := 0; n < len(*array); n++ {
  1414  					err := getPrimitive((*array)[n], a)
  1415  					if err != nil {
  1416  						return err
  1417  					}
  1418  				}
  1419  			} else {
  1420  				var o int64
  1421  				var length int64
  1422  
  1423  				l, err := offType.unpack(data, offset, &o)
  1424  				if err != nil {
  1425  					return err
  1426  				}
  1427  
  1428  				offset += l
  1429  				s, err := offType.unpack(data, int(o), &length)
  1430  				if err != nil {
  1431  					return err
  1432  				}
  1433  				o += int64(s)
  1434  
  1435  				intermediate := make([]interface{}, length)
  1436  
  1437  				if _, ok := arg.(*string); ok {
  1438  					// We have been asked to return the value as a string; make intermediate
  1439  					// array of strings; we will concatenate after
  1440  					for i, _ := range intermediate {
  1441  						intermediate[i] = new(string)
  1442  					}
  1443  				} else {
  1444  					for i, _ := range intermediate {
  1445  						intermediate[i] = a.EVM.getGoType()
  1446  					}
  1447  				}
  1448  
  1449  				for i := 0; i < int(length); i++ {
  1450  					l, err = a.EVM.unpack(data, int(o), intermediate[i])
  1451  					if err != nil {
  1452  						return err
  1453  					}
  1454  					o += int64(l)
  1455  				}
  1456  
  1457  				array = &intermediate
  1458  			}
  1459  
  1460  			// If we were supposed to return a string, convert it back
  1461  			if ret, ok := arg.(*string); ok {
  1462  				s := "["
  1463  				for i, e := range *array {
  1464  					if i > 0 {
  1465  						s += ","
  1466  					}
  1467  					s += *(e.(*string))
  1468  				}
  1469  				s += "]"
  1470  				*ret = s
  1471  			}
  1472  		} else {
  1473  			err := getPrimitive(arg, a)
  1474  			if err != nil {
  1475  				return err
  1476  			}
  1477  		}
  1478  	}
  1479  
  1480  	return nil
  1481  }
  1482  
  1483  // quick helper padding
  1484  func pad(input []byte, size int, left bool) []byte {
  1485  	if len(input) >= size {
  1486  		return input[:size]
  1487  	}
  1488  	padded := make([]byte, size)
  1489  	if left {
  1490  		copy(padded[size-len(input):], input)
  1491  	} else {
  1492  		copy(padded, input)
  1493  	}
  1494  	return padded
  1495  }