Contract methods and events
ARIADNE’s rules are enforced by one smart contract, deployed once per network as an Algorand application. Every action (publishing, reviewing, voting, commenting, flagging) is a call to one of its methods, signed by the person who acts. This page lists them all, with the events they emit and the data they store, for developers and auditors. Terms such as application, box, ASA and minimum balance are explained in the Glossary.
The contract is written in Algorand Python (compiled with puyapy 5.10.1), exposes an ARC-4 ABI, is described by an ARC-56 application specification, and emits ARC-28 events. Everything here was checked against the source and the compiled specification, which win over any other description:
projects/contracts/smart_contracts/ariadne/contract.py(methods),events.py(events),types.py(box values),keys.py(box keys),constants.py(constants);projects/contracts/smart_contracts/artifacts/ariadne/Ariadne.arc56.json(the ARC-56 specification, with the deployed bytecode).
The TestNet application is 772983107 (see Networks and addresses). The normative text is the protocol specification, sections 5 to 13, amended by the decision log.
Conventions
Section titled “Conventions”| Topic | Rule |
|---|---|
| Article number | article_id is a sequence assigned by the contract, starting at 1. Each article also has an Algorand asset (ASA) whose id is stored in the article box and in Published. |
| Addresses | ARC-4 address: the raw 32-byte public key. |
| Boxes | Named storage slots of the application, one per record (article, vote, review…). Each box raises the application’s minimum balance, which the caller covers with the pay argument. |
| CIDs | byte[36], the raw CIDv1 bytes: 0x01, the codec, 0x12 0x20 (sha2-256, 32 bytes), then the 32-byte digest. Articles must use codec 0x70 (dag-pb, a folder); reviews and comments codec 0x55 (raw, one file). Any other prefix, length or an all-zero digest is rejected. |
pay argument |
A payment transaction placed in the group just before the call, from the caller to the application address, without close-out or rekey. Its amount must cover the increase of the application’s minimum balance caused by the call (the storage deposit). Overpayment is accepted and kept; there are no refunds. |
| Fees | The caller pays every network fee of the call, including those of the inner transactions, through fee pooling. Fees are read from the network when sending, never hard-coded. |
| Statuses | 1 preprint, 2 under_review, 3 final (shown in the app as “closed version”), 4 disputed, 5 retracted. “Open” below means statuses 1 to 3. |
| Accepted author | The submitter, or a declared co-author who confirmed with accept_coauthorship. Accepted authors may not vote on, review or flag their own article. |
| Failure | Any violated precondition rejects the whole transaction group. The assertion messages are in contract.py. |
| Events | Every state-changing call emits exactly one canonical event, followed by zero to two ReputationChanged. |
Enumerations
Section titled “Enumerations”0 is invalid for every enumeration.
| Enumeration | Values |
|---|---|
| type | 1 article, 2 notes, 3 amendment, 4 dataset, 5 replication |
| status | 1 preprint, 2 under_review, 3 final, 4 disputed, 5 retracted |
| recommendation | 1 accept, 2 minor_revision, 3 major_revision, 4 reject |
| flag reason | 1 plagiarism, 2 spam, 3 fabricated_data, 4 other |
vote target (target_kind) |
1 article, 2 review, 3 comment |
| dispute outcome | 1 cleared, 2 retracted |
| reputation reason | 1 article_upvote, 2 review_useful, 3 comment_upvote, 4 comment_resolved |
| identity scheme | 1 ORCID iD |
Methods at a glance
Section titled “Methods at a glance”The storage deposit is in microAlgo (1 ALGO = 1 000 000 microAlgo) and goes to the application account through the
pay argument. It is a permanent deposit, not a fee: nothing is ever deleted.
| Method | Who may call | Allowed statuses | Deposit (pay) |
Creates |
|---|---|---|---|---|
add_field |
governance | not applicable | 2 500 + 400 × (3 + name bytes) | field box |
set_governance |
governance | not applicable | none | nothing |
resolve_dispute |
governance | disputed | none | nothing |
publish |
anyone | not applicable (the article starts as preprint) | 212 200 + 29 300 per declared co-author | ASA, article box, co-author boxes |
extend |
anyone | not applicable | none | nothing |
claim_article |
the submitter | 1 to 4 (not retracted) | none (the opt-in costs the author 100 000 on their own account) | nothing |
new_version |
the submitter | 1, 2 | none | nothing |
set_status |
the submitter | see the transition table | none | nothing |
accept_coauthorship |
a declared co-author | open (1 to 3) | none | nothing |
submit_review |
anyone but an accepted author | 1 to 4 (not retracted) | 65 800, or 91 100 with the reviewer’s first reputation box in the field | review box, reviewer index box, reputation box if missing |
vote_review |
anyone but the reviewer | open | 32 100 | vote box |
vote_article |
anyone but an accepted author | open | 28 900 | vote box |
claim_reputation |
an accepted author | open | 0, 25 300 or 50 600 | the claimer’s missing reputation boxes |
comment |
anyone | every status | 56 500, or 81 800 with the commenter’s first reputation box in the field | comment box, reputation box if missing |
vote_comment |
anyone but the comment’s author | open | 32 100 | vote box |
resolve_comment |
the submitter | open | none | nothing |
flag |
anyone but an accepted author, with reputation of at least 10 in the primary field | 1 to 4 (not retracted) | 26 500 | flag box |
declare_identity |
anyone | not applicable | none | nothing |
declare_doi |
an accepted author | any; a non-empty DOI not when retracted | none | nothing |
follow |
anyone | not applicable | none | nothing |
The create(governance) method runs once, when the application is deployed.
Governance
Section titled “Governance”Governance is one address stored in global state. On TestNet it is a native Falcon-1024 (post-quantum) account, and it pays its own fees and deposits like anyone else. It can register fields, resolve disputes and hand governance to another address; it cannot change articles, reputation or the program.
create
Section titled “create”create(governance: address) -> voidCreation only. governance must not be the zero address. Sets article_seq_next to 1 and emits GovernanceChanged
with the zero address as previous_governance. The deployer keeps no power.
add_field
Section titled “add_field”add_field(pay: pay, field_id: uint16, name: string) -> void- Sender: the governance address.
field_idis not 0 and not registered yet;nameis 1 to 96 bytes. Fields are never renamed or removed.- Creates the field box
t+field_id, whose value is the name in UTF-8. - Emits
FieldAdded.
set_governance
Section titled “set_governance”set_governance(new_governance: address) -> void- Sender: the current governance address.
new_governanceis neither the zero address nor the current one.- Emits
GovernanceChanged. This is how governance will move to a post-quantum multisig account once Algorand offers one.
resolve_dispute
Section titled “resolve_dispute”resolve_dispute(article_id: uint64, outcome: uint8) -> void- Sender: the governance address. The article must be
disputed. outcome1 (cleared) restores the status the article had before the dispute; 2 (retracted) retracts it and revokes its ASA (one inner asset-configuration transaction).- Increments
dispute_round, resets the round’s flag weight to 0 and clearsstatus_before_dispute. Flags of earlier rounds stay on record but no longer count. The last round, 65 535, takes no flags and cannot be resolved, so no article can be stuck indisputed. - Emits
DisputeResolved(with the round that was resolved). NoStatusChangedis emitted.
Publishing
Section titled “Publishing”publish
Section titled “publish”publish(pay: pay, cid: byte[36], primary_field: uint16, secondary_field: uint16, article_type: uint8, parent_article: uint64, coauthors: address[]) -> uint64- Sender: anyone. The sender becomes the submitter, for ever.
cid: a dag-pb CID (codec0x70).primary_fieldis a registered field;secondary_fieldis 0 or a registered field different from the primary.article_typeis 1 to 5.parent_articleis the number of an existing article when the type is amendment (3), and 0 for every other type.coauthors: 0 to 25 addresses in strictly ascending order of their raw 32 bytes (which proves they are distinct), never the sender. The list can never be changed afterwards.- Creates the article’s ASA (one inner transaction), the article box, the submitter’s co-author box (accepted) and one co-author box per declared address (not accepted yet). Creates no reputation box.
- Returns the new
article_idand emitsPublished. The article starts aspreprint, version 1. - Deposit: 212 200 microAlgo (ASA 100 000 + article box 82 900 + the submitter’s co-author box 29 300), plus 29 300 per declared co-author (944 700 with 25).
extend
Section titled “extend”extend() -> voidChanges nothing and emits nothing. A call to extend placed in the same group lends its opcode budget and its box
references to the other calls. A publication touches one box per declared co-author, so clients add
ceil(boxes / 8) - 1 calls to extend, where boxes = 3 + 1 with a secondary field + 1 for an amendment + the number
of co-authors (D-073). Up to 4 co-authors (5 without a secondary field) need none.
claim_article
Section titled “claim_article”claim_article(article_id: uint64) -> void- Sender: the submitter, who has opted in to the article’s ASA (paying their own opt-in deposit). The article is not claimed yet and not retracted.
- Four inner transactions move the token to the author and freeze it there for ever: unfreeze, transfer, refreeze, and an asset configuration that sets the freeze address to zero.
- Emits
ArticleClaimed. Optional: authorship lives in the article box, not in the token.
new_version
Section titled “new_version”new_version(article_id: uint64, cid: byte[36]) -> void- Sender: the submitter. Status
preprintorunder_review. cid: a dag-pb CID different from the current one. The version number grows by exactly 1 (at most 65 535).- Moves the ASA’s ARC-19 reserve to the new CID’s digest (one inner transaction), sets
prev_cidto the old CID. - Emits
Versioned. The whole version history is in these events.
set_status
Section titled “set_status”set_status(article_id: uint64, new_status: uint8) -> voidSender: the submitter. Exactly these transitions are allowed; every other one fails:
| From | To |
|---|---|
| preprint | under_review |
| preprint | retracted |
| under_review | final |
| under_review | retracted |
| final | retracted |
preprint cannot go straight to final, retracted is final for ever, and only the contract (through flags) and
governance (through resolve_dispute) move an article into or out of disputed. A retraction revokes the ASA (one inner
transaction: manager, freeze and clawback set to zero). Emits StatusChanged.
Co-authorship
Section titled “Co-authorship”accept_coauthorship
Section titled “accept_coauthorship”accept_coauthorship(article_id: uint64) -> void- Sender: an address declared in
publishthat has not confirmed yet. Status open (1 to 3). - Fails if the sender already voted on the article or reviewed it.
- Increments
author_count. The new author’s share counts from publication (seeclaim_reputation). - Emits
CoauthorAccepted. One-time and irreversible; there is no way to add, remove or replace a co-author.
Reviews
Section titled “Reviews”submit_review
Section titled “submit_review”submit_review(pay: pay, article_id: uint64, cid: byte[36], recommendation: uint8) -> uint64- Sender: anyone who is not an accepted author of the article. Status 1 to 4 (reviews stay allowed while disputed).
- One review per reviewer and article.
cidis a raw CID (codec0x55);recommendationis 1 to 4. - Creates the review box and the reviewer index box, and the reviewer’s own reputation box in the article’s primary field when it does not exist yet (later “useful” votes are paid into it).
- Returns
review_seq(1, 2, … per article) and emitsReviewed. Reviews are immutable.
vote_review
Section titled “vote_review”vote_review(pay: pay, article_id: uint64, review_seq: uint64) -> void- Sender: anyone but the reviewer, once per review. Status open.
- The vote’s weight is
1 + isqrt(rep), whererepis the voter’s reputation in the article’s primary field. - Grants
weight × 3to the reviewer, under the daily cap, except when the voter is an accepted author of the article: that vote is recorded and grants 0. - Creates a vote box. Emits
Voted(target 2), thenReputationChangedwhen something was granted.
Votes and reputation
Section titled “Votes and reputation”vote_article
Section titled “vote_article”vote_article(pay: pay, article_id: uint64) -> void- Sender: anyone but an accepted author, once per article. Status open.
- Adds the voter’s weight to the article’s
vote_totaland 1 tovote_count. It touches no reputation box, so its cost does not depend on the number of authors. - Creates a vote box. Emits
Voted(target 1,target_seq0) and neverReputationChanged.
claim_reputation
Section titled “claim_reputation”claim_reputation(pay: pay, article_id: uint64) -> void- Sender: an accepted author. Status open.
- With
N= 1 + the number of declared co-authors andT=vote_total, a confirmed co-author is entitled tofloor(T / N)and the submitter toceil(T / N). The claimable amount is the entitlement minus what the sender already claimed; it must be greater than 0. - Grants up to that amount in the primary field, under the daily cap (the grant must be greater than 0), and half of what was granted in the secondary field, if any, under that field’s cap. What the cap holds back stays claimable on a later day; the secondary field’s shortfall is not carried over.
- Creates the sender’s reputation boxes in the article’s fields when they are missing.
- Emits
ReputationClaimed, then oneReputationChangedper field that received something.
See Reputation and vote weight for the reasoning and worked examples.
Comments
Section titled “Comments”comment
Section titled “comment”comment(pay: pay, article_id: uint64, cid: byte[36], reply_to: uint64, mentions: address[]) -> uint64- Sender: anyone, accepted authors included. Allowed in every status,
retractedincluded. cidis a raw CID (codec0x55).reply_tois 0 for a new thread or the number of an existing comment of the same article; a reply’s depth is its parent’s depth + 1, at most 6.mentions: 0 to 5 addresses in strictly ascending order of their raw 32 bytes, never the sender. They are stored only in the event, for notifications, and carry no reputation.- Creates the comment box, increments the parent’s reply count, and creates the commenter’s reputation box in the primary field when it is missing.
- Returns
comment_seqand emitsCommented.
vote_comment
Section titled “vote_comment”vote_comment(pay: pay, article_id: uint64, comment_seq: uint64) -> void- Sender: anyone but the comment’s author, once per comment. Status open.
- Grants
floor(weight / 5)to the comment’s author under the daily cap (nothing for a voter of weight below 5). - Creates a vote box. Emits
Voted(target 3), thenReputationChangedwhen something was granted.
resolve_comment
Section titled “resolve_comment”resolve_comment(article_id: uint64, comment_seq: uint64) -> void- Sender: the submitter. Status open.
- The comment exists, was not written by an accepted author, and is not resolved yet. Any depth may be resolved, once.
- Grants 5 to the comment’s author, under the daily cap.
- Emits
CommentResolved, thenReputationChangedwhen something was granted.
flag(pay: pay, article_id: uint64, reason: uint8) -> void- Sender: anyone who is not an accepted author and holds a reputation box in the article’s primary field with at least 10 reputation. Status 1 to 4.
reasonis 1 to 4. One flag per address and dispute round.- The flag weighs
1 + isqrt(rep)and is added to the round’s total. When the total reaches 30 and the article is open, it becomesdisputed. While disputed, flags are still recorded and the total keeps growing, without a status change. - Creates a flag box. Emits
Flagged, whosenew_statusgives the status after the call (noStatusChanged).
See Flags, disputes and governance.
Declarations
Section titled “Declarations”These three methods (contract v3) only emit an event: no box, no deposit, network fee only. The indexer projects them and checks identities and DOIs against outside records.
declare_identity
Section titled “declare_identity”declare_identity(scheme: uint8, value: string) -> voidscheme at least 1 (1 = ORCID iD); value at most 64 bytes; an empty value withdraws the declaration. The format of
the iD (its check character) is checked by the web app and the indexer, not by the contract. Emits IdentityDeclared.
declare_doi
Section titled “declare_doi”declare_doi(article_id: uint64, version: uint16, doi: string) -> void- Sender: an accepted author of an existing article.
versionis at most the current version; 0 means every version (Zenodo’s concept DOI).- A non-empty DOI is 4 to 200 bytes, starts with
10., and needs an article that is not retracted. An empty DOI withdraws the declaration, in any status. - Emits
DoiDeclared.
follow
Section titled “follow”follow(target: address, on: bool) -> voidtarget is neither the zero address nor the sender. on true follows, false unfollows. Emits Followed.
Method selectors
Section titled “Method selectors”An ABI call starts with the first 4 bytes of the SHA-512/256 hash of the method signature. These values appear in the compiled program:
| Selector | Signature |
|---|---|
cc694eaa |
create(address)void |
5b672353 |
add_field(pay,uint16,string)void |
b1349031 |
set_governance(address)void |
99490947 |
resolve_dispute(uint64,uint8)void |
fafe4bc1 |
publish(pay,byte[36],uint16,uint16,uint8,uint64,address[])uint64 |
21ebf21b |
extend()void |
29d89a27 |
claim_article(uint64)void |
d1536be5 |
new_version(uint64,byte[36])void |
4f5856df |
set_status(uint64,uint8)void |
a1b57ed3 |
accept_coauthorship(uint64)void |
bdeb3721 |
vote_article(pay,uint64)void |
51410368 |
claim_reputation(pay,uint64)void |
9c1e9523 |
submit_review(pay,uint64,byte[36],uint8)uint64 |
81ab418c |
vote_review(pay,uint64,uint64)void |
9151ca27 |
comment(pay,uint64,byte[36],uint64,address[])uint64 |
e7c2f56f |
vote_comment(pay,uint64,uint64)void |
e585f1bd |
resolve_comment(uint64,uint64)void |
566a854f |
flag(pay,uint64,uint8)void |
cf6986fa |
declare_identity(uint8,string)void |
8baaa94e |
declare_doi(uint64,uint16,string)void |
f7bc7f0c |
follow(address,bool)void |
Events (ARC-28)
Section titled “Events (ARC-28)”Events are application logs. Each log is the event’s 4-byte selector (the first 4 bytes of the SHA-512/256 hash of the
signature, for example Published(uint8,uint64,uint64,address,uint16,uint16,uint8,uint64,byte[36],address[],uint64))
followed by the ARC-4 encoding of its fields. Every event starts with schema_version (uint8, currently 1); ts is
the block time in Unix seconds (uint64). Logs that start with 151f7c75 are ARC-4 return values, not events.
| Event | Fields after schema_version |
Emitted by | Selector |
|---|---|---|---|
FieldAdded |
field_id uint16, name string |
add_field |
8f5a55e7 |
GovernanceChanged |
previous_governance address, new_governance address, ts |
create, set_governance |
b83576f0 |
Published |
article_id uint64, asa_id uint64, author address, primary_field uint16, secondary_field uint16, article_type uint8, parent_article uint64, cid byte[36], coauthors address[], ts |
publish |
ca215569 |
ArticleClaimed |
article_id uint64, author address, ts |
claim_article |
8791e87c |
Versioned |
article_id uint64, version uint16, cid byte[36], prev_cid byte[36], ts |
new_version |
2cd407b6 |
StatusChanged |
article_id uint64, from_status uint8, to_status uint8, actor address, ts |
set_status |
70b5c208 |
CoauthorAccepted |
article_id uint64, coauthor address, author_count uint16, claimed_total uint64 (always 0), ts |
accept_coauthorship |
c2abc036 |
ReputationClaimed |
article_id uint64, claimant address, consumed uint64, ts |
claim_reputation |
2a1e4de7 |
Reviewed |
article_id uint64, review_seq uint64, reviewer address, recommendation uint8, cid byte[36], ts |
submit_review |
f7383e22 |
Voted |
target_kind uint8, article_id uint64, target_seq uint64, voter address, weight uint64, ts |
vote_article, vote_review, vote_comment |
0cbb2b9a |
Commented |
article_id uint64, comment_seq uint64, author address, reply_to uint64, root_seq uint64, depth uint8, cid byte[36], mentions address[], ts |
comment |
a211c33d |
CommentResolved |
article_id uint64, comment_seq uint64, resolved_by address, ts |
resolve_comment |
57fabb07 |
Flagged |
article_id uint64, dispute_round uint16, flagger address, reason uint8, weight uint64, round_total uint64, new_status uint8, ts |
flag |
beade69f |
DisputeResolved |
article_id uint64, dispute_round uint16 (the round resolved), outcome uint8, new_status uint8, ts |
resolve_dispute |
35e2de50 |
ReputationChanged |
address address, field_id uint16, delta uint64, new_total uint64, reason uint8, ts |
claim_reputation, vote_review, vote_comment, resolve_comment |
13bdfb7b |
IdentityDeclared |
address address, scheme uint8, value string (empty = withdrawn), ts |
declare_identity |
4dbc3ed7 |
DoiDeclared |
article_id uint64, version uint16 (0 = every version), doi string (empty = withdrawn), declared_by address, ts |
declare_doi |
05f59bfd |
Followed |
follower address, target address, on bool, ts |
follow |
6f90d760 |
Details that matter when you decode them:
- Order within a call: the canonical event first, then the
ReputationChangedevents (primary field before secondary field for a claim).vote_articlenever emitsReputationChanged; a grant of 0 emits none. target_seqis 0 for article votes, the review or comment number otherwise.Published.coauthorsandCommented.mentionsare in ascending address order, not in the order of any text.- Entering and leaving
disputedemits noStatusChanged: readFlagged.new_statusandDisputeResolved.new_status. stringvalues are counted in raw bytes by the contract, which accepts any bytes. Decode them as bytes and convert to text without rejecting invalid UTF-8, as the indexer does (D-117).- Size limits per application call: 32 logs and 1 024 bytes.
Publishedtakes 114 bytes plus 32 per co-author,Commentedwith 5 mentions 278 bytes,Flagged73 bytes. - The field names come from
events.py. Section 11 of the specification writes some of them differently (type,from,to,authorinReputationClaimed); selectors depend only on the types, and the code is authoritative.
The events carry everything needed to rebuild every box of the application. The contract’s test suite proves it by replaying the logs and rebuilding every box byte for byte; the indexer is built the same way (see Verify without trusting ariadne.press).
Storage
Section titled “Storage”Global state
Section titled “Global state”| Key | Type | Meaning |
|---|---|---|
governance |
address | the governance address |
article_seq_next |
uint64 | the next article_id, starting at 1 |
Box keys are binary; integers are big-endian; addresses are the raw 32 bytes. The deposit of a box is
2 500 + 400 × (key bytes + value bytes) microAlgo, paid by the caller whose action creates it.
| Box | Key | Key bytes | Value | Value bytes | Deposit | Created by |
|---|---|---|---|---|---|---|
| field | t + uint16 field_id |
3 | the name, UTF-8 | 1 to 96 | 2 500 + 400 × (3 + name bytes) | add_field |
| article | a + uint64 article_id |
9 | Article | 192 | 82 900 | publish |
| co-author | au + uint64 article_id + address |
42 | CoAuthor | 25 | 29 300 | publish (the submitter and each declared co-author) |
| review | r + uint64 article_id + uint64 review_seq |
17 | Review | 85 | 43 300 | submit_review |
| reviewer index | ri + uint64 article_id + address |
42 | uint64 review_seq | 8 | 22 500 | submit_review |
| comment | c + uint64 article_id + uint64 comment_seq |
17 | Comment | 118 | 56 500 | comment |
| article vote | va + uint64 article_id + address |
42 | Vote | 24 | 28 900 | vote_article |
| review vote | vr + uint64 article_id + uint64 review_seq + address |
50 | Vote | 24 | 32 100 | vote_review |
| comment vote | vc + uint64 article_id + uint64 comment_seq + address |
50 | Vote | 24 | 32 100 | vote_comment |
| flag | f + uint64 article_id + uint16 dispute_round + address |
43 | Flag | 17 | 26 500 | flag |
| reputation | p + address + uint16 field_id |
35 | Reputation | 22 | 25 300 | claim_reputation, submit_review, comment |
A reputation box is only ever created by an action of its own address, which pays for it. A vote never creates a box for anyone else.
Box values
Section titled “Box values”The values are ARC-4 static tuples, so their sizes are fixed (each bool takes one byte).
Article (192 bytes):
| Offset | Field | Type | Notes |
|---|---|---|---|
| 0 | author |
address | the submitter, immutable |
| 32 | primary_field |
uint16 | immutable |
| 34 | secondary_field |
uint16 | immutable, 0 = none |
| 36 | article_type |
uint8 | immutable |
| 37 | parent_article |
uint64 | immutable, not 0 only for amendments |
| 45 | status |
uint8 | |
| 46 | status_before_dispute |
uint8 | 0 unless disputed |
| 47 | version |
uint16 | starts at 1 |
| 49 | current_cid |
byte[36] | |
| 85 | prev_cid |
byte[36] | all zeros for version 1 |
| 121 | created_at |
uint64 | |
| 129 | updated_at |
uint64 | stamped by calls that change the article box |
| 137 | vote_total |
uint64 | sum of vote weights, never decreases |
| 145 | vote_count |
uint64 | |
| 153 | review_seq_next |
uint64 | starts at 1 |
| 161 | comment_seq_next |
uint64 | starts at 1 |
| 169 | dispute_round |
uint16 | starts at 1 |
| 171 | round_flag_weight |
uint64 | flag weight of the current round |
| 179 | author_count |
uint16 | 1 + confirmed co-authors |
| 181 | invited_count |
uint16 | declared co-authors, immutable |
| 183 | claimed |
bool | the ASA was claimed |
| 184 | asa_id |
uint64 | the article’s ASA, immutable |
| Value | Fields, in order |
|---|---|
| CoAuthor (25 bytes) | invited_at uint64, accepted bool, accepted_at uint64, claimed_total uint64 |
| Review (85 bytes) | reviewer address, cid byte[36], recommendation uint8, created_at uint64, useful_total uint64 |
| Comment (118 bytes) | author address, cid byte[36], reply_to uint64, root_seq uint64, depth uint8, created_at uint64, vote_total uint64, reply_count uint64, resolved bool, resolved_at uint64 |
| Vote (24 bytes) | weight uint64, granted uint64 (always 0 for article votes), created_at uint64 |
| Flag (17 bytes) | reason uint8, weight uint64, created_at uint64 |
| Reputation (22 bytes) | rep uint64, updated_at uint64, cap_day uint32, cap_today uint16 |
Version history, mentions and declarations are not stored in boxes: they live only in the events.
The article token (ASA)
Section titled “The article token (ASA)”publish creates one Algorand Standard Asset per article, an ARC-71 non-transferable asset whose issuer is the
application:
| Parameter | Value |
|---|---|
| total, decimals | 1, 0 |
| default frozen | true |
| unit name, asset name | ARIA, Ariadne Article |
| URL | template-ipfs://{ipfscid:1:dag-pb:reserve:sha2-256} (ARC-19) |
| reserve | the digest of the current CID, as an address; new_version moves it |
| manager | the application; the zero address once retracted |
| freeze | the application; the zero address once claimed |
| clawback | always the zero address |
After a claim nobody can move the token: clawback and freeze are zero and the holding is frozen. The article box, not the token, is the authority on authorship.
Constants
Section titled “Constants”From constants.py. They are compiled into the program and can only change with a new application.
| Constant | Value | Meaning |
|---|---|---|
REP_CAP_DAY |
50 | most reputation an address can receive per field and day, from all sources |
EPOCH_DAY_SECONDS |
86 400 | a day for the cap: floor(block time / 86 400) |
GRANT_REVIEW_NUM / DEN |
3 / 1 | a “useful” vote grants weight × 3 to the reviewer |
GRANT_COMMENT_NUM / DEN |
1 / 5 | a comment upvote grants floor(weight / 5) to its author |
GRANT_RESOLVED |
5 | a resolved comment grants 5 to its author |
MIN_FLAG_REP |
10 | reputation in the primary field needed to flag |
FLAG_THRESHOLD |
30 | flag weight in one round that makes an article disputed |
MAX_COMMENT_DEPTH |
6 | deepest reply (a new thread is depth 0) |
MAX_MENTIONS |
5 | addresses mentioned per comment |
MAX_COAUTHORS |
25 | co-authors declared per article |
MAX_FIELD_NAME |
96 | bytes in a field name |
MAX_IDENTITY_LEN |
64 | bytes in a declared identity |
MAX_DOI_LEN |
200 | bytes in a declared DOI (which starts with 10.) |
MAX_VERSION |
65 535 | last version number |
MAX_UINT16 |
65 535 | last dispute round (takes no flags) |
SCHEMA_VERSION |
1 | first field of every event |
CID_LEN |
36 | bytes in a CID |
Vote and flag weight is 1 + isqrt(rep) (rep 0 gives 1, 100 gives 11, 10 000 gives 101), using the AVM’s integer
square root; a missing reputation box reads as 0. All arithmetic is integer arithmetic.
The size limit of an article folder (20 MB) is not a contract constant: the web app and the indexer enforce it.
Measured costs
Section titled “Measured costs”Measured on LocalNet (algod 5.0.2, consensus V42) and reported in M2_REPORT.md. The approval program is 6 266 bytes
(plus 4 for the clear program, 6 270 of the 8 192 allowed); there are 21 ABI methods and 18 events. One application
call may spend 700 opcodes; the test gate keeps every call under 600, with at most 8 box references and 1 024 log bytes.
“Minimum fees” is the number of network minimum fees the whole group costs when an Ed25519 account signs it, counting
the pay transaction and the inner transactions (multiply by the network’s current minimum fee, 1 000 microAlgo when
measured). A Falcon-1024 (post-quantum) signature adds 2 minimum fees per transaction it signs.
| Method | Highest opcodes per application call | Application calls | Minimum fees (Ed25519) |
|---|---|---|---|
add_field |
111 | 1 | 2 |
set_governance |
50 | 1 | 1 |
resolve_dispute |
133 (cleared), 165 (retracted) | 1 | 1, or 2 when retracting |
publish, no co-author |
370 | 1 | 3 |
publish, 4 co-authors |
524 | 1 | 3 |
publish, 9 co-authors |
741 in total | 2 | 4 |
publish, 25 co-authors |
1 421 in total | 4 | 6 |
claim_article |
141 | 1 | 5 (the asset opt-in is a transaction of its own) |
new_version |
177 | 1 | 2 |
set_status |
104, 134 when retracting | 1 | 1, or 2 when retracting |
accept_coauthorship |
144 | 1 | 1 |
vote_article |
189 | 1 | 2 |
claim_reputation |
479 | 1 | 2 |
submit_review |
281 | 1 | 2 |
vote_review |
344 | 1 | 2 |
comment |
479 (a reply with 5 mentions and a new reputation box) | 1 | 2 |
vote_comment |
323 | 1 | 2 |
resolve_comment |
259 | 1 | 1 |
flag |
248 | 1 | 2 |
declare_identity |
55 | 1 | 1 |
declare_doi |
135 | 1 | 1 |
follow |
48 | 1 | 1 |
Each declared co-author adds about 41 opcodes to publish. For the amounts readers and authors see, in ALGO, see
Costs and deposits.