@leofcoin/chain 1.3.10 → 1.3.11
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 +7663 -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 +66838 -0
- package/dist/chain.js +440 -302
- package/dist/generate-account.browser.js +50 -0
- package/dist/messages.browser.js +328 -0
- package/dist/module/chain.js +435 -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 +100 -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,397 @@ 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 totalSize() {
|
|
825
|
+
return this.#totalSize
|
|
826
|
+
}
|
|
827
|
+
|
|
454
828
|
get lib() {
|
|
455
829
|
return lib
|
|
456
830
|
}
|
|
@@ -460,7 +834,7 @@ class Chain {
|
|
|
460
834
|
}
|
|
461
835
|
|
|
462
836
|
get nativeToken() {
|
|
463
|
-
return addresses.nativeToken
|
|
837
|
+
return addresses$1.nativeToken
|
|
464
838
|
}
|
|
465
839
|
|
|
466
840
|
get validators() {
|
|
@@ -480,10 +854,9 @@ class Chain {
|
|
|
480
854
|
async #runEpoch() {
|
|
481
855
|
this.#runningEpoch = true;
|
|
482
856
|
console.log('epoch');
|
|
483
|
-
const validators = await this.staticCall(addresses.validators, 'validators');
|
|
857
|
+
const validators = await this.staticCall(addresses$1.validators, 'validators');
|
|
484
858
|
console.log(validators);
|
|
485
859
|
if (!validators[peernet.selectedAccount]?.active) return
|
|
486
|
-
debug(`validator ${peernet.selectedAccount} active`);
|
|
487
860
|
const start = Date.now();
|
|
488
861
|
try {
|
|
489
862
|
await this.#createBlock();
|
|
@@ -502,16 +875,16 @@ class Chain {
|
|
|
502
875
|
async #setup() {
|
|
503
876
|
|
|
504
877
|
const contracts = [{
|
|
505
|
-
address: addresses.contractFactory,
|
|
878
|
+
address: addresses$1.contractFactory,
|
|
506
879
|
message: contractFactoryMessage
|
|
507
880
|
}, {
|
|
508
|
-
address: addresses.nativeToken,
|
|
881
|
+
address: addresses$1.nativeToken,
|
|
509
882
|
message: nativeTokenMessage
|
|
510
883
|
}, {
|
|
511
|
-
address: addresses.validators,
|
|
884
|
+
address: addresses$1.validators,
|
|
512
885
|
message: validatorsMessage
|
|
513
886
|
}, {
|
|
514
|
-
address: addresses.nameService,
|
|
887
|
+
address: addresses$1.nameService,
|
|
515
888
|
message: nameServiceMessage
|
|
516
889
|
}];
|
|
517
890
|
|
|
@@ -569,7 +942,7 @@ class Chain {
|
|
|
569
942
|
|
|
570
943
|
if (latest.hash && latest.hash !== '0x0') {
|
|
571
944
|
latest = await peernet.get(latest.hash, block);
|
|
572
|
-
latest = await new BlockMessage(latest);
|
|
945
|
+
latest = await new BlockMessage$1(latest);
|
|
573
946
|
}
|
|
574
947
|
|
|
575
948
|
return latest
|
|
@@ -579,11 +952,13 @@ class Chain {
|
|
|
579
952
|
// this.node = await new Node()
|
|
580
953
|
this.#participants = [];
|
|
581
954
|
this.#participating = false;
|
|
582
|
-
const initialized = await contractStore.has(addresses.contractFactory);
|
|
955
|
+
const initialized = await contractStore.has(addresses$1.contractFactory);
|
|
583
956
|
if (!initialized) await this.#setup();
|
|
584
957
|
|
|
585
958
|
|
|
586
959
|
this.utils = { BigNumber: utils.BigNumber, formatUnits: utils.formatUnits, parseUnits: utils.parseUnits };
|
|
960
|
+
|
|
961
|
+
this.state = new State();
|
|
587
962
|
|
|
588
963
|
try {
|
|
589
964
|
let localBlock;
|
|
@@ -596,7 +971,7 @@ class Chain {
|
|
|
596
971
|
localBlock = new TextDecoder().decode(localBlock);
|
|
597
972
|
if (localBlock && localBlock !== '0x0') {
|
|
598
973
|
localBlock = await peernet.get(localBlock, 'block');
|
|
599
|
-
localBlock = await new BlockMessage(localBlock);
|
|
974
|
+
localBlock = await new BlockMessage$1(localBlock);
|
|
600
975
|
this.#lastBlock = {...localBlock.decoded, hash: await localBlock.hash};
|
|
601
976
|
} else {
|
|
602
977
|
const latestBlock = await this.#getLatestBlock();
|
|
@@ -667,16 +1042,6 @@ class Chain {
|
|
|
667
1042
|
|
|
668
1043
|
#epochTimeout
|
|
669
1044
|
|
|
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
1045
|
|
|
681
1046
|
async #lastBlockHandler() {
|
|
682
1047
|
return new peernet.protos['peernet-response']({response: { hash: this.#lastBlock?.hash, index: this.#lastBlock?.index }})
|
|
@@ -685,9 +1050,10 @@ async #lastBlockHandler() {
|
|
|
685
1050
|
async resolveBlock(hash) {
|
|
686
1051
|
if (!hash) throw new Error(`expected hash, got: ${hash}`)
|
|
687
1052
|
let block = await peernet.get(hash, 'block');
|
|
688
|
-
block = await new BlockMessage(block);
|
|
1053
|
+
block = await new BlockMessage$1(block);
|
|
689
1054
|
if (!await peernet.has(hash, 'block')) await peernet.put(hash, block.encoded, 'block');
|
|
690
1055
|
const size = block.encoded.length > 0 ? block.encoded.length : block.encoded.byteLength;
|
|
1056
|
+
this.#totalSize += size;
|
|
691
1057
|
block = {...block.decoded, hash};
|
|
692
1058
|
if (this.#blocks[block.index] && this.#blocks[block.index].hash !== block.hash) throw `invalid block ${hash} @${block.index}`
|
|
693
1059
|
this.#blocks[block.index] = block;
|
|
@@ -713,51 +1079,40 @@ async resolveBlock(hash) {
|
|
|
713
1079
|
}
|
|
714
1080
|
}
|
|
715
1081
|
|
|
1082
|
+
/**
|
|
1083
|
+
*
|
|
1084
|
+
* @param {Block[]} blocks
|
|
1085
|
+
*/
|
|
716
1086
|
async #loadBlocks(blocks) {
|
|
717
1087
|
for (const block of blocks) {
|
|
718
1088
|
if (block && !block.loaded) {
|
|
719
1089
|
for (const transaction of block.transactions) {
|
|
720
1090
|
try {
|
|
721
1091
|
await this.#machine.execute(transaction.to, transaction.method, transaction.params);
|
|
722
|
-
|
|
1092
|
+
if (transaction.to === nativeToken$1) {
|
|
1093
|
+
this.#nativeCalls += 1;
|
|
1094
|
+
if (transaction.method === 'burn') this.#nativeBurns += 1;
|
|
1095
|
+
if (transaction.method === 'mint') this.#nativeMints += 1;
|
|
1096
|
+
if (transaction.method === 'transfer') this.#nativeTransfers += 1;
|
|
1097
|
+
}
|
|
1098
|
+
this.#totalTransactions += 1;
|
|
723
1099
|
} catch (error) {
|
|
724
1100
|
console.log(error);
|
|
725
1101
|
}
|
|
726
1102
|
}
|
|
727
1103
|
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
|
|
1104
|
+
debug(`loaded block: ${block.hash} @${block.index}`);
|
|
747
1105
|
}
|
|
748
1106
|
}
|
|
749
1107
|
}
|
|
750
1108
|
|
|
751
1109
|
async #executeTransaction({hash, from, to, method, params, nonce}) {
|
|
752
|
-
console.log(hash, from);
|
|
753
1110
|
try {
|
|
754
1111
|
let result = await this.#machine.execute(to, method, params, from, nonce);
|
|
755
1112
|
// if (!result) result = this.#machine.state
|
|
756
|
-
console.log({result});
|
|
757
1113
|
pubsub.publish(`transaction.completed.${hash}`, {status: 'fulfilled', hash});
|
|
758
1114
|
return result || 'no state change'
|
|
759
1115
|
} catch (error) {
|
|
760
|
-
console.log(error);
|
|
761
1116
|
pubsub.publish(`transaction.completed.${hash}`, {status: 'fail', hash, error: error});
|
|
762
1117
|
throw error
|
|
763
1118
|
}
|
|
@@ -765,26 +1120,10 @@ async resolveBlock(hash) {
|
|
|
765
1120
|
|
|
766
1121
|
async #addBlock(block) {
|
|
767
1122
|
// 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
|
-
// }
|
|
1123
|
+
const blockMessage = await new BlockMessage$1(new Uint8Array(Object.values(block)));
|
|
783
1124
|
await Promise.all(blockMessage.decoded.transactions
|
|
784
1125
|
.map(async transaction => transactionPoolStore.delete(await transaction.hash)));
|
|
785
1126
|
const hash = await blockMessage.hash;
|
|
786
|
-
// let transactions = blockMessage.decoded.transactions.map(tx => transactionJob(tx))
|
|
787
|
-
// transactions = await Promise.all(transactions)
|
|
788
1127
|
|
|
789
1128
|
await blockStore.put(hash, blockMessage.encoded);
|
|
790
1129
|
|
|
@@ -827,6 +1166,7 @@ async resolveBlock(hash) {
|
|
|
827
1166
|
async #updateState(message) {
|
|
828
1167
|
const hash = await message.hash;
|
|
829
1168
|
this.#lastBlock = { hash, ...message.decoded };
|
|
1169
|
+
await this.state.updateState(message);
|
|
830
1170
|
await chainStore.put('lastBlock', hash);
|
|
831
1171
|
}
|
|
832
1172
|
|
|
@@ -840,14 +1180,8 @@ async resolveBlock(hash) {
|
|
|
840
1180
|
// peerReputation(peerId)
|
|
841
1181
|
// {bandwith: {up, down}, uptime}
|
|
842
1182
|
this.#participating = true;
|
|
843
|
-
if (!await this.staticCall(addresses.validators, 'has', [address])) await this.createTransactionFrom(address, addresses.validators, 'addValidator', [address]);
|
|
1183
|
+
if (!await this.staticCall(addresses$1.validators, 'has', [address])) await this.createTransactionFrom(address, addresses$1.validators, 'addValidator', [address]);
|
|
844
1184
|
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
1185
|
}
|
|
852
1186
|
|
|
853
1187
|
calculateFee(transaction) {
|
|
@@ -857,25 +1191,6 @@ async resolveBlock(hash) {
|
|
|
857
1191
|
return (transaction.encoded.length / 1024) / 1e-6
|
|
858
1192
|
}
|
|
859
1193
|
|
|
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
1194
|
// todo filter tx that need to wait on prev nonce
|
|
880
1195
|
async #createBlock(limit = 1800) {
|
|
881
1196
|
// vote for transactions
|
|
@@ -893,7 +1208,7 @@ async resolveBlock(hash) {
|
|
|
893
1208
|
|
|
894
1209
|
// exclude failing tx
|
|
895
1210
|
transactions = await this.getTransactions(transactions.slice(0, transactions.length < 1800 ? transactions.length : 1800));
|
|
896
|
-
|
|
1211
|
+
|
|
897
1212
|
transactions = transactions.sort((a, b) => a.nonce - b.nonce);
|
|
898
1213
|
for (let transaction of transactions) {
|
|
899
1214
|
try {
|
|
@@ -901,15 +1216,14 @@ console.log(transactions);
|
|
|
901
1216
|
block.transactions.push(transaction);
|
|
902
1217
|
block.fees += Number(calculateFee(transaction));
|
|
903
1218
|
await accountsStore.put(transaction.from, new TextEncoder().encode(String(transaction.nonce)));
|
|
904
|
-
} catch
|
|
905
|
-
console.log(error);
|
|
1219
|
+
} catch {
|
|
906
1220
|
transaction = await new TransactionMessage(transaction);
|
|
907
1221
|
await transactionPoolStore.delete(await transaction.hash);
|
|
908
1222
|
}
|
|
909
1223
|
}
|
|
910
1224
|
// don't add empty block
|
|
911
1225
|
if (block.transactions.length === 0) return
|
|
912
|
-
const validators = await this.staticCall(addresses.validators, 'validators');
|
|
1226
|
+
const validators = await this.staticCall(addresses$1.validators, 'validators');
|
|
913
1227
|
console.log({validators});
|
|
914
1228
|
// block.validators = Object.keys(block.validators).reduce((set, key) => {
|
|
915
1229
|
// if (block.validators[key].active) {
|
|
@@ -984,7 +1298,7 @@ console.log(transactions);
|
|
|
984
1298
|
.map(async transaction => transactionPoolStore.delete(await transaction.hash)));
|
|
985
1299
|
|
|
986
1300
|
|
|
987
|
-
let blockMessage = await new BlockMessage(block);
|
|
1301
|
+
let blockMessage = await new BlockMessage$1(block);
|
|
988
1302
|
const hash = await blockMessage.hash;
|
|
989
1303
|
|
|
990
1304
|
|
|
@@ -1002,58 +1316,18 @@ console.log(transactions);
|
|
|
1002
1316
|
// transactionStore.put(message.hash, message.encoded)
|
|
1003
1317
|
}
|
|
1004
1318
|
|
|
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
|
-
}
|
|
1319
|
+
|
|
1046
1320
|
|
|
1047
|
-
async
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
await
|
|
1321
|
+
async #addTransaction(transaction) {
|
|
1322
|
+
try {
|
|
1323
|
+
transaction = await new TransactionMessage(transaction);
|
|
1324
|
+
const has = await transactionPoolStore.has(await transaction.hash);
|
|
1325
|
+
if (!has) await transactionPoolStore.put(await transaction.hash, transaction.encoded);
|
|
1326
|
+
if (this.#participating && !this.#runningEpoch) this.#runEpoch();
|
|
1327
|
+
} catch {
|
|
1328
|
+
throw new Error('invalid transaction')
|
|
1051
1329
|
}
|
|
1052
|
-
let nonce = await accountsStore.get(address);
|
|
1053
|
-
nonce = new TextDecoder().decode(nonce);
|
|
1054
|
-
return Number(nonce)
|
|
1055
1330
|
}
|
|
1056
|
-
|
|
1057
1331
|
/**
|
|
1058
1332
|
* whenever method = createContract params should hold the contract hash
|
|
1059
1333
|
*
|
|
@@ -1065,72 +1339,9 @@ console.log(transactions);
|
|
|
1065
1339
|
* @param {Array} params - array of paramters to apply to the contract method
|
|
1066
1340
|
* @param {Number} nonce - total transaction count [optional]
|
|
1067
1341
|
*/
|
|
1068
|
-
|
|
1342
|
+
async createTransaction(to, method, parameters, nonce, signature) {
|
|
1069
1343
|
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
|
-
}
|
|
1344
|
+
}
|
|
1134
1345
|
/**
|
|
1135
1346
|
* every tx done is trough contracts so no need for amount
|
|
1136
1347
|
* data is undefined when nothing is returned
|
|
@@ -1142,83 +1353,10 @@ async #signTransaction (transaction, wallet) {
|
|
|
1142
1353
|
* @param {Array} params - array of paramters to apply to the contract method
|
|
1143
1354
|
* @param {Number} nonce - total transaction count [optional]
|
|
1144
1355
|
*/
|
|
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])
|
|
1356
|
+
async createTransactionFrom(from, to, method, parameters, nonce) {
|
|
1357
|
+
const event = await super.createTransactionFrom(from, to, method, parameters, nonce);
|
|
1358
|
+
this.#addTransaction(event.message.encoded);
|
|
1359
|
+
return event
|
|
1222
1360
|
}
|
|
1223
1361
|
|
|
1224
1362
|
/**
|
|
@@ -1281,19 +1419,19 @@ async #signTransaction (transaction, wallet) {
|
|
|
1281
1419
|
}
|
|
1282
1420
|
|
|
1283
1421
|
mint(to, amount) {
|
|
1284
|
-
return this.call(addresses.nativeToken, 'mint', [to, amount])
|
|
1422
|
+
return this.call(addresses$1.nativeToken, 'mint', [to, amount])
|
|
1285
1423
|
}
|
|
1286
1424
|
|
|
1287
1425
|
transfer(from, to, amount) {
|
|
1288
|
-
return this.call(addresses.nativeToken, 'transfer', [from, to, amount])
|
|
1426
|
+
return this.call(addresses$1.nativeToken, 'transfer', [from, to, amount])
|
|
1289
1427
|
}
|
|
1290
1428
|
|
|
1291
1429
|
get balances() {
|
|
1292
|
-
return this.staticCall(addresses.nativeToken, 'balances')
|
|
1430
|
+
return this.staticCall(addresses$1.nativeToken, 'balances')
|
|
1293
1431
|
}
|
|
1294
1432
|
|
|
1295
1433
|
get contracts() {
|
|
1296
|
-
return this.staticCall(addresses.contractFactory, 'contracts')
|
|
1434
|
+
return this.staticCall(addresses$1.contractFactory, 'contracts')
|
|
1297
1435
|
}
|
|
1298
1436
|
|
|
1299
1437
|
deleteAll() {
|
|
@@ -1310,7 +1448,7 @@ async #signTransaction (transaction, wallet) {
|
|
|
1310
1448
|
* @example chain.lookup('myCoolContractName') // qmqsfddfdgfg...
|
|
1311
1449
|
*/
|
|
1312
1450
|
lookup(name) {
|
|
1313
|
-
return this.call(addresses.nameService, 'lookup', [name])
|
|
1451
|
+
return this.call(addresses$1.nameService, 'lookup', [name])
|
|
1314
1452
|
}
|
|
1315
1453
|
}
|
|
1316
1454
|
|