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.

175 lines
4.4 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
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) AddInputWithNonce(pubkey account.PubKey, amt, nonce uint64) error {
  33. addr := pubkey.Address()
  34. tx.Inputs = append(tx.Inputs, &TxInput{
  35. Address: addr,
  36. Amount: amt,
  37. Sequence: uint(nonce) + 1,
  38. Signature: account.SignatureEd25519{},
  39. PubKey: pubkey,
  40. })
  41. return nil
  42. }
  43. func (tx *SendTx) AddOutput(addr []byte, amt uint64) error {
  44. tx.Outputs = append(tx.Outputs, &TxOutput{
  45. Address: addr,
  46. Amount: amt,
  47. })
  48. return nil
  49. }
  50. func (tx *SendTx) SignInput(i int, privAccount *account.PrivAccount) error {
  51. if i >= len(tx.Inputs) {
  52. return fmt.Errorf("Index %v is greater than number of inputs (%v)", i, len(tx.Inputs))
  53. }
  54. tx.Inputs[i].PubKey = privAccount.PubKey
  55. tx.Inputs[i].Signature = privAccount.Sign(tx)
  56. return nil
  57. }
  58. //----------------------------------------------------------------------------
  59. // CallTx interface for creating tx
  60. func NewCallTx(st AccountGetter, from account.PubKey, to, data []byte, amt, gasLimit, fee uint64) (*CallTx, error) {
  61. addr := from.Address()
  62. acc := st.GetAccount(addr)
  63. if acc == nil {
  64. return nil, fmt.Errorf("Invalid address %X from pubkey %X", addr, from)
  65. }
  66. nonce := uint64(acc.Sequence)
  67. return NewCallTxWithNonce(from, to, data, amt, gasLimit, fee, nonce), nil
  68. }
  69. func NewCallTxWithNonce(from account.PubKey, to, data []byte, amt, gasLimit, fee, nonce uint64) *CallTx {
  70. addr := from.Address()
  71. input := &TxInput{
  72. Address: addr,
  73. Amount: amt,
  74. Sequence: uint(nonce) + 1,
  75. Signature: account.SignatureEd25519{},
  76. PubKey: from,
  77. }
  78. return &CallTx{
  79. Input: input,
  80. Address: to,
  81. GasLimit: gasLimit,
  82. Fee: fee,
  83. Data: data,
  84. }
  85. }
  86. func (tx *CallTx) Sign(privAccount *account.PrivAccount) {
  87. tx.Input.PubKey = privAccount.PubKey
  88. tx.Input.Signature = privAccount.Sign(tx)
  89. }
  90. //----------------------------------------------------------------------------
  91. // BondTx interface for adding inputs/outputs and adding signatures
  92. func NewBondTx(pubkey account.PubKey) (*BondTx, error) {
  93. pubkeyEd, ok := pubkey.(account.PubKeyEd25519)
  94. if !ok {
  95. return nil, fmt.Errorf("Pubkey must be ed25519")
  96. }
  97. return &BondTx{
  98. PubKey: pubkeyEd,
  99. Inputs: []*TxInput{},
  100. UnbondTo: []*TxOutput{},
  101. }, nil
  102. }
  103. func (tx *BondTx) AddInput(st AccountGetter, pubkey account.PubKey, amt uint64) error {
  104. addr := pubkey.Address()
  105. acc := st.GetAccount(addr)
  106. if acc == nil {
  107. return fmt.Errorf("Invalid address %X from pubkey %X", addr, pubkey)
  108. }
  109. tx.Inputs = append(tx.Inputs, &TxInput{
  110. Address: addr,
  111. Amount: amt,
  112. Sequence: uint(acc.Sequence) + 1,
  113. Signature: account.SignatureEd25519{},
  114. PubKey: pubkey,
  115. })
  116. return nil
  117. }
  118. func (tx *BondTx) AddInputWithNonce(pubkey account.PubKey, amt, nonce uint64) error {
  119. addr := pubkey.Address()
  120. tx.Inputs = append(tx.Inputs, &TxInput{
  121. Address: addr,
  122. Amount: amt,
  123. Sequence: uint(nonce) + 1,
  124. Signature: account.SignatureEd25519{},
  125. PubKey: pubkey,
  126. })
  127. return nil
  128. }
  129. func (tx *BondTx) AddOutput(addr []byte, amt uint64) error {
  130. tx.UnbondTo = append(tx.UnbondTo, &TxOutput{
  131. Address: addr,
  132. Amount: amt,
  133. })
  134. return nil
  135. }
  136. func (tx *BondTx) SignBond(privAccount *account.PrivAccount) error {
  137. sig := privAccount.Sign(tx)
  138. sigEd, ok := sig.(account.SignatureEd25519)
  139. if !ok {
  140. return fmt.Errorf("Bond signer must be ED25519")
  141. }
  142. tx.Signature = sigEd
  143. return nil
  144. }
  145. func (tx *BondTx) SignInput(i int, privAccount *account.PrivAccount) error {
  146. if i >= len(tx.Inputs) {
  147. return fmt.Errorf("Index %v is greater than number of inputs (%v)", i, len(tx.Inputs))
  148. }
  149. tx.Inputs[i].PubKey = privAccount.PubKey
  150. tx.Inputs[i].Signature = privAccount.Sign(tx)
  151. return nil
  152. }