@leofcoin/chain 1.3.3 → 1.3.5

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.
Files changed (46) hide show
  1. package/dist/browser/workers/machine-worker.js +0 -13
  2. package/dist/chain.js +155 -133
  3. package/dist/contracts/factory.js +1 -1
  4. package/dist/contracts/{nameService.js → name-service.js} +1 -1
  5. package/dist/contracts/native-token.js +1 -0
  6. package/dist/contracts/validators.js +1 -1
  7. package/dist/module/chain.js +152 -130
  8. package/dist/module/workers/machine-worker.js +0 -6
  9. package/dist/standards/token.js +1 -1
  10. package/dist/workers/machine-worker.js +1 -1
  11. package/package.json +20 -2
  12. package/rollup.config.js +4 -4
  13. package/src/chain.js +122 -104
  14. package/src/contracts/factory.js +58 -15
  15. package/src/contracts/{nameService.js → name-service.js} +3 -5
  16. package/src/contracts/{nativeToken.js → native-token.js} +2 -2
  17. package/src/contracts/{powerToken.js → power-token.js} +1 -1
  18. package/src/contracts/proxies/{factoryProxy.js → factory-proxy.js} +1 -1
  19. package/src/contracts/proxies/{nameServiceProxy.js → name-service-proxy.js} +1 -1
  20. package/src/contracts/proxies/{nativeTokenProxy.js → native-token-proxy.js} +1 -1
  21. package/src/contracts/proxies/{validatorsProxy.js → validators-proxy.js} +1 -1
  22. package/src/contracts/proxies/{votingProxy.js → voting-proxy.js} +1 -1
  23. package/src/contracts/{proxyManager.js → proxy-manager.js} +1 -1
  24. package/src/contracts/validators.js +35 -25
  25. package/src/fee/config.js +1 -1
  26. package/src/machine.js +30 -26
  27. package/src/standards/{proxyManager.js → proxy-manager.js} +0 -0
  28. package/src/standards/{Proxy.js → proxy.js} +4 -8
  29. package/src/standards/roles.js +7 -5
  30. package/src/standards/token.js +2 -2
  31. package/src/standards/voting.js +1 -0
  32. package/src/transactions/transaction.js +1 -3
  33. package/src/transactions/validator.js +1 -1
  34. package/src/typer.js +1 -1
  35. package/dist/865.browser.js +0 -10
  36. package/dist/chain.browser.js +0 -59745
  37. package/dist/contracts/nativeToken.js +0 -1
  38. package/dist/generate-account.browser.js +0 -50
  39. package/dist/messages.browser.js +0 -328
  40. package/dist/multi-wallet.browser.js +0 -15
  41. package/dist/node.browser.js +0 -9858
  42. package/dist/pako.browser.js +0 -6900
  43. package/dist/peernet-swarm.browser.js +0 -839
  44. package/dist/storage.browser.js +0 -3724
  45. package/dist/wrtc.browser.js +0 -28
  46. package/src/standards/Voting.js +0 -3
@@ -0,0 +1 @@
1
+ class Roles{#roles={IMPLEMENTATION_MANAGER:[],OWNER:[],MINT:[],BURN:[]};constructor(roles){if(roles){if(!(roles instanceof Object))throw new TypeError("expected roles to be an object");this.#roles={...roles,...this.#roles}}else this.#grantRole(msg.sender,"OWNER"),this.#grantRole(msg.sender,"IMPLEMENTATION_MANAGER")}get state(){return{roles:this.roles}}get roles(){return{...this.#roles}}hasRole(address,role){return!!this.#roles[role]&&this.#roles[role].includes(address)}#grantRole(address,role){if(this.hasRole(address,role))throw new Error(`${role} role already granted for ${address}`);this.#roles[role].push(address)}#revokeRole(address,role){if(!this.hasRole(address,role))throw new Error(`${role} role already revoked for ${address}`);if("OWNER"===role&&1===this.#roles[role].length)throw new Error("atleast one owner is needed!");this.#roles[role].splice(this.#roles[role].indexOf(address))}grantRole(address,role){if(!this.hasRole(address,"OWNER"))throw new Error("Not allowed");this.#grantRole(address,role)}revokeRole(address,role){if(!this.hasRole(address,"OWNER"))throw new Error("Not allowed");this.#revokeRole(address,role)}}class Token extends Roles{#name;#symbol;#holders=0;#balances={};#approvals={};#decimals=18;#totalSupply=BigNumber.from(0);constructor(name,symbol,decimals=18,state){if(!name)throw new Error("name undefined");if(!symbol)throw new Error("symbol undefined");super(state?.roles),this.#name=name,this.#symbol=symbol,this.#decimals=decimals}get state(){return{...super.state,holders:this.holders,balances:this.balances,approvals:{...this.#approvals},totalSupply:this.totalSupply}}get totalSupply(){return this.#totalSupply}get name(){return this.#name}get symbol(){return this.#symbol}get holders(){return this.#holders}get balances(){return{...this.#balances}}mint(to,amount){if(!this.hasRole(msg.sender,"MINT"))throw new Error("not allowed");this.#totalSupply=this.#totalSupply.add(amount),this.#increaseBalance(to,amount)}burn(from,amount){if(!this.hasRole(msg.sender,"BURN"))throw new Error("not allowed");this.#totalSupply=this.#totalSupply.sub(amount),this.#decreaseBalance(from,amount)}#beforeTransfer(from,to,amount){if(!this.#balances[from]||this.#balances[from]<amount)throw new Error("amount exceeds balance")}#updateHolders(address,previousBalance){"0x00"===this.#balances[address].toHexString()?this.#holders-=1:"0x00"!==this.#balances[address].toHexString()&&"0x00"===previousBalance.toHexString()&&(this.#holders+=1)}#increaseBalance(address,amount){this.#balances[address]||(this.#balances[address]=BigNumber.from(0));const previousBalance=this.#balances[address];this.#balances[address]=this.#balances[address].add(amount),this.#updateHolders(address,previousBalance)}#decreaseBalance(address,amount){const previousBalance=this.#balances[address];this.#balances[address]=this.#balances[address].sub(amount),this.#updateHolders(address,previousBalance)}balanceOf(address){return this.#balances[address]}setApproval(operator,amount){const owner=globalThis.msg.sender;this.#approvals[owner]||(this.#approvals[owner]={}),this.#approvals[owner][operator]=amount}approved(owner,operator,amount){return this.#approvals[owner][operator]===amount}transfer(from,to,amount){amount=BigNumber.from(amount),this.#beforeTransfer(from,to,amount),this.#decreaseBalance(from,amount),this.#increaseBalance(to,amount)}}class ArtOnline extends Token{constructor(state){super("ArtOnline","ART",18,state)}}export{ArtOnline as default};
@@ -1 +1 @@
1
- class Validators{#name="ArtOnlineValidators";#totalValidators=0;#validators={};#owner;#currency;#minimumBalance;get state(){return{owner:this.#owner,minimumBalance:this.#minimumBalance,currency:this.#currency,totalValidators:this.#totalValidators,validators:this.#validators}}constructor(tokenAddress,state){state?(this.#owner=state.owner,this.#minimumBalance=state.minimumBalance,this.#currency=state.currency,this.#totalValidators=state.totalValidators,this.#validators=state.validators):(this.#owner=msg.sender,this.#minimumBalance=5e4,this.#currency=tokenAddress,this.#totalValidators+=1,this.#validators[msg.sender]={firstSeen:(new Date).getTime(),active:!0})}get name(){return this.#name}get owner(){return this.#owner}get currency(){return this.#currency}get validators(){return{...this.#validators}}get totalValidators(){return this.#totalValidators}get minimumBalance(){return this.#minimumBalance}changeOwner(owner){if(msg.sender!==this.#owner)throw new Error("not an owner")}changeCurrency(currency){if(msg.sender!==this.#owner)throw new Error("not an owner");this.#currency=currency}has(validator){return Boolean(void 0!==this.#validators[validator])}async addValidator(validator){if(this.has(validator))throw new Error("already a validator");const balance=await msg.staticCall(this.currency,"balanceOf",[msg.sender]);if(balance<this.minimumBalance)throw new Error(`balance to low! got: ${balance} need: ${this.#minimumBalance}`);this.#totalValidators+=1,this.#validators[validator]={firstSeen:(new Date).getTime(),active:!0}}removeValidator(validator){if(!this.has(validator))throw new Error("validator not found");this.#totalValidators-=1,delete this.#validators[validator]}async updateValidator(validator,active){if(!this.has(validator))throw new Error("validator not found");const balance=await msg.staticCall(this.currency,"balanceOf",[msg.sender]);if(balance<this.minimumBalance&&this.#validators[validator].active&&(this.#validators[validator].active=!1),balance<this.minimumBalance)throw new Error(`balance to low! got: ${balance} need: ${this.#minimumBalance}`);this.#validators[validator].active=active}}export{Validators as default};
1
+ class Roles{#roles={IMPLEMENTATION_MANAGER:[],OWNER:[],MINT:[],BURN:[]};constructor(roles){if(roles){if(!(roles instanceof Object))throw new TypeError("expected roles to be an object");this.#roles={...roles,...this.#roles}}else this.#grantRole(msg.sender,"OWNER"),this.#grantRole(msg.sender,"IMPLEMENTATION_MANAGER")}get state(){return{roles:this.roles}}get roles(){return{...this.#roles}}hasRole(address,role){return!!this.#roles[role]&&this.#roles[role].includes(address)}#grantRole(address,role){if(this.hasRole(address,role))throw new Error(`${role} role already granted for ${address}`);this.#roles[role].push(address)}#revokeRole(address,role){if(!this.hasRole(address,role))throw new Error(`${role} role already revoked for ${address}`);if("OWNER"===role&&1===this.#roles[role].length)throw new Error("atleast one owner is needed!");this.#roles[role].splice(this.#roles[role].indexOf(address))}grantRole(address,role){if(!this.hasRole(address,"OWNER"))throw new Error("Not allowed");this.#grantRole(address,role)}revokeRole(address,role){if(!this.hasRole(address,"OWNER"))throw new Error("Not allowed");this.#revokeRole(address,role)}}class Validators extends Roles{#name="ArtOnlineValidators";#totalValidators=0;#activeValidators=0;#validators={};#currency;#minimumBalance;get state(){return{...super.state,minimumBalance:this.#minimumBalance,currency:this.#currency,totalValidators:this.#totalValidators,activeValidators:this.#activeValidators,validators:this.#validators}}constructor(tokenAddress,state){super(state?.roles),state?(this.#minimumBalance=state.minimumBalance,this.#currency=state.currency,this.#totalValidators=state.totalValidators,this.#activeValidators=state.activeValidators,this.#validators=state.validators):(this.#minimumBalance=5e4,this.#currency=tokenAddress,this.#totalValidators+=1,this.#activeValidators+=1,this.#validators[msg.sender]={firstSeen:Date.now(),lastSeen:Date.now(),active:!0})}get name(){return this.#name}get currency(){return this.#currency}get validators(){return{...this.#validators}}get totalValidators(){return this.#totalValidators}get minimumBalance(){return this.#minimumBalance}changeCurrency(currency){if(!this.hasRole(msg.sender,"OWNER"))throw new Error("not an owner");this.#currency=currency}has(validator){return Boolean(void 0!==this.#validators[validator])}#isAllowed(address){if(msg.sender!==address&&!this.hasRole(msg.sender,"OWNER"))throw new Error("sender is not the validator or owner");return!0}async addValidator(validator){if(this.#isAllowed(validator),this.has(validator))throw new Error("already a validator");const balance=await msg.staticCall(this.currency,"balanceOf",[validator]);if(balance<this.minimumBalance)throw new Error(`balance to low! got: ${balance} need: ${this.#minimumBalance}`);this.#totalValidators+=1,this.#activeValidators+=1,this.#validators[validator]={firstSeen:Date.now(),lastSeen:Date.now(),active:!0}}removeValidator(validator){if(this.#isAllowed(validator),!this.has(validator))throw new Error("validator not found");this.#totalValidators-=1,this.#validators[validator].active&&(this.#activeValidators-=1),delete this.#validators[validator]}async updateValidator(validator,active){if(this.#isAllowed(validator),!this.has(validator))throw new Error("validator not found");const balance=await msg.staticCall(this.currency,"balanceOf",[validator]);if(balance<this.minimumBalance&&active)throw new Error(`balance to low! got: ${balance} need: ${this.#minimumBalance}`);if(this.#validators[validator].active===active)throw new Error("already "+(active?"activated":"deactivated"));active?this.#activeValidators+=1:this.#activeValidators-=1,this.#validators[validator].active=active}}export{Validators as default};
@@ -3,8 +3,8 @@ import _BN from 'bn.js';
3
3
  import '@ethersproject/bytes';
4
4
  import { Logger } from '@ethersproject/logger';
5
5
  import '@ethersproject/bignumber';
6
- import { randomBytes } from 'crypto';
7
- import { join } from 'path';
6
+ import { randomBytes } from 'node:crypto';
7
+ import { join } from 'node:path';
8
8
  import EasyWorker from '@vandeurenglenn/easy-worker';
9
9
  import { FormatInterface } from '@leofcoin/codec-format-interface';
10
10
  import MultiWallet from '@leofcoin/multi-wallet';
@@ -69,26 +69,31 @@ class Machine {
69
69
 
70
70
  async #onmessage(data) {
71
71
  switch (data.type) {
72
- case 'contractError':
72
+ case 'contractError': {
73
73
  console.warn(`removing contract ${await data.hash}`);
74
74
  await contractStore.delete(await data.hash);
75
75
  break
76
+ }
76
77
 
77
- case 'executionError':
78
+ case 'executionError': {
78
79
  // console.warn(`error executing transaction ${data.message}`);
79
80
  pubsub.publish(data.id, {error: data.message});
80
81
  break
82
+ }
81
83
 
82
- case 'debug':
83
- data.messages.forEach(message => debug(message));
84
+ case 'debug': {
85
+ for (const message of data.messages) debug(message);
84
86
  break
85
- case 'machine-ready':
87
+ }
88
+ case 'machine-ready': {
86
89
  this.lastBlock = data.lastBlock;
87
90
  pubsub.publish('machine.ready', true);
88
91
  break
89
- case 'response':
92
+ }
93
+ case 'response': {
90
94
  pubsub.publish(data.id, data.value);
91
95
  break
96
+ }
92
97
  }
93
98
 
94
99
  }
@@ -124,19 +129,19 @@ class Machine {
124
129
  }
125
130
 
126
131
  async #runContract(contractMessage) {
127
- const params = contractMessage.decoded.constructorParameters;
132
+ const parameters = contractMessage.decoded.constructorParameters;
128
133
  try {
129
134
 
130
- const func = new Function(contractMessage.decoded.contract);
131
- const Contract = func();
135
+ const function_ = new Function(contractMessage.decoded.contract);
136
+ const Contract = function_();
132
137
 
133
138
  globalThis.msg = this.#createMessage(contractMessage.decoded.creator);
134
139
  // globalThis.msg = {sender: contractMessage.decoded.creator}
135
- this.#contracts[await contractMessage.hash] = await new Contract(...params);
140
+ this.#contracts[await contractMessage.hash] = await new Contract(...parameters);
136
141
  debug(`loaded contract: ${await contractMessage.hash}`);
137
142
  debug(`size: ${formatBytes(contractMessage.encoded.length)}`);
138
- } catch (e) {
139
- console.log(e);
143
+ } catch (error) {
144
+ console.log(error);
140
145
  console.warn(`removing contract ${await contractMessage.hash}`);
141
146
  await contractStore.delete(await contractMessage.hash, contractMessage.encoded);
142
147
  }
@@ -145,15 +150,14 @@ class Machine {
145
150
  * @params {ContractMessage} - contractMessage
146
151
  */
147
152
  async addContract(contractMessage) {
148
- if (!await contractStore.has(contractMessage.hash)) {
149
- await contractStore.put(contractMessage.hash, contractMessage.encoded);
150
- await this.#runContract(contractMessage);
151
- return contractMessage.hash
152
- }
153
- throw new Error('duplicate contract')
153
+ if (await contractStore.has(await contractMessage.hash)) throw new Error('duplicate contract')
154
+
155
+ await contractStore.put(await contractMessage.hash, contractMessage.encoded);
156
+ await this.#runContract(contractMessage);
157
+ return contractMessage.hash
154
158
  }
155
159
 
156
- async execute(contract, method, params) {
160
+ async execute(contract, method, parameters) {
157
161
  return new Promise((resolve, reject) => {
158
162
  const id = randomBytes(20).toString('hex');
159
163
  const message = message => {
@@ -167,22 +171,22 @@ class Machine {
167
171
  input: {
168
172
  contract,
169
173
  method,
170
- params
174
+ params: parameters
171
175
  }
172
176
  });
173
177
  })
174
178
 
175
179
  }
176
180
 
177
- addJob(contract, method, params, from, nonce) {
181
+ addJob(contract, method, parameters, from, nonce) {
178
182
  if (!this.#nonces[from]) this.#nonces[from] = nonce;
179
- if (nonce === this.#nonces[from] + 1) return this.#contracts[contract][method](...params)
183
+ if (nonce === this.#nonces[from] + 1) return this.#contracts[contract][method](...parameters)
180
184
  // return setTimeout(() => {
181
185
  // return this.addJob(contract, method, params, from, nonce)
182
186
  // }, 50)
183
187
  }
184
188
 
185
- get(contract, method, params) {
189
+ get(contract, method, parameters) {
186
190
  return new Promise((resolve, reject) => {
187
191
  const id = randomBytes(20).toString();
188
192
  const message = message => {
@@ -195,7 +199,7 @@ class Machine {
195
199
  input: {
196
200
  contract,
197
201
  method,
198
- params
202
+ params: parameters
199
203
  }
200
204
  });
201
205
  })
@@ -404,8 +408,10 @@ class Chain {
404
408
  #blocks = []
405
409
  #machine
406
410
  #runningEpoch = false
411
+ #chainSyncing = false
407
412
  #lastBlock = {index: 0, hash: '0x0', previousHash: '0x0'}
408
-
413
+ #participants = []
414
+ #participating = false
409
415
  #jail = []
410
416
 
411
417
  constructor() {
@@ -445,14 +451,14 @@ class Chain {
445
451
  console.log(validators);
446
452
  if (!validators[peernet.selectedAccount]?.active) return
447
453
 
448
- const start = new Date().getTime();
454
+ const start = Date.now();
449
455
  try {
450
456
  await this.#createBlock();
451
- } catch (e) {
452
- console.error(e);
457
+ } catch (error) {
458
+ console.error(error);
453
459
  }
454
460
 
455
- const end = new Date().getTime();
461
+ const end = Date.now();
456
462
  console.log(((end - start) / 1000) + ' s');
457
463
 
458
464
  if (await this.hasTransactionToHandle()) return this.#runEpoch()
@@ -489,7 +495,7 @@ class Chain {
489
495
  const timeout = setTimeout(() => {
490
496
  resolve([{index: 0, hash: '0x0'}]);
491
497
  debug('sync timed out');
492
- }, 10000);
498
+ }, 10_000);
493
499
 
494
500
  promises = await Promise.allSettled(promises);
495
501
  promises = promises.filter(({status}) => status === 'fulfilled');
@@ -503,11 +509,11 @@ class Chain {
503
509
 
504
510
  }
505
511
 
506
- sync() {
507
- return this.#sync()
512
+ getLatestBlock() {
513
+ return this.#getLatestBlock()
508
514
  }
509
515
 
510
- async #sync() {
516
+ async #getLatestBlock() {
511
517
  let promises = [];
512
518
 
513
519
  let data = await new peernet.protos['peernet-request']({request: 'lastBlock'});
@@ -519,26 +525,27 @@ class Chain {
519
525
  } else if (!peer.connected || peer.readyState !== 'open') ;
520
526
  }
521
527
  promises = await this.promiseRequests(promises);
522
- promises = promises.reduce((set, value) => {
523
-
524
- if (value.index > set.index) {
525
- set.index = value.index;
526
- set.hash = value.hash;
527
- }
528
- return set
529
- }, {index: 0, hash: '0x0'});
530
- // get lastblock
531
- if (promises.hash && promises.hash !== '0x0') {
532
- await peernet.get(promises.hash);
528
+ let latest = {index: 0, hash: '0x0'};
529
+
530
+ for (const value of promises) {
531
+ if (value.index > latest.index) {
532
+ latest.index = value.index;
533
+ latest.hash = value.hash;
533
534
  }
534
-
535
-
535
+ }
536
+
537
+ if (latest.hash && latest.hash !== '0x0') {
538
+ let latestBlock = await peernet.get(latest.hash, block);
539
+ latestBlock = await new BlockMessage(latestBlock);
540
+ }
541
+
542
+ return latestBlock
536
543
  }
537
544
 
538
545
  async #init() {
539
546
  // this.node = await new Node()
540
- this.participants = [];
541
- this.participating = false;
547
+ this.#participants = [];
548
+ this.#participating = false;
542
549
  const initialized = await contractStore.has(addresses.contractFactory);
543
550
  if (!initialized) await this.#setup();
544
551
 
@@ -549,7 +556,7 @@ class Chain {
549
556
  let localBlock;
550
557
  try {
551
558
  localBlock = await chainStore.get('lastBlock');
552
- } catch(e) {
559
+ } catch{
553
560
  await chainStore.put('lastBlock', '0x0');
554
561
  localBlock = await chainStore.get('lastBlock');
555
562
  }
@@ -559,13 +566,11 @@ class Chain {
559
566
  localBlock = await new BlockMessage(localBlock);
560
567
  this.#lastBlock = {...localBlock.decoded, hash: await localBlock.hash};
561
568
  } else {
562
- await this.#sync();
569
+ const latestBlock = await this.#getLatestBlock();
570
+ await this.#syncChain(latestBlock);
563
571
  }
564
- } catch (e) {
565
- console.log({e});
566
-
567
-
568
- // this.#setup()
572
+ } catch (error) {
573
+ console.log({e: error});
569
574
  }
570
575
 
571
576
  await peernet.addRequestHandler('bw-request-message', () => {
@@ -587,9 +592,6 @@ class Chain {
587
592
  // load local blocks
588
593
  await this.resolveBlocks();
589
594
  this.#machine = await new Machine(this.#blocks);
590
- // for (const block of this.#blocks) {
591
- // block.loaded = true
592
- // }
593
595
  await this.#loadBlocks(this.#blocks);
594
596
  return this
595
597
  }
@@ -601,29 +603,33 @@ class Chain {
601
603
  this.#jail.push(validatorInfo.address);
602
604
  }
603
605
 
604
- async #peerConnected(peer) {
605
- let node = await new peernet.protos['peernet-request']({request: 'lastBlock'});
606
- node = await peernet.prepareMessage(node);
607
- let response = await peer.request(node.encoded);
608
- response = await new globalThis.peernet.protos['peernet-response'](response);
609
- let lastBlock = response.decoded.response;
606
+ async #syncChain(lastBlock) {
607
+ if (this.#chainSyncing) return
610
608
 
611
609
  if (!this.lastBlock || Number(this.lastBlock.index) < Number(lastBlock.index)) {
612
- // TODO: check if valid
610
+ this.#chainSyncing = true;
611
+ // TODO: check if valid
613
612
  const localIndex = this.lastBlock ? this.lastBlock.index : 0;
614
613
  const index = lastBlock.index;
615
614
  await this.resolveBlock(lastBlock.hash);
616
- let blocksSynced = localIndex > 0 ? localIndex > index ? localIndex - index : index - localIndex : index;
615
+ let blocksSynced = localIndex > 0 ? (localIndex > index ? localIndex - index : index - localIndex) : index;
617
616
  debug(`synced ${blocksSynced} ${blocksSynced > 1 ? 'blocks' : 'block'}`);
618
617
 
619
618
  this.#blocks.length;
620
- const start = (this.#blocks.length) - blocksSynced;
619
+ const start = this.#blocks.length - blocksSynced;
621
620
  await this.#loadBlocks(this.blocks.slice(start));
622
- this.#lastBlock = this.#blocks[this.#blocks.length - 1];
623
- const message = await new BlockMessage(this.lastBlock);
624
- await blockStore.put(await message.hash, message.encoded);
625
- await chainStore.put('lastBlock', this.lastBlock.hash);
621
+ await this.#updateState(this.#blocks[this.#blocks.length - 1]);
622
+ this.#chainSyncing = false;
626
623
  }
624
+ }
625
+
626
+ async #peerConnected(peer) {
627
+ let node = await new peernet.protos['peernet-request']({request: 'lastBlock'});
628
+ node = await peernet.prepareMessage(node);
629
+ let response = await peer.request(node.encoded);
630
+ response = await new globalThis.peernet.protos['peernet-response'](response);
631
+ let lastBlock = response.decoded.response;
632
+ this.#syncChain(lastBlock);
627
633
  }
628
634
 
629
635
  #epochTimeout
@@ -633,9 +639,9 @@ class Chain {
633
639
  transaction = await new TransactionMessage(transaction);
634
640
  const has = await transactionPoolStore.has(await transaction.hash);
635
641
  if (!has) await transactionPoolStore.put(await transaction.hash, transaction.encoded);
636
- if (this.participating && !this.#runningEpoch) this.#runEpoch();
637
- } catch (e) {
638
- throw Error('invalid transaction')
642
+ if (this.#participating && !this.#runningEpoch) this.#runEpoch();
643
+ } catch {
644
+ throw new Error('invalid transaction')
639
645
  }
640
646
  }
641
647
 
@@ -648,7 +654,7 @@ async resolveBlock(hash) {
648
654
  let block = await peernet.get(hash, 'block');
649
655
  block = await new BlockMessage(block);
650
656
  if (!await peernet.has(hash, 'block')) await peernet.put(hash, block.encoded, 'block');
651
- const size = block.encoded.length || block.encoded.byteLength;
657
+ const size = block.encoded.length > 0 ? block.encoded.length : block.encoded.byteLength;
652
658
  block = {...block.decoded, hash};
653
659
  if (this.#blocks[block.index] && this.#blocks[block.index].hash !== block.hash) throw `invalid block ${hash} @${block.index}`
654
660
  this.#blocks[block.index] = block;
@@ -667,7 +673,7 @@ async resolveBlock(hash) {
667
673
  await this.resolveBlock(hash);
668
674
  this.#lastBlock = this.#blocks[this.#blocks.length - 1];
669
675
 
670
- } catch (e) {
676
+ } catch {
671
677
  await chainStore.put('lastBlock', new TextEncoder().encode('0x0'));
672
678
  return this.resolveBlocks()
673
679
  // console.log(e);
@@ -681,8 +687,8 @@ async resolveBlock(hash) {
681
687
  try {
682
688
  await this.#machine.execute(transaction.to, transaction.method, transaction.params);
683
689
 
684
- } catch (e) {
685
- console.log(e);
690
+ } catch (error) {
691
+ console.log(error);
686
692
  }
687
693
  }
688
694
  this.#blocks[block.index].loaded = true;
@@ -714,10 +720,10 @@ async resolveBlock(hash) {
714
720
  let result = await this.#machine.execute(to, method, params, from, nonce);
715
721
  // if (!result) result = this.#machine.state
716
722
  pubsub.publish(`transaction.completed.${hash}`, {status: 'fulfilled', hash});
717
- return result ? result : 'no state change'
718
- } catch (e) {
719
- pubsub.publish(`transaction.completed.${hash}`, {status: 'fail', hash, error: e});
720
- throw e
723
+ return result || 'no state change'
724
+ } catch (error) {
725
+ pubsub.publish(`transaction.completed.${hash}`, {status: 'fail', hash, error: error});
726
+ throw error
721
727
  }
722
728
  }
723
729
 
@@ -754,11 +760,15 @@ async resolveBlock(hash) {
754
760
  // await transactionStore.put(transaction.hash, transaction.encoded)
755
761
  const index = contracts.indexOf(transaction.to);
756
762
  if (index === -1) contracts.push(transaction.to);
763
+ // Todo: go trough all accounts
757
764
  promises.push(this.#executeTransaction(transaction));
765
+
758
766
  }
759
767
  try {
760
768
  promises = await Promise.allSettled(promises);
761
769
  for (let transaction of blockMessage.decoded.transactions) {
770
+ pubsub.publish('transaction-processed', transaction);
771
+ if (transaction.to === peernet.selectedAccount) pubsub.publish('account-transaction-processed', transaction);
762
772
  await accountsStore.put(transaction.from, String(transaction.nonce));
763
773
  }
764
774
 
@@ -771,8 +781,9 @@ async resolveBlock(hash) {
771
781
 
772
782
 
773
783
  pubsub.publish('block-processed', blockMessage.decoded);
774
- } catch (e) {
775
- console.log({e});
784
+
785
+ } catch (error) {
786
+ console.log({e: error});
776
787
  }
777
788
 
778
789
  }
@@ -792,7 +803,7 @@ async resolveBlock(hash) {
792
803
  // introduce peer-reputation
793
804
  // peerReputation(peerId)
794
805
  // {bandwith: {up, down}, uptime}
795
- this.participating = true;
806
+ this.#participating = true;
796
807
  if (!await this.staticCall(addresses.validators, 'has', [address])) await this.createTransactionFrom(address, addresses.validators, 'addValidator', [address]);
797
808
  if (await this.hasTransactionToHandle() && !this.#runningEpoch) await this.#runEpoch();
798
809
 
@@ -854,7 +865,7 @@ async resolveBlock(hash) {
854
865
  block.transactions.push(transaction);
855
866
  block.fees += Number(calculateFee(transaction));
856
867
  await accountsStore.put(transaction.from, new TextEncoder().encode(String(transaction.nonce)));
857
- } catch (e) {
868
+ } catch {
858
869
  transaction = await new TransactionMessage(transaction);
859
870
  await transactionPoolStore.delete(await transaction.hash);
860
871
  }
@@ -887,9 +898,7 @@ async resolveBlock(hash) {
887
898
  address: validator,
888
899
  bw: bw.up + bw.down
889
900
  });
890
- } catch(e) {
891
-
892
- }
901
+ } catch{}
893
902
 
894
903
  } else if (peernet.selectedAccount === validator) {
895
904
  block.validators.push({
@@ -917,17 +926,17 @@ async resolveBlock(hash) {
917
926
  else block.index += 1;
918
927
 
919
928
  block.previousHash = this.lastBlock?.hash || '0x0';
920
- block.timestamp = new Date().getTime();
929
+ block.timestamp = Date.now();
921
930
 
922
931
  const parts = String(block.fees).split('.');
923
932
  let decimals = 0;
924
933
  if (parts[1]) {
925
934
  const potentional = parts[1].split('e');
926
- if (potentional[0] !== parts[1]) {
927
- parts[1] = potentional[0];
928
- decimals = Number(potentional[1]?.replace(/\-|\+/g, '')) + Number(potentional[0].length);
929
- } else {
935
+ if (potentional[0] === parts[1]) {
930
936
  decimals = parts[1].length;
937
+ } else {
938
+ parts[1] = potentional[0];
939
+ decimals = Number(potentional[1]?.replace(/[+-]/g, '')) + Number(potentional[0].length);
931
940
  }
932
941
 
933
942
  }
@@ -947,9 +956,10 @@ async resolveBlock(hash) {
947
956
  debug(`created block: ${hash}`);
948
957
 
949
958
  peernet.publish('add-block', blockMessage.encoded);
950
- } catch (e) {
951
- console.log(e);
952
- throw Error(`invalid block ${block}`)
959
+ pubsub.publish('add-block', blockMessage.decoded);
960
+ } catch (error) {
961
+ console.log(error);
962
+ throw new Error(`invalid block ${block}`)
953
963
  }
954
964
  // data = await this.#machine.execute(to, method, params)
955
965
  // transactionStore.put(message.hash, message.encoded)
@@ -1018,8 +1028,8 @@ async resolveBlock(hash) {
1018
1028
  * @param {Array} params - array of paramters to apply to the contract method
1019
1029
  * @param {Number} nonce - total transaction count [optional]
1020
1030
  */
1021
- async createTransaction(to, method, params, nonce, signature) {
1022
- return this.createTransactionFrom(peernet.selectedAccount, to, method, params, nonce)
1031
+ async createTransaction(to, method, parameters, nonce, signature) {
1032
+ return this.createTransactionFrom(peernet.selectedAccount, to, method, parameters, nonce)
1023
1033
  }
1024
1034
 
1025
1035
 
@@ -1079,8 +1089,8 @@ async #signTransaction (transaction, wallet) {
1079
1089
  } else {
1080
1090
  let nonce = await accountsStore.get(transaction.from);
1081
1091
  nonce = new TextDecoder().decode(nonce);
1082
- if (transaction.nonce < nonce) throw Error(`a transaction with a higher nonce already exists`)
1083
- if (transaction.nonce === nonce) throw Error(`a transaction with the same nonce already exists`)
1092
+ if (transaction.nonce < nonce) throw new Error(`a transaction with a higher nonce already exists`)
1093
+ if (transaction.nonce === nonce) throw new Error(`a transaction with the same nonce already exists`)
1084
1094
  }
1085
1095
  return transaction
1086
1096
  }
@@ -1095,10 +1105,10 @@ async #signTransaction (transaction, wallet) {
1095
1105
  * @param {Array} params - array of paramters to apply to the contract method
1096
1106
  * @param {Number} nonce - total transaction count [optional]
1097
1107
  */
1098
- async createTransactionFrom(from, to, method, params, nonce) {
1108
+ async createTransactionFrom(from, to, method, parameters, nonce) {
1099
1109
  try {
1100
1110
 
1101
- const rawTransaction = await this.createRawTransaction({from, to, nonce, method, params});
1111
+ const rawTransaction = await this.createRawTransaction({from, to, nonce, method, params: parameters});
1102
1112
  const transaction = await this.signTransaction(rawTransaction, from);
1103
1113
  const message = await new TransactionMessage(transaction);
1104
1114
 
@@ -1114,7 +1124,7 @@ async #signTransaction (transaction, wallet) {
1114
1124
 
1115
1125
  setTimeout(async () => {
1116
1126
  pubsub.unsubscribe(`transaction.completed.${await message.hash}`, completed);
1117
- }, 10000);
1127
+ }, 10_000);
1118
1128
  };
1119
1129
  pubsub.subscribe(`transaction.completed.${await message.hash}`, completed);
1120
1130
  }
@@ -1126,9 +1136,9 @@ async #signTransaction (transaction, wallet) {
1126
1136
  peernet.publish('add-transaction', message.encoded);
1127
1137
  this.#addTransaction(message.encoded);
1128
1138
  return {hash: await message.hash, data, fee: await calculateFee(message.decoded), wait}
1129
- } catch (e) {
1130
- console.log(e);
1131
- throw e
1139
+ } catch (error) {
1140
+ console.log(error);
1141
+ throw error
1132
1142
  }
1133
1143
 
1134
1144
  }
@@ -1143,20 +1153,19 @@ async #signTransaction (transaction, wallet) {
1143
1153
  }
1144
1154
 
1145
1155
  /**
1146
- *
1147
- * @param {String} contract - a contract string (see plugins/deployContract)
1156
+ *
1157
+ * @param {String} contract
1158
+ * @param {Array} parameters
1159
+ * @returns
1148
1160
  */
1149
- async deployContract(contract, params = []) {
1150
- globalThis.msg = {sender: peernet.selectedAccount, call: this.call};
1151
-
1152
- const hash = await this.createContractAddress(creator, contract, params);
1153
- console.log(hash);
1161
+ async deployContract(contract, parameters = []) {
1162
+ const message = await createContractMessage(peernet.selectedAccount, contract, parameters);
1154
1163
  try {
1155
- const tx = await this.createTransactionFrom(peernet.selectedAccount, addresses.contractFactory, 'deployContract', [hash, creator, contract, constructorParameters]);
1156
- } catch (e) {
1157
- throw e
1164
+ await this.#machine.addContract(message);
1165
+ } catch (error) {
1166
+ throw error
1158
1167
  }
1159
- return this.#machine.addContract(message)
1168
+ return this.createTransactionFrom(peernet.selectedAccount, addresses.contractFactory, 'registerContract', [await message.hash])
1160
1169
  }
1161
1170
 
1162
1171
  #createMessage(sender = peernet.selectedAccount) {
@@ -1169,33 +1178,33 @@ console.log(hash);
1169
1178
  }
1170
1179
  }
1171
1180
 
1172
- internalCall(sender, contract, method, params) {
1181
+ internalCall(sender, contract, method, parameters) {
1173
1182
  globalThis.msg = this.#createMessage(sender);
1174
1183
 
1175
- return this.#machine.execute(contract, method, params)
1184
+ return this.#machine.execute(contract, method, parameters)
1176
1185
  }
1177
1186
 
1178
- call(contract, method, params) {
1187
+ call(contract, method, parameters) {
1179
1188
  globalThis.msg = this.#createMessage();
1180
1189
 
1181
- return this.#machine.execute(contract, method, params)
1190
+ return this.#machine.execute(contract, method, parameters)
1182
1191
  }
1183
1192
 
1184
- staticCall(contract, method, params) {
1193
+ staticCall(contract, method, parameters) {
1185
1194
  globalThis.msg = this.#createMessage();
1186
- return this.#machine.get(contract, method, params)
1195
+ return this.#machine.get(contract, method, parameters)
1187
1196
  }
1188
1197
 
1189
- delegate(contract, method, params) {
1198
+ delegate(contract, method, parameters) {
1190
1199
  globalThis.msg = this.#createMessage();
1191
1200
 
1192
- return this.#machine.execute(contract, method, params)
1201
+ return this.#machine.execute(contract, method, parameters)
1193
1202
  }
1194
1203
 
1195
- staticDelegate(contract, method, params) {
1204
+ staticDelegate(contract, method, parameters) {
1196
1205
  globalThis.msg = this.#createMessage();
1197
1206
 
1198
- return this.#machine.get(contract, method, params)
1207
+ return this.#machine.get(contract, method, parameters)
1199
1208
  }
1200
1209
 
1201
1210
  mint(to, amount) {
@@ -1210,6 +1219,19 @@ console.log(hash);
1210
1219
  return this.staticCall(addresses.nativeToken, 'balances')
1211
1220
  }
1212
1221
 
1222
+ get contracts() {
1223
+ return this.staticCall(addresses.contractFactory, 'contracts')
1224
+ }
1225
+ /**
1226
+ *
1227
+ * @param {Address} address old contract address
1228
+ * @param {Address} newAddress new contract address
1229
+ * @returns
1230
+ */
1231
+ async updateImplementation(address, newAddress) {
1232
+ return this.call(addresses.contractFactory, 'updateImplementation', [address, newAddress])
1233
+ }
1234
+
1213
1235
  deleteAll() {
1214
1236
  return this.#machine.deleteAll()
1215
1237
  }
@@ -388,10 +388,6 @@ globalThis.BigNumber = BigNumber;
388
388
  globalThis.peernet = globalThis.peernet || {};
389
389
  globalThis.contracts = {};
390
390
 
391
- const unique = arr => arr.filter((el, pos, arr) => {
392
- return arr.indexOf(el) == pos;
393
- });
394
-
395
391
  const get = (contract, method, params) => {
396
392
  let result;
397
393
  if (params?.length > 0) {
@@ -576,5 +572,3 @@ const tasks = async (e) => {
576
572
  };
577
573
 
578
574
  worker.onmessage(data => tasks(data));
579
-
580
- export { unique };
@@ -1 +1 @@
1
- class Token extends class Roles{#roles={OWNER:[],MINT:[],BURN:[]};constructor(roles){if(roles){if(!(roles instanceof Object))throw new Error("expected roles to be an object");this.#roles={...roles,...this.#roles}}else this.#grantRole(msg.sender,"OWNER")}get state(){return{roles:this.roles}}get roles(){return{...this.#roles}}hasRole(address,role){return!!this.#roles[role]&&-1!==this.#roles[role].indexOf(address)}#grantRole(address,role){if(this.hasRole(address,role))throw new Error(`${role} role already granted for ${address}`);this.#roles[role].push(address)}#revokeRole(address,role){if(!this.hasRole(address,role))throw new Error(`${role} role already revoked for ${address}`);if("OWNER"===role&&1===this.#roles[role].length)throw new Error("atleast one owner is needed!");this.#roles[role].splice(this.#roles[role].indexOf(address))}grantRole(address,role){if(!this.hasRole(address,"OWNER"))throw new Error("Not allowed");this.#grantRole(address,role)}revokeRole(address,role){if(!this.hasRole(address,"OWNER"))throw new Error("Not allowed");this.#revokeRole(address,role)}}{#name;#symbol;#holders=0;#balances={};#approvals={};#decimals=18;#totalSupply=BigNumber.from(0);constructor(name,symbol,decimals=18,state){if(!name)throw new Error("name undefined");if(!symbol)throw new Error("symbol undefined");super(state?.roles),this.#name=name,this.#symbol=symbol,this.#decimals=decimals}get state(){return{...super.state,holders:this.holders,balances:this.balances,approvals:{...this.#approvals},totalSupply:this.totalSupply}}get totalSupply(){return this.#totalSupply}get name(){return this.#name}get symbol(){return this.#symbol}get holders(){return this.#holders}get balances(){return{...this.#balances}}mint(to,amount){if(!this.hasRole(msg.sender,"MINT"))throw new Error("not allowed");this.#totalSupply=this.#totalSupply.add(amount),this.#increaseBalance(to,amount)}burn(to,amount){if(!this.hasRole(msg.sender,"BURN"))throw new Error("not allowed");this.#totalSupply=this.#totalSupply.sub(amount),this.#decreaseBalance(to,amount)}#beforeTransfer(from,to,amount){if(!this.#balances[from]||this.#balances[from]<amount)throw new Error("amount exceeds balance")}#updateHolders(address,previousBalance){"0x00"===this.#balances[address].toHexString()?this.#holders-=1:"0x00"!==this.#balances[address].toHexString()&&"0x00"===previousBalance.toHexString()&&(this.#holders+=1)}#increaseBalance(address,amount){this.#balances[address]||(this.#balances[address]=BigNumber.from(0));const previousBalance=this.#balances[address];this.#balances[address]=this.#balances[address].add(amount),this.#updateHolders(address,previousBalance)}#decreaseBalance(address,amount){const previousBalance=this.#balances[address];this.#balances[address]=this.#balances[address].sub(amount),this.#updateHolders(address,previousBalance)}balanceOf(address){return this.#balances[address]}setApproval(operator,amount){const owner=globalThis.msg.sender;this.#approvals[owner]||(this.#approvals[owner]={}),this.#approvals[owner][operator]=amount}approved(owner,operator,amount){return this.#approvals[owner][operator]===amount}transfer(from,to,amount){amount=BigNumber.from(amount),this.#beforeTransfer(from,to,amount),this.#decreaseBalance(from,amount),this.#increaseBalance(to,amount)}}export{Token as default};
1
+ class Roles{#roles={IMPLEMENTATION_MANAGER:[],OWNER:[],MINT:[],BURN:[]};constructor(roles){if(roles){if(!(roles instanceof Object))throw new TypeError("expected roles to be an object");this.#roles={...roles,...this.#roles}}else this.#grantRole(msg.sender,"OWNER"),this.#grantRole(msg.sender,"IMPLEMENTATION_MANAGER")}get state(){return{roles:this.roles}}get roles(){return{...this.#roles}}hasRole(address,role){return!!this.#roles[role]&&this.#roles[role].includes(address)}#grantRole(address,role){if(this.hasRole(address,role))throw new Error(`${role} role already granted for ${address}`);this.#roles[role].push(address)}#revokeRole(address,role){if(!this.hasRole(address,role))throw new Error(`${role} role already revoked for ${address}`);if("OWNER"===role&&1===this.#roles[role].length)throw new Error("atleast one owner is needed!");this.#roles[role].splice(this.#roles[role].indexOf(address))}grantRole(address,role){if(!this.hasRole(address,"OWNER"))throw new Error("Not allowed");this.#grantRole(address,role)}revokeRole(address,role){if(!this.hasRole(address,"OWNER"))throw new Error("Not allowed");this.#revokeRole(address,role)}}class Token extends Roles{#name;#symbol;#holders=0;#balances={};#approvals={};#decimals=18;#totalSupply=BigNumber.from(0);constructor(name,symbol,decimals=18,state){if(!name)throw new Error("name undefined");if(!symbol)throw new Error("symbol undefined");super(state?.roles),this.#name=name,this.#symbol=symbol,this.#decimals=decimals}get state(){return{...super.state,holders:this.holders,balances:this.balances,approvals:{...this.#approvals},totalSupply:this.totalSupply}}get totalSupply(){return this.#totalSupply}get name(){return this.#name}get symbol(){return this.#symbol}get holders(){return this.#holders}get balances(){return{...this.#balances}}mint(to,amount){if(!this.hasRole(msg.sender,"MINT"))throw new Error("not allowed");this.#totalSupply=this.#totalSupply.add(amount),this.#increaseBalance(to,amount)}burn(from,amount){if(!this.hasRole(msg.sender,"BURN"))throw new Error("not allowed");this.#totalSupply=this.#totalSupply.sub(amount),this.#decreaseBalance(from,amount)}#beforeTransfer(from,to,amount){if(!this.#balances[from]||this.#balances[from]<amount)throw new Error("amount exceeds balance")}#updateHolders(address,previousBalance){"0x00"===this.#balances[address].toHexString()?this.#holders-=1:"0x00"!==this.#balances[address].toHexString()&&"0x00"===previousBalance.toHexString()&&(this.#holders+=1)}#increaseBalance(address,amount){this.#balances[address]||(this.#balances[address]=BigNumber.from(0));const previousBalance=this.#balances[address];this.#balances[address]=this.#balances[address].add(amount),this.#updateHolders(address,previousBalance)}#decreaseBalance(address,amount){const previousBalance=this.#balances[address];this.#balances[address]=this.#balances[address].sub(amount),this.#updateHolders(address,previousBalance)}balanceOf(address){return this.#balances[address]}setApproval(operator,amount){const owner=globalThis.msg.sender;this.#approvals[owner]||(this.#approvals[owner]={}),this.#approvals[owner][operator]=amount}approved(owner,operator,amount){return this.#approvals[owner][operator]===amount}transfer(from,to,amount){amount=BigNumber.from(amount),this.#beforeTransfer(from,to,amount),this.#decreaseBalance(from,amount),this.#increaseBalance(to,amount)}}export{Token as default};