diff --git a/cmd/basecli/commands/cmds.go b/cmd/basecli/commands/cmds.go index 50a39024b4f1..faf54c227997 100644 --- a/cmd/basecli/commands/cmds.go +++ b/cmd/basecli/commands/cmds.go @@ -10,41 +10,48 @@ import ( "github.com/tendermint/light-client/commands" txcmd "github.com/tendermint/light-client/commands/txs" + ctypes "github.com/tendermint/tendermint/rpc/core/types" + cmn "github.com/tendermint/tmlibs/common" btypes "github.com/tendermint/basecoin/types" ) -/*** Here is the sendtx command ***/ +/******** SendTx *********/ +// SendTxCmd is CLI command to send tokens between basecoin accounts var SendTxCmd = &cobra.Command{ Use: "send", Short: "send tokens from one account to another", RunE: doSendTx, } +//nolint const ( - ToFlag = "to" - AmountFlag = "amount" - FeeFlag = "fee" - GasFlag = "gas" - SequenceFlag = "sequence" + FlagTo = "to" + FlagAmount = "amount" + FlagFee = "fee" + FlagGas = "gas" + FlagSequence = "sequence" ) func init() { flags := SendTxCmd.Flags() - flags.String(ToFlag, "", "Destination address for the bits") - flags.String(AmountFlag, "", "Coins to send in the format ,...") - flags.String(FeeFlag, "0mycoin", "Coins for the transaction fee of the format ") - flags.Int64(GasFlag, 0, "Amount of gas for this transaction") - flags.Int(SequenceFlag, -1, "Sequence number for this transaction") + flags.String(FlagTo, "", "Destination address for the bits") + flags.String(FlagAmount, "", "Coins to send in the format ,...") + flags.String(FlagFee, "0mycoin", "Coins for the transaction fee of the format ") + flags.Int64(FlagGas, 0, "Amount of gas for this transaction") + flags.Int(FlagSequence, -1, "Sequence number for this transaction") } // runDemo is an example of how to make a tx func doSendTx(cmd *cobra.Command, args []string) error { - tx := new(btypes.SendTx) // load data from json or flags + tx := new(btypes.SendTx) found, err := txcmd.LoadJSON(tx) + if err != nil { + return err + } if !found { err = readSendTxFlags(tx) } @@ -52,6 +59,7 @@ func doSendTx(cmd *cobra.Command, args []string) error { return err } + // Wrap and add signer send := &SendTx{ chainID: commands.GetChainID(), Tx: tx, @@ -64,34 +72,34 @@ func doSendTx(cmd *cobra.Command, args []string) error { return err } - // output result + // Output result return txcmd.OutputTx(bres) } func readSendTxFlags(tx *btypes.SendTx) error { // parse to address - to, err := ParseHexFlag(ToFlag) + to, err := ParseHexFlag(FlagTo) if err != nil { return errors.Errorf("To address is invalid hex: %v\n", err) } //parse the fee and amounts into coin types - tx.Fee, err = btypes.ParseCoin(viper.GetString(FeeFlag)) + tx.Fee, err = btypes.ParseCoin(viper.GetString(FlagFee)) if err != nil { return err } - amountCoins, err := btypes.ParseCoins(viper.GetString(AmountFlag)) + amountCoins, err := btypes.ParseCoins(viper.GetString(FlagAmount)) if err != nil { return err } // set the gas - tx.Gas = viper.GetInt64(GasFlag) + tx.Gas = viper.GetInt64(FlagGas) // craft the inputs and outputs tx.Inputs = []btypes.TxInput{{ Coins: amountCoins, - Sequence: viper.GetInt(SequenceFlag), + Sequence: viper.GetInt(FlagSequence), }} tx.Outputs = []btypes.TxOutput{{ Address: to, @@ -103,39 +111,53 @@ func readSendTxFlags(tx *btypes.SendTx) error { /******** AppTx *********/ +// BroadcastAppTx wraps, signs, and executes an app tx basecoin transaction +func BroadcastAppTx(tx *btypes.AppTx) (*ctypes.ResultBroadcastTxCommit, error) { + + // Generate app transaction to be broadcast + appTx := WrapAppTx(tx) + appTx.AddSigner(txcmd.GetSigner()) + + // Sign if needed and post to the node. This it the work-horse + return txcmd.SignAndPostTx(appTx) +} + +// AddAppTxFlags adds flags required by apptx func AddAppTxFlags(fs *flag.FlagSet) { - fs.String(AmountFlag, "", "Coins to send in the format ,...") - fs.String(FeeFlag, "0mycoin", "Coins for the transaction fee of the format ") - fs.Int64(GasFlag, 0, "Amount of gas for this transaction") - fs.Int(SequenceFlag, -1, "Sequence number for this transaction") + fs.String(FlagAmount, "", "Coins to send in the format ,...") + fs.String(FlagFee, "0mycoin", "Coins for the transaction fee of the format ") + fs.Int64(FlagGas, 0, "Amount of gas for this transaction") + fs.Int(FlagSequence, -1, "Sequence number for this transaction") } // ReadAppTxFlags reads in the standard flags // your command should parse info to set tx.Name and tx.Data -func ReadAppTxFlags(tx *btypes.AppTx) error { - //parse the fee and amounts into coin types - var err error - tx.Fee, err = btypes.ParseCoin(viper.GetString(FeeFlag)) +func ReadAppTxFlags() (gas int64, fee btypes.Coin, txInput btypes.TxInput, err error) { + + // Set the gas + gas = viper.GetInt64(FlagGas) + + // Parse the fee and amounts into coin types + fee, err = btypes.ParseCoin(viper.GetString(FlagFee)) if err != nil { - return err + return } - amountCoins, err := btypes.ParseCoins(viper.GetString(AmountFlag)) + + // craft the inputs + var amount btypes.Coins + amount, err = btypes.ParseCoins(viper.GetString(FlagAmount)) if err != nil { - return err + return } - - // set the gas - tx.Gas = viper.GetInt64(GasFlag) - - // craft the inputs and outputs - tx.Input = btypes.TxInput{ - Coins: amountCoins, - Sequence: viper.GetInt(SequenceFlag), + txInput = btypes.TxInput{ + Coins: amount, + Sequence: viper.GetInt(FlagSequence), } - return nil + return } +// WrapAppTx wraps the transaction with chain id func WrapAppTx(tx *btypes.AppTx) *AppTx { return &AppTx{ chainID: commands.GetChainID(), @@ -145,25 +167,7 @@ func WrapAppTx(tx *btypes.AppTx) *AppTx { /** TODO copied from basecoin cli - put in common somewhere? **/ +// ParseHexFlag parses a flag string to byte array func ParseHexFlag(flag string) ([]byte, error) { - return hex.DecodeString(StripHex(viper.GetString(flag))) -} - -// Returns true for non-empty hex-string prefixed with "0x" -func isHex(s string) bool { - if len(s) > 2 && s[:2] == "0x" { - _, err := hex.DecodeString(s[2:]) - if err != nil { - return false - } - return true - } - return false -} - -func StripHex(s string) string { - if isHex(s) { - return s[2:] - } - return s + return hex.DecodeString(cmn.StripHex(viper.GetString(flag))) } diff --git a/cmd/basecli/counter/counter.go b/cmd/basecli/counter/counter.go index b39792e2ceec..60f949fce2ff 100644 --- a/cmd/basecli/counter/counter.go +++ b/cmd/basecli/counter/counter.go @@ -12,68 +12,72 @@ import ( btypes "github.com/tendermint/basecoin/types" ) +//CounterTxCmd is the CLI command to execute the counter +// through the appTx Command var CounterTxCmd = &cobra.Command{ Use: "counter", Short: "add a vote to the counter", Long: `Add a vote to the counter. You must pass --valid for it to count and the countfee will be added to the counter.`, - RunE: doCounterTx, + RunE: counterTxCmd, } const ( - CountFeeFlag = "countfee" - ValidFlag = "valid" + flagCountFee = "countfee" + flagValid = "valid" ) func init() { fs := CounterTxCmd.Flags() bcmd.AddAppTxFlags(fs) - fs.String(CountFeeFlag, "", "Coins to send in the format ,...") - fs.Bool(ValidFlag, false, "Is count valid?") + fs.String(flagCountFee, "", "Coins to send in the format ,...") + fs.Bool(flagValid, false, "Is count valid?") } -func doCounterTx(cmd *cobra.Command, args []string) error { - tx := new(btypes.AppTx) +func counterTxCmd(cmd *cobra.Command, args []string) error { // Note: we don't support loading apptx from json currently, so skip that - // read the standard flags - err := bcmd.ReadAppTxFlags(tx) + // Read the app-specific flags + name, data, err := getAppData() if err != nil { return err } - // now read the app-specific flags - err = readCounterFlags(tx) + // Read the standard app-tx flags + gas, fee, txInput, err := bcmd.ReadAppTxFlags() if err != nil { return err } - app := bcmd.WrapAppTx(tx) - app.AddSigner(txcmd.GetSigner()) - - // Sign if needed and post. This it the work-horse - bres, err := txcmd.SignAndPostTx(app) + // Create AppTx and broadcast + tx := &btypes.AppTx{ + Gas: gas, + Fee: fee, + Name: name, + Input: txInput, + Data: data, + } + res, err := bcmd.BroadcastAppTx(tx) if err != nil { return err } - // output result - return txcmd.OutputTx(bres) + // Output result + return txcmd.OutputTx(res) } -// readCounterFlags sets the app-specific data in the AppTx -func readCounterFlags(tx *btypes.AppTx) error { - countFee, err := btypes.ParseCoins(viper.GetString(CountFeeFlag)) +func getAppData() (name string, data []byte, err error) { + countFee, err := btypes.ParseCoins(viper.GetString(flagCountFee)) if err != nil { - return err + return } ctx := counter.CounterTx{ - Valid: viper.GetBool(ValidFlag), + Valid: viper.GetBool(flagValid), Fee: countFee, } - tx.Name = counter.New().Name() - tx.Data = wire.BinaryBytes(ctx) - return nil + name = counter.New().Name() + data = wire.BinaryBytes(ctx) + return } diff --git a/cmd/basecli/counter/query.go b/cmd/basecli/counter/query.go index a1c6aeb9b59e..9a86df62574b 100644 --- a/cmd/basecli/counter/query.go +++ b/cmd/basecli/counter/query.go @@ -8,13 +8,14 @@ import ( "github.com/tendermint/basecoin/plugins/counter" ) +//CounterQueryCmd CLI command to query the counter state var CounterQueryCmd = &cobra.Command{ Use: "counter", Short: "Query counter state, with proof", - RunE: doCounterQuery, + RunE: counterQueryCmd, } -func doCounterQuery(cmd *cobra.Command, args []string) error { +func counterQueryCmd(cmd *cobra.Command, args []string) error { key := counter.New().StateKey() var cp counter.CounterPluginState @@ -25,18 +26,3 @@ func doCounterQuery(cmd *cobra.Command, args []string) error { return proofcmd.OutputProof(cp, proof.BlockHeight()) } - -/*** doesn't seem to be needed anymore??? ***/ - -// type CounterPresenter struct{} - -// func (_ CounterPresenter) MakeKey(str string) ([]byte, error) { -// key := counter.New().StateKey() -// return key, nil -// } - -// func (_ CounterPresenter) ParseData(raw []byte) (interface{}, error) { -// var cp counter.CounterPluginState -// err := wire.ReadBinaryBytes(raw, &cp) -// return cp, err -// } diff --git a/cmd/basecli/main.go b/cmd/basecli/main.go index d5116d1600cc..753e149fd4a3 100644 --- a/cmd/basecli/main.go +++ b/cmd/basecli/main.go @@ -32,26 +32,25 @@ tmcli to work for any custom abci app. func main() { commands.AddBasicFlags(BaseCli) - // prepare queries + // Prepare queries pr := proofs.RootCmd - // these are default parsers, but you optional in your app + // These are default parsers, but you optional in your app pr.AddCommand(proofs.TxCmd) pr.AddCommand(proofs.KeyCmd) pr.AddCommand(bcmd.AccountQueryCmd) pr.AddCommand(bcount.CounterQueryCmd) - // here is how you would add the custom txs... but don't really add demo in your app + // Here is how you add custom txs... but don't really add counter in your app proofs.TxPresenters.Register("base", bcmd.BaseTxPresenter{}) tr := txs.RootCmd tr.AddCommand(bcmd.SendTxCmd) tr.AddCommand(bcount.CounterTxCmd) // TODO - // txs.Register("send", bcmd.SendTxMaker{}) // txs.Register("counter", bcount.CounterTxMaker{}) - // set up the various commands to use + // Set up the various commands to use BaseCli.AddCommand( commands.InitCmd, commands.ResetCmd,