diff options
Diffstat (limited to 'accounts/abi')
-rw-r--r-- | accounts/abi/abi.go | 96 | ||||
-rw-r--r-- | accounts/abi/bind/backends/simulated.go | 5 | ||||
-rw-r--r-- | accounts/abi/numbers.go | 3 |
3 files changed, 47 insertions, 57 deletions
diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index 627a2a0c4..3d1010229 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -17,6 +17,7 @@ package abi import ( + "encoding/binary" "encoding/json" "fmt" "io" @@ -129,16 +130,15 @@ func toGoSlice(i int, t Argument, output []byte) (interface{}, error) { var size int var offset int if t.Type.IsSlice { - // 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) { 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:] // ... 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:] // ... and make sure that we've at the very least the amount of bytes // available in the buffer. @@ -147,7 +147,7 @@ func toGoSlice(i int, t Argument, output []byte) (interface{}, error) { } // reslice to match the required size - slice = slice[:(size * 32)] + slice = slice[:size*32] } else if t.Type.IsArray { //get the number of elements in the array size = t.Type.SliceSize @@ -165,33 +165,12 @@ func toGoSlice(i int, t Argument, output []byte) (interface{}, error) { inter interface{} // interface type returnOutput = slice[i*32 : i*32+32] // the return output ) - // set inter to the correct type (cast) switch elem.T { case IntTy, UintTy: - bigNum := common.BytesToBig(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) - } + inter = readInteger(t.Type.Kind, returnOutput) case BoolTy: - inter = common.BytesToBig(returnOutput).Uint64() > 0 + inter = !allZero(returnOutput) case AddressTy: inter = common.BytesToAddress(returnOutput) case HashTy: @@ -207,6 +186,38 @@ func toGoSlice(i int, t Argument, output []byte) (interface{}, error) { 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 // argument in T. 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 { case StringTy, BytesTy: // variable arrays are written at the end of the return bytes // 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) { 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 - 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) { 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. switch t.Type.T { case IntTy, UintTy: - bigNum := common.BytesToBig(returnOutput) - - // 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 - } + return readInteger(t.Type.Kind, returnOutput), nil case BoolTy: - return common.BytesToBig(returnOutput).Uint64() > 0, nil + return !allZero(returnOutput), nil case AddressTy: return common.BytesToAddress(returnOutput), nil case HashTy: diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 1c34ba0e7..5e2fcbae7 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -25,6 +25,7 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" @@ -244,7 +245,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM } // Set infinite balance to the fake caller account. from := statedb.GetOrNewStateObject(call.From) - from.SetBalance(common.MaxBig) + from.SetBalance(math.MaxBig256) // Execute the call. msg := callmsg{call} @@ -252,7 +253,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM // Create a new environment which holds all relevant information // about the transaction and calling mechanisms. vmenv := vm.NewEVM(evmContext, statedb, chainConfig, vm.Config{}) - gaspool := new(core.GasPool).AddGas(common.MaxBig) + gaspool := new(core.GasPool).AddGas(math.MaxBig256) ret, gasUsed, _, err := core.NewStateTransition(vmenv, msg, gaspool).TransitionDb() return ret, gasUsed, err } diff --git a/accounts/abi/numbers.go b/accounts/abi/numbers.go index 3d5842292..36fb6705e 100644 --- a/accounts/abi/numbers.go +++ b/accounts/abi/numbers.go @@ -21,6 +21,7 @@ import ( "reflect" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" ) var ( @@ -58,7 +59,7 @@ var ( // U256 converts a big Int into a 256bit EVM number. func U256(n *big.Int) []byte { - return common.LeftPadBytes(common.U256(n).Bytes(), 32) + return common.LeftPadBytes(math.U256(n).Bytes(), 32) } // packNum packs the given number (using the reflect value) and will cast it to appropriate number representation |