github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/accounts/abi/pack.go (about)

     1  package abi
     2  
     3  import (
     4  	"math/big"
     5  	"reflect"
     6  
     7  	"github.com/quickchainproject/quickchain/common"
     8  	"github.com/quickchainproject/quickchain/common/math"
     9  )
    10  
    11  // packBytesSlice packs the given bytes as [L, V] as the canonical representation
    12  // bytes slice
    13  func packBytesSlice(bytes []byte, l int) []byte {
    14  	len := packNum(reflect.ValueOf(l))
    15  	return append(len, common.RightPadBytes(bytes, (l+31)/32*32)...)
    16  }
    17  
    18  // packElement packs the given reflect value according to the abi specification in
    19  // t.
    20  func packElement(t Type, reflectValue reflect.Value) []byte {
    21  	switch t.T {
    22  	case IntTy, UintTy:
    23  		return packNum(reflectValue)
    24  	case StringTy:
    25  		return packBytesSlice([]byte(reflectValue.String()), reflectValue.Len())
    26  	case AddressTy:
    27  		if reflectValue.Kind() == reflect.Array {
    28  			reflectValue = mustArrayToByteSlice(reflectValue)
    29  		}
    30  
    31  		return common.LeftPadBytes(reflectValue.Bytes(), 32)
    32  	case BoolTy:
    33  		if reflectValue.Bool() {
    34  			return math.PaddedBigBytes(common.Big1, 32)
    35  		}
    36  		return math.PaddedBigBytes(common.Big0, 32)
    37  	case BytesTy:
    38  		if reflectValue.Kind() == reflect.Array {
    39  			reflectValue = mustArrayToByteSlice(reflectValue)
    40  		}
    41  		return packBytesSlice(reflectValue.Bytes(), reflectValue.Len())
    42  	case FixedBytesTy, FunctionTy:
    43  		if reflectValue.Kind() == reflect.Array {
    44  			reflectValue = mustArrayToByteSlice(reflectValue)
    45  		}
    46  		return common.RightPadBytes(reflectValue.Bytes(), 32)
    47  	default:
    48  		panic("abi: fatal error")
    49  	}
    50  }
    51  
    52  // packNum packs the given number (using the reflect value) and will cast it to appropriate number representation
    53  func packNum(value reflect.Value) []byte {
    54  	switch kind := value.Kind(); kind {
    55  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
    56  		return U256(new(big.Int).SetUint64(value.Uint()))
    57  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
    58  		return U256(big.NewInt(value.Int()))
    59  	case reflect.Ptr:
    60  		return U256(value.Interface().(*big.Int))
    61  	default:
    62  		panic("abi: fatal error")
    63  	}
    64  
    65  }