tendermint/types/tx_utils.go

261 lines
6.8 KiB
Go
Raw Normal View History

2015-05-20 17:02:59 -07:00
package types
import (
"fmt"
2015-07-19 09:40:55 -07:00
acm "github.com/tendermint/tendermint/account"
2015-07-20 11:24:57 -07:00
ptypes "github.com/tendermint/tendermint/permission/types"
2015-05-20 17:02:59 -07:00
)
type AccountGetter interface {
2015-07-19 09:40:55 -07:00
GetAccount(addr []byte) *acm.Account
2015-05-20 17:02:59 -07:00
}
//----------------------------------------------------------------------------
// SendTx interface for adding inputs/outputs and adding signatures
func NewSendTx() *SendTx {
return &SendTx{
Inputs: []*TxInput{},
Outputs: []*TxOutput{},
}
}
2015-07-19 09:40:55 -07:00
func (tx *SendTx) AddInput(st AccountGetter, pubkey acm.PubKey, amt int64) error {
2015-05-20 17:02:59 -07:00
addr := pubkey.Address()
acc := st.GetAccount(addr)
if acc == nil {
return fmt.Errorf("Invalid address %X from pubkey %X", addr, pubkey)
}
2015-05-27 12:24:45 -07:00
return tx.AddInputWithNonce(pubkey, amt, acc.Sequence+1)
2015-05-20 17:02:59 -07:00
}
2015-07-19 09:40:55 -07:00
func (tx *SendTx) AddInputWithNonce(pubkey acm.PubKey, amt int64, nonce int) error {
2015-05-22 15:22:57 -07:00
addr := pubkey.Address()
tx.Inputs = append(tx.Inputs, &TxInput{
Address: addr,
Amount: amt,
2015-05-27 12:24:45 -07:00
Sequence: nonce,
2015-07-19 09:40:55 -07:00
Signature: acm.SignatureEd25519{},
2015-05-22 15:22:57 -07:00
PubKey: pubkey,
})
return nil
}
func (tx *SendTx) AddOutput(addr []byte, amt int64) error {
2015-05-20 17:02:59 -07:00
tx.Outputs = append(tx.Outputs, &TxOutput{
Address: addr,
Amount: amt,
})
return nil
}
2015-07-19 09:40:55 -07:00
func (tx *SendTx) SignInput(chainID string, i int, privAccount *acm.PrivAccount) error {
2015-05-20 17:02:59 -07:00
if i >= len(tx.Inputs) {
return fmt.Errorf("Index %v is greater than number of inputs (%v)", i, len(tx.Inputs))
}
tx.Inputs[i].PubKey = privAccount.PubKey
2015-05-29 14:53:57 -07:00
tx.Inputs[i].Signature = privAccount.Sign(chainID, tx)
2015-05-20 17:02:59 -07:00
return nil
}
//----------------------------------------------------------------------------
// CallTx interface for creating tx
2015-07-19 09:40:55 -07:00
func NewCallTx(st AccountGetter, from acm.PubKey, to, data []byte, amt, gasLimit, fee int64) (*CallTx, error) {
2015-05-20 17:02:59 -07:00
addr := from.Address()
acc := st.GetAccount(addr)
if acc == nil {
return nil, fmt.Errorf("Invalid address %X from pubkey %X", addr, from)
}
2015-05-27 12:24:45 -07:00
nonce := acc.Sequence + 1
2015-05-22 15:22:57 -07:00
return NewCallTxWithNonce(from, to, data, amt, gasLimit, fee, nonce), nil
}
2015-07-19 09:40:55 -07:00
func NewCallTxWithNonce(from acm.PubKey, to, data []byte, amt, gasLimit, fee int64, nonce int) *CallTx {
2015-05-22 15:22:57 -07:00
addr := from.Address()
2015-05-20 17:02:59 -07:00
input := &TxInput{
Address: addr,
Amount: amt,
2015-05-27 12:24:45 -07:00
Sequence: nonce,
2015-07-19 09:40:55 -07:00
Signature: acm.SignatureEd25519{},
2015-05-20 17:02:59 -07:00
PubKey: from,
}
return &CallTx{
Input: input,
Address: to,
GasLimit: gasLimit,
Fee: fee,
Data: data,
2015-05-22 15:22:57 -07:00
}
2015-05-20 17:02:59 -07:00
}
2015-07-19 09:40:55 -07:00
func (tx *CallTx) Sign(chainID string, privAccount *acm.PrivAccount) {
2015-05-20 17:02:59 -07:00
tx.Input.PubKey = privAccount.PubKey
2015-05-29 14:53:57 -07:00
tx.Input.Signature = privAccount.Sign(chainID, tx)
2015-05-20 17:02:59 -07:00
}
2015-05-22 14:03:22 -07:00
//----------------------------------------------------------------------------
// NameTx interface for creating tx
2015-07-19 09:40:55 -07:00
func NewNameTx(st AccountGetter, from acm.PubKey, name, data string, amt, fee int64) (*NameTx, error) {
2015-05-22 14:03:22 -07:00
addr := from.Address()
acc := st.GetAccount(addr)
if acc == nil {
return nil, fmt.Errorf("Invalid address %X from pubkey %X", addr, from)
}
2015-05-27 12:24:45 -07:00
nonce := acc.Sequence + 1
2015-05-22 14:03:22 -07:00
return NewNameTxWithNonce(from, name, data, amt, fee, nonce), nil
}
2015-07-19 09:40:55 -07:00
func NewNameTxWithNonce(from acm.PubKey, name, data string, amt, fee int64, nonce int) *NameTx {
2015-05-22 14:03:22 -07:00
addr := from.Address()
input := &TxInput{
Address: addr,
Amount: amt,
2015-05-27 12:24:45 -07:00
Sequence: nonce,
2015-07-19 09:40:55 -07:00
Signature: acm.SignatureEd25519{},
2015-05-22 14:03:22 -07:00
PubKey: from,
}
return &NameTx{
Input: input,
Name: name,
Data: data,
Fee: fee,
}
}
2015-07-19 09:40:55 -07:00
func (tx *NameTx) Sign(chainID string, privAccount *acm.PrivAccount) {
2015-05-22 14:03:22 -07:00
tx.Input.PubKey = privAccount.PubKey
tx.Input.Signature = privAccount.Sign(chainID, tx)
2015-05-22 14:03:22 -07:00
}
2015-05-20 17:02:59 -07:00
//----------------------------------------------------------------------------
// BondTx interface for adding inputs/outputs and adding signatures
2015-07-19 09:40:55 -07:00
func NewBondTx(pubkey acm.PubKey) (*BondTx, error) {
pubkeyEd, ok := pubkey.(acm.PubKeyEd25519)
2015-05-20 17:02:59 -07:00
if !ok {
return nil, fmt.Errorf("Pubkey must be ed25519")
}
return &BondTx{
PubKey: pubkeyEd,
Inputs: []*TxInput{},
UnbondTo: []*TxOutput{},
}, nil
}
2015-07-19 09:40:55 -07:00
func (tx *BondTx) AddInput(st AccountGetter, pubkey acm.PubKey, amt int64) error {
2015-05-20 17:02:59 -07:00
addr := pubkey.Address()
acc := st.GetAccount(addr)
if acc == nil {
return fmt.Errorf("Invalid address %X from pubkey %X", addr, pubkey)
}
2015-05-27 12:24:45 -07:00
return tx.AddInputWithNonce(pubkey, amt, acc.Sequence+1)
2015-05-20 17:02:59 -07:00
}
2015-07-19 09:40:55 -07:00
func (tx *BondTx) AddInputWithNonce(pubkey acm.PubKey, amt int64, nonce int) error {
2015-05-22 15:22:57 -07:00
addr := pubkey.Address()
tx.Inputs = append(tx.Inputs, &TxInput{
Address: addr,
Amount: amt,
2015-05-27 12:24:45 -07:00
Sequence: nonce,
2015-07-19 09:40:55 -07:00
Signature: acm.SignatureEd25519{},
2015-05-22 15:22:57 -07:00
PubKey: pubkey,
})
return nil
}
func (tx *BondTx) AddOutput(addr []byte, amt int64) error {
2015-05-20 17:02:59 -07:00
tx.UnbondTo = append(tx.UnbondTo, &TxOutput{
Address: addr,
Amount: amt,
})
return nil
}
2015-07-19 09:40:55 -07:00
func (tx *BondTx) SignBond(chainID string, privAccount *acm.PrivAccount) error {
2015-05-29 14:53:57 -07:00
sig := privAccount.Sign(chainID, tx)
2015-07-19 09:40:55 -07:00
sigEd, ok := sig.(acm.SignatureEd25519)
2015-05-20 17:02:59 -07:00
if !ok {
return fmt.Errorf("Bond signer must be ED25519")
}
tx.Signature = sigEd
return nil
}
2015-07-19 09:40:55 -07:00
func (tx *BondTx) SignInput(chainID string, i int, privAccount *acm.PrivAccount) error {
2015-05-20 17:02:59 -07:00
if i >= len(tx.Inputs) {
return fmt.Errorf("Index %v is greater than number of inputs (%v)", i, len(tx.Inputs))
}
tx.Inputs[i].PubKey = privAccount.PubKey
2015-05-29 14:53:57 -07:00
tx.Inputs[i].Signature = privAccount.Sign(chainID, tx)
2015-05-20 17:02:59 -07:00
return nil
}
2015-06-18 15:49:27 -07:00
//----------------------------------------------------------------------
// UnbondTx interface for creating tx
func NewUnbondTx(addr []byte, height int) *UnbondTx {
2015-06-18 15:49:27 -07:00
return &UnbondTx{
Address: addr,
Height: height,
}
}
2015-07-19 09:40:55 -07:00
func (tx *UnbondTx) Sign(chainID string, privAccount *acm.PrivAccount) {
tx.Signature = privAccount.Sign(chainID, tx).(acm.SignatureEd25519)
2015-06-18 15:49:27 -07:00
}
//----------------------------------------------------------------------
// RebondTx interface for creating tx
func NewRebondTx(addr []byte, height int) *RebondTx {
2015-06-18 15:49:27 -07:00
return &RebondTx{
Address: addr,
Height: height,
}
}
2015-07-19 09:40:55 -07:00
func (tx *RebondTx) Sign(chainID string, privAccount *acm.PrivAccount) {
tx.Signature = privAccount.Sign(chainID, tx).(acm.SignatureEd25519)
2015-06-18 15:49:27 -07:00
}
2015-07-20 11:24:57 -07:00
//----------------------------------------------------------------------------
// PermissionsTx interface for creating tx
2015-07-20 11:24:57 -07:00
func NewPermissionsTx(st AccountGetter, from acm.PubKey, args ptypes.PermArgs) (*PermissionsTx, error) {
2015-07-20 11:24:57 -07:00
addr := from.Address()
acc := st.GetAccount(addr)
if acc == nil {
return nil, fmt.Errorf("Invalid address %X from pubkey %X", addr, from)
}
nonce := acc.Sequence + 1
return NewPermissionsTxWithNonce(from, args, nonce), nil
2015-07-20 11:24:57 -07:00
}
func NewPermissionsTxWithNonce(from acm.PubKey, args ptypes.PermArgs, nonce int) *PermissionsTx {
2015-07-20 11:24:57 -07:00
addr := from.Address()
input := &TxInput{
Address: addr,
Amount: 1, // NOTE: amounts can't be 0 ...
Sequence: nonce,
Signature: acm.SignatureEd25519{},
PubKey: from,
}
return &PermissionsTx{
Input: input,
PermArgs: args,
2015-07-20 11:24:57 -07:00
}
}
func (tx *PermissionsTx) Sign(chainID string, privAccount *acm.PrivAccount) {
2015-07-20 11:24:57 -07:00
tx.Input.PubKey = privAccount.PubKey
tx.Input.Signature = privAccount.Sign(chainID, tx)
}