2020-08-07 09:18:38 +00:00
|
|
|
package wallet
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
2022-08-05 10:32:37 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/cli/cmdargs"
|
2020-08-07 09:18:38 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/cli/flags"
|
|
|
|
"github.com/nspcc-dev/neo-go/cli/options"
|
2022-10-06 19:59:47 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/cli/txctx"
|
2020-09-01 13:55:00 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
2020-08-07 09:18:38 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
2022-08-17 18:55:30 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/neo"
|
2020-08-07 09:34:54 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
2024-07-09 18:24:39 +00:00
|
|
|
"github.com/urfave/cli/v2"
|
2020-08-07 09:18:38 +00:00
|
|
|
)
|
|
|
|
|
2024-07-09 18:24:39 +00:00
|
|
|
func newValidatorCommands() []*cli.Command {
|
|
|
|
return []*cli.Command{
|
2020-08-07 09:24:54 +00:00
|
|
|
{
|
|
|
|
Name: "register",
|
2024-07-03 12:35:18 +00:00
|
|
|
Usage: "Register as a new candidate",
|
2024-07-04 22:34:40 +00:00
|
|
|
UsageText: "register -w <path> -r <rpc> [-s timeout] -a <addr> [-g gas] [-e sysgas] [--out file] [--force] [--await]",
|
2020-08-07 09:24:54 +00:00
|
|
|
Action: handleRegister,
|
|
|
|
Flags: append([]cli.Flag{
|
|
|
|
walletPathFlag,
|
2022-06-23 13:50:21 +00:00
|
|
|
walletConfigFlag,
|
2022-10-06 19:59:47 +00:00
|
|
|
txctx.GasFlag,
|
|
|
|
txctx.SysGasFlag,
|
|
|
|
txctx.OutFlag,
|
|
|
|
txctx.ForceFlag,
|
2023-12-28 11:58:38 +00:00
|
|
|
txctx.AwaitFlag,
|
2024-07-09 18:24:39 +00:00
|
|
|
&flags.AddressFlag{
|
2024-07-04 22:34:40 +00:00
|
|
|
Name: "address",
|
|
|
|
Aliases: []string{"a"},
|
|
|
|
Required: true,
|
|
|
|
Usage: "Address to register",
|
2020-08-07 09:24:54 +00:00
|
|
|
},
|
|
|
|
}, options.RPC...),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "unregister",
|
2024-07-03 12:35:18 +00:00
|
|
|
Usage: "Unregister self as a candidate",
|
2024-07-04 22:34:40 +00:00
|
|
|
UsageText: "unregister -w <path> -r <rpc> [-s timeout] -a <addr> [-g gas] [-e sysgas] [--out file] [--force] [--await]",
|
2020-08-07 09:24:54 +00:00
|
|
|
Action: handleUnregister,
|
|
|
|
Flags: append([]cli.Flag{
|
|
|
|
walletPathFlag,
|
2022-06-23 13:50:21 +00:00
|
|
|
walletConfigFlag,
|
2022-10-06 19:59:47 +00:00
|
|
|
txctx.GasFlag,
|
|
|
|
txctx.SysGasFlag,
|
|
|
|
txctx.OutFlag,
|
|
|
|
txctx.ForceFlag,
|
2023-12-28 11:58:38 +00:00
|
|
|
txctx.AwaitFlag,
|
2024-07-09 18:24:39 +00:00
|
|
|
&flags.AddressFlag{
|
2024-07-04 22:34:40 +00:00
|
|
|
Name: "address",
|
|
|
|
Required: true,
|
|
|
|
Aliases: []string{"a"},
|
|
|
|
Usage: "Address to unregister",
|
2020-08-07 09:24:54 +00:00
|
|
|
},
|
|
|
|
}, options.RPC...),
|
|
|
|
},
|
2020-08-07 09:18:38 +00:00
|
|
|
{
|
|
|
|
Name: "vote",
|
2024-07-03 12:35:18 +00:00
|
|
|
Usage: "Vote for a validator",
|
2023-12-28 11:58:38 +00:00
|
|
|
UsageText: "vote -w <path> -r <rpc> [-s <timeout>] [-g gas] [-e sysgas] -a <addr> [-c <public key>] [--out file] [--force] [--await]",
|
2021-05-28 12:15:37 +00:00
|
|
|
Description: `Votes for a validator by calling "vote" method of a NEO native
|
2023-12-28 11:58:38 +00:00
|
|
|
contract. Do not provide candidate argument to perform unvoting. If --await flag is
|
|
|
|
included, the command waits for the transaction to be included in a block before exiting.
|
2021-05-28 12:15:37 +00:00
|
|
|
`,
|
|
|
|
Action: handleVote,
|
2020-08-07 09:18:38 +00:00
|
|
|
Flags: append([]cli.Flag{
|
|
|
|
walletPathFlag,
|
2022-06-23 13:50:21 +00:00
|
|
|
walletConfigFlag,
|
2022-10-06 19:59:47 +00:00
|
|
|
txctx.GasFlag,
|
|
|
|
txctx.SysGasFlag,
|
|
|
|
txctx.OutFlag,
|
|
|
|
txctx.ForceFlag,
|
2023-12-28 11:58:38 +00:00
|
|
|
txctx.AwaitFlag,
|
2024-07-09 18:24:39 +00:00
|
|
|
&flags.AddressFlag{
|
2024-07-04 22:34:40 +00:00
|
|
|
Name: "address",
|
|
|
|
Required: true,
|
|
|
|
Aliases: []string{"a"},
|
|
|
|
Usage: "Address to vote from",
|
2020-08-07 09:18:38 +00:00
|
|
|
},
|
2024-07-09 18:24:39 +00:00
|
|
|
&cli.StringFlag{
|
|
|
|
Name: "candidate",
|
|
|
|
Aliases: []string{"c"},
|
|
|
|
Usage: "Public key of candidate to vote for",
|
2020-08-07 09:18:38 +00:00
|
|
|
},
|
|
|
|
}, options.RPC...),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-07 09:24:54 +00:00
|
|
|
func handleRegister(ctx *cli.Context) error {
|
2022-08-17 18:55:30 +00:00
|
|
|
return handleNeoAction(ctx, func(contract *neo.Contract, _ util.Uint160, acc *wallet.Account) (*transaction.Transaction, error) {
|
2022-09-01 14:52:44 +00:00
|
|
|
return contract.RegisterCandidateUnsigned(acc.PublicKey())
|
2022-08-17 18:55:30 +00:00
|
|
|
})
|
2020-08-07 09:24:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func handleUnregister(ctx *cli.Context) error {
|
2022-08-17 18:55:30 +00:00
|
|
|
return handleNeoAction(ctx, func(contract *neo.Contract, _ util.Uint160, acc *wallet.Account) (*transaction.Transaction, error) {
|
2022-09-01 14:52:44 +00:00
|
|
|
return contract.UnregisterCandidateUnsigned(acc.PublicKey())
|
2022-08-17 18:55:30 +00:00
|
|
|
})
|
2020-08-07 09:24:54 +00:00
|
|
|
}
|
|
|
|
|
2022-08-17 18:55:30 +00:00
|
|
|
func handleNeoAction(ctx *cli.Context, mkTx func(*neo.Contract, util.Uint160, *wallet.Account) (*transaction.Transaction, error)) error {
|
2022-08-05 10:32:37 +00:00
|
|
|
if err := cmdargs.EnsureNone(ctx); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-06-23 13:50:21 +00:00
|
|
|
wall, pass, err := readWallet(ctx)
|
2020-08-07 09:24:54 +00:00
|
|
|
if err != nil {
|
2024-07-09 18:24:39 +00:00
|
|
|
return cli.Exit(err, 1)
|
2020-08-07 09:24:54 +00:00
|
|
|
}
|
2022-09-01 18:44:49 +00:00
|
|
|
defer wall.Close()
|
2020-08-07 09:24:54 +00:00
|
|
|
|
|
|
|
addrFlag := ctx.Generic("address").(*flags.Address)
|
|
|
|
addr := addrFlag.Uint160()
|
2023-12-04 14:02:44 +00:00
|
|
|
acc, err := options.GetUnlockedAccount(wall, addr, pass)
|
2020-08-07 09:34:54 +00:00
|
|
|
if err != nil {
|
2024-07-09 18:24:39 +00:00
|
|
|
return cli.Exit(err, 1)
|
2020-08-07 09:24:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
gctx, cancel := options.GetTimeoutContext(ctx)
|
|
|
|
defer cancel()
|
|
|
|
|
2023-12-07 07:35:37 +00:00
|
|
|
signers, err := cmdargs.GetSignersAccounts(acc, wall, nil, transaction.CalledByEntry)
|
2020-08-07 09:24:54 +00:00
|
|
|
if err != nil {
|
2024-07-09 18:24:39 +00:00
|
|
|
return cli.Exit(fmt.Errorf("invalid signers: %w", err), 1)
|
2020-08-07 09:24:54 +00:00
|
|
|
}
|
2023-12-07 07:35:37 +00:00
|
|
|
_, act, exitErr := options.GetRPCWithActor(gctx, ctx, signers)
|
|
|
|
if exitErr != nil {
|
|
|
|
return exitErr
|
2021-07-21 09:25:42 +00:00
|
|
|
}
|
|
|
|
|
2022-08-17 18:55:30 +00:00
|
|
|
contract := neo.New(act)
|
|
|
|
tx, err := mkTx(contract, addr, acc)
|
2022-07-25 19:07:13 +00:00
|
|
|
if err != nil {
|
2024-07-09 18:24:39 +00:00
|
|
|
return cli.Exit(err, 1)
|
2022-07-25 19:07:13 +00:00
|
|
|
}
|
2022-10-06 19:59:47 +00:00
|
|
|
return txctx.SignAndSend(ctx, act, acc, tx)
|
2020-08-07 09:24:54 +00:00
|
|
|
}
|
|
|
|
|
2020-08-07 09:18:38 +00:00
|
|
|
func handleVote(ctx *cli.Context) error {
|
2022-08-17 18:55:30 +00:00
|
|
|
return handleNeoAction(ctx, func(contract *neo.Contract, addr util.Uint160, acc *wallet.Account) (*transaction.Transaction, error) {
|
|
|
|
var (
|
|
|
|
err error
|
|
|
|
pub *keys.PublicKey
|
|
|
|
)
|
|
|
|
pubStr := ctx.String("candidate")
|
|
|
|
if pubStr != "" {
|
|
|
|
pub, err = keys.NewPublicKeyFromString(pubStr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("invalid public key: '%s'", pubStr)
|
|
|
|
}
|
2020-08-07 09:18:38 +00:00
|
|
|
}
|
|
|
|
|
2022-08-17 18:55:30 +00:00
|
|
|
return contract.VoteUnsigned(addr, pub)
|
2022-08-08 15:26:32 +00:00
|
|
|
})
|
2020-08-07 09:18:38 +00:00
|
|
|
}
|