@dashevo/moderation-charters-contract 4.2.0-beta.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/.mocharc.yml ADDED
@@ -0,0 +1,2 @@
1
+ require: test/bootstrap.js
2
+ recursive: true
package/Cargo.toml ADDED
@@ -0,0 +1,15 @@
1
+ [package]
2
+ name = "moderation-charters-contract"
3
+ description = "Moderation charters data contract schema and tools. A team's application to moderate a contract"
4
+ version.workspace = true
5
+ edition = "2021"
6
+ rust-version.workspace = true
7
+ license = "MIT"
8
+
9
+ [dependencies]
10
+ thiserror = "2.0.12"
11
+ platform-version = { path = "../rs-platform-version" }
12
+ serde_json = { version = "1.0" }
13
+ platform-value = { path = "../rs-platform-value" }
14
+ [dev-dependencies]
15
+ base58 = "0.2.0"
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 Dash Core Group, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,118 @@
1
+ # Moderation Charters Contract
2
+
3
+ The moderation charters system contract holds the charters of the moderation
4
+ teams that masternodes elect for data contracts that declare an elected
5
+ moderation team. It activates at protocol version 14, registered at genesis by
6
+ chains born at 14 and inserted by the upgrade to 14, and has the same ID on
7
+ every network: `EG7RGfV8fDTayC2FyVr8HwdpJh3fXDbVztcfE94UmN88`.
8
+
9
+ It has seven document types. All are immutable. The four a charter is made of
10
+ (`reason`, `submittedCharter`, `joinRequest`, `electedCharter`) are
11
+ undeletable, so everything a charter points at, and the charter itself, is a
12
+ fixed text; the three team changes are deletable.
13
+
14
+ The schema carries almost every rule through its keywords: typed arrays with
15
+ a reference per element, a reference resolved through a unique index
16
+ (`lookup`), `distinctFrom`, key requirements on key references, the
17
+ `encryptedFor` envelope, `maxBytes` for the description's 4096-byte cap and a
18
+ `propertyConstraints` rule holding the reward split to 100. What it cannot say,
19
+ the cap on additions, is checked by the batch's state validation, and
20
+ `SubmittedCharter` in `rs-dpp` only reads a proposal.
21
+
22
+ Seating writes nothing. Awarding the contest for a target writes the winning
23
+ `electedCharter` here, the only one ever written for that target, and the
24
+ target's moderation paths read it: its team moderates instead of the interim
25
+ moderators, is protected, and may charge its proposal's `moderatorsShare` of a
26
+ declared moderators fee (see [the protocol guide](../../docs/protocol/moderation-charters.md#seating)).
27
+
28
+ ## `reason`
29
+
30
+ A ground for a moderation action. Anyone may file one.
31
+
32
+ | Property | Type | Meaning |
33
+ | --- | --- | --- |
34
+ | `code` | string, 3 uppercase letters, required | Unique among the owner's reasons (`byOwnerCode`); what an action shows. An action names a reason by document id (`reasonDocumentId`), and a seated team only one its proposal lists (41203) |
35
+ | `label` | string, 1 to 64 characters, required | The reason's name |
36
+ | `description` | string, 1 to 1024 characters | What the reason covers and how the team applies it |
37
+
38
+ ## `submittedCharter`
39
+
40
+ A leader's proposal to moderate one contract, on the contract's own terms:
41
+ the target's elected moderation declaration is the team's whole mandate, so
42
+ the proposal names no abilities. Its owner is the leader, and must hold a
43
+ decryption key bound to this type so join requests can be encrypted to it.
44
+
45
+ | Property | Type | Meaning |
46
+ | --- | --- | --- |
47
+ | `targetContractId` | identifier, required, `refersTo` a contract with elected moderation | The contract the team proposes to moderate |
48
+ | `description` | string, 1 to 4096 characters and at most 4096 bytes, required | What the team would moderate and how. Informational |
49
+ | `reasons` | array of at most 64 unique reason ids, required, each `refersTo` a `reason` | The moderation reasons the team's actions may name; a team with none can take no action |
50
+ | `moderatorsShare` | integer 0 to 100 | The percentage of each moderated type's declared moderators fee the team takes; absent is the full amount, 0 a team that will not moderate and takes no rewards |
51
+ | `rewardSplit` | object, required | `leader`, `equal` and `actions` percentages summing to 100 (the `rewardSplitIsWhole` rule of `propertyConstraints`): how every settle of the target's moderators pot is paid out, a claim or a team change |
52
+
53
+ Indexes: `byTargetContract` (target, `$createdAt`) lists the proposals for a
54
+ contract in filing order; `byOwner` lists a leader's proposals.
55
+
56
+ ## `joinRequest`
57
+
58
+ An identity's offer to serve on the team of a proposal, one per identity per
59
+ proposal (`bySubmittedCharter`, unique on the proposal and the owner), with a
60
+ message only the leader can read. The owner must hold an encryption key bound
61
+ to this type.
62
+
63
+ | Property | Type | Meaning |
64
+ | --- | --- | --- |
65
+ | `submittedCharterId` | identifier, required, `refersTo` a `submittedCharter` | The proposal; `recipientId` must equal its owner (`propertyAgreement`) |
66
+ | `recipientId` | identifier, required, `refersTo` an identity public key through `recipientKeyId` | The leader and the decryption key the message is encrypted to |
67
+ | `recipientKeyId` | integer, required | The leader's key id |
68
+ | `senderKeyId` | integer, required | The owner's encryption key the shared secret is derived from |
69
+ | `encryptedMessage` | bytes, 32 to 1040, required | Why the owner wants to join, encrypted for the leader (ECDH on secp256k1, AES-256-CBC) |
70
+
71
+ ## `electedCharter`
72
+
73
+ A proposal put to the vote with its team: the only type that opens or joins
74
+ the contest for a target. Only the proposal's leader may create one, for the
75
+ proposal's own target (`propertyAgreement` on `$ownerId` and
76
+ `targetContractId`). The `byTargetContract` index is a contested unique index
77
+ keyed by the target contract with resolution `1`, the vote without a Lock
78
+ choice by masternodes (weight 1) and evonodes (weight 4): a create on it
79
+ opens or joins the contest, a tie goes to the earliest applicant, and a
80
+ single applicant is seated when the join window closes. `bySubmittedCharter`
81
+ lists the elected charters of a proposal. It is not unique: a type with a
82
+ contested unique index may carry no other unique index, and none is needed,
83
+ since an identity may contend once per contest and only the proposal's owner
84
+ may enter it, so a proposal has at most one contender at a time. The seated
85
+ leader and members act with the target's full mandate; there are no powers.
86
+
87
+ | Property | Type | Meaning |
88
+ | --- | --- | --- |
89
+ | `targetContractId` | identifier, required, `refersTo` a contract whose election is open | The contract contended for; its own `electionDelay` since its creation must have passed |
90
+ | `submittedCharterId` | identifier, required, `refersTo` a `submittedCharter` | The proposal the team runs on |
91
+ | `members` | array of at most 15 unique identity ids, required, each the owner of a `joinRequest` for this proposal (`lookup`) and none the leader (`distinctFrom`) | The team besides the leader; may be empty |
92
+
93
+ ## After the election
94
+
95
+ Once an elected charter is seated, its team can change without a new vote:
96
+
97
+ | Type | Written by | Properties | Rules |
98
+ | --- | --- | --- | --- |
99
+ | `addedModerator` | the leader | `electedCharterId`, `submittedCharterId`, `memberId` | `memberId` owns a `joinRequest` for the charter's proposal (`lookup`) and is not the leader; at most the target's `maxAddedModerators` additions per charter at a time, a consensus rule of the batch's state validation (41202); deleting it takes the member off and frees its slot |
100
+ | `removedModerator` | the leader | `electedCharterId`, `memberId` | Needs no resignation; `memberId` is one of the charter's elected `members` (`listElement`); deleting it puts the member back |
101
+ | `resignationRequest` | a member of the team | `electedCharterId`, `recipientId`, `recipientKeyId`, `senderKeyId`, `encryptedMessage` | The writer is in the charter's `members` or has an addition now (`ownerRefersTo` with `anyOf`, the addition a `deletableDocument` lookup); a message only the leader can read; deletable, which withdraws it; the leader acts on it by deleting the addition or removing an elected member |
102
+
103
+ Each exists at most once per member and charter (unique indexes). The team
104
+ that acts is the leader plus the elected members less the removals, plus the
105
+ additions (`ElectedCharter::active_members` in `rs-dpp`).
106
+
107
+ See [the protocol guide](../../docs/protocol/moderation-charters.md) for
108
+ details.
109
+
110
+ ## Install
111
+
112
+ ```sh
113
+ npm install @dashevo/moderation-charters-contract
114
+ ```
115
+
116
+ ## License
117
+
118
+ [MIT](LICENSE) © Dash Core Group, Inc.
@@ -0,0 +1,10 @@
1
+ import baseConfig from '../../eslint/base.mjs';
2
+ import mochaTestConfig from '../../eslint/mocha-tests.mjs';
3
+
4
+ export default [
5
+ ...baseConfig,
6
+ mochaTestConfig,
7
+ {
8
+ ignores: ['dist/**', 'node_modules/**'],
9
+ },
10
+ ];
@@ -0,0 +1,4 @@
1
+ module.exports = {
2
+ ownerId: '11111111111111111111111111111111',
3
+ contractId: 'EG7RGfV8fDTayC2FyVr8HwdpJh3fXDbVztcfE94UmN88',
4
+ };
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@dashevo/moderation-charters-contract",
3
+ "version": "4.2.0-beta.4",
4
+ "description": "A system contract for the charters of elected moderation teams",
5
+ "scripts": {
6
+ "lint": "eslint .",
7
+ "test": "yarn run test:unit",
8
+ "test:unit": "mocha 'test/unit/**/*.spec.js'"
9
+ },
10
+ "contributors": [
11
+ {
12
+ "name": "Samuel Westrich",
13
+ "email": "sam@dash.org",
14
+ "url": "https://github.com/quantumexplorer"
15
+ }
16
+ ],
17
+ "license": "MIT",
18
+ "devDependencies": {
19
+ "@dashevo/wasm-dpp": "workspace:*",
20
+ "chai": "^4.3.10",
21
+ "dirty-chai": "^2.0.1",
22
+ "eslint": "^9.18.0",
23
+ "mocha": "^11.1.0",
24
+ "sinon": "^18.0.1",
25
+ "sinon-chai": "^3.7.0"
26
+ }
27
+ }