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.

152 lines
3.6 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
  1. package state
  2. import (
  3. "fmt"
  4. "io"
  5. . "github.com/tendermint/tendermint/binary"
  6. . "github.com/tendermint/tendermint/blocks"
  7. . "github.com/tendermint/tendermint/common"
  8. "github.com/tendermint/tendermint/crypto"
  9. )
  10. const (
  11. AccountStatusNominal = byte(0x00)
  12. AccountStatusBonded = byte(0x01)
  13. AccountStatusUnbonding = byte(0x02)
  14. AccountStatusDupedOut = byte(0x03)
  15. )
  16. type Account struct {
  17. Id uint64 // Numeric id of account, incrementing.
  18. PubKey []byte
  19. }
  20. func ReadAccount(r io.Reader, n *int64, err *error) Account {
  21. return Account{
  22. Id: ReadUInt64(r, n, err),
  23. PubKey: ReadByteSlice(r, n, err),
  24. }
  25. }
  26. func (account Account) WriteTo(w io.Writer) (n int64, err error) {
  27. WriteUInt64(w, account.Id, &n, &err)
  28. WriteByteSlice(w, account.PubKey, &n, &err)
  29. return
  30. }
  31. func (account Account) VerifyBytes(msg []byte, sig Signature) bool {
  32. if sig.SignerId != account.Id {
  33. panic("account.id doesn't match sig.signerid")
  34. }
  35. v1 := &crypto.Verify{
  36. Message: msg,
  37. PubKey: account.PubKey,
  38. Signature: sig.Bytes,
  39. }
  40. ok := crypto.VerifyBatch([]*crypto.Verify{v1})
  41. return ok
  42. }
  43. func (account Account) Verify(o Signable) bool {
  44. sig := o.GetSignature()
  45. o.SetSignature(Signature{}) // clear
  46. msg := BinaryBytes(o)
  47. o.SetSignature(sig) // restore
  48. return account.VerifyBytes(msg, sig)
  49. }
  50. func (account Account) String() string {
  51. return fmt.Sprintf("Account{%v:%X}", account.Id, account.PubKey)
  52. }
  53. //-----------------------------------------------------------------------------
  54. type AccountDetail struct {
  55. Account
  56. Sequence uint
  57. Balance uint64
  58. Status byte
  59. }
  60. func ReadAccountDetail(r io.Reader, n *int64, err *error) *AccountDetail {
  61. return &AccountDetail{
  62. Account: ReadAccount(r, n, err),
  63. Sequence: ReadUVarInt(r, n, err),
  64. Balance: ReadUInt64(r, n, err),
  65. Status: ReadByte(r, n, err),
  66. }
  67. }
  68. func (accDet *AccountDetail) WriteTo(w io.Writer) (n int64, err error) {
  69. WriteBinary(w, accDet.Account, &n, &err)
  70. WriteUVarInt(w, accDet.Sequence, &n, &err)
  71. WriteUInt64(w, accDet.Balance, &n, &err)
  72. WriteByte(w, accDet.Status, &n, &err)
  73. return
  74. }
  75. func (accDet *AccountDetail) String() string {
  76. return fmt.Sprintf("AccountDetail{%v:%X Sequence:%v Balance:%v Status:%X}",
  77. accDet.Id, accDet.PubKey, accDet.Sequence, accDet.Balance, accDet.Status)
  78. }
  79. func (accDet *AccountDetail) Copy() *AccountDetail {
  80. accDetCopy := *accDet
  81. return &accDetCopy
  82. }
  83. //-------------------------------------
  84. var AccountDetailCodec = accountDetailCodec{}
  85. type accountDetailCodec struct{}
  86. func (abc accountDetailCodec) Encode(accDet interface{}, w io.Writer, n *int64, err *error) {
  87. WriteBinary(w, accDet.(*AccountDetail), n, err)
  88. }
  89. func (abc accountDetailCodec) Decode(r io.Reader, n *int64, err *error) interface{} {
  90. return ReadAccountDetail(r, n, err)
  91. }
  92. func (abc accountDetailCodec) Compare(o1 interface{}, o2 interface{}) int {
  93. panic("AccountDetailCodec.Compare not implemented")
  94. }
  95. //-----------------------------------------------------------------------------
  96. type PrivAccount struct {
  97. Account
  98. PrivKey []byte
  99. }
  100. // Generates a new account with private key.
  101. // The Account.Id is empty since it isn't in the blockchain.
  102. func GenPrivAccount() *PrivAccount {
  103. privKey := CRandBytes(32)
  104. pubKey := crypto.MakePubKey(privKey)
  105. return &PrivAccount{
  106. Account: Account{
  107. Id: uint64(0),
  108. PubKey: pubKey,
  109. },
  110. PrivKey: privKey,
  111. }
  112. }
  113. func (pa *PrivAccount) SignBytes(msg []byte) Signature {
  114. signature := crypto.SignMessage(msg, pa.PrivKey, pa.PubKey)
  115. sig := Signature{
  116. SignerId: pa.Id,
  117. Bytes: signature,
  118. }
  119. return sig
  120. }
  121. func (pa *PrivAccount) Sign(o Signable) {
  122. o.SetSignature(Signature{}) // clear
  123. msg := BinaryBytes(o)
  124. sig := pa.SignBytes(msg)
  125. o.SetSignature(sig)
  126. }