2020-03-02 12:39:02 +00:00
|
|
|
package wallet
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
2021-04-16 08:12:51 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/cli/flags"
|
2020-06-17 21:15:13 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/cli/options"
|
2020-10-02 13:13:17 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/cli/paramcontext"
|
2020-03-02 12:39:02 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
|
|
|
"github.com/urfave/cli"
|
|
|
|
)
|
|
|
|
|
2021-03-03 11:47:36 +00:00
|
|
|
func signStoredTransaction(ctx *cli.Context) error {
|
2020-06-25 15:46:24 +00:00
|
|
|
wall, err := openWallet(ctx.String("wallet"))
|
2020-03-02 12:39:02 +00:00
|
|
|
if err != nil {
|
|
|
|
return cli.NewExitError(err, 1)
|
|
|
|
}
|
|
|
|
defer wall.Close()
|
|
|
|
|
2020-10-02 13:13:17 +00:00
|
|
|
c, err := paramcontext.Read(ctx.String("in"))
|
2020-03-02 12:39:02 +00:00
|
|
|
if err != nil {
|
|
|
|
return cli.NewExitError(err, 1)
|
|
|
|
}
|
2021-04-16 08:12:51 +00:00
|
|
|
addrFlag := ctx.Generic("address").(*flags.Address)
|
|
|
|
if !addrFlag.IsSet {
|
|
|
|
return cli.NewExitError("address was not provided", 1)
|
2020-03-02 12:39:02 +00:00
|
|
|
}
|
2021-04-16 08:12:51 +00:00
|
|
|
acc, err := getDecryptedAccount(ctx, wall, addrFlag.Uint160())
|
2020-08-07 09:34:54 +00:00
|
|
|
if err != nil {
|
|
|
|
return cli.NewExitError(err, 1)
|
2020-03-02 12:39:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
tx, ok := c.Verifiable.(*transaction.Transaction)
|
|
|
|
if !ok {
|
|
|
|
return cli.NewExitError("verifiable item is not a transaction", 1)
|
|
|
|
}
|
|
|
|
|
2021-03-04 11:14:25 +00:00
|
|
|
ch, err := address.StringToUint160(acc.Address)
|
|
|
|
if err != nil {
|
|
|
|
return cli.NewExitError(fmt.Errorf("wallet contains invalid account: %s", acc.Address), 1)
|
|
|
|
}
|
2021-03-03 13:05:33 +00:00
|
|
|
signerFound := false
|
|
|
|
for i := range tx.Signers {
|
2021-03-04 11:14:25 +00:00
|
|
|
if tx.Signers[i].Account == ch {
|
2021-03-03 13:05:33 +00:00
|
|
|
signerFound = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !signerFound {
|
|
|
|
return cli.NewExitError("tx signers don't contain provided account", 1)
|
|
|
|
}
|
|
|
|
|
2020-03-02 12:39:02 +00:00
|
|
|
priv := acc.PrivateKey()
|
2021-03-25 16:18:01 +00:00
|
|
|
sign := priv.SignHashable(uint32(c.Network), tx)
|
2021-03-04 11:14:25 +00:00
|
|
|
if err := c.AddSignature(ch, acc.Contract, priv.PublicKey(), sign); err != nil {
|
2020-08-06 16:09:57 +00:00
|
|
|
return cli.NewExitError(fmt.Errorf("can't add signature: %w", err), 1)
|
2020-10-02 06:40:41 +00:00
|
|
|
}
|
|
|
|
if out := ctx.String("out"); out != "" {
|
2020-10-02 13:13:17 +00:00
|
|
|
if err := paramcontext.Save(c, out); err != nil {
|
2021-11-29 08:29:08 +00:00
|
|
|
return cli.NewExitError(fmt.Errorf("failed to dump resulting transaction: %w", err), 1)
|
2020-10-02 06:40:41 +00:00
|
|
|
}
|
2020-03-02 12:39:02 +00:00
|
|
|
}
|
2020-06-17 21:15:13 +00:00
|
|
|
if len(ctx.String(options.RPCEndpointFlag)) != 0 {
|
2021-03-03 13:00:04 +00:00
|
|
|
for i := range tx.Signers {
|
|
|
|
w, err := c.GetWitness(tx.Signers[i].Account)
|
|
|
|
if err != nil {
|
2021-11-29 08:29:08 +00:00
|
|
|
return cli.NewExitError(fmt.Errorf("failed to construct witness for signer #%d: %w", i, err), 1)
|
2021-03-03 13:00:04 +00:00
|
|
|
}
|
|
|
|
tx.Scripts = append(tx.Scripts, *w)
|
2020-03-02 12:39:02 +00:00
|
|
|
}
|
|
|
|
|
2020-06-17 21:15:13 +00:00
|
|
|
gctx, cancel := options.GetTimeoutContext(ctx)
|
2020-03-02 12:39:02 +00:00
|
|
|
defer cancel()
|
|
|
|
|
2021-03-03 13:00:04 +00:00
|
|
|
var err error // `GetRPCClient` returns specialized type.
|
2020-06-17 21:15:13 +00:00
|
|
|
c, err := options.GetRPCClient(gctx, ctx)
|
2020-03-02 12:39:02 +00:00
|
|
|
if err != nil {
|
2021-11-29 08:29:08 +00:00
|
|
|
return cli.NewExitError(fmt.Errorf("failed to create RPC client: %w", err), 1)
|
2020-06-17 21:15:13 +00:00
|
|
|
}
|
2020-07-21 07:31:45 +00:00
|
|
|
res, err := c.SendRawTransaction(tx)
|
|
|
|
if err != nil {
|
2021-11-29 08:29:08 +00:00
|
|
|
return cli.NewExitError(fmt.Errorf("failed to submit transaction to RPC node: %w", err), 1)
|
2020-03-02 12:39:02 +00:00
|
|
|
}
|
2020-08-28 09:11:19 +00:00
|
|
|
fmt.Fprintln(ctx.App.Writer, res.StringLE())
|
2020-07-21 07:31:45 +00:00
|
|
|
return nil
|
2020-03-02 12:39:02 +00:00
|
|
|
}
|
|
|
|
|
2020-08-28 09:11:19 +00:00
|
|
|
fmt.Fprintln(ctx.App.Writer, tx.Hash().StringLE())
|
2020-03-02 12:39:02 +00:00
|
|
|
return nil
|
|
|
|
}
|