@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
package/src/chain.js CHANGED
@@ -16,8 +16,10 @@ export default class Chain {
16
16
  #blocks = []
17
17
  #machine
18
18
  #runningEpoch = false
19
+ #chainSyncing = false
19
20
  #lastBlock = {index: 0, hash: '0x0', previousHash: '0x0'}
20
-
21
+ #participants = []
22
+ #participating = false
21
23
  #jail = []
22
24
 
23
25
  constructor() {
@@ -57,14 +59,14 @@ export default class Chain {
57
59
  console.log(validators);
58
60
  if (!validators[peernet.selectedAccount]?.active) return
59
61
 
60
- const start = new Date().getTime()
62
+ const start = Date.now()
61
63
  try {
62
64
  await this.#createBlock()
63
- } catch (e) {
64
- console.error(e);
65
+ } catch (error) {
66
+ console.error(error);
65
67
  }
66
68
 
67
- const end = new Date().getTime()
69
+ const end = Date.now()
68
70
  console.log(((end - start) / 1000) + ' s');
69
71
 
70
72
  if (await this.hasTransactionToHandle()) return this.#runEpoch()
@@ -101,7 +103,7 @@ export default class Chain {
101
103
  const timeout = setTimeout(() => {
102
104
  resolve([{index: 0, hash: '0x0'}])
103
105
  debug('sync timed out')
104
- }, 10000)
106
+ }, 10_000)
105
107
 
106
108
  promises = await Promise.allSettled(promises);
107
109
  promises = promises.filter(({status}) => status === 'fulfilled')
@@ -115,11 +117,11 @@ export default class Chain {
115
117
 
116
118
  }
117
119
 
118
- sync() {
119
- return this.#sync()
120
+ getLatestBlock() {
121
+ return this.#getLatestBlock()
120
122
  }
121
123
 
122
- async #sync() {
124
+ async #getLatestBlock() {
123
125
  let promises = [];
124
126
 
125
127
  let data = await new peernet.protos['peernet-request']({request: 'lastBlock'});
@@ -134,26 +136,27 @@ export default class Chain {
134
136
  }
135
137
  }
136
138
  promises = await this.promiseRequests(promises)
137
- promises = promises.reduce((set, value) => {
138
-
139
- if (value.index > set.index) {
140
- set.index = value.index;
141
- set.hash = value.hash;
142
- }
143
- return set
144
- }, {index: 0, hash: '0x0'});
145
- // get lastblock
146
- if (promises.hash && promises.hash !== '0x0') {
147
- let localBlock = await peernet.get(promises.hash)
139
+ let latest = {index: 0, hash: '0x0'}
140
+
141
+ for (const value of promises) {
142
+ if (value.index > latest.index) {
143
+ latest.index = value.index;
144
+ latest.hash = value.hash;
148
145
  }
149
-
150
-
146
+ }
147
+
148
+ if (latest.hash && latest.hash !== '0x0') {
149
+ let latestBlock = await peernet.get(latest.hash, block)
150
+ latestBlock = await new BlockMessage(latestBlock)
151
+ }
152
+
153
+ return latestBlock
151
154
  }
152
155
 
153
156
  async #init() {
154
157
  // this.node = await new Node()
155
- this.participants = []
156
- this.participating = false
158
+ this.#participants = []
159
+ this.#participating = false
157
160
  const initialized = await contractStore.has(addresses.contractFactory)
158
161
  if (!initialized) await this.#setup()
159
162
 
@@ -164,7 +167,7 @@ export default class Chain {
164
167
  let localBlock
165
168
  try {
166
169
  localBlock = await chainStore.get('lastBlock')
167
- } catch(e) {
170
+ } catch{
168
171
  await chainStore.put('lastBlock', '0x0')
169
172
  localBlock = await chainStore.get('lastBlock')
170
173
  }
@@ -174,13 +177,11 @@ export default class Chain {
174
177
  localBlock = await new BlockMessage(localBlock)
175
178
  this.#lastBlock = {...localBlock.decoded, hash: await localBlock.hash}
176
179
  } else {
177
- await this.#sync()
180
+ const latestBlock = await this.#getLatestBlock()
181
+ await this.#syncChain(latestBlock)
178
182
  }
179
- } catch (e) {
180
- console.log({e});
181
-
182
-
183
- // this.#setup()
183
+ } catch (error) {
184
+ console.log({e: error});
184
185
  }
185
186
 
186
187
  await peernet.addRequestHandler('bw-request-message', () => {
@@ -202,9 +203,6 @@ export default class Chain {
202
203
  // load local blocks
203
204
  await this.resolveBlocks()
204
205
  this.#machine = await new Machine(this.#blocks)
205
- // for (const block of this.#blocks) {
206
- // block.loaded = true
207
- // }
208
206
  await this.#loadBlocks(this.#blocks)
209
207
  return this
210
208
  }
@@ -216,29 +214,33 @@ export default class Chain {
216
214
  this.#jail.push(validatorInfo.address)
217
215
  }
218
216
 
219
- async #peerConnected(peer) {
220
- let node = await new peernet.protos['peernet-request']({request: 'lastBlock'})
221
- node = await peernet.prepareMessage(node)
222
- let response = await peer.request(node.encoded)
223
- response = await new globalThis.peernet.protos['peernet-response'](response)
224
- let lastBlock = response.decoded.response
217
+ async #syncChain(lastBlock) {
218
+ if (this.#chainSyncing) return
225
219
 
226
220
  if (!this.lastBlock || Number(this.lastBlock.index) < Number(lastBlock.index)) {
227
- // TODO: check if valid
221
+ this.#chainSyncing = true
222
+ // TODO: check if valid
228
223
  const localIndex = this.lastBlock ? this.lastBlock.index : 0
229
224
  const index = lastBlock.index
230
225
  await this.resolveBlock(lastBlock.hash)
231
- let blocksSynced = localIndex > 0 ? localIndex > index ? localIndex - index : index - localIndex : index
226
+ let blocksSynced = localIndex > 0 ? (localIndex > index ? localIndex - index : index - localIndex) : index
232
227
  debug(`synced ${blocksSynced} ${blocksSynced > 1 ? 'blocks' : 'block'}`)
233
228
 
234
229
  const end = this.#blocks.length
235
- const start = (this.#blocks.length) - blocksSynced
230
+ const start = this.#blocks.length - blocksSynced
236
231
  await this.#loadBlocks(this.blocks.slice(start))
237
- this.#lastBlock = this.#blocks[this.#blocks.length - 1]
238
- const message = await new BlockMessage(this.lastBlock)
239
- await blockStore.put(await message.hash, message.encoded)
240
- await chainStore.put('lastBlock', this.lastBlock.hash)
232
+ await this.#updateState(this.#blocks[this.#blocks.length - 1])
233
+ this.#chainSyncing = false
241
234
  }
235
+ }
236
+
237
+ async #peerConnected(peer) {
238
+ let node = await new peernet.protos['peernet-request']({request: 'lastBlock'})
239
+ node = await peernet.prepareMessage(node)
240
+ let response = await peer.request(node.encoded)
241
+ response = await new globalThis.peernet.protos['peernet-response'](response)
242
+ let lastBlock = response.decoded.response
243
+ this.#syncChain(lastBlock)
242
244
  }
243
245
 
244
246
  #epochTimeout
@@ -248,9 +250,9 @@ export default class Chain {
248
250
  transaction = await new TransactionMessage(transaction)
249
251
  const has = await transactionPoolStore.has(await transaction.hash)
250
252
  if (!has) await transactionPoolStore.put(await transaction.hash, transaction.encoded)
251
- if (this.participating && !this.#runningEpoch) this.#runEpoch()
252
- } catch (e) {
253
- throw Error('invalid transaction')
253
+ if (this.#participating && !this.#runningEpoch) this.#runEpoch()
254
+ } catch {
255
+ throw new Error('invalid transaction')
254
256
  }
255
257
  }
256
258
 
@@ -263,7 +265,7 @@ async resolveBlock(hash) {
263
265
  let block = await peernet.get(hash, 'block')
264
266
  block = await new BlockMessage(block)
265
267
  if (!await peernet.has(hash, 'block')) await peernet.put(hash, block.encoded, 'block')
266
- const size = block.encoded.length || block.encoded.byteLength
268
+ const size = block.encoded.length > 0 ? block.encoded.length : block.encoded.byteLength
267
269
  block = {...block.decoded, hash}
268
270
  if (this.#blocks[block.index] && this.#blocks[block.index].hash !== block.hash) throw `invalid block ${hash} @${block.index}`
269
271
  this.#blocks[block.index] = block
@@ -282,7 +284,7 @@ async resolveBlock(hash) {
282
284
  await this.resolveBlock(hash)
283
285
  this.#lastBlock = this.#blocks[this.#blocks.length - 1]
284
286
 
285
- } catch (e) {
287
+ } catch {
286
288
  await chainStore.put('lastBlock', new TextEncoder().encode('0x0'))
287
289
  return this.resolveBlocks()
288
290
  // console.log(e);
@@ -296,8 +298,8 @@ async resolveBlock(hash) {
296
298
  try {
297
299
  await this.#machine.execute(transaction.to, transaction.method, transaction.params)
298
300
 
299
- } catch (e) {
300
- console.log(e);
301
+ } catch (error) {
302
+ console.log(error);
301
303
  }
302
304
  }
303
305
  this.#blocks[block.index].loaded = true
@@ -329,10 +331,10 @@ async resolveBlock(hash) {
329
331
  let result = await this.#machine.execute(to, method, params, from, nonce)
330
332
  // if (!result) result = this.#machine.state
331
333
  pubsub.publish(`transaction.completed.${hash}`, {status: 'fulfilled', hash})
332
- return result ? result : 'no state change'
333
- } catch (e) {
334
- pubsub.publish(`transaction.completed.${hash}`, {status: 'fail', hash, error: e})
335
- throw e
334
+ return result || 'no state change'
335
+ } catch (error) {
336
+ pubsub.publish(`transaction.completed.${hash}`, {status: 'fail', hash, error: error})
337
+ throw error
336
338
  }
337
339
  }
338
340
 
@@ -369,11 +371,15 @@ async resolveBlock(hash) {
369
371
  // await transactionStore.put(transaction.hash, transaction.encoded)
370
372
  const index = contracts.indexOf(transaction.to)
371
373
  if (index === -1) contracts.push(transaction.to)
374
+ // Todo: go trough all accounts
372
375
  promises.push(this.#executeTransaction(transaction))
376
+
373
377
  }
374
378
  try {
375
379
  promises = await Promise.allSettled(promises)
376
380
  for (let transaction of blockMessage.decoded.transactions) {
381
+ pubsub.publish('transaction-processed', transaction)
382
+ if (transaction.to === peernet.selectedAccount) pubsub.publish('account-transaction-processed', transaction)
377
383
  await accountsStore.put(transaction.from, String(transaction.nonce))
378
384
  }
379
385
 
@@ -386,8 +392,9 @@ async resolveBlock(hash) {
386
392
 
387
393
 
388
394
  pubsub.publish('block-processed', blockMessage.decoded)
389
- } catch (e) {
390
- console.log({e});
395
+
396
+ } catch (error) {
397
+ console.log({e: error});
391
398
  }
392
399
 
393
400
  }
@@ -407,7 +414,7 @@ async resolveBlock(hash) {
407
414
  // introduce peer-reputation
408
415
  // peerReputation(peerId)
409
416
  // {bandwith: {up, down}, uptime}
410
- this.participating = true
417
+ this.#participating = true
411
418
  if (!await this.staticCall(addresses.validators, 'has', [address])) await this.createTransactionFrom(address, addresses.validators, 'addValidator', [address])
412
419
  if (await this.hasTransactionToHandle() && !this.#runningEpoch) await this.#runEpoch()
413
420
 
@@ -469,7 +476,7 @@ async resolveBlock(hash) {
469
476
  block.transactions.push(transaction)
470
477
  block.fees += Number(calculateFee(transaction))
471
478
  await accountsStore.put(transaction.from, new TextEncoder().encode(String(transaction.nonce)))
472
- } catch (e) {
479
+ } catch {
473
480
  transaction = await new TransactionMessage(transaction)
474
481
  await transactionPoolStore.delete(await transaction.hash)
475
482
  }
@@ -502,9 +509,7 @@ async resolveBlock(hash) {
502
509
  address: validator,
503
510
  bw: bw.up + bw.down
504
511
  })
505
- } catch(e) {
506
-
507
- }
512
+ } catch{}
508
513
 
509
514
  } else if (peernet.selectedAccount === validator) {
510
515
  block.validators.push({
@@ -532,17 +537,17 @@ async resolveBlock(hash) {
532
537
  else block.index += 1
533
538
 
534
539
  block.previousHash = this.lastBlock?.hash || '0x0'
535
- block.timestamp = new Date().getTime()
540
+ block.timestamp = Date.now()
536
541
 
537
542
  const parts = String(block.fees).split('.')
538
543
  let decimals = 0
539
544
  if (parts[1]) {
540
545
  const potentional = parts[1].split('e')
541
- if (potentional[0] !== parts[1]) {
542
- parts[1] = potentional[0]
543
- decimals = Number(potentional[1]?.replace(/\-|\+/g, '')) + Number(potentional[0].length)
544
- } else {
546
+ if (potentional[0] === parts[1]) {
545
547
  decimals = parts[1].length
548
+ } else {
549
+ parts[1] = potentional[0]
550
+ decimals = Number(potentional[1]?.replace(/[+-]/g, '')) + Number(potentional[0].length)
546
551
  }
547
552
 
548
553
  }
@@ -562,9 +567,10 @@ async resolveBlock(hash) {
562
567
  debug(`created block: ${hash}`)
563
568
 
564
569
  peernet.publish('add-block', blockMessage.encoded)
565
- } catch (e) {
566
- console.log(e);
567
- throw Error(`invalid block ${block}`)
570
+ pubsub.publish('add-block', blockMessage.decoded)
571
+ } catch (error) {
572
+ console.log(error);
573
+ throw new Error(`invalid block ${block}`)
568
574
  }
569
575
  // data = await this.#machine.execute(to, method, params)
570
576
  // transactionStore.put(message.hash, message.encoded)
@@ -633,8 +639,8 @@ async resolveBlock(hash) {
633
639
  * @param {Array} params - array of paramters to apply to the contract method
634
640
  * @param {Number} nonce - total transaction count [optional]
635
641
  */
636
- async createTransaction(to, method, params, nonce, signature) {
637
- return this.createTransactionFrom(peernet.selectedAccount, to, method, params, nonce)
642
+ async createTransaction(to, method, parameters, nonce, signature) {
643
+ return this.createTransactionFrom(peernet.selectedAccount, to, method, parameters, nonce)
638
644
  }
639
645
 
640
646
 
@@ -694,8 +700,8 @@ async #signTransaction (transaction, wallet) {
694
700
  } else {
695
701
  let nonce = await accountsStore.get(transaction.from)
696
702
  nonce = new TextDecoder().decode(nonce)
697
- if (transaction.nonce < nonce) throw Error(`a transaction with a higher nonce already exists`)
698
- if (transaction.nonce === nonce) throw Error(`a transaction with the same nonce already exists`)
703
+ if (transaction.nonce < nonce) throw new Error(`a transaction with a higher nonce already exists`)
704
+ if (transaction.nonce === nonce) throw new Error(`a transaction with the same nonce already exists`)
699
705
  }
700
706
  return transaction
701
707
  }
@@ -710,10 +716,10 @@ async #signTransaction (transaction, wallet) {
710
716
  * @param {Array} params - array of paramters to apply to the contract method
711
717
  * @param {Number} nonce - total transaction count [optional]
712
718
  */
713
- async createTransactionFrom(from, to, method, params, nonce) {
719
+ async createTransactionFrom(from, to, method, parameters, nonce) {
714
720
  try {
715
721
 
716
- const rawTransaction = await this.createRawTransaction({from, to, nonce, method, params})
722
+ const rawTransaction = await this.createRawTransaction({from, to, nonce, method, params: parameters})
717
723
  const transaction = await this.signTransaction(rawTransaction, from)
718
724
  const message = await new TransactionMessage(transaction)
719
725
 
@@ -729,7 +735,7 @@ async #signTransaction (transaction, wallet) {
729
735
 
730
736
  setTimeout(async () => {
731
737
  pubsub.unsubscribe(`transaction.completed.${await message.hash}`, completed)
732
- }, 10000)
738
+ }, 10_000)
733
739
  }
734
740
  pubsub.subscribe(`transaction.completed.${await message.hash}`, completed)
735
741
  }
@@ -741,9 +747,9 @@ async #signTransaction (transaction, wallet) {
741
747
  peernet.publish('add-transaction', message.encoded)
742
748
  this.#addTransaction(message.encoded)
743
749
  return {hash: await message.hash, data, fee: await calculateFee(message.decoded), wait}
744
- } catch (e) {
745
- console.log(e)
746
- throw e
750
+ } catch (error) {
751
+ console.log(error)
752
+ throw error
747
753
  }
748
754
 
749
755
  }
@@ -758,20 +764,19 @@ async #signTransaction (transaction, wallet) {
758
764
  }
759
765
 
760
766
  /**
761
- *
762
- * @param {String} contract - a contract string (see plugins/deployContract)
767
+ *
768
+ * @param {String} contract
769
+ * @param {Array} parameters
770
+ * @returns
763
771
  */
764
- async deployContract(contract, params = []) {
765
- globalThis.msg = {sender: peernet.selectedAccount, call: this.call}
766
-
767
- const hash = await this.createContractAddress(creator, contract, params)
768
- console.log(hash);
772
+ async deployContract(contract, parameters = []) {
773
+ const message = await createContractMessage(peernet.selectedAccount, contract, parameters)
769
774
  try {
770
- const tx = await this.createTransactionFrom(peernet.selectedAccount, addresses.contractFactory, 'deployContract', [hash, creator, contract, constructorParameters])
771
- } catch (e) {
772
- throw e
775
+ await this.#machine.addContract(message)
776
+ } catch (error) {
777
+ throw error
773
778
  }
774
- return this.#machine.addContract(message)
779
+ return this.createTransactionFrom(peernet.selectedAccount, addresses.contractFactory, 'registerContract', [await message.hash])
775
780
  }
776
781
 
777
782
  #createMessage(sender = peernet.selectedAccount) {
@@ -784,33 +789,33 @@ console.log(hash);
784
789
  }
785
790
  }
786
791
 
787
- internalCall(sender, contract, method, params) {
792
+ internalCall(sender, contract, method, parameters) {
788
793
  globalThis.msg = this.#createMessage(sender)
789
794
 
790
- return this.#machine.execute(contract, method, params)
795
+ return this.#machine.execute(contract, method, parameters)
791
796
  }
792
797
 
793
- call(contract, method, params) {
798
+ call(contract, method, parameters) {
794
799
  globalThis.msg = this.#createMessage()
795
800
 
796
- return this.#machine.execute(contract, method, params)
801
+ return this.#machine.execute(contract, method, parameters)
797
802
  }
798
803
 
799
- staticCall(contract, method, params) {
804
+ staticCall(contract, method, parameters) {
800
805
  globalThis.msg = this.#createMessage()
801
- return this.#machine.get(contract, method, params)
806
+ return this.#machine.get(contract, method, parameters)
802
807
  }
803
808
 
804
- delegate(contract, method, params) {
809
+ delegate(contract, method, parameters) {
805
810
  globalThis.msg = this.#createMessage()
806
811
 
807
- return this.#machine.execute(contract, method, params)
812
+ return this.#machine.execute(contract, method, parameters)
808
813
  }
809
814
 
810
- staticDelegate(contract, method, params) {
815
+ staticDelegate(contract, method, parameters) {
811
816
  globalThis.msg = this.#createMessage()
812
817
 
813
- return this.#machine.get(contract, method, params)
818
+ return this.#machine.get(contract, method, parameters)
814
819
  }
815
820
 
816
821
  mint(to, amount) {
@@ -825,6 +830,19 @@ console.log(hash);
825
830
  return this.staticCall(addresses.nativeToken, 'balances')
826
831
  }
827
832
 
833
+ get contracts() {
834
+ return this.staticCall(addresses.contractFactory, 'contracts')
835
+ }
836
+ /**
837
+ *
838
+ * @param {Address} address old contract address
839
+ * @param {Address} newAddress new contract address
840
+ * @returns
841
+ */
842
+ async updateImplementation(address, newAddress) {
843
+ return this.call(addresses.contractFactory, 'updateImplementation', [address, newAddress])
844
+ }
845
+
828
846
  deleteAll() {
829
847
  return this.#machine.deleteAll()
830
848
  }
@@ -12,17 +12,24 @@ export default class Factory {
12
12
  */
13
13
  #contracts = []
14
14
 
15
+ /**
16
+ * Object => address => Array[addresses]
17
+ */
18
+ #implementations = {}
19
+
15
20
  constructor(state) {
16
21
  if (state) {
17
22
  this.#contracts = state.contracts
18
23
  this.#totalContracts = state.totalContracts
24
+ this.#implementations = state.implementations
19
25
  }
20
26
  }
21
27
 
22
28
  get state() {
23
29
  return {
24
30
  totalContracts: this.#totalContracts,
25
- contracts: this.#contracts
31
+ contracts: this.#contracts,
32
+ implementations: this.#implementations
26
33
  }
27
34
  }
28
35
 
@@ -37,23 +44,59 @@ export default class Factory {
37
44
  get totalContracts() {
38
45
  return this.#totalContracts
39
46
  }
40
-
41
- isvalid(hash, creator, contract, constructorParameters = []) {
42
- const message = new ContractMessage({
43
- creator,
44
- contract,
45
- constructorParameters
46
- })
47
- return Boolean(message.hash === hash)
47
+
48
+ get implementations() {
49
+ return {...this.#implementations}
48
50
  }
49
51
 
50
- async deployContract(contractHash, creator, contract, constructorParameters = []) {
51
- if (contract.creator !== msg.sender) throw new Error('only a contract creator can deploy a contract')
52
- if (await contractStore.has(hash)) throw new Error('duplicate contract')
53
- if (!this.isValid(contractHash, creator, contract, constructorParameters)) throw new Error('invalid contract')
52
+ /**
53
+ *
54
+ * @param {Address} address contract address to register
55
+ */
56
+ async registerContract(address) {
57
+ let isAllowed = false
58
+ isAllowed = await msg.staticCall(address, 'hasRole', [msg.sender, 'IMPLEMENTATION_MANAGER'])
59
+ if (!isAllowed) throw new Error('only the implementation manager can update')
60
+ if (this.#implementations[address]) throw new Error('already registered')
54
61
 
55
- await contractStore.put(hash, encoded)
56
62
  this.#totalContracts += 1
57
- this.#contracts.push(hash)
63
+ this.#implementations[address] = []
64
+ this.#implementations[address].push(address)
65
+ this.#contracts.push(address)
66
+ }
67
+
68
+ /**
69
+ * updates the current implementation to a new address
70
+ *
71
+ * @param {Address} address the current contract address
72
+ * @param {Address} newAddress the new contract address
73
+ */
74
+ async updateImplementation(address, newAddress) {
75
+ let isAllowed = false
76
+ isAllowed = await msg.staticCall(address, 'hasRole', [msg.sender, 'IMPLEMENTATION_MANAGER'])
77
+ if (!isAllowed) throw new Error('only the implementation manager can update')
78
+ if (!this.#implementations[address]) throw new Error(`register ${address} before updating to ${newAddress}`)
79
+
80
+ this.#implementations[address].push(newAddress)
81
+ }
82
+
83
+ /**
84
+ *
85
+ * @param {Address} address the original contract address
86
+ * @returns {Address} all implementations of the original contract
87
+ */
88
+ getImplementations(address) {
89
+ return this.#implementations[address]
90
+ }
91
+
92
+ /**
93
+ *
94
+ * @param {Address} address the original contract address
95
+ * @param {Number} index the index of the implmentation item or undefined (returns the latest implementation when undefined)
96
+ * @returns {Address} the latest/selected implementation of the original contract
97
+ */
98
+ getImplementation(address, index) {
99
+ index = index || this.#implementations[address].length - 1
100
+ return this.#implementations[address][index]
58
101
  }
59
102
  }
@@ -29,9 +29,7 @@ export default class NameService {
29
29
  return {...this.#registry}
30
30
  }
31
31
 
32
- get state() {
33
-
34
- }
32
+ get state() {}
35
33
 
36
34
  // TODO: control with contract
37
35
  constructor(factoryAddress, currency, validatorAddress, price, state) {
@@ -82,8 +80,8 @@ export default class NameService {
82
80
  if (balance < this.#price) throw new Error('price exceeds balance')
83
81
  try {
84
82
  await msg.call(this.#currency, 'transfer', [msg.sender, this.#owner, this.#price])
85
- } catch (e) {
86
- throw e
83
+ } catch (error) {
84
+ throw error
87
85
  }
88
86
 
89
87
  this.#registry[name] = {
@@ -1,7 +1,7 @@
1
- import Token from './../standards/token.js'
1
+ import Token from '../standards/token.js'
2
2
 
3
3
  export default class ArtOnline extends Token {
4
4
  constructor(state) {
5
5
  super('ArtOnline', 'ART', 18, state)
6
6
  }
7
- }
7
+ }
@@ -1,4 +1,4 @@
1
- import Token from './../standards/token.js'
1
+ import Token from '../standards/token.js'
2
2
 
3
3
  export default class Power extends Token {
4
4
  constructor(state) {
@@ -1,4 +1,4 @@
1
- import Proxy from './../../standards/Proxy.js'
1
+ import Proxy from '../../standards/proxy.js'
2
2
 
3
3
  export default class FactoryProxy extends Proxy {
4
4
  /**
@@ -1,4 +1,4 @@
1
- import Proxy from './../../standards/Proxy.js'
1
+ import Proxy from '../../standards/proxy.js'
2
2
 
3
3
  export default class NameServiceProxy extends Proxy {
4
4
  /**
@@ -1,4 +1,4 @@
1
- import Proxy from './../../standards/Proxy.js'
1
+ import Proxy from '../../standards/proxy.js'
2
2
 
3
3
  export default class NativeTokenProxy extends Proxy {
4
4
  /**
@@ -1,4 +1,4 @@
1
- import Proxy from './../../standards/Proxy.js'
1
+ import Proxy from '../../standards/proxy.js'
2
2
 
3
3
  export default class ValidatorsProxy extends Proxy {
4
4
  /**
@@ -1,4 +1,4 @@
1
- import Proxy from './../../standards/Proxy.js'
1
+ import Proxy from '../../standards/proxy.js'
2
2
 
3
3
  export default class VotingProxy extends Proxy {
4
4
  /**
@@ -1,4 +1,4 @@
1
- import ProxyManager from './../standards/proxyManager.js'
1
+ import ProxyManager from '../standards/proxy-manager.js'
2
2
 
3
3
  export default class ArtOnlineProxyManager extends ProxyManager {
4
4
  constructor(state) {