github.com/digdeepmining/go-atheios@v1.5.13-0.20180902133602-d5687a2e6f43/accounts/abi/abi.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  	"encoding/json"
    21  	"fmt"
    22  	"io"
    23  	"math/big"
    24  	"reflect"
    25  	"strings"
    26  
    27  	"github.com/atheioschain/go-atheios/common"
    28  )
    29  
    30  // The ABI holds information about a contract's context and available
    31  // invokable methods. It will allow you to type check function calls and
    32  // packs data accordingly.
    33  type ABI struct {
    34  	Constructor Method
    35  	Methods     map[string]Method
    36  	Events      map[string]Event
    37  }
    38  
    39  // JSON returns a parsed ABI interface and error if it failed.
    40  func JSON(reader io.Reader) (ABI, error) {
    41  	dec := json.NewDecoder(reader)
    42  
    43  	var abi ABI
    44  	if err := dec.Decode(&abi); err != nil {
    45  		return ABI{}, err
    46  	}
    47  
    48  	return abi, nil
    49  }
    50  
    51  // Pack the given method name to conform the ABI. Method call's data
    52  // will consist of method_id, args0, arg1, ... argN. Method id consists
    53  // of 4 bytes and arguments are all 32 bytes.
    54  // Method ids are created from the first 4 bytes of the hash of the
    55  // methods string signature. (signature = baz(uint32,string32))
    56  func (abi ABI) Pack(name string, args ...interface{}) ([]byte, error) {
    57  	// Fetch the ABI of the requested method
    58  	var method Method
    59  
    60  	if name == "" {
    61  		method = abi.Constructor
    62  	} else {
    63  		m, exist := abi.Methods[name]
    64  		if !exist {
    65  			return nil, fmt.Errorf("method '%s' not found", name)
    66  		}
    67  		method = m
    68  	}
    69  	arguments, err := method.pack(method, args...)
    70  	if err != nil {
    71  		return nil, err
    72  	}
    73  	// Pack up the method ID too if not a constructor and return
    74  	if name == "" {
    75  		return arguments, nil
    76  	}
    77  	return append(method.Id(), arguments...), nil
    78  }
    79  
    80  // toGoSliceType parses the input and casts it to the proper slice defined by the ABI
    81  // argument in T.
    82  func toGoSlice(i int, t Argument, output []byte) (interface{}, error) {
    83  	index := i * 32
    84  	// The slice must, at very least be large enough for the index+32 which is exactly the size required
    85  	// for the [offset in output, size of offset].
    86  	if index+32 > len(output) {
    87  		return nil, fmt.Errorf("abi: cannot marshal in to go slice: insufficient size output %d require %d", len(output), index+32)
    88  	}
    89  	elem := t.Type.Elem
    90  
    91  	// first we need to create a slice of the type
    92  	var refSlice reflect.Value
    93  	switch elem.T {
    94  	case IntTy, UintTy, BoolTy:
    95  		// create a new reference slice matching the element type
    96  		switch t.Type.Kind {
    97  		case reflect.Bool:
    98  			refSlice = reflect.ValueOf([]bool(nil))
    99  		case reflect.Uint8:
   100  			refSlice = reflect.ValueOf([]uint8(nil))
   101  		case reflect.Uint16:
   102  			refSlice = reflect.ValueOf([]uint16(nil))
   103  		case reflect.Uint32:
   104  			refSlice = reflect.ValueOf([]uint32(nil))
   105  		case reflect.Uint64:
   106  			refSlice = reflect.ValueOf([]uint64(nil))
   107  		case reflect.Int8:
   108  			refSlice = reflect.ValueOf([]int8(nil))
   109  		case reflect.Int16:
   110  			refSlice = reflect.ValueOf([]int16(nil))
   111  		case reflect.Int32:
   112  			refSlice = reflect.ValueOf([]int32(nil))
   113  		case reflect.Int64:
   114  			refSlice = reflect.ValueOf([]int64(nil))
   115  		default:
   116  			refSlice = reflect.ValueOf([]*big.Int(nil))
   117  		}
   118  	case AddressTy: // address must be of slice Address
   119  		refSlice = reflect.ValueOf([]common.Address(nil))
   120  	case HashTy: // hash must be of slice hash
   121  		refSlice = reflect.ValueOf([]common.Hash(nil))
   122  	case FixedBytesTy:
   123  		refSlice = reflect.ValueOf([][]byte(nil))
   124  	default: // no other types are supported
   125  		return nil, fmt.Errorf("abi: unsupported slice type %v", elem.T)
   126  	}
   127  
   128  	var slice []byte
   129  	var size int
   130  	var offset int
   131  	if t.Type.IsSlice {
   132  
   133  		// get the offset which determines the start of this array ...
   134  		offset = int(common.BytesToBig(output[index : index+32]).Uint64())
   135  		if offset+32 > len(output) {
   136  			return nil, fmt.Errorf("abi: cannot marshal in to go slice: offset %d would go over slice boundary (len=%d)", len(output), offset+32)
   137  		}
   138  
   139  		slice = output[offset:]
   140  		// ... starting with the size of the array in elements ...
   141  		size = int(common.BytesToBig(slice[:32]).Uint64())
   142  		slice = slice[32:]
   143  		// ... and make sure that we've at the very least the amount of bytes
   144  		// available in the buffer.
   145  		if size*32 > len(slice) {
   146  			return nil, fmt.Errorf("abi: cannot marshal in to go slice: insufficient size output %d require %d", len(output), offset+32+size*32)
   147  		}
   148  
   149  		// reslice to match the required size
   150  		slice = slice[:(size * 32)]
   151  	} else if t.Type.IsArray {
   152  		//get the number of elements in the array
   153  		size = t.Type.SliceSize
   154  
   155  		//check to make sure array size matches up
   156  		if index+32*size > len(output) {
   157  			return nil, fmt.Errorf("abi: cannot marshal in to go array: offset %d would go over slice boundary (len=%d)", len(output), index+32*size)
   158  		}
   159  		//slice is there for a fixed amount of times
   160  		slice = output[index : index+size*32]
   161  	}
   162  
   163  	for i := 0; i < size; i++ {
   164  		var (
   165  			inter        interface{}             // interface type
   166  			returnOutput = slice[i*32 : i*32+32] // the return output
   167  		)
   168  
   169  		// set inter to the correct type (cast)
   170  		switch elem.T {
   171  		case IntTy, UintTy:
   172  			bigNum := common.BytesToBig(returnOutput)
   173  			switch t.Type.Kind {
   174  			case reflect.Uint8:
   175  				inter = uint8(bigNum.Uint64())
   176  			case reflect.Uint16:
   177  				inter = uint16(bigNum.Uint64())
   178  			case reflect.Uint32:
   179  				inter = uint32(bigNum.Uint64())
   180  			case reflect.Uint64:
   181  				inter = bigNum.Uint64()
   182  			case reflect.Int8:
   183  				inter = int8(bigNum.Int64())
   184  			case reflect.Int16:
   185  				inter = int16(bigNum.Int64())
   186  			case reflect.Int32:
   187  				inter = int32(bigNum.Int64())
   188  			case reflect.Int64:
   189  				inter = bigNum.Int64()
   190  			default:
   191  				inter = common.BytesToBig(returnOutput)
   192  			}
   193  		case BoolTy:
   194  			inter = common.BytesToBig(returnOutput).Uint64() > 0
   195  		case AddressTy:
   196  			inter = common.BytesToAddress(returnOutput)
   197  		case HashTy:
   198  			inter = common.BytesToHash(returnOutput)
   199  		case FixedBytesTy:
   200  			inter = returnOutput
   201  		}
   202  		// append the item to our reflect slice
   203  		refSlice = reflect.Append(refSlice, reflect.ValueOf(inter))
   204  	}
   205  
   206  	// return the interface
   207  	return refSlice.Interface(), nil
   208  }
   209  
   210  // toGoType parses the input and casts it to the proper type defined by the ABI
   211  // argument in T.
   212  func toGoType(i int, t Argument, output []byte) (interface{}, error) {
   213  	// we need to treat slices differently
   214  	if (t.Type.IsSlice || t.Type.IsArray) && t.Type.T != BytesTy && t.Type.T != StringTy && t.Type.T != FixedBytesTy && t.Type.T != FunctionTy {
   215  		return toGoSlice(i, t, output)
   216  	}
   217  
   218  	index := i * 32
   219  	if index+32 > len(output) {
   220  		return nil, fmt.Errorf("abi: cannot marshal in to go type: length insufficient %d require %d", len(output), index+32)
   221  	}
   222  
   223  	// Parse the given index output and check whether we need to read
   224  	// a different offset and length based on the type (i.e. string, bytes)
   225  	var returnOutput []byte
   226  	switch t.Type.T {
   227  	case StringTy, BytesTy: // variable arrays are written at the end of the return bytes
   228  		// parse offset from which we should start reading
   229  		offset := int(common.BytesToBig(output[index : index+32]).Uint64())
   230  		if offset+32 > len(output) {
   231  			return nil, fmt.Errorf("abi: cannot marshal in to go type: length insufficient %d require %d", len(output), offset+32)
   232  		}
   233  		// parse the size up until we should be reading
   234  		size := int(common.BytesToBig(output[offset : offset+32]).Uint64())
   235  		if offset+32+size > len(output) {
   236  			return nil, fmt.Errorf("abi: cannot marshal in to go type: length insufficient %d require %d", len(output), offset+32+size)
   237  		}
   238  
   239  		// get the bytes for this return value
   240  		returnOutput = output[offset+32 : offset+32+size]
   241  	default:
   242  		returnOutput = output[index : index+32]
   243  	}
   244  
   245  	// convert the bytes to whatever is specified by the ABI.
   246  	switch t.Type.T {
   247  	case IntTy, UintTy:
   248  		bigNum := common.BytesToBig(returnOutput)
   249  
   250  		// If the type is a integer convert to the integer type
   251  		// specified by the ABI.
   252  		switch t.Type.Kind {
   253  		case reflect.Uint8:
   254  			return uint8(bigNum.Uint64()), nil
   255  		case reflect.Uint16:
   256  			return uint16(bigNum.Uint64()), nil
   257  		case reflect.Uint32:
   258  			return uint32(bigNum.Uint64()), nil
   259  		case reflect.Uint64:
   260  			return uint64(bigNum.Uint64()), nil
   261  		case reflect.Int8:
   262  			return int8(bigNum.Int64()), nil
   263  		case reflect.Int16:
   264  			return int16(bigNum.Int64()), nil
   265  		case reflect.Int32:
   266  			return int32(bigNum.Int64()), nil
   267  		case reflect.Int64:
   268  			return int64(bigNum.Int64()), nil
   269  		case reflect.Ptr:
   270  			return bigNum, nil
   271  		}
   272  	case BoolTy:
   273  		return common.BytesToBig(returnOutput).Uint64() > 0, nil
   274  	case AddressTy:
   275  		return common.BytesToAddress(returnOutput), nil
   276  	case HashTy:
   277  		return common.BytesToHash(returnOutput), nil
   278  	case BytesTy, FixedBytesTy, FunctionTy:
   279  		return returnOutput, nil
   280  	case StringTy:
   281  		return string(returnOutput), nil
   282  	}
   283  	return nil, fmt.Errorf("abi: unknown type %v", t.Type.T)
   284  }
   285  
   286  // these variable are used to determine certain types during type assertion for
   287  // assignment.
   288  var (
   289  	r_interSlice = reflect.TypeOf([]interface{}{})
   290  	r_hash       = reflect.TypeOf(common.Hash{})
   291  	r_bytes      = reflect.TypeOf([]byte{})
   292  	r_byte       = reflect.TypeOf(byte(0))
   293  )
   294  
   295  // Unpack output in v according to the abi specification
   296  func (abi ABI) Unpack(v interface{}, name string, output []byte) error {
   297  	var method = abi.Methods[name]
   298  
   299  	if len(output) == 0 {
   300  		return fmt.Errorf("abi: unmarshalling empty output")
   301  	}
   302  
   303  	// make sure the passed value is a pointer
   304  	valueOf := reflect.ValueOf(v)
   305  	if reflect.Ptr != valueOf.Kind() {
   306  		return fmt.Errorf("abi: Unpack(non-pointer %T)", v)
   307  	}
   308  
   309  	var (
   310  		value = valueOf.Elem()
   311  		typ   = value.Type()
   312  	)
   313  
   314  	if len(method.Outputs) > 1 {
   315  		switch value.Kind() {
   316  		// struct will match named return values to the struct's field
   317  		// names
   318  		case reflect.Struct:
   319  			for i := 0; i < len(method.Outputs); i++ {
   320  				marshalledValue, err := toGoType(i, method.Outputs[i], output)
   321  				if err != nil {
   322  					return err
   323  				}
   324  				reflectValue := reflect.ValueOf(marshalledValue)
   325  
   326  				for j := 0; j < typ.NumField(); j++ {
   327  					field := typ.Field(j)
   328  					// TODO read tags: `abi:"fieldName"`
   329  					if field.Name == strings.ToUpper(method.Outputs[i].Name[:1])+method.Outputs[i].Name[1:] {
   330  						if err := set(value.Field(j), reflectValue, method.Outputs[i]); err != nil {
   331  							return err
   332  						}
   333  					}
   334  				}
   335  			}
   336  		case reflect.Slice:
   337  			if !value.Type().AssignableTo(r_interSlice) {
   338  				return fmt.Errorf("abi: cannot marshal tuple in to slice %T (only []interface{} is supported)", v)
   339  			}
   340  
   341  			// if the slice already contains values, set those instead of the interface slice itself.
   342  			if value.Len() > 0 {
   343  				if len(method.Outputs) > value.Len() {
   344  					return fmt.Errorf("abi: cannot marshal in to slices of unequal size (require: %v, got: %v)", len(method.Outputs), value.Len())
   345  				}
   346  
   347  				for i := 0; i < len(method.Outputs); i++ {
   348  					marshalledValue, err := toGoType(i, method.Outputs[i], output)
   349  					if err != nil {
   350  						return err
   351  					}
   352  					reflectValue := reflect.ValueOf(marshalledValue)
   353  					if err := set(value.Index(i).Elem(), reflectValue, method.Outputs[i]); err != nil {
   354  						return err
   355  					}
   356  				}
   357  				return nil
   358  			}
   359  
   360  			// create a new slice and start appending the unmarshalled
   361  			// values to the new interface slice.
   362  			z := reflect.MakeSlice(typ, 0, len(method.Outputs))
   363  			for i := 0; i < len(method.Outputs); i++ {
   364  				marshalledValue, err := toGoType(i, method.Outputs[i], output)
   365  				if err != nil {
   366  					return err
   367  				}
   368  				z = reflect.Append(z, reflect.ValueOf(marshalledValue))
   369  			}
   370  			value.Set(z)
   371  		default:
   372  			return fmt.Errorf("abi: cannot unmarshal tuple in to %v", typ)
   373  		}
   374  
   375  	} else {
   376  		marshalledValue, err := toGoType(0, method.Outputs[0], output)
   377  		if err != nil {
   378  			return err
   379  		}
   380  		if err := set(value, reflect.ValueOf(marshalledValue), method.Outputs[0]); err != nil {
   381  			return err
   382  		}
   383  	}
   384  
   385  	return nil
   386  }
   387  
   388  func (abi *ABI) UnmarshalJSON(data []byte) error {
   389  	var fields []struct {
   390  		Type      string
   391  		Name      string
   392  		Constant  bool
   393  		Indexed   bool
   394  		Anonymous bool
   395  		Inputs    []Argument
   396  		Outputs   []Argument
   397  	}
   398  
   399  	if err := json.Unmarshal(data, &fields); err != nil {
   400  		return err
   401  	}
   402  
   403  	abi.Methods = make(map[string]Method)
   404  	abi.Events = make(map[string]Event)
   405  	for _, field := range fields {
   406  		switch field.Type {
   407  		case "constructor":
   408  			abi.Constructor = Method{
   409  				Inputs: field.Inputs,
   410  			}
   411  		// empty defaults to function according to the abi spec
   412  		case "function", "":
   413  			abi.Methods[field.Name] = Method{
   414  				Name:    field.Name,
   415  				Const:   field.Constant,
   416  				Inputs:  field.Inputs,
   417  				Outputs: field.Outputs,
   418  			}
   419  		case "event":
   420  			abi.Events[field.Name] = Event{
   421  				Name:      field.Name,
   422  				Anonymous: field.Anonymous,
   423  				Inputs:    field.Inputs,
   424  			}
   425  		}
   426  	}
   427  
   428  	return nil
   429  }