diff --git a/cmd/basecli/commands/cmds.go b/cmd/basecli/commands/cmds.go index d0e10e8aae..f8cbd77059 100644 --- a/cmd/basecli/commands/cmds.go +++ b/cmd/basecli/commands/cmds.go @@ -9,11 +9,15 @@ import ( flag "github.com/spf13/pflag" "github.com/spf13/viper" + "github.com/tendermint/basecoin" "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" + "github.com/tendermint/basecoin/modules/coin" + "github.com/tendermint/basecoin/stack" + "github.com/tendermint/basecoin/txs" btypes "github.com/tendermint/basecoin/types" ) @@ -48,27 +52,25 @@ func init() { // runDemo is an example of how to make a tx func doSendTx(cmd *cobra.Command, args []string) error { // load data from json or flags - tx := new(btypes.SendTx) - found, err := txcmd.LoadJSON(tx) + var tx basecoin.Tx + found, err := txcmd.LoadJSON(&tx) if err != nil { return err } if !found { - err = readSendTxFlags(tx) + tx, err = readSendTxFlags() } if err != nil { return err } - // Wrap and add signer - send := &SendTx{ - chainID: commands.GetChainID(), - Tx: tx, - } - send.AddSigner(txcmd.GetSigner()) + // TODO: make this more flexible for middleware + // add the chain info + tx = txs.NewChain(commands.GetChainID(), tx) + stx := txs.NewSig(tx) // Sign if needed and post. This it the work-horse - bres, err := txcmd.SignAndPostTx(send) + bres, err := txcmd.SignAndPostTx(stx) if err != nil { return err } @@ -77,40 +79,50 @@ func doSendTx(cmd *cobra.Command, args []string) error { return txcmd.OutputTx(bres) } -func readSendTxFlags(tx *btypes.SendTx) error { +func readSendTxFlags() (tx basecoin.Tx, err error) { // parse to address - to, err := parseChainAddress(viper.GetString(FlagTo)) + chain, to, err := parseChainAddress(viper.GetString(FlagTo)) if err != nil { - return err + return tx, err } + toAddr := stack.SigPerm(to) + toAddr.ChainID = chain + + // //parse the fee and amounts into coin types + // tx.Fee, err = btypes.ParseCoin(viper.GetString(FlagFee)) + // if err != nil { + // return err + // } + // // set the gas + // tx.Gas = viper.GetInt64(FlagGas) - //parse the fee and amounts into coin types - tx.Fee, err = btypes.ParseCoin(viper.GetString(FlagFee)) - if err != nil { - return err - } amountCoins, err := btypes.ParseCoins(viper.GetString(FlagAmount)) if err != nil { - return err + return tx, err } - // set the gas - tx.Gas = viper.GetInt64(FlagGas) + // this could be much cooler with multisig... + var fromAddr basecoin.Actor + signer := txcmd.GetSigner() + if !signer.Empty() { + fromAddr = stack.SigPerm(signer.Address()) + } // craft the inputs and outputs - tx.Inputs = []btypes.TxInput{{ + ins := []coin.TxInput{{ + Address: fromAddr, Coins: amountCoins, Sequence: viper.GetInt(FlagSequence), }} - tx.Outputs = []btypes.TxOutput{{ - Address: to, + outs := []coin.TxOutput{{ + Address: toAddr, Coins: amountCoins, }} - return nil + return coin.NewSendTx(ins, outs), nil } -func parseChainAddress(toFlag string) ([]byte, error) { +func parseChainAddress(toFlag string) (string, []byte, error) { var toHex string var chainPrefix string spl := strings.Split(toFlag, "/") @@ -121,19 +133,16 @@ func parseChainAddress(toFlag string) ([]byte, error) { chainPrefix = spl[0] toHex = spl[1] default: - return nil, errors.Errorf("To address has too many slashes") + return "", nil, errors.Errorf("To address has too many slashes") } // convert destination address to bytes to, err := hex.DecodeString(cmn.StripHex(toHex)) if err != nil { - return nil, errors.Errorf("To address is invalid hex: %v\n", err) + return "", nil, errors.Errorf("To address is invalid hex: %v\n", err) } - if chainPrefix != "" { - to = []byte(chainPrefix + "/" + string(to)) - } - return to, nil + return chainPrefix, to, nil } //------------------------- diff --git a/cmd/basecli/commands/query.go b/cmd/basecli/commands/query.go index eb979d397a..7f3b8db56b 100644 --- a/cmd/basecli/commands/query.go +++ b/cmd/basecli/commands/query.go @@ -4,6 +4,7 @@ import ( "github.com/pkg/errors" "github.com/spf13/cobra" + "github.com/tendermint/basecoin" wire "github.com/tendermint/go-wire" lc "github.com/tendermint/light-client" lcmd "github.com/tendermint/light-client/commands" @@ -12,7 +13,6 @@ import ( "github.com/tendermint/basecoin/modules/coin" "github.com/tendermint/basecoin/stack" - btypes "github.com/tendermint/basecoin/types" ) var AccountQueryCmd = &cobra.Command{ @@ -45,7 +45,7 @@ type BaseTxPresenter struct { } func (_ BaseTxPresenter) ParseData(raw []byte) (interface{}, error) { - var tx btypes.TxS + var tx basecoin.Tx err := wire.ReadBinaryBytes(raw, &tx) return tx, err } diff --git a/context.go b/context.go index 8532cc6c9a..dbbe7b6d92 100644 --- a/context.go +++ b/context.go @@ -12,9 +12,9 @@ import ( // It doesn't just have to be a pubkey on this chain, it could stem from // another app (like multi-sig account), or even another chain (via IBC) type Actor struct { - ChainID string // this is empty unless it comes from a different chain - App string // the app that the actor belongs to - Address data.Bytes // arbitrary app-specific unique id + ChainID string `json:"chain"` // this is empty unless it comes from a different chain + App string `json:"app"` // the app that the actor belongs to + Address data.Bytes `json:"addr"` // arbitrary app-specific unique id } func NewActor(app string, addr []byte) Actor { diff --git a/modules/coin/store.go b/modules/coin/store.go index 46a1c93cd0..6170f780a6 100644 --- a/modules/coin/store.go +++ b/modules/coin/store.go @@ -90,7 +90,7 @@ func (a Accountant) MakeKey(addr basecoin.Actor) []byte { type Account struct { Coins types.Coins `json:"coins"` - Sequence int `json:"seq"` + Sequence int `json:"sequence"` } func loadAccount(store types.KVStore, key []byte) (acct Account, err error) { diff --git a/tests/cli/common.sh b/tests/cli/common.sh index b4c553ff55..7c3b886ea3 100644 --- a/tests/cli/common.sh +++ b/tests/cli/common.sh @@ -159,9 +159,13 @@ checkSendTx() { if [ -n "$DEBUG" ]; then echo $TX; echo; fi assertEquals "proper height" $2 $(echo $TX | jq .height) - assertEquals "type=send" '"send"' $(echo $TX | jq .data.type) - assertEquals "proper sender" "\"$3\"" $(echo $TX | jq .data.data.inputs[0].address) - assertEquals "proper out amount" "$4" $(echo $TX | jq .data.data.outputs[0].coins[0].amount) + assertEquals "type=sig" '"sig"' $(echo $TX | jq .data.type) + CTX=$(echo $TX | jq .data.data.tx) + assertEquals "type=chain" '"chain"' $(echo $CTX | jq .type) + STX=$(echo $CTX | jq .data.tx) + assertEquals "type=send" '"send"' $(echo $STX | jq .type) + assertEquals "proper sender" "\"$3\"" $(echo $STX | jq .data.inputs[0].address.addr) + assertEquals "proper out amount" "$4" $(echo $STX | jq .data.outputs[0].coins[0].amount) return $? } diff --git a/txs/sigs.go b/txs/sigs.go index 699b6aa520..d49dcb026a 100644 --- a/txs/sigs.go +++ b/txs/sigs.go @@ -64,16 +64,12 @@ func (s *OneSig) Next() basecoin.Tx { } func (s *OneSig) ValidateBasic() error { - // TODO: VerifyBytes here, we do it in Signers? - if s.Empty() || !s.Pubkey.VerifyBytes(s.SignBytes(), s.Sig) { - return errors.ErrUnauthorized() - } return s.Tx.ValidateBasic() } // TxBytes returns the full data with signatures func (s *OneSig) TxBytes() ([]byte, error) { - return data.ToWire(s) + return data.ToWire(s.Wrap()) } // SignBytes returns the original data passed into `NewSig` @@ -139,17 +135,12 @@ func (s *MultiSig) Next() basecoin.Tx { } func (s *MultiSig) ValidateBasic() error { - // TODO: more efficient - _, err := s.Signers() - if err != nil { - return err - } return s.Tx.ValidateBasic() } // TxBytes returns the full data with signatures func (s *MultiSig) TxBytes() ([]byte, error) { - return data.ToWire(s) + return data.ToWire(s.Wrap()) } // SignBytes returns the original data passed into `NewSig`