parent
ad17fcf347
commit
9c8ccefd35
|
@ -10,41 +10,48 @@ import (
|
||||||
|
|
||||||
"github.com/tendermint/light-client/commands"
|
"github.com/tendermint/light-client/commands"
|
||||||
txcmd "github.com/tendermint/light-client/commands/txs"
|
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"
|
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{
|
var SendTxCmd = &cobra.Command{
|
||||||
Use: "send",
|
Use: "send",
|
||||||
Short: "send tokens from one account to another",
|
Short: "send tokens from one account to another",
|
||||||
RunE: doSendTx,
|
RunE: doSendTx,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//nolint
|
||||||
const (
|
const (
|
||||||
ToFlag = "to"
|
FlagTo = "to"
|
||||||
AmountFlag = "amount"
|
FlagAmount = "amount"
|
||||||
FeeFlag = "fee"
|
FlagFee = "fee"
|
||||||
GasFlag = "gas"
|
FlagGas = "gas"
|
||||||
SequenceFlag = "sequence"
|
FlagSequence = "sequence"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
flags := SendTxCmd.Flags()
|
flags := SendTxCmd.Flags()
|
||||||
flags.String(ToFlag, "", "Destination address for the bits")
|
flags.String(FlagTo, "", "Destination address for the bits")
|
||||||
flags.String(AmountFlag, "", "Coins to send in the format <amt><coin>,<amt><coin>...")
|
flags.String(FlagAmount, "", "Coins to send in the format <amt><coin>,<amt><coin>...")
|
||||||
flags.String(FeeFlag, "0mycoin", "Coins for the transaction fee of the format <amt><coin>")
|
flags.String(FlagFee, "0mycoin", "Coins for the transaction fee of the format <amt><coin>")
|
||||||
flags.Int64(GasFlag, 0, "Amount of gas for this transaction")
|
flags.Int64(FlagGas, 0, "Amount of gas for this transaction")
|
||||||
flags.Int(SequenceFlag, -1, "Sequence number for this transaction")
|
flags.Int(FlagSequence, -1, "Sequence number for this transaction")
|
||||||
}
|
}
|
||||||
|
|
||||||
// runDemo is an example of how to make a tx
|
// runDemo is an example of how to make a tx
|
||||||
func doSendTx(cmd *cobra.Command, args []string) error {
|
func doSendTx(cmd *cobra.Command, args []string) error {
|
||||||
tx := new(btypes.SendTx)
|
|
||||||
|
|
||||||
// load data from json or flags
|
// load data from json or flags
|
||||||
|
tx := new(btypes.SendTx)
|
||||||
found, err := txcmd.LoadJSON(tx)
|
found, err := txcmd.LoadJSON(tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if !found {
|
if !found {
|
||||||
err = readSendTxFlags(tx)
|
err = readSendTxFlags(tx)
|
||||||
}
|
}
|
||||||
|
@ -52,6 +59,7 @@ func doSendTx(cmd *cobra.Command, args []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wrap and add signer
|
||||||
send := &SendTx{
|
send := &SendTx{
|
||||||
chainID: commands.GetChainID(),
|
chainID: commands.GetChainID(),
|
||||||
Tx: tx,
|
Tx: tx,
|
||||||
|
@ -64,34 +72,34 @@ func doSendTx(cmd *cobra.Command, args []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// output result
|
// Output result
|
||||||
return txcmd.OutputTx(bres)
|
return txcmd.OutputTx(bres)
|
||||||
}
|
}
|
||||||
|
|
||||||
func readSendTxFlags(tx *btypes.SendTx) error {
|
func readSendTxFlags(tx *btypes.SendTx) error {
|
||||||
// parse to address
|
// parse to address
|
||||||
to, err := ParseHexFlag(ToFlag)
|
to, err := ParseHexFlag(FlagTo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Errorf("To address is invalid hex: %v\n", err)
|
return errors.Errorf("To address is invalid hex: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
//parse the fee and amounts into coin types
|
//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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
amountCoins, err := btypes.ParseCoins(viper.GetString(AmountFlag))
|
amountCoins, err := btypes.ParseCoins(viper.GetString(FlagAmount))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the gas
|
// set the gas
|
||||||
tx.Gas = viper.GetInt64(GasFlag)
|
tx.Gas = viper.GetInt64(FlagGas)
|
||||||
|
|
||||||
// craft the inputs and outputs
|
// craft the inputs and outputs
|
||||||
tx.Inputs = []btypes.TxInput{{
|
tx.Inputs = []btypes.TxInput{{
|
||||||
Coins: amountCoins,
|
Coins: amountCoins,
|
||||||
Sequence: viper.GetInt(SequenceFlag),
|
Sequence: viper.GetInt(FlagSequence),
|
||||||
}}
|
}}
|
||||||
tx.Outputs = []btypes.TxOutput{{
|
tx.Outputs = []btypes.TxOutput{{
|
||||||
Address: to,
|
Address: to,
|
||||||
|
@ -103,39 +111,53 @@ func readSendTxFlags(tx *btypes.SendTx) error {
|
||||||
|
|
||||||
/******** AppTx *********/
|
/******** 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) {
|
func AddAppTxFlags(fs *flag.FlagSet) {
|
||||||
fs.String(AmountFlag, "", "Coins to send in the format <amt><coin>,<amt><coin>...")
|
fs.String(FlagAmount, "", "Coins to send in the format <amt><coin>,<amt><coin>...")
|
||||||
fs.String(FeeFlag, "0mycoin", "Coins for the transaction fee of the format <amt><coin>")
|
fs.String(FlagFee, "0mycoin", "Coins for the transaction fee of the format <amt><coin>")
|
||||||
fs.Int64(GasFlag, 0, "Amount of gas for this transaction")
|
fs.Int64(FlagGas, 0, "Amount of gas for this transaction")
|
||||||
fs.Int(SequenceFlag, -1, "Sequence number for this transaction")
|
fs.Int(FlagSequence, -1, "Sequence number for this transaction")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadAppTxFlags reads in the standard flags
|
// ReadAppTxFlags reads in the standard flags
|
||||||
// your command should parse info to set tx.Name and tx.Data
|
// your command should parse info to set tx.Name and tx.Data
|
||||||
func ReadAppTxFlags(tx *btypes.AppTx) error {
|
func ReadAppTxFlags() (gas int64, fee btypes.Coin, txInput btypes.TxInput, err error) {
|
||||||
//parse the fee and amounts into coin types
|
|
||||||
var err error
|
// Set the gas
|
||||||
tx.Fee, err = btypes.ParseCoin(viper.GetString(FeeFlag))
|
gas = viper.GetInt64(FlagGas)
|
||||||
|
|
||||||
|
// Parse the fee and amounts into coin types
|
||||||
|
fee, err = btypes.ParseCoin(viper.GetString(FlagFee))
|
||||||
if err != nil {
|
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 {
|
if err != nil {
|
||||||
return err
|
return
|
||||||
|
}
|
||||||
|
txInput = btypes.TxInput{
|
||||||
|
Coins: amount,
|
||||||
|
Sequence: viper.GetInt(FlagSequence),
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the gas
|
return
|
||||||
tx.Gas = viper.GetInt64(GasFlag)
|
|
||||||
|
|
||||||
// craft the inputs and outputs
|
|
||||||
tx.Input = btypes.TxInput{
|
|
||||||
Coins: amountCoins,
|
|
||||||
Sequence: viper.GetInt(SequenceFlag),
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WrapAppTx wraps the transaction with chain id
|
||||||
func WrapAppTx(tx *btypes.AppTx) *AppTx {
|
func WrapAppTx(tx *btypes.AppTx) *AppTx {
|
||||||
return &AppTx{
|
return &AppTx{
|
||||||
chainID: commands.GetChainID(),
|
chainID: commands.GetChainID(),
|
||||||
|
@ -145,25 +167,7 @@ func WrapAppTx(tx *btypes.AppTx) *AppTx {
|
||||||
|
|
||||||
/** TODO copied from basecoin cli - put in common somewhere? **/
|
/** TODO copied from basecoin cli - put in common somewhere? **/
|
||||||
|
|
||||||
|
// ParseHexFlag parses a flag string to byte array
|
||||||
func ParseHexFlag(flag string) ([]byte, error) {
|
func ParseHexFlag(flag string) ([]byte, error) {
|
||||||
return hex.DecodeString(StripHex(viper.GetString(flag)))
|
return hex.DecodeString(cmn.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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,68 +12,72 @@ import (
|
||||||
btypes "github.com/tendermint/basecoin/types"
|
btypes "github.com/tendermint/basecoin/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//CounterTxCmd is the CLI command to execute the counter
|
||||||
|
// through the appTx Command
|
||||||
var CounterTxCmd = &cobra.Command{
|
var CounterTxCmd = &cobra.Command{
|
||||||
Use: "counter",
|
Use: "counter",
|
||||||
Short: "add a vote to the counter",
|
Short: "add a vote to the counter",
|
||||||
Long: `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.`,
|
You must pass --valid for it to count and the countfee will be added to the counter.`,
|
||||||
RunE: doCounterTx,
|
RunE: counterTxCmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
CountFeeFlag = "countfee"
|
flagCountFee = "countfee"
|
||||||
ValidFlag = "valid"
|
flagValid = "valid"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
fs := CounterTxCmd.Flags()
|
fs := CounterTxCmd.Flags()
|
||||||
bcmd.AddAppTxFlags(fs)
|
bcmd.AddAppTxFlags(fs)
|
||||||
fs.String(CountFeeFlag, "", "Coins to send in the format <amt><coin>,<amt><coin>...")
|
fs.String(flagCountFee, "", "Coins to send in the format <amt><coin>,<amt><coin>...")
|
||||||
fs.Bool(ValidFlag, false, "Is count valid?")
|
fs.Bool(flagValid, false, "Is count valid?")
|
||||||
}
|
}
|
||||||
|
|
||||||
func doCounterTx(cmd *cobra.Command, args []string) error {
|
func counterTxCmd(cmd *cobra.Command, args []string) error {
|
||||||
tx := new(btypes.AppTx)
|
|
||||||
// Note: we don't support loading apptx from json currently, so skip that
|
// Note: we don't support loading apptx from json currently, so skip that
|
||||||
|
|
||||||
// read the standard flags
|
// Read the app-specific flags
|
||||||
err := bcmd.ReadAppTxFlags(tx)
|
name, data, err := getAppData()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// now read the app-specific flags
|
// Read the standard app-tx flags
|
||||||
err = readCounterFlags(tx)
|
gas, fee, txInput, err := bcmd.ReadAppTxFlags()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
app := bcmd.WrapAppTx(tx)
|
// Create AppTx and broadcast
|
||||||
app.AddSigner(txcmd.GetSigner())
|
tx := &btypes.AppTx{
|
||||||
|
Gas: gas,
|
||||||
// Sign if needed and post. This it the work-horse
|
Fee: fee,
|
||||||
bres, err := txcmd.SignAndPostTx(app)
|
Name: name,
|
||||||
|
Input: txInput,
|
||||||
|
Data: data,
|
||||||
|
}
|
||||||
|
res, err := bcmd.BroadcastAppTx(tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// output result
|
// Output result
|
||||||
return txcmd.OutputTx(bres)
|
return txcmd.OutputTx(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
// readCounterFlags sets the app-specific data in the AppTx
|
func getAppData() (name string, data []byte, err error) {
|
||||||
func readCounterFlags(tx *btypes.AppTx) error {
|
countFee, err := btypes.ParseCoins(viper.GetString(flagCountFee))
|
||||||
countFee, err := btypes.ParseCoins(viper.GetString(CountFeeFlag))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
ctx := counter.CounterTx{
|
ctx := counter.CounterTx{
|
||||||
Valid: viper.GetBool(ValidFlag),
|
Valid: viper.GetBool(flagValid),
|
||||||
Fee: countFee,
|
Fee: countFee,
|
||||||
}
|
}
|
||||||
|
|
||||||
tx.Name = counter.New().Name()
|
name = counter.New().Name()
|
||||||
tx.Data = wire.BinaryBytes(ctx)
|
data = wire.BinaryBytes(ctx)
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,13 +8,14 @@ import (
|
||||||
"github.com/tendermint/basecoin/plugins/counter"
|
"github.com/tendermint/basecoin/plugins/counter"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//CounterQueryCmd CLI command to query the counter state
|
||||||
var CounterQueryCmd = &cobra.Command{
|
var CounterQueryCmd = &cobra.Command{
|
||||||
Use: "counter",
|
Use: "counter",
|
||||||
Short: "Query counter state, with proof",
|
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()
|
key := counter.New().StateKey()
|
||||||
|
|
||||||
var cp counter.CounterPluginState
|
var cp counter.CounterPluginState
|
||||||
|
@ -25,18 +26,3 @@ func doCounterQuery(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
return proofcmd.OutputProof(cp, proof.BlockHeight())
|
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
|
|
||||||
// }
|
|
||||||
|
|
|
@ -32,26 +32,25 @@ tmcli to work for any custom abci app.
|
||||||
func main() {
|
func main() {
|
||||||
commands.AddBasicFlags(BaseCli)
|
commands.AddBasicFlags(BaseCli)
|
||||||
|
|
||||||
// prepare queries
|
// Prepare queries
|
||||||
pr := proofs.RootCmd
|
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.TxCmd)
|
||||||
pr.AddCommand(proofs.KeyCmd)
|
pr.AddCommand(proofs.KeyCmd)
|
||||||
pr.AddCommand(bcmd.AccountQueryCmd)
|
pr.AddCommand(bcmd.AccountQueryCmd)
|
||||||
pr.AddCommand(bcount.CounterQueryCmd)
|
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{})
|
proofs.TxPresenters.Register("base", bcmd.BaseTxPresenter{})
|
||||||
tr := txs.RootCmd
|
tr := txs.RootCmd
|
||||||
tr.AddCommand(bcmd.SendTxCmd)
|
tr.AddCommand(bcmd.SendTxCmd)
|
||||||
tr.AddCommand(bcount.CounterTxCmd)
|
tr.AddCommand(bcount.CounterTxCmd)
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
// txs.Register("send", bcmd.SendTxMaker{})
|
// txs.Register("send", bcmd.SendTxMaker{})
|
||||||
// txs.Register("counter", bcount.CounterTxMaker{})
|
// txs.Register("counter", bcount.CounterTxMaker{})
|
||||||
|
|
||||||
// set up the various commands to use
|
// Set up the various commands to use
|
||||||
BaseCli.AddCommand(
|
BaseCli.AddCommand(
|
||||||
commands.InitCmd,
|
commands.InitCmd,
|
||||||
commands.ResetCmd,
|
commands.ResetCmd,
|
||||||
|
|
Loading…
Reference in New Issue