You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
3.6 KiB

10 years ago
  1. package types
  2. import (
  3. "fmt"
  4. "github.com/tendermint/tendermint/account"
  5. )
  6. type AccountGetter interface {
  7. GetAccount(addr []byte) *account.Account
  8. }
  9. //----------------------------------------------------------------------------
  10. // SendTx interface for adding inputs/outputs and adding signatures
  11. func NewSendTx() *SendTx {
  12. return &SendTx{
  13. Inputs: []*TxInput{},
  14. Outputs: []*TxOutput{},
  15. }
  16. }
  17. func (tx *SendTx) AddInput(st AccountGetter, pubkey account.PubKey, amt uint64) error {
  18. addr := pubkey.Address()
  19. acc := st.GetAccount(addr)
  20. if acc == nil {
  21. return fmt.Errorf("Invalid address %X from pubkey %X", addr, pubkey)
  22. }
  23. tx.Inputs = append(tx.Inputs, &TxInput{
  24. Address: addr,
  25. Amount: amt,
  26. Sequence: uint(acc.Sequence) + 1,
  27. Signature: account.SignatureEd25519{},
  28. PubKey: pubkey,
  29. })
  30. return nil
  31. }
  32. func (tx *SendTx) AddOutput(addr []byte, amt uint64) error {
  33. tx.Outputs = append(tx.Outputs, &TxOutput{
  34. Address: addr,
  35. Amount: amt,
  36. })
  37. return nil
  38. }
  39. func (tx *SendTx) SignInput(i int, privAccount *account.PrivAccount) error {
  40. if i >= len(tx.Inputs) {
  41. return fmt.Errorf("Index %v is greater than number of inputs (%v)", i, len(tx.Inputs))
  42. }
  43. tx.Inputs[i].PubKey = privAccount.PubKey
  44. tx.Inputs[i].Signature = privAccount.Sign(tx)
  45. return nil
  46. }
  47. //----------------------------------------------------------------------------
  48. // CallTx interface for creating tx
  49. func NewCallTx(st AccountGetter, from account.PubKey, to, data []byte, amt, gasLimit, fee uint64) (*CallTx, error) {
  50. addr := from.Address()
  51. acc := st.GetAccount(addr)
  52. if acc == nil {
  53. return nil, fmt.Errorf("Invalid address %X from pubkey %X", addr, from)
  54. }
  55. input := &TxInput{
  56. Address: addr,
  57. Amount: amt,
  58. Sequence: uint(acc.Sequence) + 1,
  59. Signature: account.SignatureEd25519{},
  60. PubKey: from,
  61. }
  62. return &CallTx{
  63. Input: input,
  64. Address: to,
  65. GasLimit: gasLimit,
  66. Fee: fee,
  67. Data: data,
  68. }, nil
  69. }
  70. func (tx *CallTx) Sign(privAccount *account.PrivAccount) {
  71. tx.Input.PubKey = privAccount.PubKey
  72. tx.Input.Signature = privAccount.Sign(tx)
  73. }
  74. //----------------------------------------------------------------------------
  75. // BondTx interface for adding inputs/outputs and adding signatures
  76. func NewBondTx(pubkey account.PubKey) (*BondTx, error) {
  77. pubkeyEd, ok := pubkey.(account.PubKeyEd25519)
  78. if !ok {
  79. return nil, fmt.Errorf("Pubkey must be ed25519")
  80. }
  81. return &BondTx{
  82. PubKey: pubkeyEd,
  83. Inputs: []*TxInput{},
  84. UnbondTo: []*TxOutput{},
  85. }, nil
  86. }
  87. func (tx *BondTx) AddInput(st AccountGetter, pubkey account.PubKey, amt uint64) error {
  88. addr := pubkey.Address()
  89. acc := st.GetAccount(addr)
  90. if acc == nil {
  91. return fmt.Errorf("Invalid address %X from pubkey %X", addr, pubkey)
  92. }
  93. tx.Inputs = append(tx.Inputs, &TxInput{
  94. Address: addr,
  95. Amount: amt,
  96. Sequence: uint(acc.Sequence) + 1,
  97. Signature: account.SignatureEd25519{},
  98. PubKey: pubkey,
  99. })
  100. return nil
  101. }
  102. func (tx *BondTx) AddOutput(addr []byte, amt uint64) error {
  103. tx.UnbondTo = append(tx.UnbondTo, &TxOutput{
  104. Address: addr,
  105. Amount: amt,
  106. })
  107. return nil
  108. }
  109. func (tx *BondTx) SignBond(privAccount *account.PrivAccount) error {
  110. sig := privAccount.Sign(tx)
  111. sigEd, ok := sig.(account.SignatureEd25519)
  112. if !ok {
  113. return fmt.Errorf("Bond signer must be ED25519")
  114. }
  115. tx.Signature = sigEd
  116. return nil
  117. }
  118. func (tx *BondTx) SignInput(i int, privAccount *account.PrivAccount) error {
  119. if i >= len(tx.Inputs) {
  120. return fmt.Errorf("Index %v is greater than number of inputs (%v)", i, len(tx.Inputs))
  121. }
  122. tx.Inputs[i].PubKey = privAccount.PubKey
  123. tx.Inputs[i].Signature = privAccount.Sign(tx)
  124. return nil
  125. }