· 7 years ago · Nov 14, 2018, 02:20 PM
1Транзакции не объединÑÑŽÑ‚ÑÑ Ð² блоки, вмеÑто Ñтого транзакции закреплÑÑŽÑ‚ÑÑ Ð² определенной цепочке, поÑле конкретной транзакции.
2
3// Tx determines the structure of the transaction.
4type Tx struct {
5 Id Hash `json:"id"`
6 SenderPublicKey Hash `json:"senderPublicKey"`
7 SenderId Hash `json:"senderId"`
8 RecipientId Hash `json:"recipientId"`
9 Amount Coin `json:"amount"`
10 Fee Coin `json:"fee"`
11 Signature Hash `json:"signature"`
12 Timestamp int64 `json:"timestamp"`
13 Nonce uint32 `json:"nonce"`
14 Height uint32 `json:"height"`
15 Chain Hash `json:"chain"`
16 PreviousTx Hash `json:"previousTx"`
17}
18
19// Process called directly for transaction processing.
20// Do not use this method to write to the chain, here only the results are processed.
21func (p *DefaultProcessor) Process(tx *types.Tx, ch *Chain) error {
22 p.mup.Lock()
23 defer p.mup.Unlock()
24 recipient := p.am.Get(tx.RecipientId)
25 recipient.Balance = types.NewCoin(recipient.Balance.Uint64() + tx.Amount.Uint64())
26 recipient.LastTx = tx.Id
27
28 senderPub := types.NewPublicKeyByHex(tx.SenderPublicKey.String())
29 sender := p.am.GetByPublicKey(senderPub)
30 sender.LastTx = tx.Id
31 if senderPub.Address() == tx.SenderId.String() {
32 sender.PublicKey = senderPub
33 }
34 balance := sender.Balance.Uint64() - (tx.Amount.Uint64() + tx.Fee.Uint64())
35 sender.Balance = types.NewCoin(balance)
36
37 err := p.am.Save(recipient)
38 if err != nil {
39 return err
40 }
41
42 err = p.am.Save(sender)
43 if err != nil {
44 return err
45 }
46
47 return p.am.Commit()
48}
49
50ВмеÑто блоков иÑпользуютÑÑ Ñнепшоты, которые ÑинхронизируютÑÑ Ñо вÑеми членами Ñети(в отличии от Ñамих транзакций). Снепшоты заключают в ÑÐµÐ±Ñ Ð¿Ð¾Ñледние измененные баланÑÑ‹ аккаунтов и информации о голоÑах.
51
52// SnapShot is an alternative to blocks, stores only the latest balances after
53// account changes and information on voting for delegates.
54//
55// It is the only synchronous chain that must be synchronized with all network members.
56type SnapShot struct {
57 Version uint `json:"version"`
58 Id types.Hash `json:"id"`
59 Height uint32 `json:"height"`
60 PreviousSnapShot types.Hash `json:"previousSnapShot"`
61 GeneratorPublicKey types.Hash `json:"generatorPublicKey"`
62 Votes []Vote `json:"votes"`
63 Balances []Balance `json:"balances"`
64 Timestamp int64 `json:"timestamp"`
65 Signatures []Signature `json:"signaturess"`
66 Signature types.Hash `json:"signature"`
67 Nonce uint32 `json:"nonce"`
68
69 mu sync.Mutex
70}
71
72// SnapShotFactory is releasing new snapshots for delegates.
73type SnapShotFactory struct {
74 sm *SnapShotManager
75 am *account.AccountManager
76 ch *chain.ChainHelper
77 interval time.Duration
78 mu sync.Mutex
79 running bool
80 delegate *types.KeyPair
81}
82
83
84Ðлгоритм подпиÑи на оÑнове ÑллиптичеÑких кривых ed25519
85
86// Sign creates a signature for any element that Byteble implements.
87// Requires that you also specify generator and signature, where the public key
88// of the signer and his signature will be placed.
89// dataOffset will also help you delete the last n bytes of the byte array.
90func Sign(object interfaces.Byter, pair *types.KeyPair, generator *types.Hash,
91 signature *types.Hash, dataOffset int) {
92
93 // First of all, we need to change the generator field since
94 // this can affect the data in the array.
95 generatorHex := make([]byte, 64)
96 pub := *pair.Public()
97 hex.Encode(generatorHex, pub)
98 *generator = generatorHex
99
100 // Having received a set of bytes, we do not send the entire array for the
101 // signature, only the hash.
102 bytes := object.GetBytes()
103 data := bytes[:len(bytes)-dataOffset]
104 hashBytes := sha256.Sha256(data)
105
106 secret := *pair.Secret()
107 privateBytes := types.NewHash(secret).ToBytes()
108 sign := ed25519.Sign(privateBytes, hashBytes)
109
110 signHex := make([]byte, 128)
111 hex.Encode(signHex, sign)
112 *signature = signHex
113}
114
115// Verify verifies the validity of the generator signature by Byter object.
116// Unlike Sign does not require pointers.
117// For the validity of events, do not forget to specify the same dataOffset
118// when signing and verifying.
119func Verify(object interfaces.Byter, generator types.Hash,
120 signature types.Hash, dataOffset int) bool {
121
122 bytes := object.GetBytes()
123 data := bytes[:len(bytes)-dataOffset]
124 hashBytes := sha256.Sha256(data)
125
126 sig := make([]byte, 64)
127 gen := make([]byte, 32)
128 hex.Decode(sig, signature.ToBytes())
129 hex.Decode(gen, generator.ToBytes())
130
131 return ed25519.Verify(gen, hashBytes, sig)
132}
133
134Пара ключей, обеÑÐ¿ÐµÑ‡Ð¸Ð²Ð°ÑŽÑ‰Ð°Ñ Ñоздание приватного и публичного ключа по seed и Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿ÑƒÐ±Ð»Ð¸Ñ‡Ð½Ð¾Ð³Ð¾ ключа в Ð°Ð´Ñ€ÐµÑ Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð½ÐµÑ‚.
135
136// KeyPair this is a pair of keys: private and public.
137type KeyPair struct {
138 secret SecretKey
139 public PublicKey
140}
141
142// Public is getter for public key.
143func (k *KeyPair) Public() *PublicKey {
144 return &k.public
145}
146
147// NewKeyPair creates and returns a pointer to a key pair (public, private).
148func NewKeyPair(seed []byte) *KeyPair {
149 hash := sha256.Sha256(seed)
150 key := ed25519.NewKeyFromSeed(hash)
151
152 publicKey := make([]byte, 32)
153 copy(publicKey, key[32:])
154
155 secretKey := make([]byte, 64)
156 copy(secretKey[:32], hash)
157 copy(secretKey[32:], publicKey)
158
159 keypair := KeyPair{
160 secretKey,
161 publicKey,
162 }
163 return &keypair
164}
165
166// Secret is getter for private key.
167func (k KeyPair) Secret() *SecretKey {
168 return &k.secret
169}
170
171// Address creates address by public key.
172func (k *PublicKey) Address() string {
173 hash := sha256.Sha256(*k)
174 ripemd := ripemd160.New()
175 ripemd.Write(hash)
176 sum := ripemd.Sum([]byte{})
177
178 buffer := bytes.NewBuffer(nil)
179 buffer.WriteString(utils.ADDR_PREFIX)
180 buffer.Write(base58.Check(sum))
181
182 return buffer.String()
183}
184
185// NewPublicKeyByHex creates a public key for the string representation.
186func NewPublicKeyByHex(s string) PublicKey {
187 b, _ := hex.DecodeString(s)
188 return PublicKey(b)
189}
190
191func HasAddr(addr []byte) bool {
192 return len(addr) > 2 && addr[0] == 'B' && addr[1] == '0'
193}