@leofcoin/chain 1.4.4 → 1.4.6
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/package.json +1 -1
- package/src/chain.js +5 -5
- package/src/contract.js +3 -2
- package/src/machine.js +2 -2
- package/src/transaction.js +12 -12
- package/test/chain.js +1 -1
- package/src/contracts/factory.js +0 -52
- package/src/contracts/name-service.js +0 -106
- package/src/contracts/native-token.js +0 -7
- package/src/contracts/power-token.js +0 -7
- package/src/contracts/validators.js +0 -129
- package/src/standards/roles.js +0 -65
- package/src/standards/token.js +0 -137
- package/src/standards/voting.js +0 -1
package/package.json
CHANGED
package/src/chain.js
CHANGED
|
@@ -205,7 +205,7 @@ export default class Chain extends Contract {
|
|
|
205
205
|
for (const value of promises) {
|
|
206
206
|
if (value.index > latest.index) {
|
|
207
207
|
latest.index = value.index;
|
|
208
|
-
latest.hash = value.hash;
|
|
208
|
+
latest.hash = await value.hash();
|
|
209
209
|
}
|
|
210
210
|
}
|
|
211
211
|
|
|
@@ -391,7 +391,7 @@ async resolveBlock(hash) {
|
|
|
391
391
|
// console.log(block);
|
|
392
392
|
const blockMessage = await new BlockMessage(new Uint8Array(Object.values(block)))
|
|
393
393
|
await Promise.all(blockMessage.decoded.transactions
|
|
394
|
-
.map(async transaction => transactionPoolStore.delete(
|
|
394
|
+
.map(async transaction => transactionPoolStore.delete(transaction.hash)))
|
|
395
395
|
const hash = await blockMessage.hash()
|
|
396
396
|
|
|
397
397
|
await blockStore.put(hash, blockMessage.encoded)
|
|
@@ -557,7 +557,7 @@ async resolveBlock(hash) {
|
|
|
557
557
|
|
|
558
558
|
try {
|
|
559
559
|
await Promise.all(block.transactions
|
|
560
|
-
.map(async transaction => transactionPoolStore.delete(
|
|
560
|
+
.map(async transaction => transactionPoolStore.delete(transaction.hash)))
|
|
561
561
|
|
|
562
562
|
|
|
563
563
|
let blockMessage = await new BlockMessage(block)
|
|
@@ -581,9 +581,9 @@ async resolveBlock(hash) {
|
|
|
581
581
|
|
|
582
582
|
|
|
583
583
|
async #addTransaction(transaction) {
|
|
584
|
-
try {
|
|
585
|
-
const hash = await transaction.hash()
|
|
584
|
+
try {
|
|
586
585
|
transaction = await new TransactionMessage(transaction)
|
|
586
|
+
const hash = await transaction.hash()
|
|
587
587
|
const has = await transactionPoolStore.has(hash)
|
|
588
588
|
if (!has) await transactionPoolStore.put(hash, transaction.encoded)
|
|
589
589
|
if (this.#participating && !this.#runningEpoch) this.#runEpoch()
|
package/src/contract.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Transaction from "./transaction.js";
|
|
2
2
|
import { createContractMessage } from '@leofcoin/lib'
|
|
3
|
+
import addresses from "@leofcoin/addresses"
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* @extends {Transaction}
|
|
@@ -41,11 +42,11 @@ export default class Contract extends Transaction {
|
|
|
41
42
|
async deployContract(contract, constructorParameters = []) {
|
|
42
43
|
const message = await createContractMessage(peernet.selectedAccount, contract, constructorParameters)
|
|
43
44
|
try {
|
|
44
|
-
await contractStore.put(await message.hash, message.encoded)
|
|
45
|
+
await contractStore.put(await message.hash(), message.encoded)
|
|
45
46
|
} catch (error) {
|
|
46
47
|
throw error
|
|
47
48
|
}
|
|
48
|
-
return this.createTransactionFrom(peernet.selectedAccount, addresses.contractFactory, 'registerContract', [await message.hash])
|
|
49
|
+
return this.createTransactionFrom(peernet.selectedAccount, addresses.contractFactory, 'registerContract', [await message.hash()])
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
}
|
package/src/machine.js
CHANGED
|
@@ -50,7 +50,7 @@ export default class Machine {
|
|
|
50
50
|
break
|
|
51
51
|
}
|
|
52
52
|
case 'response': {
|
|
53
|
-
pubsub.publish(data.id, data.value)
|
|
53
|
+
pubsub.publish(data.id, data.value || true)
|
|
54
54
|
break
|
|
55
55
|
}
|
|
56
56
|
}
|
|
@@ -140,7 +140,7 @@ export default class Machine {
|
|
|
140
140
|
}
|
|
141
141
|
return new Promise((resolve, reject) => {
|
|
142
142
|
const id = randombytes(20).toString('hex')
|
|
143
|
-
const onmessage = message => {
|
|
143
|
+
const onmessage = message => {
|
|
144
144
|
pubsub.unsubscribe(id, onmessage)
|
|
145
145
|
if (message?.error) reject(message.error)
|
|
146
146
|
else resolve(message)
|
package/src/transaction.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Protocol from "./protocol.js"
|
|
2
|
-
import
|
|
2
|
+
import MultiWallet from '@leofcoin/multi-wallet'
|
|
3
3
|
import {CodecHash} from '@leofcoin/codec-format-interface'
|
|
4
4
|
import bs32 from '@vandeurenglenn/base32'
|
|
5
5
|
import { TransactionMessage, BlockMessage } from "@leofcoin/messages"
|
|
@@ -26,7 +26,7 @@ export default class Transaction extends Protocol {
|
|
|
26
26
|
.map(async tx => {
|
|
27
27
|
tx = await new TransactionMessage(tx)
|
|
28
28
|
size += tx.encoded.length
|
|
29
|
-
if (!formatBytes(size).includes('MB') || formatBytes(size).includes('MB') && Number(formatBytes(size).split(' MB')[0]) <= 0.75) _transactions.push({...tx.decoded, hash: await tx.hash})
|
|
29
|
+
if (!formatBytes(size).includes('MB') || formatBytes(size).includes('MB') && Number(formatBytes(size).split(' MB')[0]) <= 0.75) _transactions.push({...tx.decoded, hash: await tx.hash()})
|
|
30
30
|
else resolve(_transactions)
|
|
31
31
|
}))
|
|
32
32
|
|
|
@@ -52,7 +52,7 @@ export default class Transaction extends Protocol {
|
|
|
52
52
|
*/
|
|
53
53
|
async promiseTransactionsContent(transactions) {
|
|
54
54
|
transactions = await Promise.all(transactions.map(tx => new Promise(async (resolve, reject) => {
|
|
55
|
-
resolve({ ...tx.decoded, hash: await tx.hash })
|
|
55
|
+
resolve({ ...tx.decoded, hash: await tx.hash() })
|
|
56
56
|
})))
|
|
57
57
|
|
|
58
58
|
return transactions
|
|
@@ -157,7 +157,7 @@ export default class Transaction extends Protocol {
|
|
|
157
157
|
let identity = await walletStore.get('identity')
|
|
158
158
|
identity = JSON.parse(new TextDecoder().decode(identity))
|
|
159
159
|
const wallet = new MultiWallet(peernet.network)
|
|
160
|
-
wallet.recover(identity.mnemonic)
|
|
160
|
+
await wallet.recover(identity.mnemonic)
|
|
161
161
|
const account = wallet.account(0).external(0)
|
|
162
162
|
transaction.signature = await this.#signTransaction(transaction, account)
|
|
163
163
|
transaction.signature = bs32.encode(transaction.signature)
|
|
@@ -209,23 +209,23 @@ export default class Transaction extends Protocol {
|
|
|
209
209
|
|
|
210
210
|
let data
|
|
211
211
|
const wait = () => new Promise(async (resolve, reject) => {
|
|
212
|
-
if (pubsub.subscribers[`transaction.completed.${await message.hash}`]) {
|
|
213
|
-
const result = pubsub.subscribers[`transaction.completed.${await message.hash}`].value
|
|
214
|
-
result.status === 'fulfilled' ? resolve(
|
|
212
|
+
if (pubsub.subscribers[`transaction.completed.${await message.hash()}`]) {
|
|
213
|
+
const result = pubsub.subscribers[`transaction.completed.${await message.hash()}`].value
|
|
214
|
+
result.status === 'fulfilled' ? resolve(result.hash) : reject({hash: result.hash, error: result.error})
|
|
215
215
|
} else {
|
|
216
216
|
const completed = async result => {
|
|
217
|
-
result.status === 'fulfilled' ? resolve(
|
|
217
|
+
result.status === 'fulfilled' ? resolve(result.hash) : reject({hash: result.hash, error: result.error})
|
|
218
218
|
|
|
219
219
|
setTimeout(async () => {
|
|
220
|
-
pubsub.unsubscribe(`transaction.completed.${await message.hash}`, completed)
|
|
220
|
+
pubsub.unsubscribe(`transaction.completed.${await message.hash()}`, completed)
|
|
221
221
|
}, 10_000)
|
|
222
222
|
}
|
|
223
|
-
pubsub.subscribe(`transaction.completed.${await message.hash}`, completed)
|
|
223
|
+
pubsub.subscribe(`transaction.completed.${await message.hash()}`, completed)
|
|
224
224
|
}
|
|
225
225
|
})
|
|
226
|
-
await transactionPoolStore.put(await message.hash, message.encoded)
|
|
226
|
+
await transactionPoolStore.put(await message.hash(), message.encoded)
|
|
227
227
|
peernet.publish('add-transaction', message.encoded)
|
|
228
|
-
return {hash: await message.hash, data, fee: await calculateFee(message.decoded), wait, message}
|
|
228
|
+
return {hash: await message.hash(), data, fee: await calculateFee(message.decoded), wait, message}
|
|
229
229
|
} catch (error) {
|
|
230
230
|
console.log(error)
|
|
231
231
|
throw error
|
package/test/chain.js
CHANGED
|
@@ -67,7 +67,7 @@ const job = async () => {
|
|
|
67
67
|
|
|
68
68
|
console.log(`${(new Date().getTime() - start) / 1000} s`);
|
|
69
69
|
|
|
70
|
-
balances = await chain.balances
|
|
70
|
+
let balances = await chain.balances
|
|
71
71
|
console.log(`balance for ${Object.keys(balances)[0]}:${chain.utils.formatUnits(balances[Object.keys(balances)[0]]).toString()}`);
|
|
72
72
|
console.log(`balance for ${Object.keys(balances)[1]}:${chain.utils.formatUnits(balances[Object.keys(balances)[1]]).toString()}`);
|
|
73
73
|
// return
|
package/src/contracts/factory.js
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
export default class Factory {
|
|
2
|
-
/**
|
|
3
|
-
* string
|
|
4
|
-
*/
|
|
5
|
-
#name = 'ArtOnlineContractFactory'
|
|
6
|
-
/**
|
|
7
|
-
* uint
|
|
8
|
-
*/
|
|
9
|
-
#totalContracts = 0
|
|
10
|
-
/**
|
|
11
|
-
* Array => string
|
|
12
|
-
*/
|
|
13
|
-
#contracts = []
|
|
14
|
-
|
|
15
|
-
constructor(state) {
|
|
16
|
-
if (state) {
|
|
17
|
-
this.#contracts = state.contracts
|
|
18
|
-
this.#totalContracts = state.totalContracts
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
get state() {
|
|
23
|
-
return {
|
|
24
|
-
totalContracts: this.#totalContracts,
|
|
25
|
-
contracts: this.#contracts
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
get name() {
|
|
30
|
-
return this.#name
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
get contracts() {
|
|
34
|
-
return [...this.#contracts]
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
get totalContracts() {
|
|
38
|
-
return this.#totalContracts
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
*
|
|
43
|
-
* @param {Address} address contract address to register
|
|
44
|
-
*/
|
|
45
|
-
async registerContract(address) {
|
|
46
|
-
await msg.staticCall(address, 'hasRole', [msg.sender, 'OWNER'])
|
|
47
|
-
if (this.#contracts.includes(address)) throw new Error('already registered')
|
|
48
|
-
|
|
49
|
-
this.#totalContracts += 1
|
|
50
|
-
this.#contracts.push(address)
|
|
51
|
-
}
|
|
52
|
-
}
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
export default class NameService {
|
|
2
|
-
/**
|
|
3
|
-
* string
|
|
4
|
-
*/
|
|
5
|
-
#name = 'ArtOnlineNameService'
|
|
6
|
-
/**
|
|
7
|
-
* string
|
|
8
|
-
*/
|
|
9
|
-
#owner
|
|
10
|
-
/**
|
|
11
|
-
* number
|
|
12
|
-
*/
|
|
13
|
-
#price = 0
|
|
14
|
-
/**
|
|
15
|
-
* Object => string
|
|
16
|
-
*/
|
|
17
|
-
#registry = {}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* => string
|
|
21
|
-
*/
|
|
22
|
-
#currency
|
|
23
|
-
|
|
24
|
-
get name() {
|
|
25
|
-
return this.#name
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
get registry() {
|
|
29
|
-
return {...this.#registry}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
get state() {}
|
|
33
|
-
|
|
34
|
-
// TODO: control with contract
|
|
35
|
-
constructor(factoryAddress, currency, validatorAddress, price, state) {
|
|
36
|
-
if (state) {
|
|
37
|
-
this.#owner = state.owner
|
|
38
|
-
this.#registry = state.registry
|
|
39
|
-
this.#currency = state.currency
|
|
40
|
-
this.#price = state.price
|
|
41
|
-
} else {
|
|
42
|
-
this.#owner = msg.sender
|
|
43
|
-
this.#price = price
|
|
44
|
-
this.#registry['ArtOnlineContractFactory'] = {
|
|
45
|
-
owner: msg.sender,
|
|
46
|
-
address: factoryAddress
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
this.#registry['ArtOnlineToken'] = {
|
|
50
|
-
owner: msg.sender,
|
|
51
|
-
address: currency
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
this.#registry['ArtOnlineValidators'] = {
|
|
55
|
-
owner: msg.sender,
|
|
56
|
-
address: validatorAddress
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
this.#currency = currency
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
changeOwner(owner) {
|
|
64
|
-
if (msg.sender !== this.#owner) throw new Error('no owner')
|
|
65
|
-
this.#owner = owner
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
changePrice(price) {
|
|
69
|
-
if (msg.sender !== this.#owner) throw new Error('no owner')
|
|
70
|
-
this.#price = price
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
changeCurrency(currency) {
|
|
74
|
-
if (msg.sender !== this.#owner) throw new Error('no owner')
|
|
75
|
-
this.#currency = currency
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
async purchaseName(name, address) {
|
|
79
|
-
const balance = await msg.call(this.#currency, 'balanceOf', [msg.sender])
|
|
80
|
-
if (balance < this.#price) throw new Error('price exceeds balance')
|
|
81
|
-
try {
|
|
82
|
-
await msg.call(this.#currency, 'transfer', [msg.sender, this.#owner, this.#price])
|
|
83
|
-
} catch (error) {
|
|
84
|
-
throw error
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
this.#registry[name] = {
|
|
88
|
-
owner: msg.sender,
|
|
89
|
-
address
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
lookup(name) {
|
|
94
|
-
return this.#registry[name]
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
transferOwnership(name, to) {
|
|
98
|
-
if (msg.sender !== this.#registry.owner) throw new Error('not a owner')
|
|
99
|
-
this.#registry[name].owner = to
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
changeAddress(name, address) {
|
|
103
|
-
if (msg.sender !== this.#registry.owner) throw new Error('not a owner')
|
|
104
|
-
this.#registry[name].address = address
|
|
105
|
-
}
|
|
106
|
-
}
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import Roles from './../standards/roles'
|
|
2
|
-
|
|
3
|
-
export default class Validators extends Roles {
|
|
4
|
-
/**
|
|
5
|
-
* string
|
|
6
|
-
*/
|
|
7
|
-
#name = 'ArtOnlineValidators'
|
|
8
|
-
/**
|
|
9
|
-
* uint
|
|
10
|
-
*/
|
|
11
|
-
#totalValidators = 0
|
|
12
|
-
|
|
13
|
-
#activeValidators = 0
|
|
14
|
-
/**
|
|
15
|
-
* Object => string(address) => Object
|
|
16
|
-
*/
|
|
17
|
-
#validators = {}
|
|
18
|
-
|
|
19
|
-
#currency
|
|
20
|
-
|
|
21
|
-
#minimumBalance
|
|
22
|
-
|
|
23
|
-
get state() {
|
|
24
|
-
return {
|
|
25
|
-
...super.state,
|
|
26
|
-
minimumBalance: this.#minimumBalance,
|
|
27
|
-
currency: this.#currency,
|
|
28
|
-
totalValidators: this.#totalValidators,
|
|
29
|
-
activeValidators: this.#activeValidators,
|
|
30
|
-
validators: this.#validators
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
constructor(tokenAddress, state) {
|
|
35
|
-
super(state?.roles)
|
|
36
|
-
if (state) {
|
|
37
|
-
this.#minimumBalance = state.minimumBalance
|
|
38
|
-
this.#currency = state.currency
|
|
39
|
-
|
|
40
|
-
this.#totalValidators = state.totalValidators
|
|
41
|
-
this.#activeValidators = state.activeValidators
|
|
42
|
-
this.#validators = state.validators
|
|
43
|
-
} else {
|
|
44
|
-
this.#minimumBalance = 50_000
|
|
45
|
-
this.#currency = tokenAddress
|
|
46
|
-
|
|
47
|
-
this.#totalValidators += 1
|
|
48
|
-
this.#activeValidators += 1
|
|
49
|
-
this.#validators[msg.sender] = {
|
|
50
|
-
firstSeen: Date.now(),
|
|
51
|
-
lastSeen: Date.now(),
|
|
52
|
-
active: true
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
get name() {
|
|
59
|
-
return this.#name
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
get currency() {
|
|
63
|
-
return this.#currency
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
get validators() {
|
|
67
|
-
return {...this.#validators}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
get totalValidators() {
|
|
71
|
-
return this.#totalValidators
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
get minimumBalance() {
|
|
75
|
-
return this.#minimumBalance
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
changeCurrency(currency) {
|
|
79
|
-
if (!this.hasRole(msg.sender, 'OWNER')) throw new Error('not an owner')
|
|
80
|
-
this.#currency = currency
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
has(validator) {
|
|
84
|
-
return Boolean(this.#validators[validator] !== undefined)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
#isAllowed(address) {
|
|
88
|
-
if (msg.sender !== address && !this.hasRole(msg.sender, 'OWNER')) throw new Error('sender is not the validator or owner')
|
|
89
|
-
return true
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
async addValidator(validator) {
|
|
93
|
-
this.#isAllowed(validator)
|
|
94
|
-
if (this.has(validator)) throw new Error('already a validator')
|
|
95
|
-
|
|
96
|
-
const balance = await msg.staticCall(this.currency, 'balanceOf', [validator])
|
|
97
|
-
|
|
98
|
-
if (balance < this.minimumBalance) throw new Error(`balance to low! got: ${balance} need: ${this.#minimumBalance}`)
|
|
99
|
-
|
|
100
|
-
this.#totalValidators += 1
|
|
101
|
-
this.#activeValidators += 1
|
|
102
|
-
this.#validators[validator] = {
|
|
103
|
-
firstSeen: Date.now(),
|
|
104
|
-
lastSeen: Date.now(),
|
|
105
|
-
active: true
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
removeValidator(validator) {
|
|
110
|
-
this.#isAllowed(validator)
|
|
111
|
-
if (!this.has(validator)) throw new Error('validator not found')
|
|
112
|
-
|
|
113
|
-
this.#totalValidators -= 1
|
|
114
|
-
if (this.#validators[validator].active) this.#activeValidators -= 1
|
|
115
|
-
delete this.#validators[validator]
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
async updateValidator(validator, active) {
|
|
119
|
-
this.#isAllowed(validator)
|
|
120
|
-
if (!this.has(validator)) throw new Error('validator not found')
|
|
121
|
-
const balance = await msg.staticCall(this.currency, 'balanceOf', [validator])
|
|
122
|
-
if (balance < this.minimumBalance && active) throw new Error(`balance to low! got: ${balance} need: ${this.#minimumBalance}`)
|
|
123
|
-
if (this.#validators[validator].active === active) throw new Error(`already ${active ? 'activated' : 'deactivated'}`)
|
|
124
|
-
if (active) this.#activeValidators += 1
|
|
125
|
-
else this.#activeValidators -= 1
|
|
126
|
-
/** minimum balance always needs to be met */
|
|
127
|
-
this.#validators[validator].active = active
|
|
128
|
-
}
|
|
129
|
-
}
|
package/src/standards/roles.js
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
export default class Roles {
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Object => Array
|
|
5
|
-
*/
|
|
6
|
-
#roles = {
|
|
7
|
-
'OWNER': [],
|
|
8
|
-
'MINT': [],
|
|
9
|
-
'BURN': []
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
constructor(roles) {
|
|
13
|
-
// allow devs to set their own roles but always keep the default ones included
|
|
14
|
-
// also allows roles to be loaded from the stateStore
|
|
15
|
-
// carefull when including the roles make sure to add the owner
|
|
16
|
-
// because no roles are granted by default when using custom roles
|
|
17
|
-
if (roles) {
|
|
18
|
-
if (roles instanceof Object) {
|
|
19
|
-
this.#roles = {...roles, ...this.#roles}
|
|
20
|
-
} else {
|
|
21
|
-
throw new TypeError(`expected roles to be an object`)
|
|
22
|
-
}
|
|
23
|
-
} else {
|
|
24
|
-
// no roles given so fallback to default to the msg sender
|
|
25
|
-
this.#grantRole(msg.sender, 'OWNER')
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
get state() {
|
|
30
|
-
return { roles: this.roles }
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
get roles() {
|
|
34
|
-
return {...this.#roles}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
hasRole(address, role) {
|
|
38
|
-
return this.#roles[role] ? this.#roles[role].includes(address) : false
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
#grantRole(address, role) {
|
|
42
|
-
if (this.hasRole(address, role)) throw new Error(`${role} role already granted for ${address}`)
|
|
43
|
-
|
|
44
|
-
this.#roles[role].push(address)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
#revokeRole(address, role) {
|
|
48
|
-
if (!this.hasRole(address, role)) throw new Error(`${role} role already revoked for ${address}`)
|
|
49
|
-
if (role === 'OWNER' && this.#roles[role].length === 1) throw new Error(`atleast one owner is needed!`)
|
|
50
|
-
|
|
51
|
-
this.#roles[role].splice(this.#roles[role].indexOf(address))
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
grantRole(address, role) {
|
|
55
|
-
if (!this.hasRole(address, 'OWNER')) throw new Error('Not allowed')
|
|
56
|
-
|
|
57
|
-
this.#grantRole(address, role)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
revokeRole(address, role) {
|
|
61
|
-
if (!this.hasRole(address, 'OWNER')) throw new Error('Not allowed')
|
|
62
|
-
|
|
63
|
-
this.#revokeRole(address, role)
|
|
64
|
-
}
|
|
65
|
-
}
|
package/src/standards/token.js
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import Roles from './roles.js'
|
|
2
|
-
|
|
3
|
-
export default class Token extends Roles {
|
|
4
|
-
/**
|
|
5
|
-
* string
|
|
6
|
-
*/
|
|
7
|
-
#name
|
|
8
|
-
/**
|
|
9
|
-
* String
|
|
10
|
-
*/
|
|
11
|
-
#symbol
|
|
12
|
-
/**
|
|
13
|
-
* uint
|
|
14
|
-
*/
|
|
15
|
-
#holders = 0
|
|
16
|
-
/**
|
|
17
|
-
* Object => Object => uint
|
|
18
|
-
*/
|
|
19
|
-
#balances = {}
|
|
20
|
-
/**
|
|
21
|
-
* Object => Object => uint
|
|
22
|
-
*/
|
|
23
|
-
#approvals = {}
|
|
24
|
-
|
|
25
|
-
#decimals = 18
|
|
26
|
-
|
|
27
|
-
#totalSupply = BigNumber.from(0)
|
|
28
|
-
|
|
29
|
-
// this.#privateField2 = 1
|
|
30
|
-
constructor(name, symbol, decimals = 18, state) {
|
|
31
|
-
if (!name) throw new Error(`name undefined`)
|
|
32
|
-
if (!symbol) throw new Error(`symbol undefined`)
|
|
33
|
-
|
|
34
|
-
super(state?.roles)
|
|
35
|
-
|
|
36
|
-
this.#name = name
|
|
37
|
-
this.#symbol = symbol
|
|
38
|
-
this.#decimals = decimals
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// enables snapshotting
|
|
42
|
-
// needs dev attention so nothing breaks after snapshot happens
|
|
43
|
-
// iow everything that is not static needs to be included in the stateObject
|
|
44
|
-
/**
|
|
45
|
-
* @return {Object} {holders, balances, ...}
|
|
46
|
-
*/
|
|
47
|
-
get state() {
|
|
48
|
-
return {
|
|
49
|
-
...super.state,
|
|
50
|
-
holders: this.holders,
|
|
51
|
-
balances: this.balances,
|
|
52
|
-
approvals: { ...this.#approvals },
|
|
53
|
-
totalSupply: this.totalSupply
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
get totalSupply() {
|
|
58
|
-
return this.#totalSupply
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
get name() {
|
|
62
|
-
return this.#name
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
get symbol() {
|
|
66
|
-
return this.#symbol
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
get holders() {
|
|
70
|
-
return this.#holders
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
get balances() {
|
|
74
|
-
return {...this.#balances}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
mint(to, amount) {
|
|
78
|
-
if (!this.hasRole(msg.sender, 'MINT')) throw new Error('not allowed')
|
|
79
|
-
|
|
80
|
-
this.#totalSupply = this.#totalSupply.add(amount)
|
|
81
|
-
this.#increaseBalance(to, amount)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
burn(from, amount) {
|
|
85
|
-
if (!this.hasRole(msg.sender, 'BURN')) throw new Error('not allowed')
|
|
86
|
-
|
|
87
|
-
this.#totalSupply = this.#totalSupply.sub(amount)
|
|
88
|
-
this.#decreaseBalance(from, amount)
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
#beforeTransfer(from, to, amount) {
|
|
92
|
-
if (!this.#balances[from] || this.#balances[from] < amount) throw new Error('amount exceeds balance')
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
#updateHolders(address, previousBalance) {
|
|
96
|
-
if (this.#balances[address].toHexString() === '0x00') this.#holders -= 1
|
|
97
|
-
else if (this.#balances[address].toHexString() !== '0x00' && previousBalance.toHexString() === '0x00') this.#holders += 1
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
#increaseBalance(address, amount) {
|
|
101
|
-
if (!this.#balances[address]) this.#balances[address] = BigNumber.from(0)
|
|
102
|
-
const previousBalance = this.#balances[address]
|
|
103
|
-
|
|
104
|
-
this.#balances[address] = this.#balances[address].add(amount)
|
|
105
|
-
this.#updateHolders(address, previousBalance)
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
#decreaseBalance(address, amount) {
|
|
109
|
-
const previousBalance = this.#balances[address]
|
|
110
|
-
this.#balances[address] = this.#balances[address].sub(amount)
|
|
111
|
-
this.#updateHolders(address, previousBalance)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
balanceOf(address) {
|
|
115
|
-
return this.#balances[address]
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
setApproval(operator, amount) {
|
|
119
|
-
const owner = globalThis.msg.sender
|
|
120
|
-
if (!this.#approvals[owner]) this.#approvals[owner] = {}
|
|
121
|
-
this.#approvals[owner][operator] = amount
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
approved(owner, operator, amount) {
|
|
125
|
-
return this.#approvals[owner][operator] === amount
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
transfer(from, to, amount) {
|
|
129
|
-
// TODO: is BigNumber?
|
|
130
|
-
amount = BigNumber.from(amount)
|
|
131
|
-
this.#beforeTransfer(from, to, amount)
|
|
132
|
-
this.#decreaseBalance(from, amount)
|
|
133
|
-
this.#increaseBalance(to, amount)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
package/src/standards/voting.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default class ArtOnlineVoting {}
|