UNPKG

7.96 kBJavaScriptView Raw
1var crypto = require('crypto');
2var fs = require('fs');
3var cryptoLib = require('../lib/crypto.js');
4var transactionsLib = require('../lib/transactions.js');
5var accounts = require('./account.js');
6var ByteBuffer = require('bytebuffer');
7
8var sender = accounts.account(cryptoLib.generateSecret());
9
10function getBytes(block) {
11 var size = 4 + 4 + 8 + 4 + 8 + 8 + 8 + 4 + 32 + 32 + 64;
12
13 var bb = new ByteBuffer(size, true);
14 bb.writeInt(block.version);
15 bb.writeInt(block.timestamp);
16
17 if (block.previousBlock) {
18 var pb = bignum(block.previousBlock).toBuffer({size: '8'});
19
20 for (var i = 0; i < 8; i++) {
21 bb.writeByte(pb[i]);
22 }
23 } else {
24 for (var i = 0; i < 8; i++) {
25 bb.writeByte(0);
26 }
27 }
28
29 bb.writeInt(block.numberOfTransactions);
30 bb.writeLong(block.totalAmount);
31 bb.writeLong(block.totalFee);
32 bb.writeLong(block.reward);
33
34 bb.writeInt(block.payloadLength);
35
36 var payloadHashBuffer = new Buffer(block.payloadHash, 'hex');
37 for (var i = 0; i < payloadHashBuffer.length; i++) {
38 bb.writeByte(payloadHashBuffer[i]);
39 }
40
41 var generatorPublicKeyBuffer = new Buffer(block.generatorPublicKey, 'hex');
42 for (var i = 0; i < generatorPublicKeyBuffer.length; i++) {
43 bb.writeByte(generatorPublicKeyBuffer[i]);
44 }
45
46 if (block.blockSignature) {
47 var blockSignatureBuffer = new Buffer(block.blockSignature, 'hex');
48 for (var i = 0; i < blockSignatureBuffer.length; i++) {
49 bb.writeByte(blockSignatureBuffer[i]);
50 }
51 }
52
53 bb.flip();
54 var b = bb.toBuffer();
55
56 return b;
57}
58
59module.exports = {
60 new: function (genesisAccount, dapp, accountsFile) {
61 var payloadLength = 0,
62 payloadHash = crypto.createHash('sha256'),
63 transactions = [],
64 totalAmount = 0,
65 delegates = [];
66
67 // fund recipient account
68 if (accountsFile && fs.existsSync(accountsFile)) {
69 var lines = fs.readFileSync(accountsFile, 'utf8').split('\n');
70 for (var i in lines) {
71 var parts = lines[i].split('\t');
72 if (parts.length != 2) {
73 console.error('Invalid recipient balance format');
74 process.exit(1);
75 }
76 var trs = {
77 type: 0,
78 amount: Number(parts[1]) * 100000000,
79 fee: 0,
80 timestamp: 0,
81 recipientId: parts[0],
82 senderId: sender.address,
83 senderPublicKey: sender.keypair.publicKey
84 };
85 totalAmount += trs.amount;
86
87 var bytes = transactionsLib.getTransactionBytes(trs);
88 trs.signature = cryptoLib.sign(sender.keypair, bytes);
89 bytes = transactionsLib.getTransactionBytes(trs);
90 trs.id = cryptoLib.getId(bytes);
91
92 transactions.push(trs);
93 }
94 } else {
95 var balanceTransaction = {
96 type: 0,
97 amount: 10000000000000000,
98 fee: 0,
99 timestamp: 0,
100 recipientId: genesisAccount.address,
101 senderId: sender.address,
102 senderPublicKey: sender.keypair.publicKey
103 };
104
105 totalAmount += balanceTransaction.amount;
106
107 var bytes = transactionsLib.getTransactionBytes(balanceTransaction);
108 balanceTransaction.signature = cryptoLib.sign(sender.keypair, bytes);
109 bytes = transactionsLib.getTransactionBytes(balanceTransaction);
110 balanceTransaction.id = cryptoLib.getId(bytes);
111
112 transactions.push(balanceTransaction);
113 }
114
115 // make delegates
116 for (var i = 0; i < 101; i++) {
117 var delegate = accounts.account(cryptoLib.generateSecret());
118 delegates.push(delegate);
119
120 var username = "asch_g" + (i+1);
121
122 var transaction = {
123 type: 2,
124 amount: 0,
125 fee: 0,
126 timestamp: 0,
127 recipientId: null,
128 senderId: delegate.address,
129 senderPublicKey: delegate.keypair.publicKey,
130 asset: {
131 delegate: {
132 username: username
133 }
134 }
135 }
136
137 bytes = transactionsLib.getTransactionBytes(transaction);
138 transaction.signature = cryptoLib.sign(sender.keypair, bytes);
139 bytes = transactionsLib.getTransactionBytes(transaction);
140 transaction.id = cryptoLib.getId(bytes);
141
142 transactions.push(transaction);
143 }
144
145 // make votes
146 var votes = delegates.map(function (delegate) {
147 return "+" + delegate.keypair.publicKey;
148 });
149
150 var voteTransaction = {
151 type: 3,
152 amount: 0,
153 fee: 0,
154 timestamp: 0,
155 recipientId: null,
156 senderId: genesisAccount.address,
157 senderPublicKey: genesisAccount.keypair.publicKey,
158 asset: {
159 vote: {
160 votes: votes
161 }
162 }
163 }
164
165 bytes = transactionsLib.getTransactionBytes(voteTransaction);
166 voteTransaction.signature = cryptoLib.sign(genesisAccount.keypair, bytes);
167 bytes = transactionsLib.getTransactionBytes(voteTransaction);
168 voteTransaction.id = cryptoLib.getId(bytes);
169
170 transactions.push(voteTransaction);
171
172 var dappTransaction = null;
173 if (dapp) {
174 dappTransaction = {
175 type: 5,
176 amount: 0,
177 fee: 0,
178 timestamp: 0,
179 recipientId: null,
180 senderId: genesisAccount.address,
181 senderPublicKey: genesisAccount.keypair.publicKey,
182 asset: {
183 dapp: dapp
184 }
185 };
186
187 bytes = transactionsLib.getTransactionBytes(dappTransaction);
188 dappTransaction.signature = cryptoLib.sign(genesisAccount.keypair, bytes);
189 bytes = transactionsLib.getTransactionBytes(dappTransaction);
190 dappTransaction.id = cryptoLib.getId(bytes);
191
192 transactions.push(dappTransaction);
193 }
194
195 transactions = transactions.sort(function compare(a, b) {
196 if (a.type != b.type) {
197 if (a.type == 1) {
198 return 1;
199 }
200 if (b.type == 1) {
201 return -1;
202 }
203 return a.type - b.type;
204 }
205 if (a.amount != b.amount) {
206 return a.amount - b.amount;
207 }
208 return a.id.localeCompare(b.id);
209 });
210
211 transactions.forEach(function (tx) {
212 bytes = transactionsLib.getTransactionBytes(tx);
213 payloadLength += bytes.length;
214 payloadHash.update(bytes);
215 });
216
217 payloadHash = payloadHash.digest();
218
219 var block = {
220 version: 0,
221 totalAmount: totalAmount,
222 totalFee: 0,
223 reward: 0,
224 payloadHash: payloadHash.toString('hex'),
225 timestamp: 0,
226 numberOfTransactions: transactions.length,
227 payloadLength: payloadLength,
228 previousBlock: null,
229 generatorPublicKey: sender.keypair.publicKey,
230 transactions: transactions,
231 height: 1
232 };
233
234 bytes = getBytes(block);
235 block.blockSignature = cryptoLib.sign(sender.keypair, bytes);
236 bytes = getBytes(block);
237 block.id = cryptoLib.getId(bytes);
238
239 return {
240 block: block,
241 dapp: dappTransaction,
242 delegates: delegates
243 };
244 },
245
246 from: function (genesisBlock, genesisAccount, dapp) {
247 for (var i in genesisBlock.transactions) {
248 var tx = genesisBlock.transactions[i];
249
250 if (tx.type == 5) {
251 if (tx.asset.dapp.name == dapp.name) {
252 throw new Error("DApp with name '" + dapp.name + "' already exists in genesis block");
253 }
254
255 if (tx.asset.dapp.git == dapp.git) {
256 throw new Error("DApp with git '" + dapp.git + "' already exists in genesis block");
257 }
258
259 if (tx.asset.dapp.link == dapp.link) {
260 throw new Error("DApp with link '" + dapp.link + "' already exists in genesis block");
261 }
262 }
263 }
264
265 var dappTransaction = {
266 type: 5,
267 amount: 0,
268 fee: 0,
269 timestamp: 0,
270 recipientId: null,
271 senderId: genesisAccount.address,
272 senderPublicKey: genesisAccount.keypair.publicKey,
273 asset: {
274 dapp: dapp
275 }
276 };
277
278 var bytes = transactionsLib.getTransactionBytes(dappTransaction);
279 dappTransaction.signature = cryptoLib.sign(genesisAccount.keypair, bytes);
280 bytes = transactionsLib.getTransactionBytes(dappTransaction);
281 dappTransaction.id = cryptoLib.getId(bytes);
282
283 genesisBlock.payloadLength += bytes.length;
284 var payloadHash = crypto.createHash('sha256').update(new Buffer(genesisBlock.payloadHash, 'hex'));
285 payloadHash.update(bytes);
286 genesisBlock.payloadHash = payloadHash.digest().toString('hex');
287
288 genesisBlock.transactions.push(dappTransaction);
289 genesisBlock.numberOfTransactions += 1;
290 genesisBlock.generatorPublicKey = sender.keypair.publicKey;
291
292 bytes = getBytes(genesisBlock);
293 genesisBlock.blockSignature = cryptoLib.sign(sender.keypair, bytes);
294 bytes = getBytes(genesisBlock);
295 genesisBlock.id = cryptoLib.getId(bytes);
296
297 return {
298 block: genesisBlock,
299 dapp: dappTransaction
300 };
301 }
302}