tendermint/state/account.go

118 lines
2.7 KiB
Go
Raw Normal View History

package state
import (
. "github.com/tendermint/tendermint/binary"
. "github.com/tendermint/tendermint/blocks"
2014-10-03 17:59:54 -07:00
. "github.com/tendermint/tendermint/common"
"github.com/tendermint/tendermint/crypto"
"io"
)
2014-10-04 19:16:49 -07:00
const (
2014-10-07 23:11:04 -07:00
AccountDetailStatusNominal = byte(0x00)
AccountDetailStatusBonded = byte(0x01)
AccountDetailStatusUnbonding = byte(0x02)
2014-10-04 19:16:49 -07:00
)
type Account struct {
Id uint64 // Numeric id of account, incrementing.
PubKey []byte
}
2014-10-04 19:16:49 -07:00
func ReadAccount(r io.Reader, n *int64, err *error) Account {
return Account{
Id: ReadUInt64(r, n, err),
PubKey: ReadByteSlice(r, n, err),
}
}
2014-10-04 19:16:49 -07:00
func (account Account) WriteTo(w io.Writer) (n int64, err error) {
WriteUInt64(w, account.Id, &n, &err)
WriteByteSlice(w, account.PubKey, &n, &err)
return
}
2014-10-07 23:11:04 -07:00
func (account Account) VerifyBytes(msg []byte, sig Signature) bool {
2014-10-03 17:59:54 -07:00
if sig.SignerId != account.Id {
2014-10-07 19:37:20 -07:00
panic("account.id doesn't match sig.signerid")
}
2014-10-03 17:59:54 -07:00
v1 := &crypto.Verify{
Message: msg,
PubKey: account.PubKey,
Signature: sig.Bytes,
}
ok := crypto.VerifyBatch([]*crypto.Verify{v1})
return ok
}
2014-10-07 23:11:04 -07:00
func (account Account) Verify(o Signable) bool {
2014-10-07 19:37:20 -07:00
sig := o.GetSignature()
2014-10-07 23:11:04 -07:00
o.SetSignature(Signature{}) // clear
msg := BinaryBytes(o)
o.SetSignature(sig) // restore
return account.VerifyBytes(msg, sig)
2014-10-07 19:37:20 -07:00
}
2014-10-03 17:59:54 -07:00
//-----------------------------------------------------------------------------
2014-10-07 23:11:04 -07:00
type AccountDetail struct {
2014-10-03 17:59:54 -07:00
Account
2014-10-07 23:11:04 -07:00
Sequence uint64
Balance uint64
Status byte
2014-10-04 19:16:49 -07:00
}
2014-10-07 23:11:04 -07:00
func ReadAccountDetail(r io.Reader, n *int64, err *error) *AccountDetail {
return &AccountDetail{
Account: ReadAccount(r, n, err),
Sequence: ReadUInt64(r, n, err),
Balance: ReadUInt64(r, n, err),
Status: ReadByte(r, n, err),
2014-10-04 19:16:49 -07:00
}
}
2014-10-07 23:11:04 -07:00
func (accDet AccountDetail) WriteTo(w io.Writer) (n int64, err error) {
WriteBinary(w, accDet.Account, &n, &err)
WriteUInt64(w, accDet.Sequence, &n, &err)
WriteUInt64(w, accDet.Balance, &n, &err)
WriteByte(w, accDet.Status, &n, &err)
2014-10-04 19:16:49 -07:00
return
}
//-----------------------------------------------------------------------------
type PrivAccount struct {
Account
PrivKey []byte
}
2014-10-03 17:59:54 -07:00
// Generates a new account with private key.
// The Account.Id is empty since it isn't in the blockchain.
func GenPrivAccount() *PrivAccount {
2014-10-04 19:16:49 -07:00
privKey := CRandBytes(32)
2014-10-03 17:59:54 -07:00
pubKey := crypto.MakePubKey(privKey)
return &PrivAccount{
Account: Account{
Id: uint64(0),
PubKey: pubKey,
},
PrivKey: privKey,
}
}
2014-10-07 23:11:04 -07:00
func (pa *PrivAccount) SignBytes(msg []byte) Signature {
2014-10-03 17:59:54 -07:00
signature := crypto.SignMessage(msg, pa.PrivKey, pa.PubKey)
2014-10-07 19:37:20 -07:00
sig := Signature{
2014-10-03 17:59:54 -07:00
SignerId: pa.Id,
Bytes: signature,
}
2014-10-07 19:37:20 -07:00
return sig
}
2014-10-07 23:11:04 -07:00
func (pa *PrivAccount) Sign(o Signable) {
o.SetSignature(Signature{}) // clear
msg := BinaryBytes(o)
sig := pa.SignBytes(msg)
2014-10-07 19:37:20 -07:00
o.SetSignature(sig)
}