rpc: allow to use arrays in expandArrayIntoScript

Should be done together with #1363. Also removed
CreateInvocationScript function as we don't have `Invoke` RPC-call
anymore.
This commit is contained in:
Anna Shaleva 2020-08-27 11:44:40 +03:00
parent ca2e8ed528
commit 5e8ce45a84
2 changed files with 48 additions and 14 deletions

View file

@ -97,6 +97,17 @@ func expandArrayIntoScript(script *io.BinWriter, slice []Param) error {
default: default:
return errors.New("wrong boolean value") 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: default:
return fmt.Errorf("parameter type %v is not supported", fp.Type) 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) emit.AppCall(script.BinWriter, contract)
return script.Bytes(), nil 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" "encoding/hex"
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/util" "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/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -88,3 +90,38 @@ func TestInvocationScriptCreationBad(t *testing.T) {
assert.NotNil(t, err) 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)
}
}