@leofcoin/chain 1.3.3 → 1.3.4
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/dist/browser/workers/machine-worker.js +0 -13
- package/dist/chain.js +136 -125
- package/dist/contracts/factory.js +1 -1
- package/dist/contracts/{nameService.js → name-service.js} +1 -1
- package/dist/contracts/native-token.js +1 -0
- package/dist/contracts/validators.js +1 -1
- package/dist/module/chain.js +133 -122
- package/dist/module/workers/machine-worker.js +0 -6
- package/dist/standards/token.js +1 -1
- package/dist/workers/machine-worker.js +1 -1
- package/package.json +20 -2
- package/rollup.config.js +4 -4
- package/src/chain.js +103 -97
- package/src/contracts/factory.js +58 -15
- package/src/contracts/{nameService.js → name-service.js} +3 -5
- package/src/contracts/{nativeToken.js → native-token.js} +2 -2
- package/src/contracts/{powerToken.js → power-token.js} +1 -1
- package/src/contracts/proxies/{factoryProxy.js → factory-proxy.js} +1 -1
- package/src/contracts/proxies/{nameServiceProxy.js → name-service-proxy.js} +1 -1
- package/src/contracts/proxies/{nativeTokenProxy.js → native-token-proxy.js} +1 -1
- package/src/contracts/proxies/{validatorsProxy.js → validators-proxy.js} +1 -1
- package/src/contracts/proxies/{votingProxy.js → voting-proxy.js} +1 -1
- package/src/contracts/{proxyManager.js → proxy-manager.js} +1 -1
- package/src/contracts/validators.js +35 -25
- package/src/fee/config.js +1 -1
- package/src/machine.js +30 -25
- package/src/standards/{proxyManager.js → proxy-manager.js} +0 -0
- package/src/standards/{Proxy.js → proxy.js} +4 -8
- package/src/standards/roles.js +7 -5
- package/src/standards/voting.js +1 -0
- package/src/transactions/transaction.js +1 -3
- package/src/transactions/validator.js +1 -1
- package/src/typer.js +1 -1
- package/dist/865.browser.js +0 -10
- package/dist/chain.browser.js +0 -59745
- package/dist/contracts/nativeToken.js +0 -1
- package/dist/generate-account.browser.js +0 -50
- package/dist/messages.browser.js +0 -328
- package/dist/multi-wallet.browser.js +0 -15
- package/dist/node.browser.js +0 -9858
- package/dist/pako.browser.js +0 -6900
- package/dist/peernet-swarm.browser.js +0 -839
- package/dist/storage.browser.js +0 -3724
- package/dist/wrtc.browser.js +0 -28
- 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 =
|
|
62
|
+
const start = Date.now()
|
|
61
63
|
try {
|
|
62
64
|
await this.#createBlock()
|
|
63
|
-
} catch (
|
|
64
|
-
console.error(
|
|
65
|
+
} catch (error) {
|
|
66
|
+
console.error(error);
|
|
65
67
|
}
|
|
66
68
|
|
|
67
|
-
const end =
|
|
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
|
-
},
|
|
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
|
-
|
|
119
|
-
return this.#
|
|
120
|
+
getLatestBlock() {
|
|
121
|
+
return this.#getLatestBlock()
|
|
120
122
|
}
|
|
121
123
|
|
|
122
|
-
async #
|
|
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
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
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
|
|
156
|
-
this
|
|
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
|
|
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.#
|
|
180
|
+
const latestBlock = await this.#getLatestBlock()
|
|
181
|
+
await this.#syncChain(latestBlock)
|
|
178
182
|
}
|
|
179
|
-
} catch (
|
|
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 #
|
|
220
|
-
|
|
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
|
-
|
|
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 =
|
|
230
|
+
const start = this.#blocks.length - blocksSynced
|
|
236
231
|
await this.#loadBlocks(this.blocks.slice(start))
|
|
237
|
-
this.#
|
|
238
|
-
|
|
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
|
|
252
|
-
} catch
|
|
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
|
|
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
|
|
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 (
|
|
300
|
-
console.log(
|
|
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
|
|
333
|
-
} catch (
|
|
334
|
-
pubsub.publish(`transaction.completed.${hash}`, {status: 'fail', hash, error:
|
|
335
|
-
throw
|
|
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
|
-
|
|
390
|
-
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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]
|
|
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
|
-
|
|
566
|
-
|
|
567
|
-
|
|
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,
|
|
637
|
-
return this.createTransactionFrom(peernet.selectedAccount, to, method,
|
|
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,
|
|
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
|
-
},
|
|
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 (
|
|
745
|
-
console.log(
|
|
746
|
-
throw
|
|
750
|
+
} catch (error) {
|
|
751
|
+
console.log(error)
|
|
752
|
+
throw error
|
|
747
753
|
}
|
|
748
754
|
|
|
749
755
|
}
|
|
@@ -761,15 +767,15 @@ async #signTransaction (transaction, wallet) {
|
|
|
761
767
|
*
|
|
762
768
|
* @param {String} contract - a contract string (see plugins/deployContract)
|
|
763
769
|
*/
|
|
764
|
-
async deployContract(contract,
|
|
770
|
+
async deployContract(contract, parameters = []) {
|
|
765
771
|
globalThis.msg = {sender: peernet.selectedAccount, call: this.call}
|
|
766
772
|
|
|
767
|
-
const hash = await this.createContractAddress(creator, contract,
|
|
773
|
+
const hash = await this.createContractAddress(creator, contract, parameters)
|
|
768
774
|
console.log(hash);
|
|
769
775
|
try {
|
|
770
776
|
const tx = await this.createTransactionFrom(peernet.selectedAccount, addresses.contractFactory, 'deployContract', [hash, creator, contract, constructorParameters])
|
|
771
|
-
} catch (
|
|
772
|
-
throw
|
|
777
|
+
} catch (error) {
|
|
778
|
+
throw error
|
|
773
779
|
}
|
|
774
780
|
return this.#machine.addContract(message)
|
|
775
781
|
}
|
|
@@ -784,33 +790,33 @@ console.log(hash);
|
|
|
784
790
|
}
|
|
785
791
|
}
|
|
786
792
|
|
|
787
|
-
internalCall(sender, contract, method,
|
|
793
|
+
internalCall(sender, contract, method, parameters) {
|
|
788
794
|
globalThis.msg = this.#createMessage(sender)
|
|
789
795
|
|
|
790
|
-
return this.#machine.execute(contract, method,
|
|
796
|
+
return this.#machine.execute(contract, method, parameters)
|
|
791
797
|
}
|
|
792
798
|
|
|
793
|
-
call(contract, method,
|
|
799
|
+
call(contract, method, parameters) {
|
|
794
800
|
globalThis.msg = this.#createMessage()
|
|
795
801
|
|
|
796
|
-
return this.#machine.execute(contract, method,
|
|
802
|
+
return this.#machine.execute(contract, method, parameters)
|
|
797
803
|
}
|
|
798
804
|
|
|
799
|
-
staticCall(contract, method,
|
|
805
|
+
staticCall(contract, method, parameters) {
|
|
800
806
|
globalThis.msg = this.#createMessage()
|
|
801
|
-
return this.#machine.get(contract, method,
|
|
807
|
+
return this.#machine.get(contract, method, parameters)
|
|
802
808
|
}
|
|
803
809
|
|
|
804
|
-
delegate(contract, method,
|
|
810
|
+
delegate(contract, method, parameters) {
|
|
805
811
|
globalThis.msg = this.#createMessage()
|
|
806
812
|
|
|
807
|
-
return this.#machine.execute(contract, method,
|
|
813
|
+
return this.#machine.execute(contract, method, parameters)
|
|
808
814
|
}
|
|
809
815
|
|
|
810
|
-
staticDelegate(contract, method,
|
|
816
|
+
staticDelegate(contract, method, parameters) {
|
|
811
817
|
globalThis.msg = this.#createMessage()
|
|
812
818
|
|
|
813
|
-
return this.#machine.get(contract, method,
|
|
819
|
+
return this.#machine.get(contract, method, parameters)
|
|
814
820
|
}
|
|
815
821
|
|
|
816
822
|
mint(to, amount) {
|
package/src/contracts/factory.js
CHANGED
|
@@ -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
|
-
|
|
42
|
-
|
|
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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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.#
|
|
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 (
|
|
86
|
-
throw
|
|
83
|
+
} catch (error) {
|
|
84
|
+
throw error
|
|
87
85
|
}
|
|
88
86
|
|
|
89
87
|
this.#registry[name] = {
|