github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/execution/evm/abi/primitives.go (about)

     1  package abi
     2  
     3  import (
     4  	"encoding/binary"
     5  	"fmt"
     6  	"math/big"
     7  	"reflect"
     8  	"strings"
     9  	"unsafe" // just for Sizeof
    10  
    11  	"github.com/hyperledger/burrow/crypto"
    12  )
    13  
    14  // EVM Solidity calls and return values are packed into
    15  // pieces of 32 bytes, including a bool (wasting 255 out of 256 bits)
    16  const ElementSize = 32
    17  
    18  type EVMType interface {
    19  	GetSignature() string
    20  	getGoType() interface{}
    21  	pack(v interface{}) ([]byte, error)
    22  	unpack(data []byte, offset int, v interface{}) (int, error)
    23  	Dynamic() bool
    24  	ImplicitCast(o EVMType) bool
    25  }
    26  
    27  var _ EVMType = (*EVMBool)(nil)
    28  
    29  type EVMBool struct {
    30  }
    31  
    32  func (e EVMBool) String() string {
    33  	return "EVMBool"
    34  }
    35  
    36  func (e EVMBool) GetSignature() string {
    37  	return "bool"
    38  }
    39  
    40  func (e EVMBool) getGoType() interface{} {
    41  	return new(bool)
    42  }
    43  
    44  func (e EVMBool) pack(v interface{}) ([]byte, error) {
    45  	var b bool
    46  	arg := reflect.ValueOf(v)
    47  	if arg.Kind() == reflect.String {
    48  		val := arg.String()
    49  		if strings.EqualFold(val, "true") || val == "1" {
    50  			b = true
    51  		} else if strings.EqualFold(val, "false") || val == "0" {
    52  			b = false
    53  		} else {
    54  			return nil, fmt.Errorf("%s is not a valid value for EVM Bool type", val)
    55  		}
    56  	} else if arg.Kind() == reflect.Bool {
    57  		b = arg.Bool()
    58  	} else {
    59  		return nil, fmt.Errorf("%s cannot be converted to EVM Bool type", arg.Kind().String())
    60  	}
    61  	res := make([]byte, ElementSize)
    62  	if b {
    63  		res[ElementSize-1] = 1
    64  	}
    65  	return res, nil
    66  }
    67  
    68  func (e EVMBool) unpack(data []byte, offset int, v interface{}) (int, error) {
    69  	if len(data)-offset < 32 {
    70  		return 0, fmt.Errorf("%v: not enough data", e)
    71  	}
    72  	data = data[offset:]
    73  	switch v := v.(type) {
    74  	case *string:
    75  		if data[ElementSize-1] == 1 {
    76  			*v = "true"
    77  		} else if data[ElementSize-1] == 0 {
    78  			*v = "false"
    79  		} else {
    80  			return 0, fmt.Errorf("unexpected value for EVM bool")
    81  		}
    82  	case *int8:
    83  		*v = int8(data[ElementSize-1])
    84  	case *int16:
    85  		*v = int16(data[ElementSize-1])
    86  	case *int32:
    87  		*v = int32(data[ElementSize-1])
    88  	case *int64:
    89  		*v = int64(data[ElementSize-1])
    90  	case *int:
    91  		*v = int(data[ElementSize-1])
    92  	case *uint8:
    93  		*v = uint8(data[ElementSize-1])
    94  	case *uint16:
    95  		*v = uint16(data[ElementSize-1])
    96  	case *uint32:
    97  		*v = uint32(data[ElementSize-1])
    98  	case *uint64:
    99  		*v = uint64(data[ElementSize-1])
   100  	case *uint:
   101  		*v = uint(data[ElementSize-1])
   102  	case *bool:
   103  		*v = data[ElementSize-1] == 1
   104  	default:
   105  		return 0, fmt.Errorf("cannot set type %s for EVM bool", reflect.ValueOf(v).Kind().String())
   106  	}
   107  	return 32, nil
   108  }
   109  
   110  func (e EVMBool) Dynamic() bool {
   111  	return false
   112  }
   113  
   114  func (e EVMBool) ImplicitCast(o EVMType) bool {
   115  	return false
   116  }
   117  
   118  var _ EVMType = (*EVMUint)(nil)
   119  
   120  type EVMUint struct {
   121  	M uint64
   122  }
   123  
   124  func (e EVMUint) GetSignature() string {
   125  	return fmt.Sprintf("uint%d", e.M)
   126  }
   127  
   128  func (e EVMUint) getGoType() interface{} {
   129  	switch e.M {
   130  	case 8:
   131  		return new(uint8)
   132  	case 16:
   133  		return new(uint16)
   134  	case 32:
   135  		return new(uint32)
   136  	case 64:
   137  		return new(uint64)
   138  	default:
   139  		return new(big.Int)
   140  	}
   141  }
   142  
   143  func (e EVMUint) pack(v interface{}) ([]byte, error) {
   144  	n := new(big.Int)
   145  
   146  	arg := reflect.ValueOf(v)
   147  	switch arg.Kind() {
   148  	case reflect.String:
   149  		_, ok := n.SetString(arg.String(), 0)
   150  		if !ok {
   151  			return nil, fmt.Errorf("Failed to parse `%s", arg.String())
   152  		}
   153  		if n.Sign() < 0 {
   154  			return nil, fmt.Errorf("negative value not allowed for uint%d", e.M)
   155  		}
   156  	case reflect.Uint8:
   157  		fallthrough
   158  	case reflect.Uint16:
   159  		fallthrough
   160  	case reflect.Uint32:
   161  		fallthrough
   162  	case reflect.Uint64:
   163  		fallthrough
   164  	case reflect.Uint:
   165  		n.SetUint64(arg.Uint())
   166  	case reflect.Int8:
   167  		fallthrough
   168  	case reflect.Int16:
   169  		fallthrough
   170  	case reflect.Int32:
   171  		fallthrough
   172  	case reflect.Int64:
   173  		fallthrough
   174  	case reflect.Int:
   175  		x := arg.Int()
   176  		if x < 0 {
   177  			return nil, fmt.Errorf("negative value not allowed for uint%d", e.M)
   178  		}
   179  		n.SetInt64(x)
   180  	default:
   181  		t := reflect.TypeOf(new(uint64))
   182  		if reflect.TypeOf(v).ConvertibleTo(t) {
   183  			n.SetUint64(reflect.ValueOf(v).Convert(t).Uint())
   184  		} else {
   185  			return nil, fmt.Errorf("cannot convert type %s to uint%d", arg.Kind().String(), e.M)
   186  		}
   187  	}
   188  
   189  	b := n.Bytes()
   190  	if uint64(len(b)) > e.M {
   191  		return nil, fmt.Errorf("value too large for int%d", e.M)
   192  	}
   193  	return pad(b, ElementSize, true), nil
   194  }
   195  
   196  func (e EVMUint) unpack(data []byte, offset int, v interface{}) (int, error) {
   197  	if len(data)-offset < ElementSize {
   198  		return 0, fmt.Errorf("%v: not enough data", e)
   199  	}
   200  
   201  	data = data[offset:]
   202  	empty := 0
   203  	for empty = 0; empty < ElementSize; empty++ {
   204  		if data[empty] != 0 {
   205  			break
   206  		}
   207  	}
   208  
   209  	length := ElementSize - empty
   210  
   211  	switch v := v.(type) {
   212  	case *string:
   213  		b := new(big.Int)
   214  		b.SetBytes(data[empty:ElementSize])
   215  		*v = b.String()
   216  	case *big.Int:
   217  		b := new(big.Int)
   218  		*v = *b.SetBytes(data[0:ElementSize])
   219  	case *uint64:
   220  		maxLen := int(unsafe.Sizeof(*v))
   221  		if length > maxLen {
   222  			return 0, fmt.Errorf("value too large for uint64")
   223  		}
   224  		*v = binary.BigEndian.Uint64(data[ElementSize-maxLen : ElementSize])
   225  	case *uint32:
   226  		maxLen := int(unsafe.Sizeof(*v))
   227  		if length > maxLen {
   228  			return 0, fmt.Errorf("value too large for uint64")
   229  		}
   230  		*v = binary.BigEndian.Uint32(data[ElementSize-maxLen : ElementSize])
   231  	case *uint16:
   232  		maxLen := int(unsafe.Sizeof(*v))
   233  		if length > maxLen {
   234  			return 0, fmt.Errorf("value too large for uint16")
   235  		}
   236  		*v = binary.BigEndian.Uint16(data[ElementSize-maxLen : ElementSize])
   237  	case *uint8:
   238  		maxLen := 1
   239  		if length > maxLen {
   240  			return 0, fmt.Errorf("value too large for uint8")
   241  		}
   242  		*v = uint8(data[31])
   243  	case *int64:
   244  		maxLen := int(unsafe.Sizeof(*v))
   245  		if length > maxLen || (data[ElementSize-maxLen]&0x80) != 0 {
   246  			return 0, fmt.Errorf("value too large for int64")
   247  		}
   248  		*v = int64(binary.BigEndian.Uint64(data[ElementSize-maxLen : ElementSize]))
   249  	case *int32:
   250  		maxLen := int(unsafe.Sizeof(*v))
   251  		if length > maxLen || (data[ElementSize-maxLen]&0x80) != 0 {
   252  			return 0, fmt.Errorf("value too large for int32")
   253  		}
   254  		*v = int32(binary.BigEndian.Uint32(data[ElementSize-maxLen : ElementSize]))
   255  	case *int16:
   256  		maxLen := int(unsafe.Sizeof(*v))
   257  		if length > maxLen || (data[ElementSize-maxLen]&0x80) != 0 {
   258  			return 0, fmt.Errorf("value too large for int16")
   259  		}
   260  		*v = int16(binary.BigEndian.Uint16(data[ElementSize-maxLen : ElementSize]))
   261  	case *int8:
   262  		maxLen := 1
   263  		if length > maxLen || (data[ElementSize-maxLen]&0x80) != 0 {
   264  			return 0, fmt.Errorf("value too large for int8")
   265  		}
   266  		*v = int8(data[ElementSize-1])
   267  	default:
   268  		return 0, fmt.Errorf("unable to convert %s to %s", e.GetSignature(), reflect.ValueOf(v).Kind().String())
   269  	}
   270  
   271  	return 32, nil
   272  }
   273  
   274  func (e EVMUint) Dynamic() bool {
   275  	return false
   276  }
   277  
   278  func (e EVMUint) String() string {
   279  	return fmt.Sprintf("EVMUInt{%v}", e.M)
   280  }
   281  
   282  var _ EVMType = (*EVMInt)(nil)
   283  
   284  type EVMInt struct {
   285  	M uint64
   286  }
   287  
   288  func (e EVMInt) String() string {
   289  	return fmt.Sprintf("EVMInt{%v}", e.M)
   290  }
   291  
   292  func (e EVMInt) getGoType() interface{} {
   293  	switch e.M {
   294  	case 8:
   295  		return new(int8)
   296  	case 16:
   297  		return new(int16)
   298  	case 32:
   299  		return new(int32)
   300  	case 64:
   301  		return new(int64)
   302  	default:
   303  		return new(big.Int)
   304  	}
   305  }
   306  
   307  func (e EVMInt) ImplicitCast(o EVMType) bool {
   308  	i, ok := o.(EVMInt)
   309  	return ok && i.M >= e.M
   310  }
   311  
   312  func (e EVMInt) GetSignature() string {
   313  	return fmt.Sprintf("int%d", e.M)
   314  }
   315  
   316  func (e EVMInt) pack(v interface{}) ([]byte, error) {
   317  	n := new(big.Int)
   318  
   319  	switch arg := v.(type) {
   320  	case *big.Int:
   321  		n.Set(arg)
   322  	case string:
   323  		_, ok := n.SetString(arg, 0)
   324  		if !ok {
   325  			return nil, fmt.Errorf("failed to parse `%s", arg)
   326  		}
   327  	case uint:
   328  		n.SetUint64(uint64(arg))
   329  	case uint8:
   330  		n.SetUint64(uint64(arg))
   331  	case uint16:
   332  		n.SetUint64(uint64(arg))
   333  	case uint32:
   334  		n.SetUint64(uint64(arg))
   335  	case uint64:
   336  		n.SetUint64(arg)
   337  	case int:
   338  		n.SetInt64(int64(arg))
   339  	case int8:
   340  		n.SetInt64(int64(arg))
   341  	case int16:
   342  		n.SetInt64(int64(arg))
   343  	case int32:
   344  		n.SetInt64(int64(arg))
   345  	case int64:
   346  		n.SetInt64(arg)
   347  	default:
   348  		t := reflect.TypeOf(new(int64))
   349  		if reflect.TypeOf(v).ConvertibleTo(t) {
   350  			n.SetInt64(reflect.ValueOf(v).Convert(t).Int())
   351  		} else {
   352  			return nil, fmt.Errorf("cannot convert type %v to int%d", v, e.M)
   353  		}
   354  	}
   355  
   356  	b := n.Bytes()
   357  	if uint64(len(b)) > e.M {
   358  		return nil, fmt.Errorf("value too large for int%d", e.M)
   359  	}
   360  	res := pad(b, ElementSize, true)
   361  	if (res[0] & 0x80) != 0 {
   362  		return nil, fmt.Errorf("value too large for int%d", e.M)
   363  	}
   364  	if n.Sign() < 0 {
   365  		// One's complement; i.e. 0xffff is -1, not 0.
   366  		n.Add(n, big.NewInt(1))
   367  		b := n.Bytes()
   368  		res = pad(b, ElementSize, true)
   369  		for i := 0; i < len(res); i++ {
   370  			res[i] = ^res[i]
   371  		}
   372  	}
   373  	return res, nil
   374  }
   375  
   376  func (e EVMInt) unpack(data []byte, offset int, v interface{}) (int, error) {
   377  	if len(data)-offset < ElementSize {
   378  		return 0, fmt.Errorf("%v: not enough data", e)
   379  	}
   380  
   381  	data = data[offset:]
   382  	sign := (data[0] & 0x80) != 0
   383  
   384  	empty := 0
   385  	for empty = 0; empty < ElementSize; empty++ {
   386  		if (sign && data[empty] != 255) || (!sign && data[empty] != 0) {
   387  			break
   388  		}
   389  	}
   390  
   391  	length := ElementSize - empty
   392  	inv := make([]byte, ElementSize)
   393  	for i := 0; i < ElementSize; i++ {
   394  		if sign {
   395  			inv[i] = ^data[i]
   396  		} else {
   397  			inv[i] = data[i]
   398  		}
   399  	}
   400  
   401  	switch v := v.(type) {
   402  	case **big.Int:
   403  		b := new(big.Int).SetBytes(inv[empty:ElementSize])
   404  		if sign {
   405  			*v = b.Sub(big.NewInt(-1), b)
   406  		} else {
   407  			*v = b
   408  		}
   409  	case *string:
   410  		b := new(big.Int)
   411  		b.SetBytes(inv[empty:ElementSize])
   412  		if sign {
   413  			*v = b.Sub(big.NewInt(-1), b).String()
   414  		} else {
   415  			*v = b.String()
   416  		}
   417  	case *big.Int:
   418  		b := new(big.Int)
   419  		b.SetBytes(inv[0:ElementSize])
   420  		if sign {
   421  			*v = *b.Sub(big.NewInt(-1), b)
   422  		} else {
   423  			*v = *b
   424  		}
   425  	case *uint64:
   426  		if sign {
   427  			return 0, fmt.Errorf("cannot convert negative EVM int to %T", *v)
   428  		}
   429  		maxLen := int(unsafe.Sizeof(*v))
   430  		if length > maxLen {
   431  			return 0, fmt.Errorf("value too large for %T", *v)
   432  		}
   433  		*v = binary.BigEndian.Uint64(data[ElementSize-maxLen : ElementSize])
   434  	case *uint32:
   435  		if sign {
   436  			return 0, fmt.Errorf("cannot convert negative EVM int to %T", *v)
   437  		}
   438  		maxLen := int(unsafe.Sizeof(*v))
   439  		if length > maxLen {
   440  			return 0, fmt.Errorf("value too large for %T", *v)
   441  		}
   442  		*v = binary.BigEndian.Uint32(data[ElementSize-maxLen : ElementSize])
   443  	case *uint16:
   444  		if sign {
   445  			return 0, fmt.Errorf("cannot convert negative EVM int to %T", *v)
   446  		}
   447  		maxLen := int(unsafe.Sizeof(*v))
   448  		if length > maxLen {
   449  			return 0, fmt.Errorf("value too large for %T", *v)
   450  		}
   451  		*v = binary.BigEndian.Uint16(data[ElementSize-maxLen : ElementSize])
   452  	case *uint8:
   453  		if sign {
   454  			return 0, fmt.Errorf("cannot convert negative EVM int to %T", *v)
   455  		}
   456  		if length > 1 {
   457  			return 0, fmt.Errorf("value too large for %T", *v)
   458  		}
   459  		*v = data[ElementSize-1]
   460  	case *int64:
   461  		maxLen := int(unsafe.Sizeof(*v))
   462  		if length > maxLen || (inv[ElementSize-maxLen]&0x80) != 0 {
   463  			return 0, fmt.Errorf("value too large for %T", *v)
   464  		}
   465  		*v = int64(binary.BigEndian.Uint64(data[ElementSize-maxLen : ElementSize]))
   466  	case *int32:
   467  		maxLen := int(unsafe.Sizeof(*v))
   468  		if length > maxLen || (inv[ElementSize-maxLen]&0x80) != 0 {
   469  			return 0, fmt.Errorf("value too large for %T", *v)
   470  		}
   471  		*v = int32(binary.BigEndian.Uint32(data[ElementSize-maxLen : ElementSize]))
   472  	case *int16:
   473  		maxLen := int(unsafe.Sizeof(*v))
   474  		if length > maxLen || (inv[ElementSize-maxLen]&0x80) != 0 {
   475  			return 0, fmt.Errorf("value too large for %T", *v)
   476  		}
   477  		*v = int16(binary.BigEndian.Uint16(data[ElementSize-maxLen : ElementSize]))
   478  	case *int8:
   479  		if length > 1 || (inv[ElementSize-1]&0x80) != 0 {
   480  			return 0, fmt.Errorf("value too large for %T", *v)
   481  		}
   482  		*v = int8(data[ElementSize-1])
   483  	default:
   484  		return 0, fmt.Errorf("unable to convert %s to %T", e.GetSignature(), v)
   485  	}
   486  
   487  	return ElementSize, nil
   488  }
   489  
   490  func (e EVMInt) Dynamic() bool {
   491  	return false
   492  }
   493  
   494  func (e EVMUint) ImplicitCast(o EVMType) bool {
   495  	u, ok := o.(EVMUint)
   496  	return ok && u.M >= e.M
   497  }
   498  
   499  var _ EVMType = (*EVMAddress)(nil)
   500  
   501  type EVMAddress struct {
   502  }
   503  
   504  func (e EVMAddress) String() string {
   505  	return "EVMAddress"
   506  }
   507  
   508  func (e EVMAddress) getGoType() interface{} {
   509  	return new(crypto.Address)
   510  }
   511  
   512  func (e EVMAddress) GetSignature() string {
   513  	return "address"
   514  }
   515  
   516  func (e EVMAddress) pack(v interface{}) ([]byte, error) {
   517  	var bs []byte
   518  	switch a := v.(type) {
   519  	case crypto.Address:
   520  		bs = a[:]
   521  	case *crypto.Address:
   522  		bs = (*a)[:]
   523  	case string:
   524  		address, err := crypto.AddressFromHexString(a)
   525  		if err != nil {
   526  			return nil, fmt.Errorf("could not convert '%s' to address: %v", a, err)
   527  		}
   528  		bs = address[:]
   529  	case []byte:
   530  		address, err := crypto.AddressFromBytes(a)
   531  		if err != nil {
   532  			return nil, fmt.Errorf("could not convert byte 0x%X to address: %v", a, err)
   533  		}
   534  		bs = address[:]
   535  	default:
   536  		return nil, fmt.Errorf("cannot map from %s to EVM address", reflect.ValueOf(v).Kind().String())
   537  	}
   538  	return pad(bs, ElementSize, true), nil
   539  }
   540  
   541  func (e EVMAddress) unpack(data []byte, offset int, v interface{}) (int, error) {
   542  	if len(data)-offset < ElementSize {
   543  		return 0, fmt.Errorf("%v: not enough data", e)
   544  	}
   545  	addr, err := crypto.AddressFromBytes(data[offset+ElementSize-crypto.AddressLength : offset+ElementSize])
   546  	if err != nil {
   547  		return 0, err
   548  	}
   549  	switch v := v.(type) {
   550  	case *string:
   551  		*v = addr.String()
   552  	case *crypto.Address:
   553  		*v = addr
   554  	case *([]byte):
   555  		*v = data[offset+ElementSize-crypto.AddressLength : offset+ElementSize]
   556  	default:
   557  		return 0, fmt.Errorf("cannot map EVM address to %s", reflect.ValueOf(v).Kind().String())
   558  	}
   559  
   560  	return ElementSize, nil
   561  }
   562  
   563  func (e EVMAddress) Dynamic() bool {
   564  	return false
   565  }
   566  
   567  func (e EVMAddress) ImplicitCast(o EVMType) bool {
   568  	return false
   569  }
   570  
   571  var _ EVMType = (*EVMBytes)(nil)
   572  
   573  type EVMBytes struct {
   574  	M uint64
   575  }
   576  
   577  func (e EVMBytes) String() string {
   578  	if e.M == 0 {
   579  		return "EVMBytes"
   580  	}
   581  	return fmt.Sprintf("EVMBytes[%v]", e.M)
   582  }
   583  
   584  func (e EVMBytes) getGoType() interface{} {
   585  	v := make([]byte, e.M)
   586  	return &v
   587  }
   588  
   589  func (e EVMBytes) pack(v interface{}) ([]byte, error) {
   590  	b, ok := v.([]byte)
   591  	if !ok {
   592  		s, ok := v.(string)
   593  		if ok {
   594  			b = []byte(s)
   595  		} else {
   596  			return nil, fmt.Errorf("cannot map from %s to EVM bytes", reflect.ValueOf(v).Kind().String())
   597  		}
   598  	}
   599  
   600  	if e.M > 0 {
   601  		if uint64(len(b)) > e.M {
   602  			return nil, fmt.Errorf("[%d]byte to long for %s", len(b), e.GetSignature())
   603  		}
   604  		return pad(b, ElementSize, false), nil
   605  	} else {
   606  		length := EVMUint{M: 256}
   607  		p, err := length.pack(len(b))
   608  		if err != nil {
   609  			return nil, err
   610  		}
   611  		for i := 0; i < len(b); i += ElementSize {
   612  			a := b[i:]
   613  			if len(a) == 0 {
   614  				break
   615  			}
   616  			p = append(p, pad(a, ElementSize, false)...)
   617  		}
   618  
   619  		return p, nil
   620  	}
   621  }
   622  
   623  func (e EVMBytes) unpack(data []byte, offset int, v interface{}) (int, error) {
   624  	if len(data)-offset < ElementSize {
   625  		return 0, fmt.Errorf("%v: not enough data", e)
   626  	}
   627  	if e.M == 0 {
   628  		s := EVMString{}
   629  
   630  		return s.unpack(data, offset, v)
   631  	}
   632  
   633  	v2 := reflect.ValueOf(v).Elem()
   634  	switch v2.Type().Kind() {
   635  	case reflect.String:
   636  		start := 0
   637  		end := int(e.M)
   638  
   639  		for start < ElementSize-1 && data[offset+start] == 0 && start < end {
   640  			start++
   641  		}
   642  		for end > start && data[offset+end-1] == 0 {
   643  			end--
   644  		}
   645  		v2.SetString(string(data[offset+start : offset+end]))
   646  	case reflect.Array:
   647  		fallthrough
   648  	case reflect.Slice:
   649  		v2.SetBytes(data[offset : offset+int(e.M)])
   650  	default:
   651  		return 0, fmt.Errorf("cannot map EVM %s to %v", e.GetSignature(), reflect.ValueOf(v).Kind())
   652  	}
   653  
   654  	return ElementSize, nil
   655  }
   656  
   657  func (e EVMBytes) Dynamic() bool {
   658  	return e.M == 0
   659  }
   660  
   661  func (e EVMBytes) GetSignature() string {
   662  	if e.M > 0 {
   663  		return fmt.Sprintf("bytes%d", e.M)
   664  	} else {
   665  		return "bytes"
   666  	}
   667  }
   668  
   669  func (e EVMBytes) ImplicitCast(o EVMType) bool {
   670  	return false
   671  }
   672  
   673  var _ EVMType = (*EVMString)(nil)
   674  
   675  type EVMString struct {
   676  }
   677  
   678  func (e EVMString) String() string {
   679  	return "EVMString"
   680  }
   681  
   682  func (e EVMString) GetSignature() string {
   683  	return "string"
   684  }
   685  
   686  func (e EVMString) getGoType() interface{} {
   687  	return new(string)
   688  }
   689  
   690  func (e EVMString) pack(v interface{}) ([]byte, error) {
   691  	b := EVMBytes{M: 0}
   692  
   693  	return b.pack(v)
   694  }
   695  
   696  func (e EVMString) unpack(data []byte, offset int, v interface{}) (int, error) {
   697  	lenType := EVMInt{M: 64}
   698  	var length int64
   699  	l, err := lenType.unpack(data, offset, &length)
   700  	if err != nil {
   701  		return 0, fmt.Errorf("could not unpack string length prefix: %v", err)
   702  	}
   703  	offset += l
   704  
   705  	switch v := v.(type) {
   706  	case *string:
   707  		*v = string(data[offset : offset+int(length)])
   708  	case *[]byte:
   709  		*v = data[offset : offset+int(length)]
   710  	default:
   711  		return 0, fmt.Errorf("cannot map EVM string to %s", reflect.ValueOf(v).Kind().String())
   712  	}
   713  
   714  	return ElementSize, nil
   715  }
   716  
   717  func (e EVMString) Dynamic() bool {
   718  	return true
   719  }
   720  
   721  func (e EVMString) ImplicitCast(o EVMType) bool {
   722  	return false
   723  }
   724  
   725  var _ EVMType = (*EVMFixed)(nil)
   726  
   727  type EVMFixed struct {
   728  	N, M   uint64
   729  	signed bool
   730  }
   731  
   732  func (e EVMFixed) getGoType() interface{} {
   733  	// This is not right, obviously
   734  	return new(big.Float)
   735  }
   736  
   737  func (e EVMFixed) GetSignature() string {
   738  	if e.signed {
   739  		return fmt.Sprintf("fixed%dx%d", e.M, e.N)
   740  	} else {
   741  		return fmt.Sprintf("ufixed%dx%d", e.M, e.N)
   742  	}
   743  }
   744  
   745  func (e EVMFixed) pack(v interface{}) ([]byte, error) {
   746  	// The ABI spec does not describe how this should be packed; go-ethereum abi does not implement this
   747  	// need to dig in solidity to find out how this is packed
   748  	return nil, fmt.Errorf("packing of %s not implemented, patches welcome", e.GetSignature())
   749  }
   750  
   751  func (e EVMFixed) unpack(data []byte, offset int, v interface{}) (int, error) {
   752  	// The ABI spec does not describe how this should be packed; go-ethereum abi does not implement this
   753  	// need to dig in solidity to find out how this is packed
   754  	return 0, fmt.Errorf("unpacking of %s not implemented, patches welcome", e.GetSignature())
   755  }
   756  
   757  func (e EVMFixed) Dynamic() bool {
   758  	return false
   759  }
   760  
   761  func (e EVMFixed) ImplicitCast(o EVMType) bool {
   762  	return false
   763  }
   764  
   765  // quick helper padding
   766  func pad(input []byte, size int, left bool) []byte {
   767  	if len(input) >= size {
   768  		return input[:size]
   769  	}
   770  	padded := make([]byte, size)
   771  	if left {
   772  		copy(padded[size-len(input):], input)
   773  	} else {
   774  		copy(padded, input)
   775  	}
   776  	return padded
   777  }