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.

155 lines
3.7 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. if len(sig.Bytes) == 0 {
  36. panic("signature is empty")
  37. }
  38. v1 := &crypto.Verify{
  39. Message: msg,
  40. PubKey: account.PubKey,
  41. Signature: sig.Bytes,
  42. }
  43. ok := crypto.VerifyBatch([]*crypto.Verify{v1})
  44. return ok
  45. }
  46. func (account Account) Verify(o Signable) bool {
  47. sig := o.GetSignature()
  48. o.SetSignature(Signature{}) // clear
  49. msg := BinaryBytes(o)
  50. o.SetSignature(sig) // restore
  51. return account.VerifyBytes(msg, sig)
  52. }
  53. func (account Account) String() string {
  54. return fmt.Sprintf("Account{%v:%X}", account.Id, account.PubKey[:6])
  55. }
  56. //-----------------------------------------------------------------------------
  57. type AccountDetail struct {
  58. Account
  59. Sequence uint
  60. Balance uint64
  61. Status byte
  62. }
  63. func ReadAccountDetail(r io.Reader, n *int64, err *error) *AccountDetail {
  64. return &AccountDetail{
  65. Account: ReadAccount(r, n, err),
  66. Sequence: ReadUVarInt(r, n, err),
  67. Balance: ReadUInt64(r, n, err),
  68. Status: ReadByte(r, n, err),
  69. }
  70. }
  71. func (accDet *AccountDetail) WriteTo(w io.Writer) (n int64, err error) {
  72. WriteBinary(w, accDet.Account, &n, &err)
  73. WriteUVarInt(w, accDet.Sequence, &n, &err)
  74. WriteUInt64(w, accDet.Balance, &n, &err)
  75. WriteByte(w, accDet.Status, &n, &err)
  76. return
  77. }
  78. func (accDet *AccountDetail) String() string {
  79. return fmt.Sprintf("AccountDetail{%v:%X Sequence:%v Balance:%v Status:%X}",
  80. accDet.Id, accDet.PubKey, accDet.Sequence, accDet.Balance, accDet.Status)
  81. }
  82. func (accDet *AccountDetail) Copy() *AccountDetail {
  83. accDetCopy := *accDet
  84. return &accDetCopy
  85. }
  86. //-------------------------------------
  87. var AccountDetailCodec = accountDetailCodec{}
  88. type accountDetailCodec struct{}
  89. func (abc accountDetailCodec) Encode(accDet interface{}, w io.Writer, n *int64, err *error) {
  90. WriteBinary(w, accDet.(*AccountDetail), n, err)
  91. }
  92. func (abc accountDetailCodec) Decode(r io.Reader, n *int64, err *error) interface{} {
  93. return ReadAccountDetail(r, n, err)
  94. }
  95. func (abc accountDetailCodec) Compare(o1 interface{}, o2 interface{}) int {
  96. panic("AccountDetailCodec.Compare not implemented")
  97. }
  98. //-----------------------------------------------------------------------------
  99. type PrivAccount struct {
  100. Account
  101. PrivKey []byte
  102. }
  103. // Generates a new account with private key.
  104. // The Account.Id is empty since it isn't in the blockchain.
  105. func GenPrivAccount() *PrivAccount {
  106. privKey := CRandBytes(32)
  107. pubKey := crypto.MakePubKey(privKey)
  108. return &PrivAccount{
  109. Account: Account{
  110. Id: uint64(0),
  111. PubKey: pubKey,
  112. },
  113. PrivKey: privKey,
  114. }
  115. }
  116. func (pa *PrivAccount) SignBytes(msg []byte) Signature {
  117. signature := crypto.SignMessage(msg, pa.PrivKey, pa.PubKey)
  118. sig := Signature{
  119. SignerId: pa.Id,
  120. Bytes: signature,
  121. }
  122. return sig
  123. }
  124. func (pa *PrivAccount) Sign(o Signable) {
  125. o.SetSignature(Signature{}) // clear
  126. msg := BinaryBytes(o)
  127. sig := pa.SignBytes(msg)
  128. o.SetSignature(sig)
  129. }