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