From a060bde1c4c246d68902907abafc6363c606ed04 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 18 Jul 2017 20:45:48 +0200 Subject: [PATCH] Add more flags to help with multisig --- cmd/basecli/commands/cmds.go | 1 + modules/coin/commands/tx.go | 17 ++++++++++++++++- modules/fee/commands/wrap.go | 20 ++++++++++++++++++-- modules/nonce/commands/wrap.go | 25 ++++++++++++++++++++++++- 4 files changed, 59 insertions(+), 4 deletions(-) diff --git a/cmd/basecli/commands/cmds.go b/cmd/basecli/commands/cmds.go index e1b979ee3..5f5325489 100644 --- a/cmd/basecli/commands/cmds.go +++ b/cmd/basecli/commands/cmds.go @@ -73,6 +73,7 @@ func ValidateResult(res *ctypes.ResultBroadcastTxCommit) error { // If app is not specified or "", then assume auth.NameSigs func ParseAddress(input string) (res basecoin.Actor, err error) { chain, app := "", auth.NameSigs + input = strings.TrimSpace(input) spl := strings.SplitN(input, ":", 3) if len(spl) == 3 { diff --git a/modules/coin/commands/tx.go b/modules/coin/commands/tx.go index ce1c33a7f..81e786d4a 100644 --- a/modules/coin/commands/tx.go +++ b/modules/coin/commands/tx.go @@ -23,12 +23,14 @@ var SendTxCmd = &cobra.Command{ const ( FlagTo = "to" FlagAmount = "amount" + FlagFrom = "from" ) func init() { flags := SendTxCmd.Flags() flags.String(FlagTo, "", "Destination address for the bits") flags.String(FlagAmount, "", "Coins to send in the format ,...") + flags.String(FlagFrom, "", "Address sending coins, if not first signer") } // doSendTx is an example of how to make a tx @@ -70,6 +72,11 @@ func readSendTxFlags() (tx basecoin.Tx, err error) { return tx, err } + fromAddr, err := readFromAddr() + if err != nil { + return tx, err + } + amountCoins, err := coin.ParseCoins(viper.GetString(FlagAmount)) if err != nil { return tx, err @@ -77,7 +84,7 @@ func readSendTxFlags() (tx basecoin.Tx, err error) { // craft the inputs and outputs ins := []coin.TxInput{{ - Address: bcmd.GetSignerAct(), + Address: fromAddr, Coins: amountCoins, }} outs := []coin.TxOutput{{ @@ -87,3 +94,11 @@ func readSendTxFlags() (tx basecoin.Tx, err error) { return coin.NewSendTx(ins, outs), nil } + +func readFromAddr() (basecoin.Actor, error) { + from := viper.GetString(FlagFrom) + if from == "" { + return bcmd.GetSignerAct(), nil + } + return bcmd.ParseAddress(from) +} diff --git a/modules/fee/commands/wrap.go b/modules/fee/commands/wrap.go index deb4f42ef..c464c15c9 100644 --- a/modules/fee/commands/wrap.go +++ b/modules/fee/commands/wrap.go @@ -12,7 +12,8 @@ import ( //nolint const ( - FlagFee = "fee" + FlagFee = "fee" + FlagPayer = "payer" ) // FeeWrapper wraps a tx with an optional fee payment @@ -32,11 +33,26 @@ func (FeeWrapper) Wrap(tx basecoin.Tx) (res basecoin.Tx, err error) { if toll.IsZero() { return tx, nil } - res = fee.NewFee(tx, toll, bcmd.GetSignerAct()) + + payer, err := readPayer() + if err != nil { + return res, err + } + + res = fee.NewFee(tx, toll, payer) return } // Register adds the sequence flags to the cli func (FeeWrapper) Register(fs *pflag.FlagSet) { fs.String(FlagFee, "0mycoin", "Coins for the transaction fee of the format ") + fs.String(FlagPayer, "", "Account to pay fee if not current signer (for multisig)") +} + +func readPayer() (basecoin.Actor, error) { + payer := viper.GetString(FlagPayer) + if payer == "" { + return bcmd.GetSignerAct(), nil + } + return bcmd.ParseAddress(payer) } diff --git a/modules/nonce/commands/wrap.go b/modules/nonce/commands/wrap.go index 533462b9f..b63f0e273 100644 --- a/modules/nonce/commands/wrap.go +++ b/modules/nonce/commands/wrap.go @@ -2,6 +2,7 @@ package commands import ( "fmt" + "strings" "github.com/spf13/pflag" "github.com/spf13/viper" @@ -14,6 +15,7 @@ import ( // nolint const ( FlagSequence = "sequence" + FlagNonceKey = "nonce-key" ) // NonceWrapper wraps a tx with a nonce @@ -30,7 +32,10 @@ func (NonceWrapper) Wrap(tx basecoin.Tx) (res basecoin.Tx, err error) { if seq < 0 { return res, fmt.Errorf("sequence must be greater than 0") } - signers := []basecoin.Actor{bcmd.GetSignerAct()} + signers, err := readNonceKey() + if err != nil { + return res, err + } res = nonce.NewTx(uint32(seq), signers, tx) return } @@ -38,4 +43,22 @@ func (NonceWrapper) Wrap(tx basecoin.Tx) (res basecoin.Tx, err error) { // Register adds the sequence flags to the cli func (NonceWrapper) Register(fs *pflag.FlagSet) { fs.Int(FlagSequence, -1, "Sequence number for this transaction") + fs.String(FlagNonceKey, "", "Set of comma-separated addresses for the nonce (for multisig)") +} + +func readNonceKey() (signers []basecoin.Actor, err error) { + nonce := viper.GetString(FlagNonceKey) + if nonce == "" { + return []basecoin.Actor{bcmd.GetSignerAct()}, nil + } + + var act basecoin.Actor + for _, k := range strings.Split(nonce, ",") { + act, err = bcmd.ParseAddress(k) + if err != nil { + return + } + signers = append(signers, act) + } + return }