diff --git a/cli/wallet/validator.go b/cli/wallet/validator.go new file mode 100644 index 000000000..1cb0eb8c4 --- /dev/null +++ b/cli/wallet/validator.go @@ -0,0 +1,100 @@ +package wallet + +import ( + "fmt" + + "github.com/nspcc-dev/neo-go/cli/flags" + "github.com/nspcc-dev/neo-go/cli/options" + "github.com/nspcc-dev/neo-go/pkg/crypto/keys" + "github.com/nspcc-dev/neo-go/pkg/io" + "github.com/nspcc-dev/neo-go/pkg/rpc/client" + "github.com/nspcc-dev/neo-go/pkg/vm/emit" + "github.com/nspcc-dev/neo-go/pkg/vm/opcode" + "github.com/urfave/cli" +) + +func newValidatorCommands() []cli.Command { + return []cli.Command{ + { + Name: "vote", + Usage: "vote for a validator", + UsageText: "vote -w -r [-s ] [-g gas] -a -c ", + Action: handleVote, + Flags: append([]cli.Flag{ + walletPathFlag, + gasFlag, + flags.AddressFlag{ + Name: "address, a", + Usage: "Address to vote from", + }, + cli.StringFlag{ + Name: "candidate, c", + Usage: "Public key of candidate to vote for", + }, + }, options.RPC...), + }, + } +} + +func handleVote(ctx *cli.Context) error { + wall, err := openWallet(ctx.String("wallet")) + if err != nil { + return cli.NewExitError(err, 1) + } + + addrFlag := ctx.Generic("address").(*flags.Address) + addr := addrFlag.Uint160() + acc := wall.GetAccount(addr) + if acc == nil { + return cli.NewExitError(fmt.Errorf("can't find account for the address: %s", addrFlag), 1) + } + + var pub *keys.PublicKey + pubStr := ctx.String("candidate") + if pubStr != "" { + pub, err = keys.NewPublicKeyFromString(pubStr) + if err != nil { + return cli.NewExitError(fmt.Errorf("invalid public key: '%s'", pubStr), 1) + } + } + + gctx, cancel := options.GetTimeoutContext(ctx) + defer cancel() + + c, err := options.GetRPCClient(gctx, ctx) + if err != nil { + return err + } + + var pubArg interface{} + if pub != nil { + pubArg = pub.Bytes() + } + + gas := flags.Fixed8FromContext(ctx, "gas") + w := io.NewBufBinWriter() + emit.AppCallWithOperationAndArgs(w.BinWriter, client.NeoContractHash, "vote", addr.BytesBE(), pubArg) + emit.Opcode(w.BinWriter, opcode.ASSERT) + + tx, err := c.CreateTxFromScript(w.Bytes(), acc, int64(gas)) + if err != nil { + return cli.NewExitError(err, 1) + } + + if pass, err := readPassword("Password > "); err != nil { + return cli.NewExitError(err, 1) + } else if err := acc.Decrypt(pass); err != nil { + return cli.NewExitError(err, 1) + } + + if err = acc.SignTx(tx); err != nil { + return cli.NewExitError(fmt.Errorf("can't sign tx: %v", err), 1) + } + + res, err := c.SendRawTransaction(tx) + if err != nil { + return cli.NewExitError(err, 1) + } + fmt.Println(res.StringLE()) + return nil +} diff --git a/cli/wallet/wallet.go b/cli/wallet/wallet.go index c71a9f7b7..4b956beb7 100644 --- a/cli/wallet/wallet.go +++ b/cli/wallet/wallet.go @@ -13,11 +13,7 @@ import ( "github.com/nspcc-dev/neo-go/cli/options" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/encoding/address" - "github.com/nspcc-dev/neo-go/pkg/io" - "github.com/nspcc-dev/neo-go/pkg/rpc/client" "github.com/nspcc-dev/neo-go/pkg/util" - "github.com/nspcc-dev/neo-go/pkg/vm/emit" - "github.com/nspcc-dev/neo-go/pkg/vm/opcode" "github.com/nspcc-dev/neo-go/pkg/wallet" "github.com/urfave/cli" "golang.org/x/crypto/ssh/terminal" @@ -191,22 +187,9 @@ func NewCommands() []cli.Command { Subcommands: newNEP5Commands(), }, { - Name: "vote", - Usage: "vote for a validator", - UsageText: "vote -w -r [-t ] [-g gas] -a -k ", - Action: handleVote, - Flags: append([]cli.Flag{ - walletPathFlag, - gasFlag, - flags.AddressFlag{ - Name: "addr, a", - Usage: "Address to vote from", - }, - cli.StringFlag{ - Name: "key, k", - Usage: "Public key of candidate to vote for", - }, - }, options.RPC...), + Name: "candidate", + Usage: "work with candidates", + Subcommands: newValidatorCommands(), }, }, }} @@ -535,69 +518,6 @@ func createWallet(ctx *cli.Context) error { return nil } -func handleVote(ctx *cli.Context) error { - wall, err := openWallet(ctx.String("wallet")) - if err != nil { - return cli.NewExitError(err, 1) - } - - addrFlag := ctx.Generic("addr").(*flags.Address) - addr := addrFlag.Uint160() - acc := wall.GetAccount(addr) - if acc == nil { - return cli.NewExitError(fmt.Errorf("can't find account for the address: %s", addrFlag), 1) - } - - var pub *keys.PublicKey - pubStr := ctx.String("key") - if pubStr != "" { - pub, err = keys.NewPublicKeyFromString(pubStr) - if err != nil { - return cli.NewExitError(fmt.Errorf("invalid public key: '%s'", pubStr), 1) - } - } - - gctx, cancel := options.GetTimeoutContext(ctx) - defer cancel() - - c, err := options.GetRPCClient(gctx, ctx) - if err != nil { - return err - } - - var pubArg interface{} - if pub != nil { - pubArg = pub.Bytes() - } - - gas := flags.Fixed8FromContext(ctx, "gas") - w := io.NewBufBinWriter() - emit.AppCallWithOperationAndArgs(w.BinWriter, client.NeoContractHash, "vote", addr.BytesBE(), pubArg) - emit.Opcode(w.BinWriter, opcode.ASSERT) - - tx, err := c.CreateTxFromScript(w.Bytes(), acc, int64(gas)) - if err != nil { - return cli.NewExitError(err, 1) - } - - if pass, err := readPassword("Password > "); err != nil { - return cli.NewExitError(err, 1) - } else if err := acc.Decrypt(pass); err != nil { - return cli.NewExitError(err, 1) - } - - if err = acc.SignTx(tx); err != nil { - return cli.NewExitError(fmt.Errorf("can't sign tx: %v", err), 1) - } - - res, err := c.SendRawTransaction(tx) - if err != nil { - return cli.NewExitError(err, 1) - } - fmt.Println(res.StringLE()) - return nil -} - func readAccountInfo() (string, string, error) { buf := bufio.NewReader(os.Stdin) fmt.Print("Enter the name of the account > ")