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.

260 lines
6.8 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
9 years ago
  1. package types
  2. import (
  3. "fmt"
  4. acm "github.com/tendermint/tendermint/account"
  5. ptypes "github.com/tendermint/tendermint/permission/types"
  6. )
  7. type AccountGetter interface {
  8. GetAccount(addr []byte) *acm.Account
  9. }
  10. //----------------------------------------------------------------------------
  11. // SendTx interface for adding inputs/outputs and adding signatures
  12. func NewSendTx() *SendTx {
  13. return &SendTx{
  14. Inputs: []*TxInput{},
  15. Outputs: []*TxOutput{},
  16. }
  17. }
  18. func (tx *SendTx) AddInput(st AccountGetter, pubkey acm.PubKey, amt int64) error {
  19. addr := pubkey.Address()
  20. acc := st.GetAccount(addr)
  21. if acc == nil {
  22. return fmt.Errorf("Invalid address %X from pubkey %X", addr, pubkey)
  23. }
  24. return tx.AddInputWithNonce(pubkey, amt, acc.Sequence+1)
  25. }
  26. func (tx *SendTx) AddInputWithNonce(pubkey acm.PubKey, amt int64, nonce int) error {
  27. addr := pubkey.Address()
  28. tx.Inputs = append(tx.Inputs, &TxInput{
  29. Address: addr,
  30. Amount: amt,
  31. Sequence: nonce,
  32. Signature: acm.SignatureEd25519{},
  33. PubKey: pubkey,
  34. })
  35. return nil
  36. }
  37. func (tx *SendTx) AddOutput(addr []byte, amt int64) error {
  38. tx.Outputs = append(tx.Outputs, &TxOutput{
  39. Address: addr,
  40. Amount: amt,
  41. })
  42. return nil
  43. }
  44. func (tx *SendTx) SignInput(chainID string, i int, privAccount *acm.PrivAccount) error {
  45. if i >= len(tx.Inputs) {
  46. return fmt.Errorf("Index %v is greater than number of inputs (%v)", i, len(tx.Inputs))
  47. }
  48. tx.Inputs[i].PubKey = privAccount.PubKey
  49. tx.Inputs[i].Signature = privAccount.Sign(chainID, tx)
  50. return nil
  51. }
  52. //----------------------------------------------------------------------------
  53. // CallTx interface for creating tx
  54. func NewCallTx(st AccountGetter, from acm.PubKey, to, data []byte, amt, gasLimit, fee int64) (*CallTx, error) {
  55. addr := from.Address()
  56. acc := st.GetAccount(addr)
  57. if acc == nil {
  58. return nil, fmt.Errorf("Invalid address %X from pubkey %X", addr, from)
  59. }
  60. nonce := acc.Sequence + 1
  61. return NewCallTxWithNonce(from, to, data, amt, gasLimit, fee, nonce), nil
  62. }
  63. func NewCallTxWithNonce(from acm.PubKey, to, data []byte, amt, gasLimit, fee int64, nonce int) *CallTx {
  64. addr := from.Address()
  65. input := &TxInput{
  66. Address: addr,
  67. Amount: amt,
  68. Sequence: nonce,
  69. Signature: acm.SignatureEd25519{},
  70. PubKey: from,
  71. }
  72. return &CallTx{
  73. Input: input,
  74. Address: to,
  75. GasLimit: gasLimit,
  76. Fee: fee,
  77. Data: data,
  78. }
  79. }
  80. func (tx *CallTx) Sign(chainID string, privAccount *acm.PrivAccount) {
  81. tx.Input.PubKey = privAccount.PubKey
  82. tx.Input.Signature = privAccount.Sign(chainID, tx)
  83. }
  84. //----------------------------------------------------------------------------
  85. // NameTx interface for creating tx
  86. func NewNameTx(st AccountGetter, from acm.PubKey, name, data string, amt, fee int64) (*NameTx, error) {
  87. addr := from.Address()
  88. acc := st.GetAccount(addr)
  89. if acc == nil {
  90. return nil, fmt.Errorf("Invalid address %X from pubkey %X", addr, from)
  91. }
  92. nonce := acc.Sequence + 1
  93. return NewNameTxWithNonce(from, name, data, amt, fee, nonce), nil
  94. }
  95. func NewNameTxWithNonce(from acm.PubKey, name, data string, amt, fee int64, nonce int) *NameTx {
  96. addr := from.Address()
  97. input := &TxInput{
  98. Address: addr,
  99. Amount: amt,
  100. Sequence: nonce,
  101. Signature: acm.SignatureEd25519{},
  102. PubKey: from,
  103. }
  104. return &NameTx{
  105. Input: input,
  106. Name: name,
  107. Data: data,
  108. Fee: fee,
  109. }
  110. }
  111. func (tx *NameTx) Sign(chainID string, privAccount *acm.PrivAccount) {
  112. tx.Input.PubKey = privAccount.PubKey
  113. tx.Input.Signature = privAccount.Sign(chainID, tx)
  114. }
  115. //----------------------------------------------------------------------------
  116. // BondTx interface for adding inputs/outputs and adding signatures
  117. func NewBondTx(pubkey acm.PubKey) (*BondTx, error) {
  118. pubkeyEd, ok := pubkey.(acm.PubKeyEd25519)
  119. if !ok {
  120. return nil, fmt.Errorf("Pubkey must be ed25519")
  121. }
  122. return &BondTx{
  123. PubKey: pubkeyEd,
  124. Inputs: []*TxInput{},
  125. UnbondTo: []*TxOutput{},
  126. }, nil
  127. }
  128. func (tx *BondTx) AddInput(st AccountGetter, pubkey acm.PubKey, amt int64) error {
  129. addr := pubkey.Address()
  130. acc := st.GetAccount(addr)
  131. if acc == nil {
  132. return fmt.Errorf("Invalid address %X from pubkey %X", addr, pubkey)
  133. }
  134. return tx.AddInputWithNonce(pubkey, amt, acc.Sequence+1)
  135. }
  136. func (tx *BondTx) AddInputWithNonce(pubkey acm.PubKey, amt int64, nonce int) error {
  137. addr := pubkey.Address()
  138. tx.Inputs = append(tx.Inputs, &TxInput{
  139. Address: addr,
  140. Amount: amt,
  141. Sequence: nonce,
  142. Signature: acm.SignatureEd25519{},
  143. PubKey: pubkey,
  144. })
  145. return nil
  146. }
  147. func (tx *BondTx) AddOutput(addr []byte, amt int64) error {
  148. tx.UnbondTo = append(tx.UnbondTo, &TxOutput{
  149. Address: addr,
  150. Amount: amt,
  151. })
  152. return nil
  153. }
  154. func (tx *BondTx) SignBond(chainID string, privAccount *acm.PrivAccount) error {
  155. sig := privAccount.Sign(chainID, tx)
  156. sigEd, ok := sig.(acm.SignatureEd25519)
  157. if !ok {
  158. return fmt.Errorf("Bond signer must be ED25519")
  159. }
  160. tx.Signature = sigEd
  161. return nil
  162. }
  163. func (tx *BondTx) SignInput(chainID string, i int, privAccount *acm.PrivAccount) error {
  164. if i >= len(tx.Inputs) {
  165. return fmt.Errorf("Index %v is greater than number of inputs (%v)", i, len(tx.Inputs))
  166. }
  167. tx.Inputs[i].PubKey = privAccount.PubKey
  168. tx.Inputs[i].Signature = privAccount.Sign(chainID, tx)
  169. return nil
  170. }
  171. //----------------------------------------------------------------------
  172. // UnbondTx interface for creating tx
  173. func NewUnbondTx(addr []byte, height int) *UnbondTx {
  174. return &UnbondTx{
  175. Address: addr,
  176. Height: height,
  177. }
  178. }
  179. func (tx *UnbondTx) Sign(chainID string, privAccount *acm.PrivAccount) {
  180. tx.Signature = privAccount.Sign(chainID, tx).(acm.SignatureEd25519)
  181. }
  182. //----------------------------------------------------------------------
  183. // RebondTx interface for creating tx
  184. func NewRebondTx(addr []byte, height int) *RebondTx {
  185. return &RebondTx{
  186. Address: addr,
  187. Height: height,
  188. }
  189. }
  190. func (tx *RebondTx) Sign(chainID string, privAccount *acm.PrivAccount) {
  191. tx.Signature = privAccount.Sign(chainID, tx).(acm.SignatureEd25519)
  192. }
  193. //----------------------------------------------------------------------------
  194. // PermissionsTx interface for creating tx
  195. func NewPermissionsTx(st AccountGetter, from acm.PubKey, args ptypes.PermArgs) (*PermissionsTx, error) {
  196. addr := from.Address()
  197. acc := st.GetAccount(addr)
  198. if acc == nil {
  199. return nil, fmt.Errorf("Invalid address %X from pubkey %X", addr, from)
  200. }
  201. nonce := acc.Sequence + 1
  202. return NewPermissionsTxWithNonce(from, args, nonce), nil
  203. }
  204. func NewPermissionsTxWithNonce(from acm.PubKey, args ptypes.PermArgs, nonce int) *PermissionsTx {
  205. addr := from.Address()
  206. input := &TxInput{
  207. Address: addr,
  208. Amount: 1, // NOTE: amounts can't be 0 ...
  209. Sequence: nonce,
  210. Signature: acm.SignatureEd25519{},
  211. PubKey: from,
  212. }
  213. return &PermissionsTx{
  214. Input: input,
  215. PermArgs: args,
  216. }
  217. }
  218. func (tx *PermissionsTx) Sign(chainID string, privAccount *acm.PrivAccount) {
  219. tx.Input.PubKey = privAccount.PubKey
  220. tx.Input.Signature = privAccount.Sign(chainID, tx)
  221. }