Skip to content

Commit

Permalink
Abi/dynamic types (ethereum#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
vedhavyas authored Nov 7, 2018
1 parent ded4e8a commit dabca31
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 34 deletions.
40 changes: 15 additions & 25 deletions accounts/abi/pack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func TestPack(t *testing.T) {
{
"uint8[]",
[]uint8{1, 2},
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
},
{
"uint16",
Expand All @@ -52,7 +52,7 @@ func TestPack(t *testing.T) {
{
"uint16[]",
[]uint16{1, 2},
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
},
{
"uint32",
Expand All @@ -62,7 +62,7 @@ func TestPack(t *testing.T) {
{
"uint32[]",
[]uint32{1, 2},
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
},
{
"uint64",
Expand All @@ -72,7 +72,7 @@ func TestPack(t *testing.T) {
{
"uint64[]",
[]uint64{1, 2},
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
},
{
"uint256",
Expand All @@ -82,7 +82,7 @@ func TestPack(t *testing.T) {
{
"uint256[]",
[]*big.Int{big.NewInt(1), big.NewInt(2)},
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
},
{
"int8",
Expand All @@ -92,7 +92,7 @@ func TestPack(t *testing.T) {
{
"int8[]",
[]int8{1, 2},
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
},
{
"int16",
Expand All @@ -102,7 +102,7 @@ func TestPack(t *testing.T) {
{
"int16[]",
[]int16{1, 2},
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
},
{
"int32",
Expand All @@ -112,7 +112,7 @@ func TestPack(t *testing.T) {
{
"int32[]",
[]int32{1, 2},
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
},
{
"int64",
Expand All @@ -122,7 +122,7 @@ func TestPack(t *testing.T) {
{
"int64[]",
[]int64{1, 2},
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
},
{
"int256",
Expand All @@ -132,7 +132,7 @@ func TestPack(t *testing.T) {
{
"int256[]",
[]*big.Int{big.NewInt(1), big.NewInt(2)},
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
},
{
"bytes1",
Expand Down Expand Up @@ -308,18 +308,12 @@ func TestPack(t *testing.T) {
//web3.eth.abi.encodeParameter('address[]', ['0x0100000000000000000000000000000000000000','0x0200000000000000000000000000000000000000']);
"address[]",
[]common.Address{{1}, {2}},
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020" +
"0000000000000000000000000000000000000000000000000000000000000002" +
"0000000000000000000000000100000000000000000000000000000000000000" +
"0000000000000000000000000200000000000000000000000000000000000000"),
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000"),
},
{
"bytes32[]",
[]common.Hash{{1}, {2}},
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020" + //offset: 32
"0000000000000000000000000000000000000000000000000000000000000002" + //len: 2
"0100000000000000000000000000000000000000000000000000000000000000" + // 1
"0200000000000000000000000000000000000000000000000000000000000000"), // 2
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000201000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000"),
},
{
"function",
Expand All @@ -329,15 +323,12 @@ func TestPack(t *testing.T) {
{
"string",
"foobar",
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020" + // offset: 32
"0000000000000000000000000000000000000000000000000000000000000006" + // len: 6
"666f6f6261720000000000000000000000000000000000000000000000000000"), // "foobar"
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000006666f6f6261720000000000000000000000000000000000000000000000000000"),
},
{
"string[]",
[]string{"hello", "foobar"},
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020" + // offset array 32
"0000000000000000000000000000000000000000000000000000000000000002" + // len(array) = 2
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002" + // len(array) = 2
"0000000000000000000000000000000000000000000000000000000000000040" + // offset 64 to i=0
"0000000000000000000000000000000000000000000000000000000000000080" + // offset 128 to i=1
"0000000000000000000000000000000000000000000000000000000000000005" + // len(str[0]) = 5
Expand All @@ -352,8 +343,7 @@ func TestPack(t *testing.T) {
// '0x0400000000000000000000000000000000000000000000000000000000000000','0x0500000000000000000000000000000000000000000000000000000000000000']]);
"bytes32[][]",
[][]common.Hash{{{1}, {2}}, {{3}, {4}, {5}}},
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020" + // offset array 32
"0000000000000000000000000000000000000000000000000000000000000002" + // len(array) = 2
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002" + // len(array) = 2
"0000000000000000000000000000000000000000000000000000000000000040" + // offset 64 to i=0
"00000000000000000000000000000000000000000000000000000000000000a0" + // offset 160 to i=1
"0000000000000000000000000000000000000000000000000000000000000002" + // len(array[0]) = 2
Expand Down
47 changes: 38 additions & 9 deletions accounts/abi/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,27 +183,56 @@ func (t Type) pack(v reflect.Value) ([]byte, error) {
return nil, err
}

if t.T == SliceTy || t.T == ArrayTy {
var packed []byte
switch t.T {
case SliceTy, ArrayTy:
var ret []byte

if t.requiresLengthPrefix() {
// append length
ret = append(ret, packNum(reflect.ValueOf(v.Len()))...)
}

// calculate offset if any
offset := 0
offsetReq := t.Elem.requiresLengthPrefix()
if offsetReq {
offset = getOffset(*t.Elem) * v.Len()
}

var tail []byte
for i := 0; i < v.Len(); i++ {
val, err := t.Elem.pack(v.Index(i))
if err != nil {
return nil, err
}
packed = append(packed, val...)
}
if t.T == SliceTy {
return packBytesSlice(packed, v.Len()), nil
} else if t.T == ArrayTy {
return packed, nil

if !offsetReq {
ret = append(ret, val...)
continue
}

ret = append(ret, packNum(reflect.ValueOf(offset))...)
offset += len(val)
tail = append(tail, val...)
}

return append(ret, tail...), nil
default:
return packElement(t, v), nil
}
return packElement(t, v), nil
}

// requireLengthPrefix returns whether the type requires any sort of length
// prefixing.
func (t Type) requiresLengthPrefix() bool {
return t.T == StringTy || t.T == BytesTy || t.T == SliceTy
}

// getOffset returns the offset to be added for t
func getOffset(t Type) int {
if t.T == ArrayTy {
return 32 * t.Size
}

return 32
}

0 comments on commit dabca31

Please sign in to comment.