gitee.com/lh-her-team/common@v1.5.1/evmutils/abi/abi.go (about)

     1  package abi
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io"
     7  
     8  	"gitee.com/lh-her-team/common/evmutils"
     9  	"gitee.com/lh-her-team/common/evmutils/abi/burrow/abi"
    10  )
    11  
    12  type ABI struct {
    13  	spec *abi.Spec
    14  }
    15  
    16  // NewAbi create a new ABI instance by abi string
    17  // @param abiData
    18  // @return *ABI
    19  // @return error
    20  func NewAbi(abiJSON string) (*ABI, error) {
    21  	spec, err := abi.ReadSpec([]byte(abiJSON))
    22  	if err != nil {
    23  		return nil, err
    24  	}
    25  	return &ABI{spec: spec}, nil
    26  }
    27  
    28  // NewAbiFromFile create an ABI instance by abi json file path
    29  // @param fpath
    30  // @return *ABI
    31  // @return error
    32  func NewAbiFromFile(fpath string) (*ABI, error) {
    33  	spec, err := abi.ReadSpecFile(fpath)
    34  	if err != nil {
    35  		return nil, err
    36  	}
    37  	return &ABI{spec: spec}, nil
    38  }
    39  
    40  // JSON create an ABI instance by Json Reader
    41  // @param reader
    42  // @return *ABI
    43  // @return error
    44  func JSON(reader io.Reader) (*ABI, error) {
    45  	buf := new(bytes.Buffer)
    46  	_, err := buf.ReadFrom(reader)
    47  	if err != nil {
    48  		return nil, err
    49  	}
    50  	abiString := buf.String()
    51  	return NewAbi(abiString)
    52  }
    53  
    54  // Pack encode function name and arguments to a binary data
    55  // @param funcName
    56  // @param args
    57  // @return []byte
    58  // @return error
    59  func (a *ABI) Pack(funcName string, args ...interface{}) ([]byte, error) {
    60  	data, _, err := a.spec.Pack(funcName, convertArgs(args...)...)
    61  	return data, err
    62  }
    63  
    64  // Unpack decode function out put binary data to interface(string) array
    65  // @param funcName
    66  // @param data
    67  // @return []interface{}
    68  // @return error
    69  func (a *ABI) Unpack(funcName string, data []byte) ([]interface{}, error) {
    70  	fspec, ok := a.spec.Functions[funcName]
    71  	if !ok {
    72  		return nil, fmt.Errorf("no such function %s", funcName)
    73  	}
    74  	args := make([]string, len(fspec.Outputs))
    75  	intf := make([]interface{}, len(args))
    76  	for i := range args {
    77  		intf[i] = &args[i]
    78  	}
    79  	err := abi.Unpack(fspec.Outputs, data, intf...)
    80  	if err != nil {
    81  		return nil, err
    82  	}
    83  	returnArgs := make([]interface{}, len(args))
    84  	for i, arg := range args {
    85  		returnArgs[i] = arg
    86  	}
    87  	return returnArgs, nil
    88  }
    89  
    90  func convertArgs(args ...interface{}) []interface{} {
    91  	returns := make([]interface{}, len(args))
    92  	for i, arg := range args {
    93  		returns[i] = convertType(arg)
    94  	}
    95  	return returns
    96  }
    97  
    98  func convertType(arg interface{}) interface{} {
    99  	switch arg := arg.(type) {
   100  	case evmutils.Address:
   101  		addr := arg
   102  		return addr[:]
   103  	case *evmutils.Address:
   104  		addr := *arg
   105  		return addr[:]
   106  	case []evmutils.Address:
   107  		addrs := []string{}
   108  		for _, addr := range arg {
   109  			addrs = append(addrs, addr.String())
   110  		}
   111  		return addrs
   112  	case []*evmutils.Address:
   113  		addrs := []string{}
   114  		for _, addr := range arg {
   115  			addrs = append(addrs, addr.String())
   116  		}
   117  		return addrs
   118  	default:
   119  		//fmt.Printf("%#v\n", t)
   120  		return arg
   121  	}
   122  }