github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/accounts/abi/pack.go (about) 1 // This file is part of the go-sberex library. The go-sberex library is 2 // free software: you can redistribute it and/or modify it under the terms 3 // of the GNU Lesser General Public License as published by the Free 4 // Software Foundation, either version 3 of the License, or (at your option) 5 // any later version. 6 // 7 // The go-sberex library is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 10 // General Public License <http://www.gnu.org/licenses/> for more details. 11 12 package abi 13 14 import ( 15 "math/big" 16 "reflect" 17 18 "github.com/Sberex/go-sberex/common" 19 "github.com/Sberex/go-sberex/common/math" 20 ) 21 22 // packBytesSlice packs the given bytes as [L, V] as the canonical representation 23 // bytes slice 24 func packBytesSlice(bytes []byte, l int) []byte { 25 len := packNum(reflect.ValueOf(l)) 26 return append(len, common.RightPadBytes(bytes, (l+31)/32*32)...) 27 } 28 29 // packElement packs the given reflect value according to the abi specification in 30 // t. 31 func packElement(t Type, reflectValue reflect.Value) []byte { 32 switch t.T { 33 case IntTy, UintTy: 34 return packNum(reflectValue) 35 case StringTy: 36 return packBytesSlice([]byte(reflectValue.String()), reflectValue.Len()) 37 case AddressTy: 38 if reflectValue.Kind() == reflect.Array { 39 reflectValue = mustArrayToByteSlice(reflectValue) 40 } 41 42 return common.LeftPadBytes(reflectValue.Bytes(), 32) 43 case BoolTy: 44 if reflectValue.Bool() { 45 return math.PaddedBigBytes(common.Big1, 32) 46 } 47 return math.PaddedBigBytes(common.Big0, 32) 48 case BytesTy: 49 if reflectValue.Kind() == reflect.Array { 50 reflectValue = mustArrayToByteSlice(reflectValue) 51 } 52 return packBytesSlice(reflectValue.Bytes(), reflectValue.Len()) 53 case FixedBytesTy, FunctionTy: 54 if reflectValue.Kind() == reflect.Array { 55 reflectValue = mustArrayToByteSlice(reflectValue) 56 } 57 return common.RightPadBytes(reflectValue.Bytes(), 32) 58 default: 59 panic("abi: fatal error") 60 } 61 } 62 63 // packNum packs the given number (using the reflect value) and will cast it to appropriate number representation 64 func packNum(value reflect.Value) []byte { 65 switch kind := value.Kind(); kind { 66 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 67 return U256(new(big.Int).SetUint64(value.Uint())) 68 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 69 return U256(big.NewInt(value.Int())) 70 case reflect.Ptr: 71 return U256(value.Interface().(*big.Int)) 72 default: 73 panic("abi: fatal error") 74 } 75 76 }