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

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
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 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. }