Merge pull request #1367 from nspcc-dev/rpc/array_func_params

rpc: allow to use arrays in expandArrayIntoScript
This commit is contained in:
Roman Khimov 2020-08-27 17:31:07 +03:00 committed by GitHub
commit 5d306297e9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 14 deletions

View file

@ -97,6 +97,17 @@ func expandArrayIntoScript(script *io.BinWriter, slice []Param) error {
default:
return errors.New("wrong boolean value")
}
case smartcontract.ArrayType:
val, err := fp.Value.GetArray()
if err != nil {
return err
}
err = expandArrayIntoScript(script, val)
if err != nil {
return err
}
emit.Int(script, int64(len(val)))
emit.Opcode(script, opcode.PACK)
default:
return fmt.Errorf("parameter type %v is not supported", fp.Type)
}
@ -135,17 +146,3 @@ func CreateFunctionInvocationScript(contract util.Uint160, params Params) ([]byt
emit.AppCall(script.BinWriter, contract)
return script.Bytes(), nil
}
// CreateInvocationScript creates a script to invoke given contract with
// given parameters. It differs from CreateFunctionInvocationScript in that it
// expects one array of FuncParams and expands it onto the stack as independent
// elements.
func CreateInvocationScript(contract util.Uint160, funcParams []Param) ([]byte, error) {
script := io.NewBufBinWriter()
err := expandArrayIntoScript(script.BinWriter, funcParams)
if err != nil {
return nil, err
}
emit.AppCall(script.BinWriter, contract)
return script.Bytes(), nil
}

View file

@ -4,8 +4,10 @@ import (
"encoding/hex"
"testing"
"github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -88,3 +90,38 @@ func TestInvocationScriptCreationBad(t *testing.T) {
assert.NotNil(t, err)
}
}
func TestExpandArrayIntoScript(t *testing.T) {
testCases := []struct {
Input []Param
Expected []byte
}{
{
Input: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.StringType, Value: Param{Value: "a"}}}},
Expected: []byte{byte(opcode.PUSHDATA1), 1, byte('a')},
},
{
Input: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.ArrayType, Value: Param{Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.StringType, Value: Param{Value: "a"}}}}}}}},
Expected: []byte{byte(opcode.PUSHDATA1), 1, byte('a'), byte(opcode.PUSH1), byte(opcode.PACK)},
},
}
for _, c := range testCases {
script := io.NewBufBinWriter()
err := expandArrayIntoScript(script.BinWriter, c.Input)
require.NoError(t, err)
require.Equal(t, c.Expected, script.Bytes())
}
errorCases := [][]Param{
{
{Type: FuncParamT, Value: FuncParam{Type: smartcontract.ArrayType, Value: Param{Value: "a"}}},
},
{
{Type: FuncParamT, Value: FuncParam{Type: smartcontract.ArrayType, Value: Param{Value: []Param{{Type: FuncParamT, Value: nil}}}}},
},
}
for _, c := range errorCases {
script := io.NewBufBinWriter()
err := expandArrayIntoScript(script.BinWriter, c)
require.Error(t, err)
}
}