aboutsummaryrefslogtreecommitdiffstats
path: root/accounts/abi/method.go
diff options
context:
space:
mode:
authorJeffrey Wilcke <geffobscura@gmail.com>2016-04-07 17:39:22 +0800
committerJeffrey Wilcke <geffobscura@gmail.com>2016-04-20 22:43:57 +0800
commit5127ec10cb84a615f4d5b314e4c3c102efefe4c9 (patch)
tree46d8098b82b00f329c45abc9d520f8230a0c5e5f /accounts/abi/method.go
parent18580e152c1a2480b6245ebba4c62c202ed20ac6 (diff)
downloaddexon-5127ec10cb84a615f4d5b314e4c3c102efefe4c9.tar.gz
dexon-5127ec10cb84a615f4d5b314e4c3c102efefe4c9.tar.zst
dexon-5127ec10cb84a615f4d5b314e4c3c102efefe4c9.zip
accouns/abi: refactored ABI package
Refactored the abi package parsing and type handling. Relying mostly on package reflect as opposed to most of our own type reflection. Our own type reflection is still used however for cases such as Bytes and FixedBytes (abi: bytes•). This also inclused several fixes for slice handling of arbitrary and fixed size for all supported types. This also further removes implicit type casting such as assigning, for example `[2]T{} = []T{1}` will fail, however `[2]T{} == []T{1, 2}` (notice assigning *slice* to fixed size *array*). Assigning arrays to slices will always succeed if they are of the same element type. Incidentally also fixes #2379
Diffstat (limited to 'accounts/abi/method.go')
-rw-r--r--accounts/abi/method.go39
1 files changed, 39 insertions, 0 deletions
diff --git a/accounts/abi/method.go b/accounts/abi/method.go
index 206c7d408..cad0cd27f 100644
--- a/accounts/abi/method.go
+++ b/accounts/abi/method.go
@@ -18,6 +18,7 @@ package abi
import (
"fmt"
+ "reflect"
"strings"
"github.com/ethereum/go-ethereum/crypto"
@@ -38,6 +39,44 @@ type Method struct {
Outputs []Argument
}
+func (m Method) pack(method Method, args ...interface{}) ([]byte, error) {
+ // Make sure arguments match up and pack them
+ if len(args) != len(method.Inputs) {
+ return nil, fmt.Errorf("argument count mismatch: %d for %d", len(args), len(method.Inputs))
+ }
+ // variable input is the output appended at the end of packed
+ // output. This is used for strings and bytes types input.
+ var variableInput []byte
+
+ var ret []byte
+ for i, a := range args {
+ input := method.Inputs[i]
+ // pack the input
+ packed, err := input.Type.pack(reflect.ValueOf(a))
+ if err != nil {
+ return nil, fmt.Errorf("`%s` %v", method.Name, err)
+ }
+
+ // check for a slice type (string, bytes, slice)
+ if input.Type.T == StringTy || input.Type.T == BytesTy || input.Type.IsSlice || input.Type.IsArray {
+ // calculate the offset
+ offset := len(method.Inputs)*32 + len(variableInput)
+ // set the offset
+ ret = append(ret, packNum(reflect.ValueOf(offset), UintTy)...)
+ // Append the packed output to the variable input. The variable input
+ // will be appended at the end of the input.
+ variableInput = append(variableInput, packed...)
+ } else {
+ // append the packed value to the input
+ ret = append(ret, packed...)
+ }
+ }
+ // append the variable input at the end of the packed input
+ ret = append(ret, variableInput...)
+
+ return ret, nil
+}
+
// Sig returns the methods string signature according to the ABI spec.
//
// Example