aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeffrey Wilcke <jeffrey@ethereum.org>2015-11-03 22:22:37 +0800
committerJeffrey Wilcke <jeffrey@ethereum.org>2015-11-03 22:22:37 +0800
commitdda3bf3ce7ef109541adb6f0020f8d2dd28e5e51 (patch)
tree8cb768f270b8e64af7631d71037fff30322c5d36
parent6dfbbc3e11cd5c88ed7d4311b30222d5c3f6cd0f (diff)
parent1f72952f043e9df3df71eb27a6ed7c6bef93a3f2 (diff)
downloaddexon-dda3bf3ce7ef109541adb6f0020f8d2dd28e5e51.tar.gz
dexon-dda3bf3ce7ef109541adb6f0020f8d2dd28e5e51.tar.zst
dexon-dda3bf3ce7ef109541adb6f0020f8d2dd28e5e51.zip
Merge pull request #1943 from obscuren/abi-fixes
accounts/abi: ABI fixes & added types
-rw-r--r--accounts/abi/abi.go12
-rw-r--r--accounts/abi/abi_test.go75
-rw-r--r--accounts/abi/type.go14
3 files changed, 80 insertions, 21 deletions
diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go
index de3128902..3f05bfe2d 100644
--- a/accounts/abi/abi.go
+++ b/accounts/abi/abi.go
@@ -36,7 +36,7 @@ import (
type Method struct {
Name string
Const bool
- Input []Argument
+ Inputs []Argument
Return Type // not yet implemented
}
@@ -49,9 +49,9 @@ type Method struct {
// Please note that "int" is substitute for its canonical representation "int256"
func (m Method) String() (out string) {
out += m.Name
- types := make([]string, len(m.Input))
+ types := make([]string, len(m.Inputs))
i := 0
- for _, input := range m.Input {
+ for _, input := range m.Inputs {
types[i] = input.Type.String()
i++
}
@@ -104,7 +104,7 @@ func (abi ABI) pack(name string, args ...interface{}) ([]byte, error) {
var ret []byte
for i, a := range args {
- input := method.Input[i]
+ input := method.Inputs[i]
packed, err := input.Type.pack(a)
if err != nil {
@@ -129,8 +129,8 @@ func (abi ABI) Pack(name string, args ...interface{}) ([]byte, error) {
}
// start with argument count match
- if len(args) != len(method.Input) {
- return nil, fmt.Errorf("argument count mismatch: %d for %d", len(args), len(method.Input))
+ if len(args) != len(method.Inputs) {
+ return nil, fmt.Errorf("argument count mismatch: %d for %d", len(args), len(method.Inputs))
}
arguments, err := abi.pack(name, args...)
diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go
index 7706de05d..96dd3ee62 100644
--- a/accounts/abi/abi_test.go
+++ b/accounts/abi/abi_test.go
@@ -18,35 +18,38 @@ package abi
import (
"bytes"
+ "fmt"
+ "log"
"math/big"
"reflect"
"strings"
"testing"
+ "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
const jsondata = `
[
{ "name" : "balance", "const" : true },
- { "name" : "send", "const" : false, "input" : [ { "name" : "amount", "type" : "uint256" } ] }
+ { "name" : "send", "const" : false, "inputs" : [ { "name" : "amount", "type" : "uint256" } ] }
]`
const jsondata2 = `
[
{ "name" : "balance", "const" : true },
- { "name" : "send", "const" : false, "input" : [ { "name" : "amount", "type" : "uint256" } ] },
- { "name" : "test", "const" : false, "input" : [ { "name" : "number", "type" : "uint32" } ] },
- { "name" : "string", "const" : false, "input" : [ { "name" : "input", "type" : "string" } ] },
- { "name" : "bool", "const" : false, "input" : [ { "name" : "input", "type" : "bool" } ] },
- { "name" : "address", "const" : false, "input" : [ { "name" : "input", "type" : "address" } ] },
- { "name" : "string32", "const" : false, "input" : [ { "name" : "input", "type" : "string32" } ] },
- { "name" : "uint64[2]", "const" : false, "input" : [ { "name" : "input", "type" : "uint64[2]" } ] },
- { "name" : "uint64[]", "const" : false, "input" : [ { "name" : "input", "type" : "uint64[]" } ] },
- { "name" : "foo", "const" : false, "input" : [ { "name" : "input", "type" : "uint32" } ] },
- { "name" : "bar", "const" : false, "input" : [ { "name" : "input", "type" : "uint32" }, { "name" : "string", "type" : "uint16" } ] },
- { "name" : "slice", "const" : false, "input" : [ { "name" : "input", "type" : "uint32[2]" } ] },
- { "name" : "slice256", "const" : false, "input" : [ { "name" : "input", "type" : "uint256[2]" } ] }
+ { "name" : "send", "const" : false, "inputs" : [ { "name" : "amount", "type" : "uint256" } ] },
+ { "name" : "test", "const" : false, "inputs" : [ { "name" : "number", "type" : "uint32" } ] },
+ { "name" : "string", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "string" } ] },
+ { "name" : "bool", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "bool" } ] },
+ { "name" : "address", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "address" } ] },
+ { "name" : "string32", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "string32" } ] },
+ { "name" : "uint64[2]", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint64[2]" } ] },
+ { "name" : "uint64[]", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint64[]" } ] },
+ { "name" : "foo", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32" } ] },
+ { "name" : "bar", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32" }, { "name" : "string", "type" : "uint16" } ] },
+ { "name" : "slice", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32[2]" } ] },
+ { "name" : "slice256", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint256[2]" } ] }
]`
func TestType(t *testing.T) {
@@ -344,3 +347,49 @@ func TestPackSliceBig(t *testing.T) {
t.Errorf("expected %x got %x", sig, packed)
}
}
+
+func ExampleJSON() {
+ const definition = `[{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"isBar","outputs":[{"name":"","type":"bool"}],"type":"function"}]`
+
+ abi, err := JSON(strings.NewReader(definition))
+ if err != nil {
+ log.Fatalln(err)
+ }
+ out, err := abi.Pack("isBar", common.HexToAddress("01"))
+ if err != nil {
+ log.Fatalln(err)
+ }
+
+ fmt.Printf("%x\n", out)
+ // Output:
+ // 1f2c40920000000000000000000000000000000000000000000000000000000000000001
+}
+
+func TestBytes(t *testing.T) {
+ const definition = `[
+ { "name" : "balance", "const" : true, "inputs" : [ { "name" : "address", "type" : "bytes20" } ] },
+ { "name" : "send", "const" : false, "inputs" : [ { "name" : "amount", "type" : "uint256" } ] }
+]`
+
+ abi, err := JSON(strings.NewReader(definition))
+ if err != nil {
+ t.Fatal(err)
+ }
+ ok := make([]byte, 20)
+ _, err = abi.Pack("balance", ok)
+ if err != nil {
+ t.Error(err)
+ }
+
+ toosmall := make([]byte, 19)
+ _, err = abi.Pack("balance", toosmall)
+ if err != nil {
+ t.Error(err)
+ }
+
+ toobig := make([]byte, 21)
+ _, err = abi.Pack("balance", toobig)
+ if err == nil {
+ t.Error("expected error")
+ }
+}
diff --git a/accounts/abi/type.go b/accounts/abi/type.go
index b16822d3b..16d7491e7 100644
--- a/accounts/abi/type.go
+++ b/accounts/abi/type.go
@@ -43,7 +43,7 @@ type Type struct {
stringKind string // holds the unparsed string for deriving signatures
}
-// New type returns a fully parsed Type given by the input string or an error if it can't be parsed.
+// NewType returns a fully parsed Type given by the input string or an error if it can't be parsed.
//
// Strings can be in the format of:
//
@@ -130,6 +130,10 @@ func NewType(t string) (typ Type, err error) {
if vsize > 0 {
typ.Size = 32
}
+ case "bytes":
+ typ.Kind = reflect.Slice
+ typ.Type = byte_ts
+ typ.Size = vsize
default:
return Type{}, fmt.Errorf("unsupported arg type: %s", t)
}
@@ -200,7 +204,13 @@ func (t Type) pack(v interface{}) ([]byte, error) {
} else {
return common.LeftPadBytes(common.Big0.Bytes(), 32), nil
}
+ case reflect.Array:
+ if v, ok := value.Interface().(common.Address); ok {
+ return t.pack(v[:])
+ } else if v, ok := value.Interface().(common.Hash); ok {
+ return t.pack(v[:])
+ }
}
- panic("unreached")
+ return nil, fmt.Errorf("ABI: bad input given %T", value.Kind())
}