@leofcoin/chain 1.3.10 → 1.3.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/demo/chain.browser.js +7667 -570
- package/demo/workers/machine-worker.js +28 -566
- package/dist/865.browser.js +10 -0
- package/dist/browser/workers/865.js +10 -0
- package/dist/browser/workers/block-worker.js +13175 -0
- package/dist/browser/workers/machine-worker.js +13385 -0
- package/dist/browser/workers/pool-worker.js +8503 -0
- package/dist/browser/workers/transaction-worker.js +8495 -0
- package/dist/chain.browser.js +66842 -0
- package/dist/chain.js +444 -302
- package/dist/generate-account.browser.js +50 -0
- package/dist/messages.browser.js +328 -0
- package/dist/module/chain.js +439 -298
- package/dist/multi-wallet.browser.js +15 -0
- package/dist/node.browser.js +9858 -0
- package/dist/pako.browser.js +6900 -0
- package/dist/peernet-swarm.browser.js +839 -0
- package/dist/storage.browser.js +3724 -0
- package/dist/wrtc.browser.js +28 -0
- package/package.json +4 -3
- package/rollup.config.js +17 -27
- package/src/chain.js +104 -269
- package/src/contract.js +51 -0
- package/src/protocol.js +3 -0
- package/src/state.js +2 -2
- package/src/transaction.js +233 -0
- package/test/chain.js +3 -1
- package/webpack.config.js +2 -1
package/dist/chain.js
CHANGED
|
@@ -5,10 +5,11 @@ var _BN = require('bn.js');
|
|
|
5
5
|
require('@ethersproject/bytes');
|
|
6
6
|
var logger = require('@ethersproject/logger');
|
|
7
7
|
require('@ethersproject/bignumber');
|
|
8
|
-
var
|
|
9
|
-
var
|
|
8
|
+
var crypto = require('crypto');
|
|
9
|
+
var path = require('path');
|
|
10
10
|
var EasyWorker = require('@vandeurenglenn/easy-worker');
|
|
11
11
|
var codecFormatInterface = require('@leofcoin/codec-format-interface');
|
|
12
|
+
var pako = require('pako');
|
|
12
13
|
var MultiWallet = require('@leofcoin/multi-wallet');
|
|
13
14
|
var index = require('@leofcoin/codec-format-interface/dist/index');
|
|
14
15
|
var bs32 = require('@vandeurenglenn/base32');
|
|
@@ -17,6 +18,7 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
|
|
|
17
18
|
|
|
18
19
|
var _BN__default = /*#__PURE__*/_interopDefaultLegacy(_BN);
|
|
19
20
|
var EasyWorker__default = /*#__PURE__*/_interopDefaultLegacy(EasyWorker);
|
|
21
|
+
var pako__default = /*#__PURE__*/_interopDefaultLegacy(pako);
|
|
20
22
|
var MultiWallet__default = /*#__PURE__*/_interopDefaultLegacy(MultiWallet);
|
|
21
23
|
var bs32__default = /*#__PURE__*/_interopDefaultLegacy(bs32);
|
|
22
24
|
|
|
@@ -24,17 +26,17 @@ var contractFactory$2 = "ihny2gqg6c6mwy5mhbrs5ulkkozsgwtk5vuz5krjidouy4mbwfdbjnb
|
|
|
24
26
|
var nativeToken$2 = "ihny2gqhoockyg7yg4n5bpxuldahfavpqnmpoe2bn4ivnxmk7redc2ltwkb";
|
|
25
27
|
var nameService$2 = "ihny2gqgztp3vj6qy7fgrfer7y5c5hxnp6imdz6v5spi4edkwtm5fkd5z2h";
|
|
26
28
|
var validators$2 = "ihny2gqh4e2pr4pbtpkamhj3htsvuoydy3wotaudoeaktgcdwmoij66pecp";
|
|
27
|
-
var addresses = {
|
|
29
|
+
var addresses$1 = {
|
|
28
30
|
contractFactory: contractFactory$2,
|
|
29
31
|
nativeToken: nativeToken$2,
|
|
30
32
|
nameService: nameService$2,
|
|
31
33
|
validators: validators$2
|
|
32
34
|
};
|
|
33
35
|
|
|
34
|
-
const contractFactory$1 = addresses.contractFactory;
|
|
35
|
-
const nameService$1 = addresses.nameService;
|
|
36
|
-
const nativeToken$1 = addresses.nativeToken;
|
|
37
|
-
const validators$1 = addresses.validators;
|
|
36
|
+
const contractFactory$1 = addresses$1.contractFactory;
|
|
37
|
+
const nameService$1 = addresses$1.nameService;
|
|
38
|
+
const nativeToken$1 = addresses$1.nativeToken;
|
|
39
|
+
const validators$1 = addresses$1.validators;
|
|
38
40
|
|
|
39
41
|
const version$1 = "bignumber/5.6.2";
|
|
40
42
|
|
|
@@ -134,7 +136,7 @@ message BlockMessage {
|
|
|
134
136
|
}
|
|
135
137
|
`;
|
|
136
138
|
|
|
137
|
-
class BlockMessage extends codecFormatInterface.FormatInterface {
|
|
139
|
+
class BlockMessage$1 extends codecFormatInterface.FormatInterface {
|
|
138
140
|
get keys() {
|
|
139
141
|
return ['index', 'previousHash', 'timestamp', 'reward', 'fees', 'transactions', 'validators']
|
|
140
142
|
}
|
|
@@ -251,7 +253,7 @@ class Machine {
|
|
|
251
253
|
};
|
|
252
254
|
pubsub.subscribe('machine.ready', machineReady);
|
|
253
255
|
|
|
254
|
-
this.worker = await new EasyWorker__default["default"](
|
|
256
|
+
this.worker = await new EasyWorker__default["default"](path.join(__dirname, './workers/machine-worker.js'), {serialization: 'advanced', type:'module'});
|
|
255
257
|
this.worker.onmessage(this.#onmessage.bind(this));
|
|
256
258
|
|
|
257
259
|
// const blocks = await blockStore.values()
|
|
@@ -278,7 +280,7 @@ class Machine {
|
|
|
278
280
|
async #runContract(contractMessage) {
|
|
279
281
|
const hash = await contractMessage.hash;
|
|
280
282
|
return new Promise((resolve, reject) => {
|
|
281
|
-
const id =
|
|
283
|
+
const id = crypto.randomBytes(20).toString('hex');
|
|
282
284
|
const onmessage = message => {
|
|
283
285
|
pubsub.unsubscribe(id, onmessage);
|
|
284
286
|
if (message?.error) reject(message.error);
|
|
@@ -319,14 +321,13 @@ class Machine {
|
|
|
319
321
|
message = await contractStore.get(parameters[0]);
|
|
320
322
|
message = await new ContractMessage(message);
|
|
321
323
|
}
|
|
322
|
-
console.log(message);
|
|
323
324
|
if (!this.#contracts[await message.hash]) await this.#runContract(message);
|
|
324
325
|
}
|
|
325
326
|
} catch (error) {
|
|
326
327
|
throw new Error(`contract deployment failed for ${parameters[0]}\n${error.message}`)
|
|
327
328
|
}
|
|
328
329
|
return new Promise((resolve, reject) => {
|
|
329
|
-
const id =
|
|
330
|
+
const id = crypto.randomBytes(20).toString('hex');
|
|
330
331
|
const onmessage = message => {
|
|
331
332
|
pubsub.unsubscribe(id, onmessage);
|
|
332
333
|
if (message?.error) reject(message.error);
|
|
@@ -356,7 +357,7 @@ class Machine {
|
|
|
356
357
|
|
|
357
358
|
get(contract, method, parameters) {
|
|
358
359
|
return new Promise((resolve, reject) => {
|
|
359
|
-
const id =
|
|
360
|
+
const id = crypto.randomBytes(20).toString();
|
|
360
361
|
const onmessage = message => {
|
|
361
362
|
pubsub.unsubscribe(id, onmessage);
|
|
362
363
|
resolve(message);
|
|
@@ -433,24 +434,401 @@ const calculateFee = async transaction => {
|
|
|
433
434
|
return Number.parseFloat(fee.toString()).toFixed(decimals)
|
|
434
435
|
};
|
|
435
436
|
|
|
437
|
+
class State {
|
|
438
|
+
constructor() {
|
|
439
|
+
// return this.#init()
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// async #init() {
|
|
443
|
+
// const state = await stateStore.get()
|
|
444
|
+
// for (const [key, value] of Object.entries(state)) {
|
|
445
|
+
//
|
|
446
|
+
// }
|
|
447
|
+
//
|
|
448
|
+
// return this
|
|
449
|
+
// }
|
|
450
|
+
|
|
451
|
+
async put(key, value, isCompressed = true) {
|
|
452
|
+
value = isCompressed ? value : await pako__default["default"].deflate(value);
|
|
453
|
+
await stateStore.put(key, value);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
async get(key, isCompressed = true) {
|
|
457
|
+
const value = await stateStore.get(key);
|
|
458
|
+
return isCompressed = pako__default["default"].inflate(value)
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
updateState(block) {
|
|
462
|
+
// block.decoded.index
|
|
463
|
+
// this.#isUpdateNeeded()
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
class Protocol {
|
|
468
|
+
limit = 1800
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
class Transaction extends Protocol {
|
|
472
|
+
constructor() {
|
|
473
|
+
super();
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
*
|
|
478
|
+
* @param {Address[]} transactions
|
|
479
|
+
* @returns transactions to include
|
|
480
|
+
*/
|
|
481
|
+
async getTransactions (transactions) {
|
|
482
|
+
return new Promise(async (resolve, reject) => {
|
|
483
|
+
let size = 0;
|
|
484
|
+
const _transactions = [];
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
await Promise.all(transactions
|
|
488
|
+
.map(async tx => {
|
|
489
|
+
tx = await new TransactionMessage(tx);
|
|
490
|
+
size += tx.encoded.length;
|
|
491
|
+
if (!formatBytes(size).includes('MB') || formatBytes(size).includes('MB') && Number(formatBytes(size).split(' MB')[0]) <= 0.75) _transactions.push({...tx.decoded, hash: await tx.hash});
|
|
492
|
+
else resolve(_transactions);
|
|
493
|
+
}));
|
|
494
|
+
|
|
495
|
+
return resolve(_transactions)
|
|
496
|
+
})
|
|
497
|
+
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
*
|
|
502
|
+
* @param {Transaction[]} transactions An array containing Transactions
|
|
503
|
+
* @returns {TransactionMessage}
|
|
504
|
+
*/
|
|
505
|
+
async promiseTransactions(transactions) {
|
|
506
|
+
transactions = await Promise.all(transactions.map(tx => new TransactionMessage(tx)));
|
|
507
|
+
return transactions
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
*
|
|
512
|
+
* @param {Transaction[]} transactions An array containing Transactions
|
|
513
|
+
* @returns {Object} {transaction.decoded, transaction.hash}
|
|
514
|
+
*/
|
|
515
|
+
async promiseTransactionsContent(transactions) {
|
|
516
|
+
transactions = await Promise.all(transactions.map(tx => new Promise(async (resolve, reject) => {
|
|
517
|
+
resolve({ ...tx.decoded, hash: await tx.hash });
|
|
518
|
+
})));
|
|
519
|
+
|
|
520
|
+
return transactions
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* When a nonce isn't found for an address fallback to just checking the transactionnPoolStore
|
|
525
|
+
* @param {Address} address
|
|
526
|
+
* @returns {Number} nonce
|
|
527
|
+
*/
|
|
528
|
+
async #getNonceFallback(address) {
|
|
529
|
+
let transactions = await transactionPoolStore.values();
|
|
530
|
+
transactions = await this.promiseTransactions(transactions);
|
|
531
|
+
transactions = transactions.filter(tx => tx.decoded.from === address);
|
|
532
|
+
transactions = await this.promiseTransactionsContent(transactions);
|
|
533
|
+
|
|
534
|
+
if (this.lastBlock?.hash && transactions.length === 0 && this.lastBlock.hash !== '0x0') {
|
|
535
|
+
|
|
536
|
+
let block = await peernet.get(this.lastBlock.hash);
|
|
537
|
+
block = await new BlockMessage(block);
|
|
538
|
+
|
|
539
|
+
// for (let tx of block.decoded?.transactions) {
|
|
540
|
+
// tx = await peernet.get(tx, 'transaction')
|
|
541
|
+
// transactions.push(new TransactionMessage(tx))
|
|
542
|
+
// }
|
|
543
|
+
transactions = transactions.filter(tx => tx.from === address);
|
|
544
|
+
while (transactions.length === 0 && block.decoded.index !== 0 && block.decoded.previousHash !== '0x0') {
|
|
545
|
+
block = await blockStore.get(block.decoded.previousHash);
|
|
546
|
+
block = await new BlockMessage(block);
|
|
547
|
+
transactions = block.decoded.transactions.filter(tx => tx.from === address);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
}
|
|
551
|
+
if (transactions.length === 0) return 0
|
|
552
|
+
|
|
553
|
+
transactions = transactions.sort((a, b) => a.timestamp - b.timestamp);
|
|
554
|
+
return transactions[transactions.length - 1].nonce
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* Get amount of transactions by address
|
|
559
|
+
* @param {Address} address The address to get the nonce for
|
|
560
|
+
* @returns {Number} nonce
|
|
561
|
+
*/
|
|
562
|
+
async getNonce(address) {
|
|
563
|
+
if (!await accountsStore.has(address)) {
|
|
564
|
+
const nonce = await this.#getNonceFallback(address);
|
|
565
|
+
await accountsStore.put(address, new TextEncoder().encode(String(nonce)));
|
|
566
|
+
}
|
|
567
|
+
// todo: are those in the pool in cluded also ? they need to be included!!!
|
|
568
|
+
let nonce = await accountsStore.get(address);
|
|
569
|
+
nonce = new TextDecoder().decode(nonce);
|
|
570
|
+
return Number(nonce)
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
/**
|
|
574
|
+
* whenever method = createContract params should hold the contract hash
|
|
575
|
+
*
|
|
576
|
+
* example: [hash]
|
|
577
|
+
* createTransaction('0x0', 'createContract', [hash])
|
|
578
|
+
*
|
|
579
|
+
* @param {String} to - the contract address for the contract to interact with
|
|
580
|
+
* @param {String} method - the method/function to run
|
|
581
|
+
* @param {Array} params - array of paramters to apply to the contract method
|
|
582
|
+
* @param {Number} nonce - total transaction count [optional]
|
|
583
|
+
*/
|
|
584
|
+
async createTransaction(to, method, parameters, nonce, signature) {
|
|
585
|
+
return this.createTransactionFrom(peernet.selectedAccount, to, method, parameters, nonce)
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
/**
|
|
589
|
+
*
|
|
590
|
+
* @param {Transaction} transaction
|
|
591
|
+
* @param {String} transaction.from address
|
|
592
|
+
* @param {String} transaction.to address
|
|
593
|
+
* @param {Object} transaction.params {}
|
|
594
|
+
* @param {String} transaction.params.method get, call
|
|
595
|
+
* @param {Buffer} transaction.params.data
|
|
596
|
+
* @returns
|
|
597
|
+
*/
|
|
598
|
+
async createTransactionHash(transaction) {
|
|
599
|
+
// todo: validate
|
|
600
|
+
const peernetHash = await new index.CodecHash(transaction, {name: 'transaction-message'});
|
|
601
|
+
return peernetHash.digest
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* @param {Transaction} transaction
|
|
606
|
+
* @param {object} wallet any wallet/signer that supports sign(RAWtransaction)
|
|
607
|
+
*/
|
|
608
|
+
async #signTransaction (transaction, wallet) {
|
|
609
|
+
return wallet.sign(await this.createTransactionHash(transaction))
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
/**
|
|
613
|
+
*
|
|
614
|
+
* @param {RawTransaction} transaction
|
|
615
|
+
* @param {Signer} signer
|
|
616
|
+
* @returns {Transaction} a signed transaction
|
|
617
|
+
*/
|
|
618
|
+
async signTransaction(transaction, signer) {
|
|
619
|
+
let identity = await walletStore.get('identity');
|
|
620
|
+
identity = JSON.parse(new TextDecoder().decode(identity));
|
|
621
|
+
const wallet = new MultiWallet__default["default"](peernet.network);
|
|
622
|
+
wallet.recover(identity.mnemonic);
|
|
623
|
+
const account = wallet.account(0).external(0);
|
|
624
|
+
transaction.signature = await this.#signTransaction(transaction, account);
|
|
625
|
+
transaction.signature = bs32__default["default"].encode(transaction.signature);
|
|
626
|
+
return transaction
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
/**
|
|
630
|
+
*
|
|
631
|
+
* @param {Transaction} transaction
|
|
632
|
+
* @param {Address} transaction.from
|
|
633
|
+
* @param {Address} transaction.to
|
|
634
|
+
* @param {String} transaction.method
|
|
635
|
+
* @param {Array} transaction.params
|
|
636
|
+
* @param {Number} transaction.nonce
|
|
637
|
+
*
|
|
638
|
+
* @returns {RawTransaction} transaction
|
|
639
|
+
*/
|
|
640
|
+
async ensureNonce(transaction) {
|
|
641
|
+
if (!transaction.from) transaction.from = peernet.selectedAccount;
|
|
642
|
+
transaction.timestamp = Date.now();
|
|
643
|
+
|
|
644
|
+
if (transaction.nonce === undefined) {
|
|
645
|
+
transaction.nonce = await this.getNonce(transaction.from);
|
|
646
|
+
} else {
|
|
647
|
+
let nonce = await accountsStore.get(transaction.from);
|
|
648
|
+
nonce = new TextDecoder().decode(nonce);
|
|
649
|
+
if (transaction.nonce < nonce) throw new Error(`a transaction with a higher nonce already exists`)
|
|
650
|
+
if (transaction.nonce === nonce) throw new Error(`a transaction with the same nonce already exists`)
|
|
651
|
+
}
|
|
652
|
+
return transaction
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* every tx done is trough contracts so no need for amount
|
|
657
|
+
* data is undefined when nothing is returned
|
|
658
|
+
* error is thrown on error so undefined data doesn't mean there is an error...
|
|
659
|
+
*
|
|
660
|
+
* @param {Address} from - the sender address
|
|
661
|
+
* @param {Address} to - the contract address for the contract to interact with
|
|
662
|
+
* @param {String} method - the method/function to run
|
|
663
|
+
* @param {Array} params - array of paramters to apply to the contract method
|
|
664
|
+
* @param {Number} nonce - total transaction count [optional]
|
|
665
|
+
*/
|
|
666
|
+
async createTransactionFrom(from, to, method, parameters, nonce) {
|
|
667
|
+
try {
|
|
668
|
+
const rawTransaction = await this.ensureNonce({from, to, nonce, method, params: parameters});
|
|
669
|
+
const transaction = await this.signTransaction(rawTransaction, from);
|
|
670
|
+
const message = await new TransactionMessage(transaction);
|
|
671
|
+
|
|
672
|
+
let data;
|
|
673
|
+
const wait = () => new Promise(async (resolve, reject) => {
|
|
674
|
+
if (pubsub.subscribers[`transaction.completed.${await message.hash}`]) {
|
|
675
|
+
const result = pubsub.subscribers[`transaction.completed.${await message.hash}`].value;
|
|
676
|
+
result.status === 'fulfilled' ? resolve(await result.hash) : reject({hash: await result.hash, error: result.error});
|
|
677
|
+
} else {
|
|
678
|
+
const completed = async result => {
|
|
679
|
+
result.status === 'fulfilled' ? resolve(await result.hash) : reject({hash: await result.hash, error: result.error});
|
|
680
|
+
|
|
681
|
+
setTimeout(async () => {
|
|
682
|
+
pubsub.unsubscribe(`transaction.completed.${await message.hash}`, completed);
|
|
683
|
+
}, 10_000);
|
|
684
|
+
};
|
|
685
|
+
pubsub.subscribe(`transaction.completed.${await message.hash}`, completed);
|
|
686
|
+
}
|
|
687
|
+
});
|
|
688
|
+
await transactionPoolStore.put(await message.hash, message.encoded);
|
|
689
|
+
peernet.publish('add-transaction', message.encoded);
|
|
690
|
+
return {hash: await message.hash, data, fee: await calculateFee(message.decoded), wait, message}
|
|
691
|
+
} catch (error) {
|
|
692
|
+
console.log(error);
|
|
693
|
+
throw error
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
/**
|
|
699
|
+
* @extends {Transaction}
|
|
700
|
+
*/
|
|
701
|
+
class Contract extends Transaction {
|
|
702
|
+
constructor() {
|
|
703
|
+
super();
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
/**
|
|
707
|
+
*
|
|
708
|
+
* @param {Address} creator
|
|
709
|
+
* @param {String} contract
|
|
710
|
+
* @param {Array} constructorParameters
|
|
711
|
+
* @returns lib.createContractMessage
|
|
712
|
+
*/
|
|
713
|
+
async createContractMessage(creator, contract, constructorParameters = []) {
|
|
714
|
+
return createContractMessage(creator, contract, constructorParameters)
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
*
|
|
719
|
+
* @param {Address} creator
|
|
720
|
+
* @param {String} contract
|
|
721
|
+
* @param {Array} constructorParameters
|
|
722
|
+
* @returns {Address}
|
|
723
|
+
*/
|
|
724
|
+
async createContractAddress(creator, contract, constructorParameters = []) {
|
|
725
|
+
contract = await this.createContractMessage(creator, contract, constructorParameters);
|
|
726
|
+
return contract.hash
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
/**
|
|
730
|
+
*
|
|
731
|
+
* @param {String} contract
|
|
732
|
+
* @param {Array} parameters
|
|
733
|
+
* @returns
|
|
734
|
+
*/
|
|
735
|
+
async deployContract(contract, constructorParameters = []) {
|
|
736
|
+
const message = await createContractMessage(peernet.selectedAccount, contract, constructorParameters);
|
|
737
|
+
try {
|
|
738
|
+
await contractStore.put(await message.hash, message.encoded);
|
|
739
|
+
} catch (error) {
|
|
740
|
+
throw error
|
|
741
|
+
}
|
|
742
|
+
return this.createTransactionFrom(peernet.selectedAccount, addresses.contractFactory, 'registerContract', [await message.hash])
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
}
|
|
746
|
+
|
|
436
747
|
globalThis.BigNumber = utils.BigNumber;
|
|
437
748
|
|
|
438
749
|
// check if browser or local
|
|
439
|
-
class Chain {
|
|
750
|
+
class Chain extends Contract {
|
|
751
|
+
/** {Address[]} */
|
|
440
752
|
#validators = []
|
|
753
|
+
/** {Block[]} */
|
|
441
754
|
#blocks = []
|
|
755
|
+
|
|
442
756
|
#machine
|
|
757
|
+
/** {Boolean} */
|
|
443
758
|
#runningEpoch = false
|
|
759
|
+
|
|
760
|
+
/** {Boolean} */
|
|
444
761
|
#chainSyncing = false
|
|
762
|
+
|
|
763
|
+
/** {Number} */
|
|
764
|
+
#totalSize = 0
|
|
765
|
+
|
|
766
|
+
/**
|
|
767
|
+
* {Block} {index, hash, previousHash}
|
|
768
|
+
*/
|
|
445
769
|
#lastBlock = {index: 0, hash: '0x0', previousHash: '0x0'}
|
|
770
|
+
|
|
771
|
+
/**
|
|
772
|
+
* amount the native token has been iteracted with
|
|
773
|
+
*/
|
|
774
|
+
#nativeCalls = 0
|
|
775
|
+
|
|
776
|
+
/**
|
|
777
|
+
* amount the native token has been iteracted with
|
|
778
|
+
*/
|
|
779
|
+
#nativeTransfers = 0
|
|
780
|
+
|
|
781
|
+
/**
|
|
782
|
+
* amount of native token burned
|
|
783
|
+
* {Number}
|
|
784
|
+
*/
|
|
785
|
+
#nativeBurns = 0
|
|
786
|
+
|
|
787
|
+
/**
|
|
788
|
+
* amount of native tokens minted
|
|
789
|
+
* {Number}
|
|
790
|
+
*/
|
|
791
|
+
#nativeMints = 0
|
|
792
|
+
|
|
793
|
+
/**
|
|
794
|
+
* total amount of transactions
|
|
795
|
+
* {Number}
|
|
796
|
+
*/
|
|
797
|
+
#totalTransactions = 0
|
|
798
|
+
|
|
446
799
|
#participants = []
|
|
447
800
|
#participating = false
|
|
448
801
|
#jail = []
|
|
449
802
|
|
|
450
803
|
constructor() {
|
|
804
|
+
super();
|
|
451
805
|
return this.#init()
|
|
452
806
|
}
|
|
453
807
|
|
|
808
|
+
get nativeMints() {
|
|
809
|
+
return this.#nativeMints
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
get nativeBurns() {
|
|
813
|
+
return this.#nativeBurns
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
get nativeTransfers() {
|
|
817
|
+
return this.#nativeTransfers
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
get totalTransactions() {
|
|
821
|
+
return this.#totalTransactions
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
get nativeCalls() {
|
|
825
|
+
return this.#nativeCalls
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
get totalSize() {
|
|
829
|
+
return this.#totalSize
|
|
830
|
+
}
|
|
831
|
+
|
|
454
832
|
get lib() {
|
|
455
833
|
return lib
|
|
456
834
|
}
|
|
@@ -460,7 +838,7 @@ class Chain {
|
|
|
460
838
|
}
|
|
461
839
|
|
|
462
840
|
get nativeToken() {
|
|
463
|
-
return addresses.nativeToken
|
|
841
|
+
return addresses$1.nativeToken
|
|
464
842
|
}
|
|
465
843
|
|
|
466
844
|
get validators() {
|
|
@@ -480,10 +858,9 @@ class Chain {
|
|
|
480
858
|
async #runEpoch() {
|
|
481
859
|
this.#runningEpoch = true;
|
|
482
860
|
console.log('epoch');
|
|
483
|
-
const validators = await this.staticCall(addresses.validators, 'validators');
|
|
861
|
+
const validators = await this.staticCall(addresses$1.validators, 'validators');
|
|
484
862
|
console.log(validators);
|
|
485
863
|
if (!validators[peernet.selectedAccount]?.active) return
|
|
486
|
-
debug(`validator ${peernet.selectedAccount} active`);
|
|
487
864
|
const start = Date.now();
|
|
488
865
|
try {
|
|
489
866
|
await this.#createBlock();
|
|
@@ -502,16 +879,16 @@ class Chain {
|
|
|
502
879
|
async #setup() {
|
|
503
880
|
|
|
504
881
|
const contracts = [{
|
|
505
|
-
address: addresses.contractFactory,
|
|
882
|
+
address: addresses$1.contractFactory,
|
|
506
883
|
message: contractFactoryMessage
|
|
507
884
|
}, {
|
|
508
|
-
address: addresses.nativeToken,
|
|
885
|
+
address: addresses$1.nativeToken,
|
|
509
886
|
message: nativeTokenMessage
|
|
510
887
|
}, {
|
|
511
|
-
address: addresses.validators,
|
|
888
|
+
address: addresses$1.validators,
|
|
512
889
|
message: validatorsMessage
|
|
513
890
|
}, {
|
|
514
|
-
address: addresses.nameService,
|
|
891
|
+
address: addresses$1.nameService,
|
|
515
892
|
message: nameServiceMessage
|
|
516
893
|
}];
|
|
517
894
|
|
|
@@ -569,7 +946,7 @@ class Chain {
|
|
|
569
946
|
|
|
570
947
|
if (latest.hash && latest.hash !== '0x0') {
|
|
571
948
|
latest = await peernet.get(latest.hash, block);
|
|
572
|
-
latest = await new BlockMessage(latest);
|
|
949
|
+
latest = await new BlockMessage$1(latest);
|
|
573
950
|
}
|
|
574
951
|
|
|
575
952
|
return latest
|
|
@@ -579,11 +956,13 @@ class Chain {
|
|
|
579
956
|
// this.node = await new Node()
|
|
580
957
|
this.#participants = [];
|
|
581
958
|
this.#participating = false;
|
|
582
|
-
const initialized = await contractStore.has(addresses.contractFactory);
|
|
959
|
+
const initialized = await contractStore.has(addresses$1.contractFactory);
|
|
583
960
|
if (!initialized) await this.#setup();
|
|
584
961
|
|
|
585
962
|
|
|
586
963
|
this.utils = { BigNumber: utils.BigNumber, formatUnits: utils.formatUnits, parseUnits: utils.parseUnits };
|
|
964
|
+
|
|
965
|
+
this.state = new State();
|
|
587
966
|
|
|
588
967
|
try {
|
|
589
968
|
let localBlock;
|
|
@@ -596,7 +975,7 @@ class Chain {
|
|
|
596
975
|
localBlock = new TextDecoder().decode(localBlock);
|
|
597
976
|
if (localBlock && localBlock !== '0x0') {
|
|
598
977
|
localBlock = await peernet.get(localBlock, 'block');
|
|
599
|
-
localBlock = await new BlockMessage(localBlock);
|
|
978
|
+
localBlock = await new BlockMessage$1(localBlock);
|
|
600
979
|
this.#lastBlock = {...localBlock.decoded, hash: await localBlock.hash};
|
|
601
980
|
} else {
|
|
602
981
|
const latestBlock = await this.#getLatestBlock();
|
|
@@ -667,16 +1046,6 @@ class Chain {
|
|
|
667
1046
|
|
|
668
1047
|
#epochTimeout
|
|
669
1048
|
|
|
670
|
-
async #addTransaction(transaction) {
|
|
671
|
-
try {
|
|
672
|
-
transaction = await new TransactionMessage(transaction);
|
|
673
|
-
const has = await transactionPoolStore.has(await transaction.hash);
|
|
674
|
-
if (!has) await transactionPoolStore.put(await transaction.hash, transaction.encoded);
|
|
675
|
-
if (this.#participating && !this.#runningEpoch) this.#runEpoch();
|
|
676
|
-
} catch {
|
|
677
|
-
throw new Error('invalid transaction')
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
1049
|
|
|
681
1050
|
async #lastBlockHandler() {
|
|
682
1051
|
return new peernet.protos['peernet-response']({response: { hash: this.#lastBlock?.hash, index: this.#lastBlock?.index }})
|
|
@@ -685,9 +1054,10 @@ async #lastBlockHandler() {
|
|
|
685
1054
|
async resolveBlock(hash) {
|
|
686
1055
|
if (!hash) throw new Error(`expected hash, got: ${hash}`)
|
|
687
1056
|
let block = await peernet.get(hash, 'block');
|
|
688
|
-
block = await new BlockMessage(block);
|
|
1057
|
+
block = await new BlockMessage$1(block);
|
|
689
1058
|
if (!await peernet.has(hash, 'block')) await peernet.put(hash, block.encoded, 'block');
|
|
690
1059
|
const size = block.encoded.length > 0 ? block.encoded.length : block.encoded.byteLength;
|
|
1060
|
+
this.#totalSize += size;
|
|
691
1061
|
block = {...block.decoded, hash};
|
|
692
1062
|
if (this.#blocks[block.index] && this.#blocks[block.index].hash !== block.hash) throw `invalid block ${hash} @${block.index}`
|
|
693
1063
|
this.#blocks[block.index] = block;
|
|
@@ -713,51 +1083,40 @@ async resolveBlock(hash) {
|
|
|
713
1083
|
}
|
|
714
1084
|
}
|
|
715
1085
|
|
|
1086
|
+
/**
|
|
1087
|
+
*
|
|
1088
|
+
* @param {Block[]} blocks
|
|
1089
|
+
*/
|
|
716
1090
|
async #loadBlocks(blocks) {
|
|
717
1091
|
for (const block of blocks) {
|
|
718
1092
|
if (block && !block.loaded) {
|
|
719
1093
|
for (const transaction of block.transactions) {
|
|
720
1094
|
try {
|
|
721
1095
|
await this.#machine.execute(transaction.to, transaction.method, transaction.params);
|
|
722
|
-
|
|
1096
|
+
if (transaction.to === nativeToken$1) {
|
|
1097
|
+
this.#nativeCalls += 1;
|
|
1098
|
+
if (transaction.method === 'burn') this.#nativeBurns += 1;
|
|
1099
|
+
if (transaction.method === 'mint') this.#nativeMints += 1;
|
|
1100
|
+
if (transaction.method === 'transfer') this.#nativeTransfers += 1;
|
|
1101
|
+
}
|
|
1102
|
+
this.#totalTransactions += 1;
|
|
723
1103
|
} catch (error) {
|
|
724
1104
|
console.log(error);
|
|
725
1105
|
}
|
|
726
1106
|
}
|
|
727
1107
|
this.#blocks[block.index].loaded = true;
|
|
728
|
-
|
|
729
|
-
// let message = await peernet.get(block.hash, 'block')
|
|
730
|
-
|
|
731
|
-
// const compressed = pako.deflate(message);
|
|
732
|
-
// const result = pako.inflate(compressed);
|
|
733
|
-
// console.log(result.length, compressed.length);
|
|
734
|
-
//
|
|
735
|
-
// console.log(result.length - compressed.length);
|
|
736
|
-
|
|
737
|
-
// message = new BlockMessage(message)
|
|
738
|
-
// for (const transaction of message.decoded.transactions) {
|
|
739
|
-
// try {
|
|
740
|
-
// await this.#machine.execute(transaction.to, transaction.method, transaction.params)
|
|
741
|
-
//
|
|
742
|
-
// } catch (e) {
|
|
743
|
-
// // console.log(e);
|
|
744
|
-
// }
|
|
745
|
-
// }
|
|
746
|
-
// block.loaded = true
|
|
1108
|
+
debug(`loaded block: ${block.hash} @${block.index}`);
|
|
747
1109
|
}
|
|
748
1110
|
}
|
|
749
1111
|
}
|
|
750
1112
|
|
|
751
1113
|
async #executeTransaction({hash, from, to, method, params, nonce}) {
|
|
752
|
-
console.log(hash, from);
|
|
753
1114
|
try {
|
|
754
1115
|
let result = await this.#machine.execute(to, method, params, from, nonce);
|
|
755
1116
|
// if (!result) result = this.#machine.state
|
|
756
|
-
console.log({result});
|
|
757
1117
|
pubsub.publish(`transaction.completed.${hash}`, {status: 'fulfilled', hash});
|
|
758
1118
|
return result || 'no state change'
|
|
759
1119
|
} catch (error) {
|
|
760
|
-
console.log(error);
|
|
761
1120
|
pubsub.publish(`transaction.completed.${hash}`, {status: 'fail', hash, error: error});
|
|
762
1121
|
throw error
|
|
763
1122
|
}
|
|
@@ -765,26 +1124,10 @@ async resolveBlock(hash) {
|
|
|
765
1124
|
|
|
766
1125
|
async #addBlock(block) {
|
|
767
1126
|
// console.log(block);
|
|
768
|
-
const blockMessage = await new BlockMessage(new Uint8Array(Object.values(block)));
|
|
769
|
-
// if (!Buffer.isBuffer(block)) block = Buffer.from(block, 'hex')
|
|
770
|
-
// const transactionJob = async transaction => {
|
|
771
|
-
// try {
|
|
772
|
-
// transaction = await transactionPoolStore.get(transaction)
|
|
773
|
-
// } catch (e) {
|
|
774
|
-
// try {
|
|
775
|
-
// transaction = await peernet.get(transaction, 'transaction')
|
|
776
|
-
// } catch (e) {
|
|
777
|
-
// console.warn(`couldn't resolve ${transaction}`);
|
|
778
|
-
// }
|
|
779
|
-
// }
|
|
780
|
-
// transaction = new TransactionMessage(transaction)
|
|
781
|
-
// return transaction
|
|
782
|
-
// }
|
|
1127
|
+
const blockMessage = await new BlockMessage$1(new Uint8Array(Object.values(block)));
|
|
783
1128
|
await Promise.all(blockMessage.decoded.transactions
|
|
784
1129
|
.map(async transaction => transactionPoolStore.delete(await transaction.hash)));
|
|
785
1130
|
const hash = await blockMessage.hash;
|
|
786
|
-
// let transactions = blockMessage.decoded.transactions.map(tx => transactionJob(tx))
|
|
787
|
-
// transactions = await Promise.all(transactions)
|
|
788
1131
|
|
|
789
1132
|
await blockStore.put(hash, blockMessage.encoded);
|
|
790
1133
|
|
|
@@ -827,6 +1170,7 @@ async resolveBlock(hash) {
|
|
|
827
1170
|
async #updateState(message) {
|
|
828
1171
|
const hash = await message.hash;
|
|
829
1172
|
this.#lastBlock = { hash, ...message.decoded };
|
|
1173
|
+
await this.state.updateState(message);
|
|
830
1174
|
await chainStore.put('lastBlock', hash);
|
|
831
1175
|
}
|
|
832
1176
|
|
|
@@ -840,14 +1184,8 @@ async resolveBlock(hash) {
|
|
|
840
1184
|
// peerReputation(peerId)
|
|
841
1185
|
// {bandwith: {up, down}, uptime}
|
|
842
1186
|
this.#participating = true;
|
|
843
|
-
if (!await this.staticCall(addresses.validators, 'has', [address])) await this.createTransactionFrom(address, addresses.validators, 'addValidator', [address]);
|
|
1187
|
+
if (!await this.staticCall(addresses$1.validators, 'has', [address])) await this.createTransactionFrom(address, addresses$1.validators, 'addValidator', [address]);
|
|
844
1188
|
if (await this.hasTransactionToHandle() && !this.#runningEpoch) await this.#runEpoch();
|
|
845
|
-
|
|
846
|
-
// const runEpoch = () => setTimeout(async () => {
|
|
847
|
-
// if (await this.hasTransactionToHandle() && !this.#runningEpoch) await this.#runEpoch()
|
|
848
|
-
// runEpoch()
|
|
849
|
-
// }, 5000)
|
|
850
|
-
// runEpoch()
|
|
851
1189
|
}
|
|
852
1190
|
|
|
853
1191
|
calculateFee(transaction) {
|
|
@@ -857,25 +1195,6 @@ async resolveBlock(hash) {
|
|
|
857
1195
|
return (transaction.encoded.length / 1024) / 1e-6
|
|
858
1196
|
}
|
|
859
1197
|
|
|
860
|
-
async getTransactions (transactions) {
|
|
861
|
-
return new Promise(async (resolve, reject) => {
|
|
862
|
-
let size = 0;
|
|
863
|
-
const _transactions = [];
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
await Promise.all(transactions
|
|
867
|
-
.map(async tx => {
|
|
868
|
-
tx = await new TransactionMessage(tx);
|
|
869
|
-
size += tx.encoded.length;
|
|
870
|
-
if (!formatBytes(size).includes('MB') || formatBytes(size).includes('MB') && Number(formatBytes(size).split(' MB')[0]) <= 0.75) _transactions.push({...tx.decoded, hash: await tx.hash});
|
|
871
|
-
else resolve(_transactions);
|
|
872
|
-
}));
|
|
873
|
-
|
|
874
|
-
return resolve(_transactions)
|
|
875
|
-
})
|
|
876
|
-
|
|
877
|
-
}
|
|
878
|
-
|
|
879
1198
|
// todo filter tx that need to wait on prev nonce
|
|
880
1199
|
async #createBlock(limit = 1800) {
|
|
881
1200
|
// vote for transactions
|
|
@@ -893,7 +1212,7 @@ async resolveBlock(hash) {
|
|
|
893
1212
|
|
|
894
1213
|
// exclude failing tx
|
|
895
1214
|
transactions = await this.getTransactions(transactions.slice(0, transactions.length < 1800 ? transactions.length : 1800));
|
|
896
|
-
|
|
1215
|
+
|
|
897
1216
|
transactions = transactions.sort((a, b) => a.nonce - b.nonce);
|
|
898
1217
|
for (let transaction of transactions) {
|
|
899
1218
|
try {
|
|
@@ -901,15 +1220,14 @@ console.log(transactions);
|
|
|
901
1220
|
block.transactions.push(transaction);
|
|
902
1221
|
block.fees += Number(calculateFee(transaction));
|
|
903
1222
|
await accountsStore.put(transaction.from, new TextEncoder().encode(String(transaction.nonce)));
|
|
904
|
-
} catch
|
|
905
|
-
console.log(error);
|
|
1223
|
+
} catch {
|
|
906
1224
|
transaction = await new TransactionMessage(transaction);
|
|
907
1225
|
await transactionPoolStore.delete(await transaction.hash);
|
|
908
1226
|
}
|
|
909
1227
|
}
|
|
910
1228
|
// don't add empty block
|
|
911
1229
|
if (block.transactions.length === 0) return
|
|
912
|
-
const validators = await this.staticCall(addresses.validators, 'validators');
|
|
1230
|
+
const validators = await this.staticCall(addresses$1.validators, 'validators');
|
|
913
1231
|
console.log({validators});
|
|
914
1232
|
// block.validators = Object.keys(block.validators).reduce((set, key) => {
|
|
915
1233
|
// if (block.validators[key].active) {
|
|
@@ -984,7 +1302,7 @@ console.log(transactions);
|
|
|
984
1302
|
.map(async transaction => transactionPoolStore.delete(await transaction.hash)));
|
|
985
1303
|
|
|
986
1304
|
|
|
987
|
-
let blockMessage = await new BlockMessage(block);
|
|
1305
|
+
let blockMessage = await new BlockMessage$1(block);
|
|
988
1306
|
const hash = await blockMessage.hash;
|
|
989
1307
|
|
|
990
1308
|
|
|
@@ -1002,58 +1320,18 @@ console.log(transactions);
|
|
|
1002
1320
|
// transactionStore.put(message.hash, message.encoded)
|
|
1003
1321
|
}
|
|
1004
1322
|
|
|
1005
|
-
|
|
1006
|
-
transactions = await Promise.all(transactions.map(tx => new TransactionMessage(tx)));
|
|
1007
|
-
return transactions
|
|
1008
|
-
}
|
|
1009
|
-
|
|
1010
|
-
async promiseTransactionsContent(transactions) {
|
|
1011
|
-
transactions = await Promise.all(transactions.map(tx => new Promise(async (resolve, reject) => {
|
|
1012
|
-
resolve({ ...tx.decoded, hash: await tx.hash });
|
|
1013
|
-
})));
|
|
1014
|
-
|
|
1015
|
-
return transactions
|
|
1016
|
-
}
|
|
1017
|
-
|
|
1018
|
-
async #getNonceFallback(address) {
|
|
1019
|
-
let transactions = await transactionPoolStore.values();
|
|
1020
|
-
transactions = await this.promiseTransactions(transactions);
|
|
1021
|
-
transactions = transactions.filter(tx => tx.decoded.from === address);
|
|
1022
|
-
transactions = await this.promiseTransactionsContent(transactions);
|
|
1023
|
-
|
|
1024
|
-
if (this.lastBlock?.hash && transactions.length === 0 && this.lastBlock.hash !== '0x0') {
|
|
1025
|
-
|
|
1026
|
-
let block = await peernet.get(this.lastBlock.hash);
|
|
1027
|
-
block = await new BlockMessage(block);
|
|
1028
|
-
|
|
1029
|
-
// for (let tx of block.decoded?.transactions) {
|
|
1030
|
-
// tx = await peernet.get(tx, 'transaction')
|
|
1031
|
-
// transactions.push(new TransactionMessage(tx))
|
|
1032
|
-
// }
|
|
1033
|
-
transactions = transactions.filter(tx => tx.from === address);
|
|
1034
|
-
while (transactions.length === 0 && block.decoded.index !== 0 && block.decoded.previousHash !== '0x0') {
|
|
1035
|
-
block = await blockStore.get(block.decoded.previousHash);
|
|
1036
|
-
block = await new BlockMessage(block);
|
|
1037
|
-
transactions = block.decoded.transactions.filter(tx => tx.from === address);
|
|
1038
|
-
}
|
|
1039
|
-
|
|
1040
|
-
}
|
|
1041
|
-
if (transactions.length === 0) return 0
|
|
1042
|
-
|
|
1043
|
-
transactions = transactions.sort((a, b) => a.timestamp - b.timestamp);
|
|
1044
|
-
return transactions[transactions.length - 1].nonce
|
|
1045
|
-
}
|
|
1323
|
+
|
|
1046
1324
|
|
|
1047
|
-
async
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
await
|
|
1325
|
+
async #addTransaction(transaction) {
|
|
1326
|
+
try {
|
|
1327
|
+
transaction = await new TransactionMessage(transaction);
|
|
1328
|
+
const has = await transactionPoolStore.has(await transaction.hash);
|
|
1329
|
+
if (!has) await transactionPoolStore.put(await transaction.hash, transaction.encoded);
|
|
1330
|
+
if (this.#participating && !this.#runningEpoch) this.#runEpoch();
|
|
1331
|
+
} catch {
|
|
1332
|
+
throw new Error('invalid transaction')
|
|
1051
1333
|
}
|
|
1052
|
-
let nonce = await accountsStore.get(address);
|
|
1053
|
-
nonce = new TextDecoder().decode(nonce);
|
|
1054
|
-
return Number(nonce)
|
|
1055
1334
|
}
|
|
1056
|
-
|
|
1057
1335
|
/**
|
|
1058
1336
|
* whenever method = createContract params should hold the contract hash
|
|
1059
1337
|
*
|
|
@@ -1065,72 +1343,9 @@ console.log(transactions);
|
|
|
1065
1343
|
* @param {Array} params - array of paramters to apply to the contract method
|
|
1066
1344
|
* @param {Number} nonce - total transaction count [optional]
|
|
1067
1345
|
*/
|
|
1068
|
-
|
|
1346
|
+
async createTransaction(to, method, parameters, nonce, signature) {
|
|
1069
1347
|
return this.createTransactionFrom(peernet.selectedAccount, to, method, parameters, nonce)
|
|
1070
|
-
}
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
/**
|
|
1075
|
-
*
|
|
1076
|
-
* @param {Transaction} transaction
|
|
1077
|
-
* @param {String} transaction.from address
|
|
1078
|
-
* @param {String} transaction.to address
|
|
1079
|
-
* @param {Object} transaction.params {}
|
|
1080
|
-
* @param {String} transaction.params.method get, call
|
|
1081
|
-
* @param {Buffer} transaction.params.data
|
|
1082
|
-
* @returns
|
|
1083
|
-
*/
|
|
1084
|
-
async createTransactionHash(transaction) {
|
|
1085
|
-
// todo: validate
|
|
1086
|
-
const peernetHash = await new index.CodecHash(transaction, {name: 'transaction-message'});
|
|
1087
|
-
return peernetHash.digest
|
|
1088
|
-
}
|
|
1089
|
-
|
|
1090
|
-
/**
|
|
1091
|
-
* @param {Transaction} transaction
|
|
1092
|
-
* @param {object} wallet any wallet/signer that supports sign(RAWtransaction)
|
|
1093
|
-
*/
|
|
1094
|
-
async #signTransaction (transaction, wallet) {
|
|
1095
|
-
return wallet.sign(await this.createTransactionHash(transaction))
|
|
1096
|
-
}
|
|
1097
|
-
|
|
1098
|
-
async signTransaction(transaction, signer) {
|
|
1099
|
-
let identity = await walletStore.get('identity');
|
|
1100
|
-
identity = JSON.parse(new TextDecoder().decode(identity));
|
|
1101
|
-
const wallet = new MultiWallet__default["default"](peernet.network);
|
|
1102
|
-
wallet.recover(identity.mnemonic);
|
|
1103
|
-
const account = wallet.account(0).external(0);
|
|
1104
|
-
transaction.signature = await this.#signTransaction(transaction, account);
|
|
1105
|
-
transaction.signature = bs32__default["default"].encode(transaction.signature);
|
|
1106
|
-
return transaction
|
|
1107
|
-
}
|
|
1108
|
-
|
|
1109
|
-
/**
|
|
1110
|
-
*
|
|
1111
|
-
* @param {Transaction} transaction
|
|
1112
|
-
* @param {Address} transaction.from
|
|
1113
|
-
* @param {Address} transaction.to
|
|
1114
|
-
* @param {String} transaction.method
|
|
1115
|
-
* @param {Array} transaction.params
|
|
1116
|
-
* @param {Number} transaction.nonce
|
|
1117
|
-
*
|
|
1118
|
-
* @returns {RawTransaction} transaction
|
|
1119
|
-
*/
|
|
1120
|
-
async createRawTransaction(transaction) {
|
|
1121
|
-
if (!transaction.from) transaction.from = peernet.selectedAccount;
|
|
1122
|
-
transaction.timestamp = Date.now();
|
|
1123
|
-
|
|
1124
|
-
if (transaction.nonce === undefined) {
|
|
1125
|
-
transaction.nonce = await this.getNonce(transaction.from);
|
|
1126
|
-
} else {
|
|
1127
|
-
let nonce = await accountsStore.get(transaction.from);
|
|
1128
|
-
nonce = new TextDecoder().decode(nonce);
|
|
1129
|
-
if (transaction.nonce < nonce) throw new Error(`a transaction with a higher nonce already exists`)
|
|
1130
|
-
if (transaction.nonce === nonce) throw new Error(`a transaction with the same nonce already exists`)
|
|
1131
|
-
}
|
|
1132
|
-
return transaction
|
|
1133
|
-
}
|
|
1348
|
+
}
|
|
1134
1349
|
/**
|
|
1135
1350
|
* every tx done is trough contracts so no need for amount
|
|
1136
1351
|
* data is undefined when nothing is returned
|
|
@@ -1142,83 +1357,10 @@ async #signTransaction (transaction, wallet) {
|
|
|
1142
1357
|
* @param {Array} params - array of paramters to apply to the contract method
|
|
1143
1358
|
* @param {Number} nonce - total transaction count [optional]
|
|
1144
1359
|
*/
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
const rawTransaction = await this.createRawTransaction({from, to, nonce, method, params: parameters});
|
|
1150
|
-
const transaction = await this.signTransaction(rawTransaction, from);
|
|
1151
|
-
const message = await new TransactionMessage(transaction);
|
|
1152
|
-
|
|
1153
|
-
let data;
|
|
1154
|
-
// await transactionPoolStore.put(message.hash, new TextEncoder().encode(JSON.stringify({signature, message: message.encoded})))
|
|
1155
|
-
const wait = () => new Promise(async (resolve, reject) => {
|
|
1156
|
-
if (pubsub.subscribers[`transaction.completed.${await message.hash}`]) {
|
|
1157
|
-
const result = pubsub.subscribers[`transaction.completed.${await message.hash}`].value;
|
|
1158
|
-
result.status === 'fulfilled' ? resolve(await result.hash) : reject({hash: await result.hash, error: result.error});
|
|
1159
|
-
} else {
|
|
1160
|
-
const completed = async result => {
|
|
1161
|
-
result.status === 'fulfilled' ? resolve(await result.hash) : reject({hash: await result.hash, error: result.error});
|
|
1162
|
-
|
|
1163
|
-
setTimeout(async () => {
|
|
1164
|
-
pubsub.unsubscribe(`transaction.completed.${await message.hash}`, completed);
|
|
1165
|
-
}, 10_000);
|
|
1166
|
-
};
|
|
1167
|
-
pubsub.subscribe(`transaction.completed.${await message.hash}`, completed);
|
|
1168
|
-
}
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
});
|
|
1172
|
-
|
|
1173
|
-
await transactionPoolStore.put(await message.hash, message.encoded);
|
|
1174
|
-
peernet.publish('add-transaction', message.encoded);
|
|
1175
|
-
this.#addTransaction(message.encoded);
|
|
1176
|
-
debug('creating tx');
|
|
1177
|
-
return {hash: await message.hash, data, fee: await calculateFee(message.decoded), wait}
|
|
1178
|
-
} catch (error) {
|
|
1179
|
-
console.log(error);
|
|
1180
|
-
throw error
|
|
1181
|
-
}
|
|
1182
|
-
|
|
1183
|
-
}
|
|
1184
|
-
|
|
1185
|
-
/**
|
|
1186
|
-
*
|
|
1187
|
-
* @param {Address} creator
|
|
1188
|
-
* @param {String} contract
|
|
1189
|
-
* @param {Array} constructorParameters
|
|
1190
|
-
* @returns lib.createContractMessage
|
|
1191
|
-
*/
|
|
1192
|
-
async createContractMessage(creator, contract, constructorParameters = []) {
|
|
1193
|
-
return createContractMessage(creator, contract, constructorParameters)
|
|
1194
|
-
}
|
|
1195
|
-
|
|
1196
|
-
/**
|
|
1197
|
-
*
|
|
1198
|
-
* @param {Address} creator
|
|
1199
|
-
* @param {String} contract
|
|
1200
|
-
* @param {Array} constructorParameters
|
|
1201
|
-
* @returns {Address}
|
|
1202
|
-
*/
|
|
1203
|
-
async createContractAddress(creator, contract, constructorParameters = []) {
|
|
1204
|
-
contract = await this.createContractMessage(creator, contract, constructorParameters);
|
|
1205
|
-
return contract.hash
|
|
1206
|
-
}
|
|
1207
|
-
|
|
1208
|
-
/**
|
|
1209
|
-
*
|
|
1210
|
-
* @param {String} contract
|
|
1211
|
-
* @param {Array} parameters
|
|
1212
|
-
* @returns
|
|
1213
|
-
*/
|
|
1214
|
-
async deployContract(contract, constructorParameters = []) {
|
|
1215
|
-
const message = await createContractMessage(peernet.selectedAccount, contract, constructorParameters);
|
|
1216
|
-
try {
|
|
1217
|
-
await contractStore.put(await message.hash, message.encoded);
|
|
1218
|
-
} catch (error) {
|
|
1219
|
-
throw error
|
|
1220
|
-
}
|
|
1221
|
-
return this.createTransactionFrom(peernet.selectedAccount, addresses.contractFactory, 'registerContract', [await message.hash])
|
|
1360
|
+
async createTransactionFrom(from, to, method, parameters, nonce) {
|
|
1361
|
+
const event = await super.createTransactionFrom(from, to, method, parameters, nonce);
|
|
1362
|
+
this.#addTransaction(event.message.encoded);
|
|
1363
|
+
return event
|
|
1222
1364
|
}
|
|
1223
1365
|
|
|
1224
1366
|
/**
|
|
@@ -1281,19 +1423,19 @@ async #signTransaction (transaction, wallet) {
|
|
|
1281
1423
|
}
|
|
1282
1424
|
|
|
1283
1425
|
mint(to, amount) {
|
|
1284
|
-
return this.call(addresses.nativeToken, 'mint', [to, amount])
|
|
1426
|
+
return this.call(addresses$1.nativeToken, 'mint', [to, amount])
|
|
1285
1427
|
}
|
|
1286
1428
|
|
|
1287
1429
|
transfer(from, to, amount) {
|
|
1288
|
-
return this.call(addresses.nativeToken, 'transfer', [from, to, amount])
|
|
1430
|
+
return this.call(addresses$1.nativeToken, 'transfer', [from, to, amount])
|
|
1289
1431
|
}
|
|
1290
1432
|
|
|
1291
1433
|
get balances() {
|
|
1292
|
-
return this.staticCall(addresses.nativeToken, 'balances')
|
|
1434
|
+
return this.staticCall(addresses$1.nativeToken, 'balances')
|
|
1293
1435
|
}
|
|
1294
1436
|
|
|
1295
1437
|
get contracts() {
|
|
1296
|
-
return this.staticCall(addresses.contractFactory, 'contracts')
|
|
1438
|
+
return this.staticCall(addresses$1.contractFactory, 'contracts')
|
|
1297
1439
|
}
|
|
1298
1440
|
|
|
1299
1441
|
deleteAll() {
|
|
@@ -1310,7 +1452,7 @@ async #signTransaction (transaction, wallet) {
|
|
|
1310
1452
|
* @example chain.lookup('myCoolContractName') // qmqsfddfdgfg...
|
|
1311
1453
|
*/
|
|
1312
1454
|
lookup(name) {
|
|
1313
|
-
return this.call(addresses.nameService, 'lookup', [name])
|
|
1455
|
+
return this.call(addresses$1.nameService, 'lookup', [name])
|
|
1314
1456
|
}
|
|
1315
1457
|
}
|
|
1316
1458
|
|