cli: add Required flag for CLI parameters

Required field is added for CLI commands. MarkRequired function change
required parameter.

Closes #2861

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
This commit is contained in:
Ekaterina Pavlova 2023-12-21 15:33:30 +03:00
parent de98b39a95
commit 8503a9f54e
15 changed files with 226 additions and 154 deletions

View file

@ -1,6 +1,10 @@
package flags package flags
import "strings" import (
"strings"
"github.com/urfave/cli"
)
func eachName(longName string, fn func(string)) { func eachName(longName string, fn func(string)) {
parts := strings.Split(longName, ",") parts := strings.Split(longName, ",")
@ -9,3 +13,28 @@ func eachName(longName string, fn func(string)) {
fn(name) fn(name)
} }
} }
// MarkRequired marks flags with specified names as required.
func MarkRequired(flagSet []cli.Flag, names ...string) []cli.Flag {
updatedflagSet := make([]cli.Flag, 0, len(flagSet))
for _, flag := range flagSet {
for _, n := range names {
if n == flag.GetName() {
switch f := (flag).(type) {
case cli.StringFlag:
f.Required = true
flag = f
case cli.IntFlag:
f.Required = true
flag = f
case cli.BoolFlag:
f.Required = true
flag = f
}
break
}
}
updatedflagSet = append(updatedflagSet, flag)
}
return updatedflagSet
}

View file

@ -228,12 +228,10 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) {
// ownerOf: missing contract hash // ownerOf: missing contract hash
cmdOwnerOf := []string{"neo-go", "wallet", "nep11", "ownerOf", cmdOwnerOf := []string{"neo-go", "wallet", "nep11", "ownerOf",
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0], "--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
} "--token", h.StringLE()}
e.RunWithError(t, cmdOwnerOf...)
cmdOwnerOf = append(cmdOwnerOf, "--token", h.StringLE())
// ownerOf: missing token ID // ownerOf: bad token ID
e.RunWithError(t, cmdOwnerOf...) e.RunWithError(t, append(cmdOwnerOf, "--id", "test")...)
cmdOwnerOf = append(cmdOwnerOf, "--id", hex.EncodeToString(tokenID)) cmdOwnerOf = append(cmdOwnerOf, "--id", hex.EncodeToString(tokenID))
// ownerOf: good // ownerOf: good
@ -259,12 +257,10 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) {
cmdProperties := []string{ cmdProperties := []string{
"neo-go", "wallet", "nep11", "properties", "neo-go", "wallet", "nep11", "properties",
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0], "--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
} "--token", h.StringLE()}
e.RunWithError(t, cmdProperties...)
cmdProperties = append(cmdProperties, "--token", h.StringLE())
// properties: no token ID // properties: bad token ID
e.RunWithError(t, cmdProperties...) e.RunWithError(t, append(cmdProperties, "--id", "test")...)
cmdProperties = append(cmdProperties, "--id", hex.EncodeToString(tokenID)) cmdProperties = append(cmdProperties, "--id", hex.EncodeToString(tokenID))
// properties: ok // properties: ok
@ -312,12 +308,12 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) {
// transfer: unimported token with symbol id specified // transfer: unimported token with symbol id specified
e.In.WriteString(nftOwnerPass + "\r") e.In.WriteString(nftOwnerPass + "\r")
e.RunWithError(t, append(cmdTransfer, e.RunWithError(t, append(cmdTransfer,
"--token", "HASHY")...) "--token", "HASHY", "--id", "test")...)
cmdTransfer = append(cmdTransfer, "--token", h.StringLE()) cmdTransfer = append(cmdTransfer, "--token", h.StringLE())
// transfer: no id specified // transfer: bad id
e.In.WriteString(nftOwnerPass + "\r") e.In.WriteString(nftOwnerPass + "\r")
e.RunWithError(t, cmdTransfer...) e.RunWithError(t, append(cmdTransfer, "--id", "test")...)
// transfer: good // transfer: good
e.In.WriteString(nftOwnerPass + "\r") e.In.WriteString(nftOwnerPass + "\r")
@ -506,10 +502,10 @@ func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) {
cmdOwnerOf := []string{"neo-go", "wallet", "nep11", "ownerOfD", cmdOwnerOf := []string{"neo-go", "wallet", "nep11", "ownerOfD",
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0], "--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
} }
e.RunWithError(t, cmdOwnerOf...) e.RunWithError(t, append(cmdOwnerOf, "--id", "")...)
cmdOwnerOf = append(cmdOwnerOf, "--token", h.StringLE()) cmdOwnerOf = append(cmdOwnerOf, "--token", h.StringLE(), "--id", "")
// ownerOfD: missing token ID // ownerOfD: bad token ID
e.RunWithError(t, cmdOwnerOf...) e.RunWithError(t, cmdOwnerOf...)
cmdOwnerOf = append(cmdOwnerOf, "--id", hex.EncodeToString(token1ID)) cmdOwnerOf = append(cmdOwnerOf, "--id", hex.EncodeToString(token1ID))
@ -539,11 +535,11 @@ func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) {
"neo-go", "wallet", "nep11", "properties", "neo-go", "wallet", "nep11", "properties",
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0], "--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
} }
e.RunWithError(t, cmdProperties...) e.RunWithError(t, append(cmdProperties, "--id", "")...)
cmdProperties = append(cmdProperties, "--token", h.StringLE()) cmdProperties = append(cmdProperties, "--token", h.StringLE())
// properties: no token ID // properties: bad token ID
e.RunWithError(t, cmdProperties...) e.RunWithError(t, append(cmdProperties, "--id", "")...)
cmdProperties = append(cmdProperties, "--id", hex.EncodeToString(token2ID)) cmdProperties = append(cmdProperties, "--id", hex.EncodeToString(token2ID))
// properties: additional parameter // properties: additional parameter
@ -596,12 +592,12 @@ func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) {
// transfer: unimported token with symbol id specified // transfer: unimported token with symbol id specified
e.In.WriteString(testcli.ValidatorPass + "\r") e.In.WriteString(testcli.ValidatorPass + "\r")
e.RunWithError(t, append(cmdTransfer, e.RunWithError(t, append(cmdTransfer,
"--token", "NFSO")...) "--token", "NFSO", "--id", "")...)
cmdTransfer = append(cmdTransfer, "--token", h.StringLE()) cmdTransfer = append(cmdTransfer, "--token", h.StringLE())
// transfer: no id specified // transfer: bad id specified
e.In.WriteString(testcli.ValidatorPass + "\r") e.In.WriteString(testcli.ValidatorPass + "\r")
e.RunWithError(t, cmdTransfer...) e.RunWithError(t, append(cmdTransfer, "--id", "")...)
// transfer: good // transfer: good
e.In.WriteString(testcli.ValidatorPass + "\r") e.In.WriteString(testcli.ValidatorPass + "\r")

View file

@ -111,7 +111,7 @@ func TestNEP17Balance(t *testing.T) {
e.CheckEOF(t) e.CheckEOF(t)
}) })
t.Run("Bad wallet", func(t *testing.T) { t.Run("Bad wallet", func(t *testing.T) {
e.RunWithError(t, append(cmdbalance, "--wallet", "/dev/null")...) e.RunWithError(t, append(cmdbalance, "--wallet", "/dev/null", "--rpc-endpoint", "http://"+e.RPC.Addresses()[0])...)
}) })
} }

View file

@ -43,35 +43,36 @@ func NewCommands() []cli.Command {
Usage: "Get candidates and votes", Usage: "Get candidates and votes",
UsageText: "neo-go query candidates -r endpoint [-s timeout]", UsageText: "neo-go query candidates -r endpoint [-s timeout]",
Action: queryCandidates, Action: queryCandidates,
Flags: options.RPC, Flags: flags.MarkRequired(options.RPC,
options.RPCEndpointFlag+", r"),
}, },
{ {
Name: "committee", Name: "committee",
Usage: "Get committee list", Usage: "Get committee list",
UsageText: "neo-go query committee -r endpoint [-s timeout]", UsageText: "neo-go query committee -r endpoint [-s timeout]",
Action: queryCommittee, Action: queryCommittee,
Flags: options.RPC, Flags: flags.MarkRequired(options.RPC, options.RPCEndpointFlag+", r"),
}, },
{ {
Name: "height", Name: "height",
Usage: "Get node height", Usage: "Get node height",
UsageText: "neo-go query height -r endpoint [-s timeout]", UsageText: "neo-go query height -r endpoint [-s timeout]",
Action: queryHeight, Action: queryHeight,
Flags: options.RPC, Flags: flags.MarkRequired(options.RPC, options.RPCEndpointFlag+", r"),
}, },
{ {
Name: "tx", Name: "tx",
Usage: "Query transaction status", Usage: "Query transaction status",
UsageText: "neo-go query tx <hash> -r endpoint [-s timeout] [-v]", UsageText: "neo-go query tx <hash> -r endpoint [-s timeout] [-v]",
Action: queryTx, Action: queryTx,
Flags: queryTxFlags, Flags: flags.MarkRequired(queryTxFlags, options.RPCEndpointFlag+", r"),
}, },
{ {
Name: "voter", Name: "voter",
Usage: "Print NEO holder account state", Usage: "Print NEO holder account state",
UsageText: "neo-go query voter <address> -r endpoint [-s timeout]", UsageText: "neo-go query voter <address> -r endpoint [-s timeout]",
Action: queryVoter, Action: queryVoter,
Flags: options.RPC, Flags: flags.MarkRequired(options.RPC, options.RPCEndpointFlag+", r"),
}, },
}, },
}} }}

View file

@ -55,6 +55,7 @@ func NewCommands() []cli.Command {
}, },
cli.StringFlag{ cli.StringFlag{
Name: "out, o", Name: "out, o",
Required: true,
Usage: "Output file (stdout if not given)", Usage: "Output file (stdout if not given)",
}, },
) )
@ -63,6 +64,7 @@ func NewCommands() []cli.Command {
cfgCountInFlags = append(cfgCountInFlags, cfgCountInFlags = append(cfgCountInFlags,
cli.StringFlag{ cli.StringFlag{
Name: "in, i", Name: "in, i",
Required: true,
Usage: "Input file (stdin if not given)", Usage: "Input file (stdin if not given)",
}, },
cli.StringFlag{ cli.StringFlag{

View file

@ -30,6 +30,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/vm/vmstate" "github.com/nspcc-dev/neo-go/pkg/vm/vmstate"
"github.com/nspcc-dev/neo-go/pkg/wallet" "github.com/nspcc-dev/neo-go/pkg/wallet"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/urfave/cli"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
@ -58,10 +59,10 @@ func TestCalcHash(t *testing.T) {
e.RunWithError(t, append(cmd, "--in", nefPath, "--manifest", manifestPath)...) e.RunWithError(t, append(cmd, "--in", nefPath, "--manifest", manifestPath)...)
}) })
t.Run("no nef file", func(t *testing.T) { t.Run("no nef file", func(t *testing.T) {
e.RunWithError(t, append(cmd, "--sender", sender.StringLE(), "--manifest", manifestPath)...) e.RunWithError(t, append(cmd, "--sender", sender.StringLE(), "--manifest", manifestPath, "--in", "")...)
}) })
t.Run("no manifest file", func(t *testing.T) { t.Run("no manifest file", func(t *testing.T) {
e.RunWithError(t, append(cmd, "--sender", sender.StringLE(), "--in", nefPath)...) e.RunWithError(t, append(cmd, "--sender", sender.StringLE(), "--in", nefPath, "--manifest", "")...)
}) })
t.Run("invalid nef path", func(t *testing.T) { t.Run("invalid nef path", func(t *testing.T) {
e.RunWithError(t, append(cmd, "--sender", sender.StringLE(), e.RunWithError(t, append(cmd, "--sender", sender.StringLE(),
@ -220,9 +221,6 @@ func TestContractInitAndCompile(t *testing.T) {
tmpDir := t.TempDir() tmpDir := t.TempDir()
e := testcli.NewExecutor(t, false) e := testcli.NewExecutor(t, false)
t.Run("no path is provided", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "init")
})
t.Run("invalid path", func(t *testing.T) { t.Run("invalid path", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "init", "--name", "\x00") e.RunWithError(t, "neo-go", "contract", "init", "--name", "\x00")
}) })
@ -244,9 +242,6 @@ func TestContractInitAndCompile(t *testing.T) {
nefPath := filepath.Join(tmpDir, "testcontract.nef") nefPath := filepath.Join(tmpDir, "testcontract.nef")
manifestPath := filepath.Join(tmpDir, "testcontract.manifest.json") manifestPath := filepath.Join(tmpDir, "testcontract.manifest.json")
cmd := []string{"neo-go", "contract", "compile"} cmd := []string{"neo-go", "contract", "compile"}
t.Run("missing source", func(t *testing.T) {
e.RunWithError(t, cmd...)
})
cmd = append(cmd, "--in", srcPath, "--out", nefPath, "--manifest", manifestPath) cmd = append(cmd, "--in", srcPath, "--out", nefPath, "--manifest", manifestPath)
t.Run("missing config, but require manifest", func(t *testing.T) { t.Run("missing config, but require manifest", func(t *testing.T) {
@ -447,7 +442,7 @@ func TestDeployWithSigners(t *testing.T) {
}) })
t.Run("missing RPC", func(t *testing.T) { t.Run("missing RPC", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "deploy", e.RunWithError(t, "neo-go", "contract", "deploy",
"--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr, "--wallet", testcli.ValidatorWallet, "-r", "", "--address", testcli.ValidatorAddr,
"--in", nefName, "--manifest", manifestName, "--in", nefName, "--manifest", manifestName,
"[", "str1", "str2", "]") "[", "str1", "str2", "]")
}) })
@ -477,28 +472,28 @@ func TestContractManifestGroups(t *testing.T) {
"--out", nefName, "--manifest", manifestName) "--out", nefName, "--manifest", manifestName)
t.Run("missing wallet", func(t *testing.T) { t.Run("missing wallet", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "manifest", "add-group") e.RunWithError(t, "neo-go", "contract", "manifest", "add-group", "-s", "test", "--nef", "test", "--manifest", "test")
}) })
t.Run("invalid wallet", func(t *testing.T) { t.Run("invalid wallet", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "manifest", "add-group", e.RunWithError(t, "neo-go", "contract", "manifest", "add-group",
"--wallet", t.TempDir()) "--wallet", t.TempDir(), "-s", "test", "--nef", "test", "--manifest", "test")
}) })
t.Run("invalid sender", func(t *testing.T) { t.Run("invalid sender", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "manifest", "add-group", e.RunWithError(t, "neo-go", "contract", "manifest", "add-group",
"--wallet", testcli.TestWalletPath, "--address", testcli.TestWalletAccount, "--wallet", testcli.TestWalletPath, "--address", testcli.TestWalletAccount,
"--sender", "not-a-sender") "--sender", "not-a-sender", "--nef", "test", "--manifest", "test")
}) })
t.Run("invalid NEF file", func(t *testing.T) { t.Run("invalid NEF file", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "manifest", "add-group", e.RunWithError(t, "neo-go", "contract", "manifest", "add-group",
"--wallet", testcli.TestWalletPath, "--address", testcli.TestWalletAccount, "--wallet", testcli.TestWalletPath, "--address", testcli.TestWalletAccount,
"--sender", testcli.TestWalletAccount, "--nef", tmpDir) "--sender", testcli.TestWalletAccount, "--nef", tmpDir, "--manifest", "test")
}) })
t.Run("corrupted NEF file", func(t *testing.T) { t.Run("corrupted NEF file", func(t *testing.T) {
f := filepath.Join(tmpDir, "invalid.nef") f := filepath.Join(tmpDir, "invalid.nef")
require.NoError(t, os.WriteFile(f, []byte{1, 2, 3}, os.ModePerm)) require.NoError(t, os.WriteFile(f, []byte{1, 2, 3}, os.ModePerm))
e.RunWithError(t, "neo-go", "contract", "manifest", "add-group", e.RunWithError(t, "neo-go", "contract", "manifest", "add-group",
"--wallet", testcli.TestWalletPath, "--address", testcli.TestWalletAccount, "--wallet", testcli.TestWalletPath, "--address", testcli.TestWalletAccount,
"--sender", testcli.TestWalletAccount, "--nef", f) "--sender", testcli.TestWalletAccount, "--nef", f, "--manifest", "test")
}) })
t.Run("invalid manifest file", func(t *testing.T) { t.Run("invalid manifest file", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "manifest", "add-group", e.RunWithError(t, "neo-go", "contract", "manifest", "add-group",
@ -558,10 +553,6 @@ func TestContract_TestInvokeScript(t *testing.T) {
"--config", "testdata/deploy/neo-go.yml", "--config", "testdata/deploy/neo-go.yml",
"--out", goodNef, "--manifest", manifestName) "--out", goodNef, "--manifest", manifestName)
t.Run("missing in", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "testinvokescript",
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0])
})
t.Run("unexisting in", func(t *testing.T) { t.Run("unexisting in", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "testinvokescript", e.RunWithError(t, "neo-go", "contract", "testinvokescript",
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0], "--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
@ -683,10 +674,6 @@ func TestComlileAndInvokeFunction(t *testing.T) {
t.Run("invalid cosigner", func(t *testing.T) { t.Run("invalid cosigner", func(t *testing.T) {
e.RunWithError(t, append(cmd, "--", "notahash")...) e.RunWithError(t, append(cmd, "--", "notahash")...)
}) })
t.Run("missing RPC address", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "testinvokefunction",
h.StringLE(), "getValue")
})
e.Run(t, cmd...) e.Run(t, cmd...)
@ -960,9 +947,6 @@ func TestContractInspect(t *testing.T) {
"--out", nefName, "--manifest", manifestName) "--out", nefName, "--manifest", manifestName)
cmd := []string{"neo-go", "contract", "inspect"} cmd := []string{"neo-go", "contract", "inspect"}
t.Run("missing input", func(t *testing.T) {
e.RunWithError(t, cmd...)
})
t.Run("with raw '.go'", func(t *testing.T) { t.Run("with raw '.go'", func(t *testing.T) {
e.RunWithError(t, append(cmd, "--in", srcPath)...) e.RunWithError(t, append(cmd, "--in", srcPath)...)
e.Run(t, append(cmd, "--in", srcPath, "--compile")...) e.Run(t, append(cmd, "--in", srcPath, "--compile")...)
@ -1095,3 +1079,52 @@ func TestContractCompile_NEFSizeCheck(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "compile", "--in", in) e.RunWithError(t, "neo-go", "contract", "compile", "--in", in)
require.NoFileExists(t, filepath.Join(tmpDir, "main.nef")) require.NoFileExists(t, filepath.Join(tmpDir, "main.nef"))
} }
func TestSmartcontractCommands(t *testing.T) {
tmpDir := t.TempDir()
app := cli.NewApp()
app.Commands = smartcontract.NewCommands()
app.ExitErrHandler = func(*cli.Context, error) {}
manifestF := filepath.Join(tmpDir, "manifest.json")
bindingF := filepath.Join(tmpDir, "binding.yml")
nefF := filepath.Join(tmpDir, "out.nef")
checkError := func(t *testing.T, msg string, args ...string) {
// cli.ExitError doesn't implement wraping properly, so we check for an error message.
err := app.Run(append([]string{"", "contract"}, args...))
require.True(t, strings.Contains(err.Error(), msg), "got: %v", err)
}
cmd := []string{"compile",
"--manifest", manifestF,
"--bindings", bindingF,
"--out", nefF,
}
t.Run("contract compile missing in", func(t *testing.T) {
checkError(t, "Required flag \"in\" not set", cmd...)
})
cmd = []string{"deploy",
"-r", "test",
"-w", "test",
}
t.Run("contract deploy missing in, manifest", func(t *testing.T) {
checkError(t, "Required flags \"in, manifest\" not set", cmd...)
})
cmd = []string{"testinvokescript",
"-r", "test"}
t.Run("contract testinvokescript missing in", func(t *testing.T) {
checkError(t, "Required flag \"in\" not set", cmd...)
})
t.Run("contract init missing name", func(t *testing.T) {
checkError(t, "Required flag \"name\" not set", "init", "--skip")
})
t.Run("contract inspect missing in, manifest", func(t *testing.T) {
checkError(t, "Required flags \"in, manifest\" not set", "calc-hash", "--s", random.Uint160().StringLE())
})
t.Run("contract manifest add-group missing in, manifest", func(t *testing.T) {
checkError(t, "Required flags \"sender, nef, manifest\" not set", "manifest", "add-group", "-w", random.Uint160().StringLE())
})
}

View file

@ -75,38 +75,41 @@ func RuntimeNotify(args []any) {
// NewCommands returns 'contract' command. // NewCommands returns 'contract' command.
func NewCommands() []cli.Command { func NewCommands() []cli.Command {
testInvokeScriptFlags := []cli.Flag{ testInvokeScriptFlags := append([]cli.Flag{
cli.StringFlag{ cli.StringFlag{
Name: "in, i", Name: "in, i",
Required: true,
Usage: "Input location of the .nef file that needs to be invoked", Usage: "Input location of the .nef file that needs to be invoked",
}, },
options.Historic, options.Historic,
} }, options.RPC...)
testInvokeScriptFlags = append(testInvokeScriptFlags, options.RPC...) testInvokeFunctionFlags := append([]cli.Flag{options.Historic}, options.RPC...)
testInvokeFunctionFlags := []cli.Flag{options.Historic} invokeFunctionFlags := append([]cli.Flag{
testInvokeFunctionFlags = append(testInvokeFunctionFlags, options.RPC...)
invokeFunctionFlags := []cli.Flag{
addressFlag, addressFlag,
txctx.GasFlag, txctx.GasFlag,
txctx.SysGasFlag, txctx.SysGasFlag,
txctx.OutFlag, txctx.OutFlag,
txctx.ForceFlag, txctx.ForceFlag,
} }, options.Wallet...)
invokeFunctionFlags = append(invokeFunctionFlags, options.Wallet...)
invokeFunctionFlags = append(invokeFunctionFlags, options.RPC...) invokeFunctionFlags = append(invokeFunctionFlags, options.RPC...)
deployFlags := append(invokeFunctionFlags, []cli.Flag{ deployFlags := append(invokeFunctionFlags, []cli.Flag{
cli.StringFlag{ cli.StringFlag{
Name: "in, i", Name: "in, i",
Required: true,
Usage: "Input file for the smart contract (*.nef)", Usage: "Input file for the smart contract (*.nef)",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "manifest, m", Name: "manifest, m",
Required: true,
Usage: "Manifest input file (*.manifest.json)", Usage: "Manifest input file (*.manifest.json)",
}, },
}...) }...)
manifestAddGroupFlags := append([]cli.Flag{ manifestAddGroupFlags := append([]cli.Flag{
cli.StringFlag{ cli.StringFlag{
Name: "sender, s", Name: "sender, s",
Required: true,
Usage: "deploy transaction sender", Usage: "deploy transaction sender",
}, },
flags.AddressFlag{ flags.AddressFlag{
@ -115,10 +118,12 @@ func NewCommands() []cli.Command {
}, },
cli.StringFlag{ cli.StringFlag{
Name: "nef, n", Name: "nef, n",
Required: true,
Usage: "path to the NEF file", Usage: "path to the NEF file",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "manifest, m", Name: "manifest, m",
Required: true,
Usage: "path to the manifest", Usage: "path to the manifest",
}, },
}, options.Wallet...) }, options.Wallet...)
@ -141,6 +146,7 @@ func NewCommands() []cli.Command {
Flags: []cli.Flag{ Flags: []cli.Flag{
cli.StringFlag{ cli.StringFlag{
Name: "in, i", Name: "in, i",
Required: true,
Usage: "Input file for the smart contract to be compiled (*.go file or directory)", Usage: "Input file for the smart contract to be compiled (*.go file or directory)",
}, },
cli.StringFlag{ cli.StringFlag{
@ -188,20 +194,20 @@ func NewCommands() []cli.Command {
{ {
Name: "deploy", Name: "deploy",
Usage: "deploy a smart contract (.nef with description)", Usage: "deploy a smart contract (.nef with description)",
UsageText: "neo-go contract deploy -r endpoint -w wallet [-a address] [-g gas] [-e sysgas] --in contract.nef --manifest contract.manifest.json [--out file] [--force] [data]", UsageText: "neo-go contract deploy -r endpoint -w wallet [--wallet-config path] [-a address] [-g gas] [-e sysgas] --in contract.nef --manifest contract.manifest.json [--out file] [--force] [data]",
Description: `Deploys given contract into the chain. The gas parameter is for additional Description: `Deploys given contract into the chain. The gas parameter is for additional
gas to be added as a network fee to prioritize the transaction. The data gas to be added as a network fee to prioritize the transaction. The data
parameter is an optional parameter to be passed to '_deploy' method. parameter is an optional parameter to be passed to '_deploy' method.
`, `,
Action: contractDeploy, Action: contractDeploy,
Flags: deployFlags, Flags: flags.MarkRequired(deployFlags, options.RPCEndpointFlag+", r"),
}, },
generateWrapperCmd, generateWrapperCmd,
generateRPCWrapperCmd, generateRPCWrapperCmd,
{ {
Name: "invokefunction", Name: "invokefunction",
Usage: "invoke deployed contract on the blockchain", Usage: "invoke deployed contract on the blockchain",
UsageText: "neo-go contract invokefunction -r endpoint -w wallet [-a address] [-g gas] [-e sysgas] [--out file] [--force] scripthash [method] [arguments...] [--] [signers...]", UsageText: "neo-go contract invokefunction -r endpoint -w wallet [--wallet-config path] [-a address] [-g gas] [-e sysgas] [--out file] [--force] scripthash [method] [arguments...] [--] [signers...]",
Description: `Executes given (as a script hash) deployed script with the given method, Description: `Executes given (as a script hash) deployed script with the given method,
arguments and signers. Sender is included in the list of signers by default arguments and signers. Sender is included in the list of signers by default
with None witness scope. If you'd like to change default sender's scope, with None witness scope. If you'd like to change default sender's scope,
@ -210,7 +216,7 @@ func NewCommands() []cli.Command {
command sends an invocation transaction to the network. command sends an invocation transaction to the network.
`, `,
Action: invokeFunction, Action: invokeFunction,
Flags: invokeFunctionFlags, Flags: flags.MarkRequired(invokeFunctionFlags, options.RPCEndpointFlag+", r"),
}, },
{ {
Name: "testinvokefunction", Name: "testinvokefunction",
@ -230,7 +236,7 @@ func NewCommands() []cli.Command {
` + cmdargs.SignersParsingDoc + ` ` + cmdargs.SignersParsingDoc + `
`, `,
Action: testInvokeFunction, Action: testInvokeFunction,
Flags: testInvokeFunctionFlags, Flags: flags.MarkRequired(testInvokeFunctionFlags, options.RPCEndpointFlag+", r"),
}, },
{ {
Name: "testinvokescript", Name: "testinvokescript",
@ -241,7 +247,7 @@ func NewCommands() []cli.Command {
for the details about parameters. for the details about parameters.
`, `,
Action: testInvokeScript, Action: testInvokeScript,
Flags: testInvokeScriptFlags, Flags: flags.MarkRequired(testInvokeScriptFlags, options.RPCEndpointFlag+", r"),
}, },
{ {
Name: "init", Name: "init",
@ -251,6 +257,7 @@ func NewCommands() []cli.Command {
Flags: []cli.Flag{ Flags: []cli.Flag{
cli.StringFlag{ cli.StringFlag{
Name: "name, n", Name: "name, n",
Required: true,
Usage: "name of the smart-contract to be initialized", Usage: "name of the smart-contract to be initialized",
}, },
cli.BoolFlag{ cli.BoolFlag{
@ -271,6 +278,7 @@ func NewCommands() []cli.Command {
}, },
cli.StringFlag{ cli.StringFlag{
Name: "in, i", Name: "in, i",
Required: true,
Usage: "input file of the program (either .go or .nef)", Usage: "input file of the program (either .go or .nef)",
}, },
}, },
@ -287,10 +295,12 @@ func NewCommands() []cli.Command {
}, },
cli.StringFlag{ cli.StringFlag{
Name: "in", Name: "in",
Required: true,
Usage: "path to NEF file", Usage: "path to NEF file",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "manifest, m", Name: "manifest, m",
Required: true,
Usage: "path to manifest file", Usage: "path to manifest file",
}, },
}, },

View file

@ -67,7 +67,7 @@ flag is included, the specified value is added to the resulting conflicting tran
in both scenarios. in both scenarios.
`, `,
Action: cancelTx, Action: cancelTx,
Flags: txCancelFlags, Flags: flags.MarkRequired(txCancelFlags, options.RPCEndpointFlag+", r"),
}, },
{ {
Name: "txdump", Name: "txdump",

View file

@ -153,8 +153,8 @@ func TestRegisterCandidate(t *testing.T) {
vs, err = e.Chain.GetEnrollments() vs, err = e.Chain.GetEnrollments()
require.Equal(t, 0, len(vs)) require.Equal(t, 0, len(vs))
// query voter: missing address // query voter: bad address
e.RunWithError(t, "neo-go", "query", "voter") e.RunWithError(t, "neo-go", "query", "voter", "-r", "")
// Excessive parameters. // Excessive parameters.
e.RunWithError(t, "neo-go", "query", "voter", "--rpc-endpoint", "http://"+e.RPC.Addresses()[0], validatorAddress, validatorAddress) e.RunWithError(t, "neo-go", "query", "voter", "--rpc-endpoint", "http://"+e.RPC.Addresses()[0], validatorAddress, validatorAddress)
e.RunWithError(t, "neo-go", "query", "committee", "--rpc-endpoint", "http://"+e.RPC.Addresses()[0], "something") e.RunWithError(t, "neo-go", "query", "committee", "--rpc-endpoint", "http://"+e.RPC.Addresses()[0], "something")

View file

@ -80,11 +80,11 @@ func TestSignMultisigTx(t *testing.T) {
"--out", txPath) "--out", txPath)
// missing wallet // missing wallet
e.RunWithError(t, "neo-go", "wallet", "sign") e.RunWithError(t, "neo-go", "wallet", "sign", "--in", "")
// missing in // missing in
e.RunWithError(t, "neo-go", "wallet", "sign", e.RunWithError(t, "neo-go", "wallet", "sign",
"--wallet", wallet2Path) "--wallet", wallet2Path, "--in", "")
// missing address // missing address
e.RunWithError(t, "neo-go", "wallet", "sign", e.RunWithError(t, "neo-go", "wallet", "sign",

View file

@ -66,14 +66,14 @@ func newNEP11Commands() []cli.Command {
account (if they use the same names/symbols). account (if they use the same names/symbols).
`, `,
Action: getNEP11Balance, Action: getNEP11Balance,
Flags: balanceFlags, Flags: flags.MarkRequired(balanceFlags, options.RPCEndpointFlag+", r"),
}, },
{ {
Name: "import", Name: "import",
Usage: "import NEP-11 token to a wallet", Usage: "import NEP-11 token to a wallet",
UsageText: "import -w wallet [--wallet-config path] --rpc-endpoint <node> --timeout <time> --token <hash>", UsageText: "import -w wallet [--wallet-config path] --rpc-endpoint <node> [--timeout <time>] --token <hash>",
Action: importNEP11Token, Action: importNEP11Token,
Flags: importFlags, Flags: flags.MarkRequired(importFlags, options.RPCEndpointFlag+", r"),
}, },
{ {
Name: "info", Name: "info",
@ -103,7 +103,7 @@ func newNEP11Commands() []cli.Command {
Usage: "transfer NEP-11 tokens", Usage: "transfer NEP-11 tokens",
UsageText: "transfer -w wallet [--wallet-config path] --rpc-endpoint <node> --timeout <time> --from <addr> --to <addr> --token <hash-or-name> --id <token-id> [--amount string] [data] [-- <cosigner1:Scope> [<cosigner2> [...]]]", UsageText: "transfer -w wallet [--wallet-config path] --rpc-endpoint <node> --timeout <time> --from <addr> --to <addr> --token <hash-or-name> --id <token-id> [--amount string] [data] [-- <cosigner1:Scope> [<cosigner2> [...]]]",
Action: transferNEP11, Action: transferNEP11,
Flags: transferFlags, Flags: flags.MarkRequired(transferFlags, options.RPCEndpointFlag+", r", "from", "to", tokenID.GetName(), tokenFlag.GetName()),
Description: `Transfers specified NEP-11 token with optional cosigners list attached to Description: `Transfers specified NEP-11 token with optional cosigners list attached to
the transfer. Amount should be specified for divisible NEP-11 the transfer. Amount should be specified for divisible NEP-11
tokens and omitted for non-divisible NEP-11 tokens. See tokens and omitted for non-divisible NEP-11 tokens. See
@ -118,54 +118,54 @@ func newNEP11Commands() []cli.Command {
Usage: "print properties of NEP-11 token", Usage: "print properties of NEP-11 token",
UsageText: "properties --rpc-endpoint <node> [--timeout <time>] --token <hash> --id <token-id> [--historic <block/hash>]", UsageText: "properties --rpc-endpoint <node> [--timeout <time>] --token <hash> --id <token-id> [--historic <block/hash>]",
Action: printNEP11Properties, Action: printNEP11Properties,
Flags: append([]cli.Flag{ Flags: flags.MarkRequired(append([]cli.Flag{
tokenAddressFlag, tokenAddressFlag,
tokenID, tokenID,
options.Historic, options.Historic,
}, options.RPC...), }, options.RPC...), options.RPCEndpointFlag+", r", tokenID.GetName()),
}, },
{ {
Name: "ownerOf", Name: "ownerOf",
Usage: "print owner of non-divisible NEP-11 token with the specified ID", Usage: "print owner of non-divisible NEP-11 token with the specified ID",
UsageText: "ownerOf --rpc-endpoint <node> [--timeout <time>] --token <hash> --id <token-id> [--historic <block/hash>]", UsageText: "ownerOf --rpc-endpoint <node> [--timeout <time>] --token <hash> --id <token-id> [--historic <block/hash>]",
Action: printNEP11NDOwner, Action: printNEP11NDOwner,
Flags: append([]cli.Flag{ Flags: flags.MarkRequired(append([]cli.Flag{
tokenAddressFlag, tokenAddressFlag,
tokenID, tokenID,
options.Historic, options.Historic,
}, options.RPC...), }, options.RPC...), options.RPCEndpointFlag+", r", tokenID.GetName()),
}, },
{ {
Name: "ownerOfD", Name: "ownerOfD",
Usage: "print set of owners of divisible NEP-11 token with the specified ID (" + maxIters + " will be printed at max)", Usage: "print set of owners of divisible NEP-11 token with the specified ID (" + maxIters + " will be printed at max)",
UsageText: "ownerOfD --rpc-endpoint <node> [--timeout <time>] --token <hash> --id <token-id> [--historic <block/hash>]", UsageText: "ownerOfD --rpc-endpoint <node> [--timeout <time>] --token <hash> --id <token-id> [--historic <block/hash>]",
Action: printNEP11DOwner, Action: printNEP11DOwner,
Flags: append([]cli.Flag{ Flags: flags.MarkRequired(append([]cli.Flag{
tokenAddressFlag, tokenAddressFlag,
tokenID, tokenID,
options.Historic, options.Historic,
}, options.RPC...), }, options.RPC...), options.RPCEndpointFlag+", r", tokenID.GetName()),
}, },
{ {
Name: "tokensOf", Name: "tokensOf",
Usage: "print list of tokens IDs for the specified NFT owner (" + maxIters + " will be printed at max)", Usage: "print list of tokens IDs for the specified NFT owner (" + maxIters + " will be printed at max)",
UsageText: "tokensOf --rpc-endpoint <node> [--timeout <time>] --token <hash> --address <addr> [--historic <block/hash>]", UsageText: "tokensOf --rpc-endpoint <node> [--timeout <time>] --token <hash> --address <addr> [--historic <block/hash>]",
Action: printNEP11TokensOf, Action: printNEP11TokensOf,
Flags: append([]cli.Flag{ Flags: flags.MarkRequired(append([]cli.Flag{
tokenAddressFlag, tokenAddressFlag,
ownerAddressFlag, ownerAddressFlag,
options.Historic, options.Historic,
}, options.RPC...), }, options.RPC...), options.RPCEndpointFlag+", r"),
}, },
{ {
Name: "tokens", Name: "tokens",
Usage: "print list of tokens IDs minted by the specified NFT (optional method; " + maxIters + " will be printed at max)", Usage: "print list of tokens IDs minted by the specified NFT (optional method; " + maxIters + " will be printed at max)",
UsageText: "tokens --rpc-endpoint <node> [--timeout <time>] --token <hash> [--historic <block/hash>]", UsageText: "tokens --rpc-endpoint <node> [--timeout <time>] --token <hash> [--historic <block/hash>]",
Action: printNEP11Tokens, Action: printNEP11Tokens,
Flags: append([]cli.Flag{ Flags: flags.MarkRequired(append([]cli.Flag{
tokenAddressFlag, tokenAddressFlag,
options.Historic, options.Historic,
}, options.RPC...), }, options.RPC...), options.RPCEndpointFlag+", r"),
}, },
} }
} }

View file

@ -112,14 +112,14 @@ func newNEP17Commands() []cli.Command {
account (if they use the same names/symbols). account (if they use the same names/symbols).
`, `,
Action: getNEP17Balance, Action: getNEP17Balance,
Flags: balanceFlags, Flags: flags.MarkRequired(balanceFlags, options.RPCEndpointFlag+", r"),
}, },
{ {
Name: "import", Name: "import",
Usage: "import NEP-17 token to a wallet", Usage: "import NEP-17 token to a wallet",
UsageText: "import -w wallet [--wallet-config path] --rpc-endpoint <node> --timeout <time> --token <hash>", UsageText: "import -w wallet [--wallet-config path] --rpc-endpoint <node> --timeout <time> --token <hash>",
Action: importNEP17Token, Action: importNEP17Token,
Flags: importFlags, Flags: flags.MarkRequired(importFlags, options.RPCEndpointFlag+", r"),
}, },
{ {
Name: "info", Name: "info",
@ -147,9 +147,9 @@ func newNEP17Commands() []cli.Command {
{ {
Name: "transfer", Name: "transfer",
Usage: "transfer NEP-17 tokens", Usage: "transfer NEP-17 tokens",
UsageText: "transfer -w wallet [--wallet-config path] --rpc-endpoint <node> --timeout <time> --from <addr> --to <addr> --token <hash-or-name> --amount string [data] [-- <cosigner1:Scope> [<cosigner2> [...]]]", UsageText: "transfer -w wallet [--wallet-config path] --rpc-endpoint <node> [--timeout <time>] --from <addr> --to <addr> --token <hash-or-name> --amount string [data] [-- <cosigner1:Scope> [<cosigner2> [...]]]",
Action: transferNEP17, Action: transferNEP17,
Flags: transferFlags, Flags: flags.MarkRequired(transferFlags, options.RPCEndpointFlag+", r", "from", "to", "amount"),
Description: `Transfers specified NEP-17 token amount with optional 'data' parameter and cosigners Description: `Transfers specified NEP-17 token amount with optional 'data' parameter and cosigners
list attached to the transfer. See 'contract testinvokefunction' documentation list attached to the transfer. See 'contract testinvokefunction' documentation
for the details about 'data' parameter and cosigners syntax. If no 'data' is for the details about 'data' parameter and cosigners syntax. If no 'data' is
@ -160,10 +160,10 @@ func newNEP17Commands() []cli.Command {
{ {
Name: "multitransfer", Name: "multitransfer",
Usage: "transfer NEP-17 tokens to multiple recipients", Usage: "transfer NEP-17 tokens to multiple recipients",
UsageText: `multitransfer -w wallet [--wallet-config path] --rpc-endpoint <node> --timeout <time> --from <addr>` + UsageText: `multitransfer -w wallet [--wallet-config path] --rpc-endpoint <node> [--timeout <time>] --from <addr>` +
` <token1>:<addr1>:<amount1> [<token2>:<addr2>:<amount2> [...]] [-- <cosigner1:Scope> [<cosigner2> [...]]]`, ` <token1>:<addr1>:<amount1> [<token2>:<addr2>:<amount2> [...]] [-- <cosigner1:Scope> [<cosigner2> [...]]]`,
Action: multiTransferNEP17, Action: multiTransferNEP17,
Flags: multiTransferFlags, Flags: flags.MarkRequired(multiTransferFlags, options.RPCEndpointFlag+", r", "from"),
}, },
} }
} }

View file

@ -22,7 +22,7 @@ func newValidatorCommands() []cli.Command {
Usage: "register as a new candidate", Usage: "register as a new candidate",
UsageText: "register -w <path> -r <rpc> -a <addr> [-g gas] [-e sysgas] [--out file] [--force]", UsageText: "register -w <path> -r <rpc> -a <addr> [-g gas] [-e sysgas] [--out file] [--force]",
Action: handleRegister, Action: handleRegister,
Flags: append([]cli.Flag{ Flags: flags.MarkRequired(append([]cli.Flag{
walletPathFlag, walletPathFlag,
walletConfigFlag, walletConfigFlag,
txctx.GasFlag, txctx.GasFlag,
@ -33,14 +33,14 @@ func newValidatorCommands() []cli.Command {
Name: "address, a", Name: "address, a",
Usage: "Address to register", Usage: "Address to register",
}, },
}, options.RPC...), }, options.RPC...), options.RPCEndpointFlag+", r"),
}, },
{ {
Name: "unregister", Name: "unregister",
Usage: "unregister self as a candidate", Usage: "unregister self as a candidate",
UsageText: "unregister -w <path> -r <rpc> -a <addr> [-g gas] [-e sysgas] [--out file] [--force]", UsageText: "unregister -w <path> -r <rpc> -a <addr> [-g gas] [-e sysgas] [--out file] [--force]",
Action: handleUnregister, Action: handleUnregister,
Flags: append([]cli.Flag{ Flags: flags.MarkRequired(append([]cli.Flag{
walletPathFlag, walletPathFlag,
walletConfigFlag, walletConfigFlag,
txctx.GasFlag, txctx.GasFlag,
@ -51,7 +51,7 @@ func newValidatorCommands() []cli.Command {
Name: "address, a", Name: "address, a",
Usage: "Address to unregister", Usage: "Address to unregister",
}, },
}, options.RPC...), }, options.RPC...), options.RPCEndpointFlag+", r"),
}, },
{ {
Name: "vote", Name: "vote",
@ -61,7 +61,7 @@ func newValidatorCommands() []cli.Command {
contract. Do not provide candidate argument to perform unvoting. contract. Do not provide candidate argument to perform unvoting.
`, `,
Action: handleVote, Action: handleVote,
Flags: append([]cli.Flag{ Flags: flags.MarkRequired(append([]cli.Flag{
walletPathFlag, walletPathFlag,
walletConfigFlag, walletConfigFlag,
txctx.GasFlag, txctx.GasFlag,
@ -76,7 +76,7 @@ func newValidatorCommands() []cli.Command {
Name: "candidate, c", Name: "candidate, c",
Usage: "Public key of candidate to vote for", Usage: "Public key of candidate to vote for",
}, },
}, options.RPC...), }, options.RPC...), options.RPCEndpointFlag+", r"),
}, },
} }
} }

View file

@ -57,6 +57,7 @@ var (
} }
wifFlag = cli.StringFlag{ wifFlag = cli.StringFlag{
Name: "wif", Name: "wif",
Required: true,
Usage: "WIF to import", Usage: "WIF to import",
} }
decryptFlag = cli.BoolFlag{ decryptFlag = cli.BoolFlag{
@ -65,6 +66,7 @@ var (
} }
inFlag = cli.StringFlag{ inFlag = cli.StringFlag{
Name: "in", Name: "in",
Required: true,
Usage: "file with JSON transaction", Usage: "file with JSON transaction",
} }
fromAddrFlag = flags.AddressFlag{ fromAddrFlag = flags.AddressFlag{
@ -151,6 +153,7 @@ func NewCommands() []cli.Command {
walletConfigFlag, walletConfigFlag,
cli.StringFlag{ cli.StringFlag{
Name: "out, o", Name: "out, o",
Required: true,
Usage: "where to write converted wallet", Usage: "where to write converted wallet",
}, },
}, },
@ -247,6 +250,7 @@ func NewCommands() []cli.Command {
}, },
cli.IntFlag{ cli.IntFlag{
Name: "min, m", Name: "min, m",
Required: true,
Usage: "Minimal number of signatures", Usage: "Minimal number of signatures",
}, },
}, },
@ -254,9 +258,9 @@ func NewCommands() []cli.Command {
{ {
Name: "import-deployed", Name: "import-deployed",
Usage: "import deployed contract", Usage: "import deployed contract",
UsageText: "import-deployed -w wallet [--wallet-config path] --wif <wif> --contract <hash> [--name <account_name>]", UsageText: "import-deployed -w wallet [--wallet-config path] --wif <wif> --contract <hash> [--name <account_name>], -r <endpoint>",
Action: importDeployed, Action: importDeployed,
Flags: append([]cli.Flag{ Flags: flags.MarkRequired(append([]cli.Flag{
walletPathFlag, walletPathFlag,
walletConfigFlag, walletConfigFlag,
wifFlag, wifFlag,
@ -268,7 +272,7 @@ func NewCommands() []cli.Command {
Name: "contract, c", Name: "contract, c",
Usage: "Contract hash or address", Usage: "Contract hash or address",
}, },
}, options.RPC...), }, options.RPC...), options.RPCEndpointFlag+", r"),
}, },
{ {
Name: "remove", Name: "remove",

View file

@ -260,7 +260,7 @@ func TestWalletInit(t *testing.T) {
t.Run("Import", func(t *testing.T) { t.Run("Import", func(t *testing.T) {
t.Run("WIF", func(t *testing.T) { t.Run("WIF", func(t *testing.T) {
t.Run("missing wallet", func(t *testing.T) { t.Run("missing wallet", func(t *testing.T) {
e.RunWithError(t, "neo-go", "wallet", "import") e.RunWithError(t, "neo-go", "wallet", "import", "--wif", "")
}) })
priv, err := keys.NewPrivateKey() priv, err := keys.NewPrivateKey()
require.NoError(t, err) require.NoError(t, err)
@ -425,25 +425,25 @@ func TestWalletInit(t *testing.T) {
}) })
t.Run("Multisig", func(t *testing.T) { t.Run("Multisig", func(t *testing.T) {
t.Run("missing wallet", func(t *testing.T) { t.Run("missing wallet", func(t *testing.T) {
e.RunWithError(t, "neo-go", "wallet", "import-multisig") e.RunWithError(t, "neo-go", "wallet", "import-multisig", "--wif", "", "--min", "2")
}) })
t.Run("insufficient pubs", func(t *testing.T) { t.Run("insufficient pubs", func(t *testing.T) {
e.RunWithError(t, "neo-go", "wallet", "import-multisig", e.RunWithError(t, "neo-go", "wallet", "import-multisig",
"--wallet", walletPath, "--wallet", walletPath,
"--min", "2") "--min", "2", "--wif", "")
}) })
privs, pubs := testcli.GenerateKeys(t, 4) privs, pubs := testcli.GenerateKeys(t, 4)
cmd := []string{"neo-go", "wallet", "import-multisig", cmd := []string{"neo-go", "wallet", "import-multisig",
"--wallet", walletPath, "--wallet", walletPath,
"--min", "2"} "--min", "2"}
t.Run("invalid pub encoding", func(t *testing.T) { t.Run("invalid pub encoding", func(t *testing.T) {
e.RunWithError(t, append(cmd, hex.EncodeToString(pubs[1].Bytes()), e.RunWithError(t, append(cmd, "--wif", "", hex.EncodeToString(pubs[1].Bytes()),
hex.EncodeToString(pubs[1].Bytes()), hex.EncodeToString(pubs[1].Bytes()),
hex.EncodeToString(pubs[2].Bytes()), hex.EncodeToString(pubs[2].Bytes()),
"not-a-pub")...) "not-a-pub")...)
}) })
t.Run("missing WIF", func(t *testing.T) { t.Run("bad WIF", func(t *testing.T) {
e.RunWithError(t, append(cmd, hex.EncodeToString(pubs[0].Bytes()), e.RunWithError(t, append(cmd, "--wif", "", hex.EncodeToString(pubs[0].Bytes()),
hex.EncodeToString(pubs[1].Bytes()), hex.EncodeToString(pubs[1].Bytes()),
hex.EncodeToString(pubs[2].Bytes()), hex.EncodeToString(pubs[2].Bytes()),
hex.EncodeToString(pubs[3].Bytes()))...) hex.EncodeToString(pubs[3].Bytes()))...)
@ -618,22 +618,19 @@ func TestWalletImportDeployed(t *testing.T) {
priv, err := keys.NewPrivateKey() priv, err := keys.NewPrivateKey()
require.NoError(t, err) require.NoError(t, err)
t.Run("missing wallet", func(t *testing.T) { t.Run("bad wallet", func(t *testing.T) {
e.RunWithError(t, "neo-go", "wallet", "import-deployed") e.RunWithError(t, "neo-go", "wallet", "import-deployed", "--wallet", "", "--wif", priv.WIF(), "--contract", h.StringLE(), "--rpc-endpoint", "http://"+e.RPC.Addresses()[0])
}) })
t.Run("missing contract sh", func(t *testing.T) { t.Run("missing contract sh", func(t *testing.T) {
e.RunWithError(t, "neo-go", "wallet", "import-deployed", e.RunWithError(t, "neo-go", "wallet", "import-deployed",
"--wallet", walletPath) "--wallet", walletPath, "--wif", priv.WIF(), "--rpc-endpoint", "http://"+e.RPC.Addresses()[0])
}) })
t.Run("missing WIF", func(t *testing.T) { t.Run("bad WIF", func(t *testing.T) {
e.RunWithError(t, "neo-go", "wallet", "import-deployed", e.RunWithError(t, "neo-go", "wallet", "import-deployed", "--wallet", walletPath, "--wif", "", "--contract", h.StringLE(), "--rpc-endpoint", "http://"+e.RPC.Addresses()[0])
"--wallet", walletPath, "--contract", h.StringLE())
}) })
t.Run("missing endpoint", func(t *testing.T) { t.Run("bad endpoint", func(t *testing.T) {
e.In.WriteString("acc\rpass\rpass\r") e.In.WriteString("acc\rpass\rpass\r")
e.RunWithError(t, "neo-go", "wallet", "import-deployed", e.RunWithError(t, "neo-go", "wallet", "import-deployed", "--wallet", walletPath, "--wif", priv.WIF(), "--contract", h.StringLE(), "--rpc-endpoint", "")
"--wallet", walletPath, "--contract", h.StringLE(),
"--wif", priv.WIF())
}) })
t.Run("unknown contract", func(t *testing.T) { t.Run("unknown contract", func(t *testing.T) {
e.In.WriteString("acc\rpass\rpass\r") e.In.WriteString("acc\rpass\rpass\r")
@ -965,11 +962,11 @@ func TestWalletConvert(t *testing.T) {
outPath := filepath.Join(tmpDir, "wallet.json") outPath := filepath.Join(tmpDir, "wallet.json")
cmd := []string{"neo-go", "wallet", "convert"} cmd := []string{"neo-go", "wallet", "convert"}
t.Run("missing wallet", func(t *testing.T) { t.Run("missing wallet", func(t *testing.T) {
e.RunWithError(t, cmd...) e.RunWithError(t, append(cmd, "-w", "", "--out", "")...)
}) })
cmd = append(cmd, "--wallet", "testdata/testwallet_NEO2.json") cmd = append(cmd, "--wallet", "testdata/testwallet_NEO2.json")
t.Run("missing out path", func(t *testing.T) { t.Run("missing out path", func(t *testing.T) {
e.RunWithError(t, cmd...) e.RunWithError(t, append(cmd, "--out", "")...)
}) })
t.Run("invalid out path", func(t *testing.T) { t.Run("invalid out path", func(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()