From e3302bb1bb8ffc5f2f310b6ea1f63237cbfee362 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 9 Feb 2017 21:48:42 -0500 Subject: [PATCH] CLI fee and amount now use string inputs specifying the coin type readme update intermin --- README.md | 2 +- cmd/commands/flags.go | 18 +++----- cmd/commands/tx.go | 56 +++++++++++++++---------- cmd/commands/utils.go | 44 ++++++++++++++++++- docs/guide/src/example-plugin/plugin.go | 2 +- plugins/counter/counter_test.go | 2 +- 6 files changed, 87 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index c6303458aa..b765165b61 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ This will create the `basecoin` binary in `$GOPATH/bin`. The basecoin CLI can be used to start a stand-alone basecoin instance (`basecoin start`), or to start basecoin with Tendermint in the same process (`basecoin start --in-proc`). -It can also be used to send transactions, eg. `basecoin tx send --to 0x4793A333846E5104C46DD9AB9A00E31821B2F301 --amount 100` +It can also be used to send transactions, eg. `basecoin tx send --to 0x4793A333846E5104C46DD9AB9A00E31821B2F301 --amount 100btc,10gold` See `basecoin --help` and `basecoin [cmd] --help` for more details`. ## Learn more diff --git a/cmd/commands/flags.go b/cmd/commands/flags.go index 00aae351cd..980c0b67a1 100644 --- a/cmd/commands/flags.go +++ b/cmd/commands/flags.go @@ -48,10 +48,10 @@ var ( Usage: "Destination address for the transaction", } - AmountFlag = cli.IntFlag{ + AmountFlag = cli.StringFlag{ Name: "amount", - Value: 0, - Usage: "Amount of coins to send in the transaction", + Value: "", + Usage: "Coins to send in transaction of the format ,,... (eg: 1gold,2silver,5btc)", } FromFlag = cli.StringFlag{ @@ -66,22 +66,16 @@ var ( Usage: "Sequence number for the account", } - CoinFlag = cli.StringFlag{ - Name: "coin", - Value: "mycoin", - Usage: "Specify a coin denomination", - } - GasFlag = cli.IntFlag{ Name: "gas", Value: 0, Usage: "The amount of gas for the transaction", } - FeeFlag = cli.IntFlag{ + FeeFlag = cli.StringFlag{ Name: "fee", - Value: 0, - Usage: "The transaction fee", + Value: "", + Usage: "Coins for the transaction fee of the format ,,... (eg: 1gold,2silver,5btc)", } DataFlag = cli.StringFlag{ diff --git a/cmd/commands/tx.go b/cmd/commands/tx.go index 9b8ce21cd8..f54b6d0c27 100644 --- a/cmd/commands/tx.go +++ b/cmd/commands/tx.go @@ -23,7 +23,6 @@ var TxFlags = []cli.Flag{ FromFlag, AmountFlag, - CoinFlag, GasFlag, FeeFlag, SeqFlag, @@ -71,9 +70,9 @@ func RegisterTxSubcommand(cmd cli.Command) { func cmdSendTx(c *cli.Context) error { toHex := c.String("to") fromFile := c.String("from") - amount := int64(c.Int("amount")) - coin := c.String("coin") - gas, fee := c.Int("gas"), int64(c.Int("fee")) + amount := c.String("amount") + gas := int64(c.Int("gas")) + fee := c.String("fee") chainID := c.String("chain_id") // convert destination address to bytes @@ -91,12 +90,22 @@ func cmdSendTx(c *cli.Context) error { return err } + //parse the fee and amounts into coin types + feeCoin, err := ParseCoin(fee) + if err != nil { + return err + } + amountCoins, err := ParseCoins(amount) + if err != nil { + return err + } + // craft the tx - input := types.NewTxInput(privKey.PubKey, types.Coins{types.Coin{coin, amount}}, sequence) - output := newOutput(to, coin, amount) + input := types.NewTxInput(privKey.PubKey, amountCoins, sequence) + output := newOutput(to, amountCoins) tx := &types.SendTx{ - Gas: int64(gas), - Fee: types.Coin{coin, fee}, + Gas: gas, + Fee: feeCoin, Inputs: []types.TxInput{input}, Outputs: []types.TxOutput{output}, } @@ -128,9 +137,9 @@ func cmdAppTx(c *cli.Context) error { func AppTx(c *cli.Context, name string, data []byte) error { fromFile := c.String("from") - amount := int64(c.Int("amount")) - coin := c.String("coin") - gas, fee := c.Int("gas"), int64(c.Int("fee")) + amount := c.String("amount") + fee := c.String("fee") + gas := int64(c.Int("gas")) chainID := c.String("chain_id") privKey := tmtypes.LoadPrivValidator(fromFile) @@ -140,10 +149,20 @@ func AppTx(c *cli.Context, name string, data []byte) error { return err } - input := types.NewTxInput(privKey.PubKey, types.Coins{types.Coin{coin, amount}}, sequence) + //parse the fee and amounts into coin types + feeCoin, err := ParseCoin(fee) + if err != nil { + return err + } + amountCoins, err := ParseCoins(amount) + if err != nil { + return err + } + + input := types.NewTxInput(privKey.PubKey, amountCoins, sequence) tx := &types.AppTx{ - Gas: int64(gas), - Fee: types.Coin{coin, fee}, + Gas: gas, + Fee: feeCoin, Name: name, Input: input, Data: data, @@ -205,15 +224,10 @@ func getSeq(c *cli.Context, address []byte) (int, error) { return acc.Sequence + 1, nil } -func newOutput(to []byte, coin string, amount int64) types.TxOutput { +func newOutput(to []byte, amount types.Coins) types.TxOutput { return types.TxOutput{ Address: to, - Coins: types.Coins{ - types.Coin{ - Denom: coin, - Amount: amount, - }, - }, + Coins: amount, } } diff --git a/cmd/commands/utils.go b/cmd/commands/utils.go index 92a805734a..fa57267b34 100644 --- a/cmd/commands/utils.go +++ b/cmd/commands/utils.go @@ -3,9 +3,13 @@ package commands import ( "encoding/hex" "errors" + "regexp" + "strconv" + "strings" "github.com/urfave/cli" + "github.com/tendermint/basecoin/state" "github.com/tendermint/basecoin/types" abci "github.com/tendermint/abci/types" @@ -35,6 +39,44 @@ func StripHex(s string) string { return s } +func ParseCoin(str string) (types.Coin, error) { + + var coin types.Coin + + coins, err := ParseCoins(str) + + if err != nil { + return coin, err + } + + if len(coins) > 0 { + coin = coins[0] + } + + return coin, nil +} + +//regex codes from +var reAmt = regexp.MustCompile("(\\d+)") +var reCoin = regexp.MustCompile("([^\\d\\W]+)") + +func ParseCoins(str string) (types.Coins, error) { + + split := strings.Split(str, ",") + var coins []types.Coin + + for _, el := range split { + amt, err := strconv.Atoi(reAmt.FindString(el)) + if err != nil { + return coins, err + } + coin := reCoin.FindString(el) + coins = append(coins, types.Coin{coin, int64(amt)}) + } + + return coins, nil +} + func Query(tmAddr string, key []byte) (*abci.ResponseQuery, error) { clientURI := client.NewClientURI(tmAddr) tmResult := new(ctypes.TMResult) @@ -58,7 +100,7 @@ func Query(tmAddr string, key []byte) (*abci.ResponseQuery, error) { // fetch the account by querying the app func getAcc(tmAddr string, address []byte) (*types.Account, error) { - key := append([]byte("base/a/"), address...) + key := state.AccountKey(address) response, err := Query(tmAddr, key) if err != nil { return nil, err diff --git a/docs/guide/src/example-plugin/plugin.go b/docs/guide/src/example-plugin/plugin.go index e930ffbf90..f6fd5d6a62 100644 --- a/docs/guide/src/example-plugin/plugin.go +++ b/docs/guide/src/example-plugin/plugin.go @@ -69,7 +69,7 @@ func (ep *ExamplePlugin) RunTx(store types.KVStore, ctx types.CallContext, txByt return abci.OK } -func (ep *ExamplePlugin) InitChain(store types.KVStore, vals []*abci.Validator) { +func (cp *ExamplePlugin) InitChain(store types.KVStore, vals []*abci.Validator) { } func (ep *ExamplePlugin) BeginBlock(store types.KVStore, hash []byte, header *abci.Header) { diff --git a/plugins/counter/counter_test.go b/plugins/counter/counter_test.go index 0b8ee4a866..a4c4236230 100644 --- a/plugins/counter/counter_test.go +++ b/plugins/counter/counter_test.go @@ -39,7 +39,7 @@ func TestCounterPlugin(t *testing.T) { tx := &types.AppTx{ Gas: gas, Fee: fee, - Name: "counter", + Name: counterPlugin.Name(), Input: types.NewTxInput(test1Acc.PubKey, inputCoins, inputSequence), Data: wire.BinaryBytes(CounterTx{Valid: true, Fee: appFee}), }