accounts/abi: replace uses of BytesToBig with use of encoding/binary

This commit is contained in:
Felix Lange 2017-02-22 12:53:18 +01:00
parent d6e5e9d9bb
commit 746e59c1e2

View file

@ -17,6 +17,7 @@
package abi package abi
import ( import (
"encoding/binary"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
@ -129,16 +130,15 @@ func toGoSlice(i int, t Argument, output []byte) (interface{}, error) {
var size int var size int
var offset int var offset int
if t.Type.IsSlice { if t.Type.IsSlice {
// get the offset which determines the start of this array ... // get the offset which determines the start of this array ...
offset = int(common.BytesToBig(output[index : index+32]).Uint64()) offset = int(binary.BigEndian.Uint64(output[index+24 : index+32]))
if offset+32 > len(output) { if offset+32 > len(output) {
return nil, fmt.Errorf("abi: cannot marshal in to go slice: offset %d would go over slice boundary (len=%d)", len(output), offset+32) return nil, fmt.Errorf("abi: cannot marshal in to go slice: offset %d would go over slice boundary (len=%d)", len(output), offset+32)
} }
slice = output[offset:] slice = output[offset:]
// ... starting with the size of the array in elements ... // ... starting with the size of the array in elements ...
size = int(common.BytesToBig(slice[:32]).Uint64()) size = int(binary.BigEndian.Uint64(slice[24:32]))
slice = slice[32:] slice = slice[32:]
// ... and make sure that we've at the very least the amount of bytes // ... and make sure that we've at the very least the amount of bytes
// available in the buffer. // available in the buffer.
@ -147,7 +147,7 @@ func toGoSlice(i int, t Argument, output []byte) (interface{}, error) {
} }
// reslice to match the required size // reslice to match the required size
slice = slice[:(size * 32)] slice = slice[:size*32]
} else if t.Type.IsArray { } else if t.Type.IsArray {
//get the number of elements in the array //get the number of elements in the array
size = t.Type.SliceSize size = t.Type.SliceSize
@ -165,33 +165,12 @@ func toGoSlice(i int, t Argument, output []byte) (interface{}, error) {
inter interface{} // interface type inter interface{} // interface type
returnOutput = slice[i*32 : i*32+32] // the return output returnOutput = slice[i*32 : i*32+32] // the return output
) )
// set inter to the correct type (cast) // set inter to the correct type (cast)
switch elem.T { switch elem.T {
case IntTy, UintTy: case IntTy, UintTy:
bigNum := common.BytesToBig(returnOutput) inter = readInteger(t.Type.Kind, returnOutput)
switch t.Type.Kind {
case reflect.Uint8:
inter = uint8(bigNum.Uint64())
case reflect.Uint16:
inter = uint16(bigNum.Uint64())
case reflect.Uint32:
inter = uint32(bigNum.Uint64())
case reflect.Uint64:
inter = bigNum.Uint64()
case reflect.Int8:
inter = int8(bigNum.Int64())
case reflect.Int16:
inter = int16(bigNum.Int64())
case reflect.Int32:
inter = int32(bigNum.Int64())
case reflect.Int64:
inter = bigNum.Int64()
default:
inter = common.BytesToBig(returnOutput)
}
case BoolTy: case BoolTy:
inter = common.BytesToBig(returnOutput).Uint64() > 0 inter = !allZero(returnOutput)
case AddressTy: case AddressTy:
inter = common.BytesToAddress(returnOutput) inter = common.BytesToAddress(returnOutput)
case HashTy: case HashTy:
@ -207,6 +186,38 @@ func toGoSlice(i int, t Argument, output []byte) (interface{}, error) {
return refSlice.Interface(), nil return refSlice.Interface(), nil
} }
func readInteger(kind reflect.Kind, b []byte) interface{} {
switch kind {
case reflect.Uint8:
return uint8(b[len(b)-1])
case reflect.Uint16:
return binary.BigEndian.Uint16(b[len(b)-2:])
case reflect.Uint32:
return binary.BigEndian.Uint32(b[len(b)-4:])
case reflect.Uint64:
return binary.BigEndian.Uint64(b[len(b)-8:])
case reflect.Int8:
return int8(b[len(b)-1])
case reflect.Int16:
return int16(binary.BigEndian.Uint16(b[len(b)-2:]))
case reflect.Int32:
return int32(binary.BigEndian.Uint32(b[len(b)-4:]))
case reflect.Int64:
return int64(binary.BigEndian.Uint64(b[len(b)-8:]))
default:
return new(big.Int).SetBytes(b)
}
}
func allZero(b []byte) bool {
for _, byte := range b {
if byte != 0 {
return false
}
}
return true
}
// toGoType parses the input and casts it to the proper type defined by the ABI // toGoType parses the input and casts it to the proper type defined by the ABI
// argument in T. // argument in T.
func toGoType(i int, t Argument, output []byte) (interface{}, error) { func toGoType(i int, t Argument, output []byte) (interface{}, error) {
@ -226,12 +237,12 @@ func toGoType(i int, t Argument, output []byte) (interface{}, error) {
switch t.Type.T { switch t.Type.T {
case StringTy, BytesTy: // variable arrays are written at the end of the return bytes case StringTy, BytesTy: // variable arrays are written at the end of the return bytes
// parse offset from which we should start reading // parse offset from which we should start reading
offset := int(common.BytesToBig(output[index : index+32]).Uint64()) offset := int(binary.BigEndian.Uint64(output[index+24 : index+32]))
if offset+32 > len(output) { if offset+32 > len(output) {
return nil, fmt.Errorf("abi: cannot marshal in to go type: length insufficient %d require %d", len(output), offset+32) return nil, fmt.Errorf("abi: cannot marshal in to go type: length insufficient %d require %d", len(output), offset+32)
} }
// parse the size up until we should be reading // parse the size up until we should be reading
size := int(common.BytesToBig(output[offset : offset+32]).Uint64()) size := int(binary.BigEndian.Uint64(output[offset+24 : offset+32]))
if offset+32+size > len(output) { if offset+32+size > len(output) {
return nil, fmt.Errorf("abi: cannot marshal in to go type: length insufficient %d require %d", len(output), offset+32+size) return nil, fmt.Errorf("abi: cannot marshal in to go type: length insufficient %d require %d", len(output), offset+32+size)
} }
@ -245,32 +256,9 @@ func toGoType(i int, t Argument, output []byte) (interface{}, error) {
// convert the bytes to whatever is specified by the ABI. // convert the bytes to whatever is specified by the ABI.
switch t.Type.T { switch t.Type.T {
case IntTy, UintTy: case IntTy, UintTy:
bigNum := common.BytesToBig(returnOutput) return readInteger(t.Type.Kind, returnOutput), nil
// If the type is a integer convert to the integer type
// specified by the ABI.
switch t.Type.Kind {
case reflect.Uint8:
return uint8(bigNum.Uint64()), nil
case reflect.Uint16:
return uint16(bigNum.Uint64()), nil
case reflect.Uint32:
return uint32(bigNum.Uint64()), nil
case reflect.Uint64:
return uint64(bigNum.Uint64()), nil
case reflect.Int8:
return int8(bigNum.Int64()), nil
case reflect.Int16:
return int16(bigNum.Int64()), nil
case reflect.Int32:
return int32(bigNum.Int64()), nil
case reflect.Int64:
return int64(bigNum.Int64()), nil
case reflect.Ptr:
return bigNum, nil
}
case BoolTy: case BoolTy:
return common.BytesToBig(returnOutput).Uint64() > 0, nil return !allZero(returnOutput), nil
case AddressTy: case AddressTy:
return common.BytesToAddress(returnOutput), nil return common.BytesToAddress(returnOutput), nil
case HashTy: case HashTy: