|
|
|
@ -49,7 +49,9 @@ const jsondata2 = ` |
|
|
|
|
{ "type" : "function", "name" : "foo", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32" } ] }, |
|
|
|
|
{ "type" : "function", "name" : "bar", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32" }, { "name" : "string", "type" : "uint16" } ] }, |
|
|
|
|
{ "type" : "function", "name" : "slice", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32[2]" } ] }, |
|
|
|
|
{ "type" : "function", "name" : "slice256", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint256[2]" } ] } |
|
|
|
|
{ "type" : "function", "name" : "slice256", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint256[2]" } ] }, |
|
|
|
|
{ "type" : "function", "name" : "sliceAddress", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "address[]" } ] }, |
|
|
|
|
{ "type" : "function", "name" : "sliceMultiAddress", "const" : false, "inputs" : [ { "name" : "a", "type" : "address[]" }, { "name" : "b", "type" : "address[]" } ] } |
|
|
|
|
]` |
|
|
|
|
|
|
|
|
|
func TestType(t *testing.T) { |
|
|
|
@ -57,7 +59,7 @@ func TestType(t *testing.T) { |
|
|
|
|
if err != nil { |
|
|
|
|
t.Error(err) |
|
|
|
|
} |
|
|
|
|
if typ.Kind != reflect.Ptr { |
|
|
|
|
if typ.Kind != reflect.Uint { |
|
|
|
|
t.Error("expected uint32 to have kind Ptr") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -65,10 +67,10 @@ func TestType(t *testing.T) { |
|
|
|
|
if err != nil { |
|
|
|
|
t.Error(err) |
|
|
|
|
} |
|
|
|
|
if typ.Kind != reflect.Slice { |
|
|
|
|
t.Error("expected uint32[] to have type slice") |
|
|
|
|
if !typ.IsSlice { |
|
|
|
|
t.Error("expected uint32[] to be slice") |
|
|
|
|
} |
|
|
|
|
if typ.Type != ubig_ts { |
|
|
|
|
if typ.Type != ubig_t { |
|
|
|
|
t.Error("expcted uith32[] to have type uint64") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -76,13 +78,13 @@ func TestType(t *testing.T) { |
|
|
|
|
if err != nil { |
|
|
|
|
t.Error(err) |
|
|
|
|
} |
|
|
|
|
if typ.Kind != reflect.Slice { |
|
|
|
|
t.Error("expected uint32[2] to have kind slice") |
|
|
|
|
if !typ.IsSlice { |
|
|
|
|
t.Error("expected uint32[2] to be slice") |
|
|
|
|
} |
|
|
|
|
if typ.Type != ubig_ts { |
|
|
|
|
if typ.Type != ubig_t { |
|
|
|
|
t.Error("expcted uith32[2] to have type uint64") |
|
|
|
|
} |
|
|
|
|
if typ.Size != 2 { |
|
|
|
|
if typ.SliceSize != 2 { |
|
|
|
|
t.Error("expected uint32[2] to have a size of 2") |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -147,10 +149,6 @@ func TestTestNumbers(t *testing.T) { |
|
|
|
|
t.Errorf("expected send( ptr ) to throw, requires *big.Int instead of *int") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if _, err := abi.Pack("send", 1000); err != nil { |
|
|
|
|
t.Error("expected send(1000) to cast to big") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if _, err := abi.Pack("test", uint32(1000)); err != nil { |
|
|
|
|
t.Error(err) |
|
|
|
|
} |
|
|
|
@ -202,17 +200,7 @@ func TestTestSlice(t *testing.T) { |
|
|
|
|
t.FailNow() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
addr := make([]byte, 20) |
|
|
|
|
if _, err := abi.Pack("address", addr); err != nil { |
|
|
|
|
t.Error(err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
addr = make([]byte, 21) |
|
|
|
|
if _, err := abi.Pack("address", addr); err == nil { |
|
|
|
|
t.Error("expected address of 21 width to throw") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
slice := make([]byte, 2) |
|
|
|
|
slice := make([]uint64, 2) |
|
|
|
|
if _, err := abi.Pack("uint64[2]", slice); err != nil { |
|
|
|
|
t.Error(err) |
|
|
|
|
} |
|
|
|
@ -222,16 +210,18 @@ func TestTestSlice(t *testing.T) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func TestTestAddress(t *testing.T) { |
|
|
|
|
func TestImplicitTypeCasts(t *testing.T) { |
|
|
|
|
abi, err := JSON(strings.NewReader(jsondata2)) |
|
|
|
|
if err != nil { |
|
|
|
|
t.Error(err) |
|
|
|
|
t.FailNow() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
addr := make([]byte, 20) |
|
|
|
|
if _, err := abi.Pack("address", addr); err != nil { |
|
|
|
|
t.Error(err) |
|
|
|
|
slice := make([]uint8, 2) |
|
|
|
|
_, err = abi.Pack("uint64[2]", slice) |
|
|
|
|
expStr := "`uint64[2]` abi: cannot use type uint8 as type uint64" |
|
|
|
|
if err.Error() != expStr { |
|
|
|
|
t.Errorf("expected %v, got %v", expStr, err) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -310,44 +300,69 @@ func TestPackSlice(t *testing.T) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sig := crypto.Keccak256([]byte("slice(uint32[2])"))[:4] |
|
|
|
|
sig = append(sig, make([]byte, 64)...) |
|
|
|
|
sig[35] = 1 |
|
|
|
|
sig[67] = 2 |
|
|
|
|
sig = append(sig, common.LeftPadBytes([]byte{32}, 32)...) |
|
|
|
|
sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) |
|
|
|
|
sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) |
|
|
|
|
sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) |
|
|
|
|
|
|
|
|
|
packed, err := abi.Pack("slice", []uint32{1, 2}) |
|
|
|
|
if err != nil { |
|
|
|
|
t.Error(err) |
|
|
|
|
t.FailNow() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if !bytes.Equal(packed, sig) { |
|
|
|
|
t.Errorf("expected %x got %x", sig, packed) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func TestPackSliceBig(t *testing.T) { |
|
|
|
|
abi, err := JSON(strings.NewReader(jsondata2)) |
|
|
|
|
var addrA, addrB = common.Address{1}, common.Address{2} |
|
|
|
|
sig = abi.Methods["sliceAddress"].Id() |
|
|
|
|
sig = append(sig, common.LeftPadBytes([]byte{32}, 32)...) |
|
|
|
|
sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) |
|
|
|
|
sig = append(sig, common.LeftPadBytes(addrA[:], 32)...) |
|
|
|
|
sig = append(sig, common.LeftPadBytes(addrB[:], 32)...) |
|
|
|
|
|
|
|
|
|
packed, err = abi.Pack("sliceAddress", []common.Address{addrA, addrB}) |
|
|
|
|
if err != nil { |
|
|
|
|
t.Error(err) |
|
|
|
|
t.FailNow() |
|
|
|
|
t.Fatal(err) |
|
|
|
|
} |
|
|
|
|
if !bytes.Equal(packed, sig) { |
|
|
|
|
t.Errorf("expected %x got %x", sig, packed) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sig := crypto.Keccak256([]byte("slice256(uint256[2])"))[:4] |
|
|
|
|
sig = append(sig, make([]byte, 64)...) |
|
|
|
|
sig[35] = 1 |
|
|
|
|
sig[67] = 2 |
|
|
|
|
var addrC, addrD = common.Address{3}, common.Address{4} |
|
|
|
|
sig = abi.Methods["sliceMultiAddress"].Id() |
|
|
|
|
sig = append(sig, common.LeftPadBytes([]byte{64}, 32)...) |
|
|
|
|
sig = append(sig, common.LeftPadBytes([]byte{160}, 32)...) |
|
|
|
|
sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) |
|
|
|
|
sig = append(sig, common.LeftPadBytes(addrA[:], 32)...) |
|
|
|
|
sig = append(sig, common.LeftPadBytes(addrB[:], 32)...) |
|
|
|
|
sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) |
|
|
|
|
sig = append(sig, common.LeftPadBytes(addrC[:], 32)...) |
|
|
|
|
sig = append(sig, common.LeftPadBytes(addrD[:], 32)...) |
|
|
|
|
|
|
|
|
|
packed, err := abi.Pack("slice256", []*big.Int{big.NewInt(1), big.NewInt(2)}) |
|
|
|
|
packed, err = abi.Pack("sliceMultiAddress", []common.Address{addrA, addrB}, []common.Address{addrC, addrD}) |
|
|
|
|
if err != nil { |
|
|
|
|
t.Fatal(err) |
|
|
|
|
} |
|
|
|
|
if !bytes.Equal(packed, sig) { |
|
|
|
|
t.Errorf("expected %x got %x", sig, packed) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sig = crypto.Keccak256([]byte("slice256(uint256[2])"))[:4] |
|
|
|
|
sig = append(sig, common.LeftPadBytes([]byte{32}, 32)...) |
|
|
|
|
sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) |
|
|
|
|
sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) |
|
|
|
|
sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) |
|
|
|
|
|
|
|
|
|
packed, err = abi.Pack("slice256", []*big.Int{big.NewInt(1), big.NewInt(2)}) |
|
|
|
|
if err != nil { |
|
|
|
|
t.Error(err) |
|
|
|
|
t.FailNow() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if !bytes.Equal(packed, sig) { |
|
|
|
|
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"}]` |
|
|
|
|
|
|
|
|
@ -370,7 +385,7 @@ func TestInputVariableInputLength(t *testing.T) { |
|
|
|
|
{ "type" : "function", "name" : "strOne", "const" : true, "inputs" : [ { "name" : "str", "type" : "string" } ] }, |
|
|
|
|
{ "type" : "function", "name" : "bytesOne", "const" : true, "inputs" : [ { "name" : "str", "type" : "bytes" } ] }, |
|
|
|
|
{ "type" : "function", "name" : "strTwo", "const" : true, "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "str1", "type" : "string" } ] } |
|
|
|
|
]` |
|
|
|
|
]` |
|
|
|
|
|
|
|
|
|
abi, err := JSON(strings.NewReader(definition)) |
|
|
|
|
if err != nil { |
|
|
|
@ -493,35 +508,6 @@ func TestInputVariableInputLength(t *testing.T) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func TestBytes(t *testing.T) { |
|
|
|
|
const definition = `[ |
|
|
|
|
{ "type" : "function", "name" : "balance", "const" : true, "inputs" : [ { "name" : "address", "type" : "bytes20" } ] }, |
|
|
|
|
{ "type" : "function", "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") |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func TestDefaultFunctionParsing(t *testing.T) { |
|
|
|
|
const definition = `[{ "name" : "balance" }]` |
|
|
|
|
|
|
|
|
@ -713,12 +699,15 @@ func TestUnmarshal(t *testing.T) { |
|
|
|
|
{ "name" : "bytes", "const" : false, "outputs": [ { "type": "bytes" } ] }, |
|
|
|
|
{ "name" : "fixed", "const" : false, "outputs": [ { "type": "bytes32" } ] }, |
|
|
|
|
{ "name" : "multi", "const" : false, "outputs": [ { "type": "bytes" }, { "type": "bytes" } ] }, |
|
|
|
|
{ "name" : "addressSliceSingle", "const" : false, "outputs": [ { "type": "address[]" } ] }, |
|
|
|
|
{ "name" : "addressSliceDouble", "const" : false, "outputs": [ { "name": "a", "type": "address[]" }, { "name": "b", "type": "address[]" } ] }, |
|
|
|
|
{ "name" : "mixedBytes", "const" : true, "outputs": [ { "name": "a", "type": "bytes" }, { "name": "b", "type": "bytes32" } ] }]` |
|
|
|
|
|
|
|
|
|
abi, err := JSON(strings.NewReader(definition)) |
|
|
|
|
if err != nil { |
|
|
|
|
t.Fatal(err) |
|
|
|
|
} |
|
|
|
|
buff := new(bytes.Buffer) |
|
|
|
|
|
|
|
|
|
// marshal int
|
|
|
|
|
var Int *big.Int |
|
|
|
@ -743,7 +732,6 @@ func TestUnmarshal(t *testing.T) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// marshal dynamic bytes max length 32
|
|
|
|
|
buff := new(bytes.Buffer) |
|
|
|
|
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020")) |
|
|
|
|
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020")) |
|
|
|
|
bytesOut := common.RightPadBytes([]byte("hello"), 32) |
|
|
|
@ -862,4 +850,71 @@ func TestUnmarshal(t *testing.T) { |
|
|
|
|
if !bytes.Equal(fixed, out[1].([]byte)) { |
|
|
|
|
t.Errorf("expected %x, got %x", fixed, out[1]) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// marshal address slice
|
|
|
|
|
buff.Reset() |
|
|
|
|
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020")) // offset
|
|
|
|
|
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) // size
|
|
|
|
|
buff.Write(common.Hex2Bytes("0000000000000000000000000100000000000000000000000000000000000000")) |
|
|
|
|
|
|
|
|
|
var outAddr []common.Address |
|
|
|
|
err = abi.Unpack(&outAddr, "addressSliceSingle", buff.Bytes()) |
|
|
|
|
if err != nil { |
|
|
|
|
t.Fatal("didn't expect error:", err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if len(outAddr) != 1 { |
|
|
|
|
t.Fatal("expected 1 item, got", len(outAddr)) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if outAddr[0] != (common.Address{1}) { |
|
|
|
|
t.Errorf("expected %x, got %x", common.Address{1}, outAddr[0]) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// marshal multiple address slice
|
|
|
|
|
buff.Reset() |
|
|
|
|
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040")) // offset
|
|
|
|
|
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000080")) // offset
|
|
|
|
|
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) // size
|
|
|
|
|
buff.Write(common.Hex2Bytes("0000000000000000000000000100000000000000000000000000000000000000")) |
|
|
|
|
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002")) // size
|
|
|
|
|
buff.Write(common.Hex2Bytes("0000000000000000000000000200000000000000000000000000000000000000")) |
|
|
|
|
buff.Write(common.Hex2Bytes("0000000000000000000000000300000000000000000000000000000000000000")) |
|
|
|
|
|
|
|
|
|
var outAddrStruct struct { |
|
|
|
|
A []common.Address |
|
|
|
|
B []common.Address |
|
|
|
|
} |
|
|
|
|
err = abi.Unpack(&outAddrStruct, "addressSliceDouble", buff.Bytes()) |
|
|
|
|
if err != nil { |
|
|
|
|
t.Fatal("didn't expect error:", err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if len(outAddrStruct.A) != 1 { |
|
|
|
|
t.Fatal("expected 1 item, got", len(outAddrStruct.A)) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if outAddrStruct.A[0] != (common.Address{1}) { |
|
|
|
|
t.Errorf("expected %x, got %x", common.Address{1}, outAddrStruct.A[0]) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if len(outAddrStruct.B) != 2 { |
|
|
|
|
t.Fatal("expected 1 item, got", len(outAddrStruct.B)) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if outAddrStruct.B[0] != (common.Address{2}) { |
|
|
|
|
t.Errorf("expected %x, got %x", common.Address{2}, outAddrStruct.B[0]) |
|
|
|
|
} |
|
|
|
|
if outAddrStruct.B[1] != (common.Address{3}) { |
|
|
|
|
t.Errorf("expected %x, got %x", common.Address{3}, outAddrStruct.B[1]) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// marshal invalid address slice
|
|
|
|
|
buff.Reset() |
|
|
|
|
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000100")) |
|
|
|
|
|
|
|
|
|
err = abi.Unpack(&outAddr, "addressSliceSingle", buff.Bytes()) |
|
|
|
|
if err == nil { |
|
|
|
|
t.Fatal("expected error:", err) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|