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

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