forked from TrueCloudLab/neoneo-go
1518019be8
Some commands don't accept arguments, but users try giving them and don't notice a mistake. It's a bit more user-friendly to tell the user that there is something wrong with the way he tries to use the command.
94 lines
2.6 KiB
Go
94 lines
2.6 KiB
Go
package wallet
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/nspcc-dev/neo-go/cli/cmdargs"
|
|
"github.com/nspcc-dev/neo-go/cli/flags"
|
|
"github.com/nspcc-dev/neo-go/cli/options"
|
|
"github.com/nspcc-dev/neo-go/cli/paramcontext"
|
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
|
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
|
"github.com/urfave/cli"
|
|
)
|
|
|
|
func signStoredTransaction(ctx *cli.Context) error {
|
|
if err := cmdargs.EnsureNone(ctx); err != nil {
|
|
return err
|
|
}
|
|
wall, pass, err := readWallet(ctx)
|
|
if err != nil {
|
|
return cli.NewExitError(err, 1)
|
|
}
|
|
|
|
c, err := paramcontext.Read(ctx.String("in"))
|
|
if err != nil {
|
|
return cli.NewExitError(err, 1)
|
|
}
|
|
addrFlag := ctx.Generic("address").(*flags.Address)
|
|
if !addrFlag.IsSet {
|
|
return cli.NewExitError("address was not provided", 1)
|
|
}
|
|
acc, err := getDecryptedAccount(wall, addrFlag.Uint160(), pass)
|
|
if err != nil {
|
|
return cli.NewExitError(err, 1)
|
|
}
|
|
|
|
tx, ok := c.Verifiable.(*transaction.Transaction)
|
|
if !ok {
|
|
return cli.NewExitError("verifiable item is not a transaction", 1)
|
|
}
|
|
|
|
ch, err := address.StringToUint160(acc.Address)
|
|
if err != nil {
|
|
return cli.NewExitError(fmt.Errorf("wallet contains invalid account: %s", acc.Address), 1)
|
|
}
|
|
signerFound := false
|
|
for i := range tx.Signers {
|
|
if tx.Signers[i].Account == ch {
|
|
signerFound = true
|
|
break
|
|
}
|
|
}
|
|
if !signerFound {
|
|
return cli.NewExitError("tx signers don't contain provided account", 1)
|
|
}
|
|
|
|
priv := acc.PrivateKey()
|
|
sign := priv.SignHashable(uint32(c.Network), tx)
|
|
if err := c.AddSignature(ch, acc.Contract, priv.PublicKey(), sign); err != nil {
|
|
return cli.NewExitError(fmt.Errorf("can't add signature: %w", err), 1)
|
|
}
|
|
if out := ctx.String("out"); out != "" {
|
|
if err := paramcontext.Save(c, out); err != nil {
|
|
return cli.NewExitError(fmt.Errorf("failed to dump resulting transaction: %w", err), 1)
|
|
}
|
|
}
|
|
if len(ctx.String(options.RPCEndpointFlag)) != 0 {
|
|
for i := range tx.Signers {
|
|
w, err := c.GetWitness(tx.Signers[i].Account)
|
|
if err != nil {
|
|
return cli.NewExitError(fmt.Errorf("failed to construct witness for signer #%d: %w", i, err), 1)
|
|
}
|
|
tx.Scripts = append(tx.Scripts, *w)
|
|
}
|
|
|
|
gctx, cancel := options.GetTimeoutContext(ctx)
|
|
defer cancel()
|
|
|
|
var err error // `GetRPCClient` returns specialized type.
|
|
c, err := options.GetRPCClient(gctx, ctx)
|
|
if err != nil {
|
|
return cli.NewExitError(fmt.Errorf("failed to create RPC client: %w", err), 1)
|
|
}
|
|
res, err := c.SendRawTransaction(tx)
|
|
if err != nil {
|
|
return cli.NewExitError(fmt.Errorf("failed to submit transaction to RPC node: %w", err), 1)
|
|
}
|
|
fmt.Fprintln(ctx.App.Writer, res.StringLE())
|
|
return nil
|
|
}
|
|
|
|
fmt.Fprintln(ctx.App.Writer, tx.Hash().StringLE())
|
|
return nil
|
|
}
|