cli/rpc: hide parameter encoding details for Invoke* calls

The script is passed as a hex string, but no one should care. The hash is a
hex-encoded LE value, but no one should care either. Hex might change to
base64, LE to BE, no one outside these functions should care about that.
This commit is contained in:
Roman Khimov 2020-07-02 16:38:33 +03:00
parent 0819583413
commit 4f8e4628dc
5 changed files with 32 additions and 24 deletions

View file

@ -399,8 +399,10 @@ func invokeInternal(ctx *cli.Context, signAndPush bool) error {
if !args.Present() { if !args.Present() {
return cli.NewExitError(errNoScriptHash, 1) return cli.NewExitError(errNoScriptHash, 1)
} }
script := args[0] script, err := util.Uint160DecodeStringLE(args[0])
if err != nil {
return cli.NewExitError(fmt.Errorf("incorrect script hash: %v", err), 1)
}
if len(args) <= 1 { if len(args) <= 1 {
return cli.NewExitError(errNoMethod, 1) return cli.NewExitError(errNoMethod, 1)
} }
@ -510,8 +512,7 @@ func testInvokeScript(ctx *cli.Context) error {
return err return err
} }
scriptHex := hex.EncodeToString(nefFile.Script) resp, err := c.InvokeScript(nefFile.Script, cosigners)
resp, err := c.InvokeScript(scriptHex, cosigners)
if err != nil { if err != nil {
return cli.NewExitError(err, 1) return cli.NewExitError(err, 1)
} }
@ -659,7 +660,7 @@ func contractDeploy(ctx *cli.Context) error {
return cli.NewExitError(fmt.Errorf("failed to create deployment script: %v", err), 1) return cli.NewExitError(fmt.Errorf("failed to create deployment script: %v", err), 1)
} }
// It doesn't require any cosigners. // It doesn't require any cosigners.
invRes, err := c.InvokeScript(hex.EncodeToString(txScript), nil) invRes, err := c.InvokeScript(txScript, nil)
if err != nil { if err != nil {
return cli.NewExitError(fmt.Errorf("failed to test-invoke deployment script: %v", err), 1) return cli.NewExitError(fmt.Errorf("failed to test-invoke deployment script: %v", err), 1)
} }

View file

@ -1,7 +1,6 @@
package client package client
import ( import (
"encoding/hex"
"errors" "errors"
"fmt" "fmt"
@ -25,7 +24,7 @@ var (
// NEP5Decimals invokes `decimals` NEP5 method on a specified contract. // NEP5Decimals invokes `decimals` NEP5 method on a specified contract.
func (c *Client) NEP5Decimals(tokenHash util.Uint160) (int64, error) { func (c *Client) NEP5Decimals(tokenHash util.Uint160) (int64, error) {
result, err := c.InvokeFunction(tokenHash.StringLE(), "decimals", []smartcontract.Parameter{}, nil) result, err := c.InvokeFunction(tokenHash, "decimals", []smartcontract.Parameter{}, nil)
if err != nil { if err != nil {
return 0, err return 0, err
} else if result.State != "HALT" || len(result.Stack) == 0 { } else if result.State != "HALT" || len(result.Stack) == 0 {
@ -37,7 +36,7 @@ func (c *Client) NEP5Decimals(tokenHash util.Uint160) (int64, error) {
// NEP5Name invokes `name` NEP5 method on a specified contract. // NEP5Name invokes `name` NEP5 method on a specified contract.
func (c *Client) NEP5Name(tokenHash util.Uint160) (string, error) { func (c *Client) NEP5Name(tokenHash util.Uint160) (string, error) {
result, err := c.InvokeFunction(tokenHash.StringLE(), "name", []smartcontract.Parameter{}, nil) result, err := c.InvokeFunction(tokenHash, "name", []smartcontract.Parameter{}, nil)
if err != nil { if err != nil {
return "", err return "", err
} else if result.State != "HALT" || len(result.Stack) == 0 { } else if result.State != "HALT" || len(result.Stack) == 0 {
@ -49,7 +48,7 @@ func (c *Client) NEP5Name(tokenHash util.Uint160) (string, error) {
// NEP5Symbol invokes `symbol` NEP5 method on a specified contract. // NEP5Symbol invokes `symbol` NEP5 method on a specified contract.
func (c *Client) NEP5Symbol(tokenHash util.Uint160) (string, error) { func (c *Client) NEP5Symbol(tokenHash util.Uint160) (string, error) {
result, err := c.InvokeFunction(tokenHash.StringLE(), "symbol", []smartcontract.Parameter{}, nil) result, err := c.InvokeFunction(tokenHash, "symbol", []smartcontract.Parameter{}, nil)
if err != nil { if err != nil {
return "", err return "", err
} else if result.State != "HALT" || len(result.Stack) == 0 { } else if result.State != "HALT" || len(result.Stack) == 0 {
@ -61,7 +60,7 @@ func (c *Client) NEP5Symbol(tokenHash util.Uint160) (string, error) {
// NEP5TotalSupply invokes `totalSupply` NEP5 method on a specified contract. // NEP5TotalSupply invokes `totalSupply` NEP5 method on a specified contract.
func (c *Client) NEP5TotalSupply(tokenHash util.Uint160) (int64, error) { func (c *Client) NEP5TotalSupply(tokenHash util.Uint160) (int64, error) {
result, err := c.InvokeFunction(tokenHash.StringLE(), "totalSupply", []smartcontract.Parameter{}, nil) result, err := c.InvokeFunction(tokenHash, "totalSupply", []smartcontract.Parameter{}, nil)
if err != nil { if err != nil {
return 0, err return 0, err
} else if result.State != "HALT" || len(result.Stack) == 0 { } else if result.State != "HALT" || len(result.Stack) == 0 {
@ -73,7 +72,7 @@ func (c *Client) NEP5TotalSupply(tokenHash util.Uint160) (int64, error) {
// NEP5BalanceOf invokes `balanceOf` NEP5 method on a specified contract. // NEP5BalanceOf invokes `balanceOf` NEP5 method on a specified contract.
func (c *Client) NEP5BalanceOf(tokenHash util.Uint160) (int64, error) { func (c *Client) NEP5BalanceOf(tokenHash util.Uint160) (int64, error) {
result, err := c.InvokeFunction(tokenHash.StringLE(), "balanceOf", []smartcontract.Parameter{}, nil) result, err := c.InvokeFunction(tokenHash, "balanceOf", []smartcontract.Parameter{}, nil)
if err != nil { if err != nil {
return 0, err return 0, err
} else if result.State != "HALT" || len(result.Stack) == 0 { } else if result.State != "HALT" || len(result.Stack) == 0 {
@ -127,7 +126,7 @@ func (c *Client) CreateNEP5TransferTx(acc *wallet.Account, to util.Uint160, toke
}, },
} }
result, err := c.InvokeScript(hex.EncodeToString(script), []transaction.Cosigner{ result, err := c.InvokeScript(script, []transaction.Cosigner{
{ {
Account: from, Account: from,
Scopes: transaction.Global, Scopes: transaction.Global,

View file

@ -29,7 +29,7 @@ func (c *Client) GetFeePerByte() (int64, error) {
} }
func (c *Client) invokeNativePolicyMethod(operation string) (int64, error) { func (c *Client) invokeNativePolicyMethod(operation string) (int64, error) {
result, err := c.InvokeFunction(PolicyContractHash.StringLE(), operation, []smartcontract.Parameter{}, nil) result, err := c.InvokeFunction(PolicyContractHash, operation, []smartcontract.Parameter{}, nil)
if err != nil { if err != nil {
return 0, err return 0, err
} else if result.State != "HALT" || len(result.Stack) == 0 { } else if result.State != "HALT" || len(result.Stack) == 0 {
@ -41,7 +41,7 @@ func (c *Client) invokeNativePolicyMethod(operation string) (int64, error) {
// GetBlockedAccounts invokes `getBlockedAccounts` method on a native Policy contract. // GetBlockedAccounts invokes `getBlockedAccounts` method on a native Policy contract.
func (c *Client) GetBlockedAccounts() (native.BlockedAccounts, error) { func (c *Client) GetBlockedAccounts() (native.BlockedAccounts, error) {
result, err := c.InvokeFunction(PolicyContractHash.StringLE(), "getBlockedAccounts", []smartcontract.Parameter{}, nil) result, err := c.InvokeFunction(PolicyContractHash, "getBlockedAccounts", []smartcontract.Parameter{}, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} else if result.State != "HALT" || len(result.Stack) == 0 { } else if result.State != "HALT" || len(result.Stack) == 0 {

View file

@ -349,16 +349,16 @@ func (c *Client) GetVersion() (*result.Version, error) {
// InvokeScript returns the result of the given script after running it true the VM. // InvokeScript returns the result of the given script after running it true the VM.
// NOTE: This is a test invoke and will not affect the blockchain. // NOTE: This is a test invoke and will not affect the blockchain.
func (c *Client) InvokeScript(script string, cosigners []transaction.Cosigner) (*result.Invoke, error) { func (c *Client) InvokeScript(script []byte, cosigners []transaction.Cosigner) (*result.Invoke, error) {
var p = request.NewRawParams(script) var p = request.NewRawParams(hex.EncodeToString(script))
return c.invokeSomething("invokescript", p, cosigners) return c.invokeSomething("invokescript", p, cosigners)
} }
// InvokeFunction returns the results after calling the smart contract scripthash // InvokeFunction returns the results after calling the smart contract scripthash
// with the given operation and parameters. // with the given operation and parameters.
// NOTE: this is test invoke and will not affect the blockchain. // NOTE: this is test invoke and will not affect the blockchain.
func (c *Client) InvokeFunction(script, operation string, params []smartcontract.Parameter, cosigners []transaction.Cosigner) (*result.Invoke, error) { func (c *Client) InvokeFunction(contract util.Uint160, operation string, params []smartcontract.Parameter, cosigners []transaction.Cosigner) (*result.Invoke, error) {
var p = request.NewRawParams(script, operation, params) var p = request.NewRawParams(contract.StringLE(), operation, params)
return c.invokeSomething("invokefunction", p, cosigners) return c.invokeSomething("invokefunction", p, cosigners)
} }

View file

@ -616,7 +616,11 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
if err != nil { if err != nil {
panic(err) panic(err)
} }
return c.InvokeFunction("af7c7328eee5a275a3bcaee2bf0cf662b5e739be", "balanceOf", []smartcontract.Parameter{ contr, err := util.Uint160DecodeStringLE("af7c7328eee5a275a3bcaee2bf0cf662b5e739be")
if err != nil {
panic(err)
}
return c.InvokeFunction(contr, "balanceOf", []smartcontract.Parameter{
{ {
Type: smartcontract.Hash160Type, Type: smartcontract.Hash160Type,
Value: hash, Value: hash,
@ -649,7 +653,11 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
{ {
name: "positive", name: "positive",
invoke: func(c *Client) (interface{}, error) { invoke: func(c *Client) (interface{}, error) {
return c.InvokeScript("00046e616d656724058e5e1b6008847cd662728549088a9ee82191", []transaction.Cosigner{{ script, err := hex.DecodeString("00046e616d656724058e5e1b6008847cd662728549088a9ee82191")
if err != nil {
panic(err)
}
return c.InvokeScript(script, []transaction.Cosigner{{
Account: util.Uint160{1, 2, 3}, Account: util.Uint160{1, 2, 3},
}}) }})
}, },
@ -952,13 +960,13 @@ var rpcClientErrorCases = map[string][]rpcClientErrorCase{
{ {
name: "invokefunction_invalid_params_error", name: "invokefunction_invalid_params_error",
invoke: func(c *Client) (interface{}, error) { invoke: func(c *Client) (interface{}, error) {
return c.InvokeFunction("", "", []smartcontract.Parameter{}, nil) return c.InvokeFunction(util.Uint160{}, "", []smartcontract.Parameter{}, nil)
}, },
}, },
{ {
name: "invokescript_invalid_params_error", name: "invokescript_invalid_params_error",
invoke: func(c *Client) (interface{}, error) { invoke: func(c *Client) (interface{}, error) {
return c.InvokeScript("", nil) return c.InvokeScript([]byte{}, nil)
}, },
}, },
{ {
@ -1134,13 +1142,13 @@ var rpcClientErrorCases = map[string][]rpcClientErrorCase{
{ {
name: "invokefunction_unmarshalling_error", name: "invokefunction_unmarshalling_error",
invoke: func(c *Client) (interface{}, error) { invoke: func(c *Client) (interface{}, error) {
return c.InvokeFunction("", "", []smartcontract.Parameter{}, nil) return c.InvokeFunction(util.Uint160{}, "", []smartcontract.Parameter{}, nil)
}, },
}, },
{ {
name: "invokescript_unmarshalling_error", name: "invokescript_unmarshalling_error",
invoke: func(c *Client) (interface{}, error) { invoke: func(c *Client) (interface{}, error) {
return c.InvokeScript("", nil) return c.InvokeScript([]byte{}, nil)
}, },
}, },
{ {