From 0d4ad9f76c30becd3113f23172c8614120a7998a Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Tue, 3 Mar 2020 10:35:21 +0300 Subject: [PATCH] cli: add --out flag to the `wallet transfer` command When transferring assets from multisig accounts, it is useful to export tx into a file, so that other participants can sign it too. --- cli/wallet/wallet.go | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/cli/wallet/wallet.go b/cli/wallet/wallet.go index 2928192ac..98b36f68a 100644 --- a/cli/wallet/wallet.go +++ b/cli/wallet/wallet.go @@ -3,8 +3,10 @@ package wallet import ( "bufio" "context" + "encoding/json" "errors" "fmt" + "io/ioutil" "os" "strings" "syscall" @@ -15,6 +17,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/rpc/client" "github.com/nspcc-dev/neo-go/pkg/rpc/request" + context2 "github.com/nspcc-dev/neo-go/pkg/smartcontract/context" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/wallet" "github.com/urfave/cli" @@ -47,6 +50,10 @@ var ( Name: "timeout, t", Usage: "Timeout for the operation", } + outFlag = cli.StringFlag{ + Name: "out", + Usage: "file to put JSON transaction to", + } ) // NewCommands returns 'wallet' command. @@ -144,12 +151,13 @@ func NewCommands() []cli.Command { Name: "transfer", Usage: "transfer NEO/GAS", UsageText: "transfer --path --from --to " + - " --amount --asset [NEO|GAS|]", + " --amount --asset [NEO|GAS|] [--out ]", Action: transferAsset, Flags: []cli.Flag{ walletPathFlag, rpcFlag, timeoutFlag, + outFlag, cli.StringFlag{ Name: "from", Usage: "Address to send an asset from", @@ -431,9 +439,23 @@ func transferAsset(ctx *cli.Context) error { Position: 1, }) - _ = acc.SignTx(tx) - if err := c.SendRawTransaction(tx); err != nil { - return cli.NewExitError(err, 1) + if outFile := ctx.String("out"); outFile != "" { + priv := acc.PrivateKey() + pub := priv.PublicKey() + sign := priv.Sign(tx.GetSignedPart()) + c := context2.NewParameterContext("Neo.Core.ContractTransaction", tx) + if err := c.AddSignature(acc.Contract, pub, sign); err != nil { + return cli.NewExitError(fmt.Errorf("can't add signature: %v", err), 1) + } else if data, err := json.Marshal(c); err != nil { + return cli.NewExitError(fmt.Errorf("can't marshal tx to JSON: %v", err), 1) + } else if err := ioutil.WriteFile(outFile, data, 0644); err != nil { + return cli.NewExitError(fmt.Errorf("can't write tx to file: %v", err), 1) + } + } else { + _ = acc.SignTx(tx) + if err := c.SendRawTransaction(tx); err != nil { + return cli.NewExitError(err, 1) + } } fmt.Println(tx.Hash().StringLE())