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.

224 lines
5.9 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 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 int64) 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. return tx.AddInputWithNonce(pubkey, amt, acc.Sequence+1)
  24. }
  25. func (tx *SendTx) AddInputWithNonce(pubkey account.PubKey, amt int64, nonce int) error {
  26. addr := pubkey.Address()
  27. tx.Inputs = append(tx.Inputs, &TxInput{
  28. Address: addr,
  29. Amount: amt,
  30. Sequence: nonce,
  31. Signature: account.SignatureEd25519{},
  32. PubKey: pubkey,
  33. })
  34. return nil
  35. }
  36. func (tx *SendTx) AddOutput(addr []byte, amt int64) error {
  37. tx.Outputs = append(tx.Outputs, &TxOutput{
  38. Address: addr,
  39. Amount: amt,
  40. })
  41. return nil
  42. }
  43. func (tx *SendTx) SignInput(chainID string, i int, privAccount *account.PrivAccount) error {
  44. if i >= len(tx.Inputs) {
  45. return fmt.Errorf("Index %v is greater than number of inputs (%v)", i, len(tx.Inputs))
  46. }
  47. tx.Inputs[i].PubKey = privAccount.PubKey
  48. tx.Inputs[i].Signature = privAccount.Sign(chainID, tx)
  49. return nil
  50. }
  51. //----------------------------------------------------------------------------
  52. // CallTx interface for creating tx
  53. func NewCallTx(st AccountGetter, from account.PubKey, to, data []byte, amt, gasLimit, fee int64) (*CallTx, error) {
  54. addr := from.Address()
  55. acc := st.GetAccount(addr)
  56. if acc == nil {
  57. return nil, fmt.Errorf("Invalid address %X from pubkey %X", addr, from)
  58. }
  59. nonce := acc.Sequence + 1
  60. return NewCallTxWithNonce(from, to, data, amt, gasLimit, fee, nonce), nil
  61. }
  62. func NewCallTxWithNonce(from account.PubKey, to, data []byte, amt, gasLimit, fee int64, nonce int) *CallTx {
  63. addr := from.Address()
  64. input := &TxInput{
  65. Address: addr,
  66. Amount: amt,
  67. Sequence: nonce,
  68. Signature: account.SignatureEd25519{},
  69. PubKey: from,
  70. }
  71. return &CallTx{
  72. Input: input,
  73. Address: to,
  74. GasLimit: gasLimit,
  75. Fee: fee,
  76. Data: data,
  77. }
  78. }
  79. func (tx *CallTx) Sign(chainID string, privAccount *account.PrivAccount) {
  80. tx.Input.PubKey = privAccount.PubKey
  81. tx.Input.Signature = privAccount.Sign(chainID, tx)
  82. }
  83. //----------------------------------------------------------------------------
  84. // NameTx interface for creating tx
  85. func NewNameTx(st AccountGetter, from account.PubKey, name, data string, amt, fee int64) (*NameTx, error) {
  86. addr := from.Address()
  87. acc := st.GetAccount(addr)
  88. if acc == nil {
  89. return nil, fmt.Errorf("Invalid address %X from pubkey %X", addr, from)
  90. }
  91. nonce := acc.Sequence + 1
  92. return NewNameTxWithNonce(from, name, data, amt, fee, nonce), nil
  93. }
  94. func NewNameTxWithNonce(from account.PubKey, name, data string, amt, fee int64, nonce int) *NameTx {
  95. addr := from.Address()
  96. input := &TxInput{
  97. Address: addr,
  98. Amount: amt,
  99. Sequence: nonce,
  100. Signature: account.SignatureEd25519{},
  101. PubKey: from,
  102. }
  103. return &NameTx{
  104. Input: input,
  105. Name: name,
  106. Data: data,
  107. Fee: fee,
  108. }
  109. }
  110. func (tx *NameTx) Sign(chainID string, privAccount *account.PrivAccount) {
  111. tx.Input.PubKey = privAccount.PubKey
  112. tx.Input.Signature = privAccount.Sign(chainID, tx)
  113. }
  114. //----------------------------------------------------------------------------
  115. // BondTx interface for adding inputs/outputs and adding signatures
  116. func NewBondTx(pubkey account.PubKey) (*BondTx, error) {
  117. pubkeyEd, ok := pubkey.(account.PubKeyEd25519)
  118. if !ok {
  119. return nil, fmt.Errorf("Pubkey must be ed25519")
  120. }
  121. return &BondTx{
  122. PubKey: pubkeyEd,
  123. Inputs: []*TxInput{},
  124. UnbondTo: []*TxOutput{},
  125. }, nil
  126. }
  127. func (tx *BondTx) AddInput(st AccountGetter, pubkey account.PubKey, amt int64) error {
  128. addr := pubkey.Address()
  129. acc := st.GetAccount(addr)
  130. if acc == nil {
  131. return fmt.Errorf("Invalid address %X from pubkey %X", addr, pubkey)
  132. }
  133. return tx.AddInputWithNonce(pubkey, amt, acc.Sequence+1)
  134. }
  135. func (tx *BondTx) AddInputWithNonce(pubkey account.PubKey, amt int64, nonce int) error {
  136. addr := pubkey.Address()
  137. tx.Inputs = append(tx.Inputs, &TxInput{
  138. Address: addr,
  139. Amount: amt,
  140. Sequence: nonce,
  141. Signature: account.SignatureEd25519{},
  142. PubKey: pubkey,
  143. })
  144. return nil
  145. }
  146. func (tx *BondTx) AddOutput(addr []byte, amt int64) error {
  147. tx.UnbondTo = append(tx.UnbondTo, &TxOutput{
  148. Address: addr,
  149. Amount: amt,
  150. })
  151. return nil
  152. }
  153. func (tx *BondTx) SignBond(chainID string, privAccount *account.PrivAccount) error {
  154. sig := privAccount.Sign(chainID, tx)
  155. sigEd, ok := sig.(account.SignatureEd25519)
  156. if !ok {
  157. return fmt.Errorf("Bond signer must be ED25519")
  158. }
  159. tx.Signature = sigEd
  160. return nil
  161. }
  162. func (tx *BondTx) SignInput(chainID string, i int, privAccount *account.PrivAccount) error {
  163. if i >= len(tx.Inputs) {
  164. return fmt.Errorf("Index %v is greater than number of inputs (%v)", i, len(tx.Inputs))
  165. }
  166. tx.Inputs[i].PubKey = privAccount.PubKey
  167. tx.Inputs[i].Signature = privAccount.Sign(chainID, tx)
  168. return nil
  169. }
  170. //----------------------------------------------------------------------
  171. // UnbondTx interface for creating tx
  172. func NewUnbondTx(addr []byte, height int) *UnbondTx {
  173. return &UnbondTx{
  174. Address: addr,
  175. Height: height,
  176. }
  177. }
  178. func (tx *UnbondTx) Sign(chainID string, privAccount *account.PrivAccount) {
  179. tx.Signature = privAccount.Sign(chainID, tx).(account.SignatureEd25519)
  180. }
  181. //----------------------------------------------------------------------
  182. // RebondTx interface for creating tx
  183. func NewRebondTx(addr []byte, height int) *RebondTx {
  184. return &RebondTx{
  185. Address: addr,
  186. Height: height,
  187. }
  188. }
  189. func (tx *RebondTx) Sign(chainID string, privAccount *account.PrivAccount) {
  190. tx.Signature = privAccount.Sign(chainID, tx).(account.SignatureEd25519)
  191. }