Skip to content

Commit 5421a08

Browse files
VoR0220karalabe
authored andcommitted
accounts/abi: reorganizing package with small fixes (ethereum#14610)
* accounts/abi: reorganizing package and some notes and a quick correction of name. Signed-off-by: RJ Catalano <[email protected]> get rid of some imports Signed-off-by: RJ Catalano <[email protected]> * accounts/abi: move file names Signed-off-by: RJ Catalano <[email protected]> * accounts/abi: fix boolean decode function Signed-off-by: RJ Catalano <[email protected]> * accounts/abi: fix for the array set and for creating a bool Signed-off-by: RJ Catalano <[email protected]> * accounts/abi: be very very very correct Signed-off-by: RJ Catalano <[email protected]> * accounts/abi: fix up error message and variable names Signed-off-by: RJ Catalano <[email protected]> * accounts/abi: take out unnecessary argument in pack method Signed-off-by: RJ Catalano <[email protected]> * accounts/abi: add bool unpack test and add a panic to readBool function Signed-off-by: RJ Catalano <[email protected]> * accounts/abi: fix panic message Signed-off-by: RJ Catalano <[email protected]> * accounts/abi: change from panic to basic error Signed-off-by: RJ Catalano <[email protected]> * accounts/abi: fix nil to false Signed-off-by: RJ Catalano <[email protected]> * accounts/abi: fill out type regex tests and fill with the correct type for integers Signed-off-by: RJ Catalano <[email protected]> * accounts/abi: move packNumbers into pack.go. Signed-off-by: RJ Catalano <[email protected]> * accounts/abi: separation of the testing suite into appropriately named files. Signed-off-by: RJ Catalano <[email protected]> * account/abi: change to hex string tests. Signed-off-by: RJ Catalano <[email protected]> * account/abi: fix up rest of tests to hex Signed-off-by: RJ Catalano <[email protected]> * accounts/abi: declare bool at the package level Signed-off-by: RJ Catalano <[email protected]> * accounts/abi: use errors package in the error file. Signed-off-by: RJ Catalano <[email protected]> * accounts/abi: fix ugly hack and fix error type declaration. Signed-off-by: RJ Catalano <[email protected]>
1 parent cf611c5 commit 5421a08

File tree

13 files changed

+1487
-1085
lines changed

13 files changed

+1487
-1085
lines changed

accounts/abi/abi.go

Lines changed: 1 addition & 196 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,9 @@
1717
package abi
1818

1919
import (
20-
"encoding/binary"
2120
"encoding/json"
2221
"fmt"
2322
"io"
24-
"math/big"
2523
"reflect"
2624
"strings"
2725

@@ -67,7 +65,7 @@ func (abi ABI) Pack(name string, args ...interface{}) ([]byte, error) {
6765
}
6866
method = m
6967
}
70-
arguments, err := method.pack(method, args...)
68+
arguments, err := method.pack(args...)
7169
if err != nil {
7270
return nil, err
7371
}
@@ -78,199 +76,6 @@ func (abi ABI) Pack(name string, args ...interface{}) ([]byte, error) {
7876
return append(method.Id(), arguments...), nil
7977
}
8078

81-
// toGoSliceType parses the input and casts it to the proper slice defined by the ABI
82-
// argument in T.
83-
func toGoSlice(i int, t Argument, output []byte) (interface{}, error) {
84-
index := i * 32
85-
// The slice must, at very least be large enough for the index+32 which is exactly the size required
86-
// for the [offset in output, size of offset].
87-
if index+32 > len(output) {
88-
return nil, fmt.Errorf("abi: cannot marshal in to go slice: insufficient size output %d require %d", len(output), index+32)
89-
}
90-
elem := t.Type.Elem
91-
92-
// first we need to create a slice of the type
93-
var refSlice reflect.Value
94-
switch elem.T {
95-
case IntTy, UintTy, BoolTy:
96-
// create a new reference slice matching the element type
97-
switch t.Type.Kind {
98-
case reflect.Bool:
99-
refSlice = reflect.ValueOf([]bool(nil))
100-
case reflect.Uint8:
101-
refSlice = reflect.ValueOf([]uint8(nil))
102-
case reflect.Uint16:
103-
refSlice = reflect.ValueOf([]uint16(nil))
104-
case reflect.Uint32:
105-
refSlice = reflect.ValueOf([]uint32(nil))
106-
case reflect.Uint64:
107-
refSlice = reflect.ValueOf([]uint64(nil))
108-
case reflect.Int8:
109-
refSlice = reflect.ValueOf([]int8(nil))
110-
case reflect.Int16:
111-
refSlice = reflect.ValueOf([]int16(nil))
112-
case reflect.Int32:
113-
refSlice = reflect.ValueOf([]int32(nil))
114-
case reflect.Int64:
115-
refSlice = reflect.ValueOf([]int64(nil))
116-
default:
117-
refSlice = reflect.ValueOf([]*big.Int(nil))
118-
}
119-
case AddressTy: // address must be of slice Address
120-
refSlice = reflect.ValueOf([]common.Address(nil))
121-
case HashTy: // hash must be of slice hash
122-
refSlice = reflect.ValueOf([]common.Hash(nil))
123-
case FixedBytesTy:
124-
refSlice = reflect.ValueOf([][]byte(nil))
125-
default: // no other types are supported
126-
return nil, fmt.Errorf("abi: unsupported slice type %v", elem.T)
127-
}
128-
129-
var slice []byte
130-
var size int
131-
var offset int
132-
if t.Type.IsSlice {
133-
// get the offset which determines the start of this array ...
134-
offset = int(binary.BigEndian.Uint64(output[index+24 : index+32]))
135-
if offset+32 > len(output) {
136-
return nil, fmt.Errorf("abi: cannot marshal in to go slice: offset %d would go over slice boundary (len=%d)", len(output), offset+32)
137-
}
138-
139-
slice = output[offset:]
140-
// ... starting with the size of the array in elements ...
141-
size = int(binary.BigEndian.Uint64(slice[24:32]))
142-
slice = slice[32:]
143-
// ... and make sure that we've at the very least the amount of bytes
144-
// available in the buffer.
145-
if size*32 > len(slice) {
146-
return nil, fmt.Errorf("abi: cannot marshal in to go slice: insufficient size output %d require %d", len(output), offset+32+size*32)
147-
}
148-
149-
// reslice to match the required size
150-
slice = slice[:size*32]
151-
} else if t.Type.IsArray {
152-
//get the number of elements in the array
153-
size = t.Type.SliceSize
154-
155-
//check to make sure array size matches up
156-
if index+32*size > len(output) {
157-
return nil, fmt.Errorf("abi: cannot marshal in to go array: offset %d would go over slice boundary (len=%d)", len(output), index+32*size)
158-
}
159-
//slice is there for a fixed amount of times
160-
slice = output[index : index+size*32]
161-
}
162-
163-
for i := 0; i < size; i++ {
164-
var (
165-
inter interface{} // interface type
166-
returnOutput = slice[i*32 : i*32+32] // the return output
167-
)
168-
// set inter to the correct type (cast)
169-
switch elem.T {
170-
case IntTy, UintTy:
171-
inter = readInteger(t.Type.Kind, returnOutput)
172-
case BoolTy:
173-
inter = !allZero(returnOutput)
174-
case AddressTy:
175-
inter = common.BytesToAddress(returnOutput)
176-
case HashTy:
177-
inter = common.BytesToHash(returnOutput)
178-
case FixedBytesTy:
179-
inter = returnOutput
180-
}
181-
// append the item to our reflect slice
182-
refSlice = reflect.Append(refSlice, reflect.ValueOf(inter))
183-
}
184-
185-
// return the interface
186-
return refSlice.Interface(), nil
187-
}
188-
189-
func readInteger(kind reflect.Kind, b []byte) interface{} {
190-
switch kind {
191-
case reflect.Uint8:
192-
return uint8(b[len(b)-1])
193-
case reflect.Uint16:
194-
return binary.BigEndian.Uint16(b[len(b)-2:])
195-
case reflect.Uint32:
196-
return binary.BigEndian.Uint32(b[len(b)-4:])
197-
case reflect.Uint64:
198-
return binary.BigEndian.Uint64(b[len(b)-8:])
199-
case reflect.Int8:
200-
return int8(b[len(b)-1])
201-
case reflect.Int16:
202-
return int16(binary.BigEndian.Uint16(b[len(b)-2:]))
203-
case reflect.Int32:
204-
return int32(binary.BigEndian.Uint32(b[len(b)-4:]))
205-
case reflect.Int64:
206-
return int64(binary.BigEndian.Uint64(b[len(b)-8:]))
207-
default:
208-
return new(big.Int).SetBytes(b)
209-
}
210-
}
211-
212-
func allZero(b []byte) bool {
213-
for _, byte := range b {
214-
if byte != 0 {
215-
return false
216-
}
217-
}
218-
return true
219-
}
220-
221-
// toGoType parses the input and casts it to the proper type defined by the ABI
222-
// argument in T.
223-
func toGoType(i int, t Argument, output []byte) (interface{}, error) {
224-
// we need to treat slices differently
225-
if (t.Type.IsSlice || t.Type.IsArray) && t.Type.T != BytesTy && t.Type.T != StringTy && t.Type.T != FixedBytesTy && t.Type.T != FunctionTy {
226-
return toGoSlice(i, t, output)
227-
}
228-
229-
index := i * 32
230-
if index+32 > len(output) {
231-
return nil, fmt.Errorf("abi: cannot marshal in to go type: length insufficient %d require %d", len(output), index+32)
232-
}
233-
234-
// Parse the given index output and check whether we need to read
235-
// a different offset and length based on the type (i.e. string, bytes)
236-
var returnOutput []byte
237-
switch t.Type.T {
238-
case StringTy, BytesTy: // variable arrays are written at the end of the return bytes
239-
// parse offset from which we should start reading
240-
offset := int(binary.BigEndian.Uint64(output[index+24 : index+32]))
241-
if offset+32 > len(output) {
242-
return nil, fmt.Errorf("abi: cannot marshal in to go type: length insufficient %d require %d", len(output), offset+32)
243-
}
244-
// parse the size up until we should be reading
245-
size := int(binary.BigEndian.Uint64(output[offset+24 : offset+32]))
246-
if offset+32+size > len(output) {
247-
return nil, fmt.Errorf("abi: cannot marshal in to go type: length insufficient %d require %d", len(output), offset+32+size)
248-
}
249-
250-
// get the bytes for this return value
251-
returnOutput = output[offset+32 : offset+32+size]
252-
default:
253-
returnOutput = output[index : index+32]
254-
}
255-
256-
// convert the bytes to whatever is specified by the ABI.
257-
switch t.Type.T {
258-
case IntTy, UintTy:
259-
return readInteger(t.Type.Kind, returnOutput), nil
260-
case BoolTy:
261-
return !allZero(returnOutput), nil
262-
case AddressTy:
263-
return common.BytesToAddress(returnOutput), nil
264-
case HashTy:
265-
return common.BytesToHash(returnOutput), nil
266-
case BytesTy, FixedBytesTy, FunctionTy:
267-
return returnOutput, nil
268-
case StringTy:
269-
return string(returnOutput), nil
270-
}
271-
return nil, fmt.Errorf("abi: unknown type %v", t.Type.T)
272-
}
273-
27479
// these variable are used to determine certain types during type assertion for
27580
// assignment.
27681
var (

0 commit comments

Comments
 (0)