forked from cerc-io/plugeth
accounts/abi: include fixed array size in offset for dynamic type
This commit is contained in:
parent
8d8034fe59
commit
a5330fe0c5
@ -367,6 +367,56 @@ func TestInputVariableInputLength(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestInputFixedArrayAndVariableInputLength(t *testing.T) {
|
||||||
|
const definition = `[
|
||||||
|
{ "type" : "function", "name" : "fixedArrStr", "constant" : true, "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "fixedArr", "type" : "uint256[2]" } ] },
|
||||||
|
{ "type" : "function", "name" : "fixedArrBytes", "constant" : true, "inputs" : [ { "name" : "str", "type" : "bytes" }, { "name" : "fixedArr", "type" : "uint256[2]" } ] }
|
||||||
|
]`
|
||||||
|
|
||||||
|
abi, err := JSON(strings.NewReader(definition))
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// test fixed array of uint256 and a string
|
||||||
|
arrin := [2]*big.Int{big.NewInt(1), big.NewInt(2)}
|
||||||
|
strin := "hello world"
|
||||||
|
fixedArrStrPack, err := abi.Pack("fixedArrStr", strin, arrin)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
offset := make([]byte, 32)
|
||||||
|
offset[31] = 96
|
||||||
|
length := make([]byte, 32)
|
||||||
|
length[31] = byte(len(strin))
|
||||||
|
strvalue := common.RightPadBytes([]byte(strin), 32)
|
||||||
|
arrinvalue1 := common.LeftPadBytes(arrin[0].Bytes(), 32)
|
||||||
|
arrinvalue2 := common.LeftPadBytes(arrin[1].Bytes(), 32)
|
||||||
|
exp := append(offset, arrinvalue1...)
|
||||||
|
exp = append(exp, arrinvalue2...)
|
||||||
|
exp = append(exp, append(length, strvalue...)...)
|
||||||
|
|
||||||
|
// ignore first 4 bytes of the output. This is the function identifier
|
||||||
|
fixedArrStrPack = fixedArrStrPack[4:]
|
||||||
|
if !bytes.Equal(fixedArrStrPack, exp) {
|
||||||
|
t.Errorf("expected %x, got %x\n", exp, fixedArrStrPack)
|
||||||
|
}
|
||||||
|
|
||||||
|
// test fixed array of uint256 and a byte array
|
||||||
|
bytesin := []byte(strin)
|
||||||
|
fixedArrBytesPack, err := abi.Pack("fixedArrBytes", bytesin, arrin)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore first 4 bytes of the output. This is the function identifier
|
||||||
|
fixedArrBytesPack = fixedArrBytesPack[4:]
|
||||||
|
if !bytes.Equal(fixedArrBytesPack, exp) {
|
||||||
|
t.Errorf("expected %x, got %x\n", exp, fixedArrBytesPack)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestDefaultFunctionParsing(t *testing.T) {
|
func TestDefaultFunctionParsing(t *testing.T) {
|
||||||
const definition = `[{ "name" : "balance" }]`
|
const definition = `[{ "name" : "balance" }]`
|
||||||
|
|
||||||
|
@ -48,6 +48,16 @@ func (method Method) pack(args ...interface{}) ([]byte, error) {
|
|||||||
// output. This is used for strings and bytes types input.
|
// output. This is used for strings and bytes types input.
|
||||||
var variableInput []byte
|
var variableInput []byte
|
||||||
|
|
||||||
|
// input offset is the bytes offset for packed output
|
||||||
|
inputOffset := 0
|
||||||
|
for _, input := range method.Inputs {
|
||||||
|
if input.Type.IsArray {
|
||||||
|
inputOffset += (32 * input.Type.SliceSize)
|
||||||
|
} else {
|
||||||
|
inputOffset += 32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var ret []byte
|
var ret []byte
|
||||||
for i, a := range args {
|
for i, a := range args {
|
||||||
input := method.Inputs[i]
|
input := method.Inputs[i]
|
||||||
@ -60,7 +70,8 @@ func (method Method) pack(args ...interface{}) ([]byte, error) {
|
|||||||
// check for a slice type (string, bytes, slice)
|
// check for a slice type (string, bytes, slice)
|
||||||
if input.Type.requiresLengthPrefix() {
|
if input.Type.requiresLengthPrefix() {
|
||||||
// calculate the offset
|
// calculate the offset
|
||||||
offset := len(method.Inputs)*32 + len(variableInput)
|
offset := inputOffset + len(variableInput)
|
||||||
|
|
||||||
// set the offset
|
// set the offset
|
||||||
ret = append(ret, packNum(reflect.ValueOf(offset))...)
|
ret = append(ret, packNum(reflect.ValueOf(offset))...)
|
||||||
// Append the packed output to the variable input. The variable input
|
// Append the packed output to the variable input. The variable input
|
||||||
|
Loading…
Reference in New Issue
Block a user