ProtocolState
Global singleton storing protocol configuration and auto-incrementing counters. Location:lib.rs:472-481
PDA Seeds: ["protocol_state"]
Space: 8 + ProtocolState::INIT_SPACE (8-byte discriminator + 83 bytes)
Fields
Protocol admin wallet with permission to modify global settings. Set during
initialize_protocol.Auto-incrementing counter for NKA specimen numbers. Starts at 0, incremented by
submit_null_result. Used to derive sequential IDs (NKA-0001, NKA-0002, …).Auto-incrementing counter for bounty numbers. Starts at 0, incremented by
create_bounty. Used to derive sequential IDs (NB-0001, NB-0002, …).Protocol fee rate in basis points (1/100th of a percent). Default: 250 (2.5%). Used in
approve_bounty_submission to calculate treasury fee.Example: 250 = 2.5%, 100 = 1%, 1000 = 10%Treasury wallet address receiving protocol fees. Validated by admin during initialization. Must have an associated USDC token account.
PDA bump seed for the ProtocolState account. Stored to avoid recomputation in subsequent instructions.
Code Reference
NullResult
Stores complete scientific metadata for a single Null Knowledge Asset (NKA). Location:lib.rs:483-498
PDA Seeds: ["null_result", researcher.key().as_ref(), &(nka_counter + 1).to_le_bytes()]
Space: 8 + NullResult::INIT_SPACE (8-byte discriminator + 601 bytes)
Fields
Wallet address of the researcher who submitted this NKA. Used for
has_one constraint in submit_to_bounty.Sequential identifier assigned from
protocol_state.nka_counter. Displayed as NKA-{specimen_number:04} in the frontend.UTF-8 encoded hypothesis tested in the experiment. Fixed-size buffer, zero-padded. Maximum 128 bytes.Example: “Increasing dopamine levels improves working memory in rats”
UTF-8 encoded summary of experimental methodology. Fixed-size buffer, zero-padded. Maximum 128 bytes.Example: “Double-blind RCT with 50 subjects, t-test analysis”
UTF-8 encoded description of what was expected. Fixed-size buffer, zero-padded. Maximum 128 bytes.Example: “Significant improvement in test scores (p < 0.05)”
UTF-8 encoded description of what actually occurred. Fixed-size buffer, zero-padded. Maximum 128 bytes.Example: “No significant difference observed (p = 0.42)”
Statistical p-value stored as fixed-point integer (multiply by 10000). To convert:
p_value / 10000.0.Example: 4200 = 0.42, 500 = 0.05, 8700 = 0.87Number of subjects/observations in the experiment. Stored as raw integer.Example:
50, 1000, 250SHA-256 hash of the underlying dataset file. Provides tamper-proof link between on-chain record and off-chain data. Can be all zeros if no file attached.Computation:
SHA256(raw_data_file_bytes)Verification status of the null result:
0= Pending (default)1= Verified (community validated)2= Disputed (challenged by peers)
Unix timestamp of submission. Set via
Clock::get()?.unix_timestamp in submit_null_result:62.PDA bump seed for this NullResult account.
Code Reference
NullBounty
Bounty posted by a creator seeking a specific null result. Escrows USDC in a PDA-controlled vault. Location:lib.rs:500-515
PDA Seeds: ["null_bounty", creator.key().as_ref(), &(bounty_counter + 1).to_le_bytes()]
Vault Seeds: ["bounty_vault", bounty.key().as_ref()]
Space: 8 + NullBounty::INIT_SPACE (8-byte discriminator + 419 bytes)
Fields
Wallet address of the bounty creator. Used for
has_one constraint in approve_bounty_submission and close_bounty.Sequential identifier assigned from
protocol_state.bounty_counter. Displayed as NB-{bounty_number:04} in the frontend.UTF-8 encoded description of the desired null result. Fixed-size buffer, zero-padded. Maximum 256 bytes.Example: “Negative result for CRISPR-based treatment of Huntington’s disease in mouse models”
USDC reward in base units (6 decimals). Must be > 0 (validated in
create_bounty:78). Escrowed in vault on creation.Example: 1000000 = 1 USDC, 2500000 = 2.5 USDCUSDC token mint address. Stored to validate transfers in
approve_bounty_submission and close_bounty.Address of the PDA token account holding escrowed USDC. Authority is the vault itself.
Unix timestamp deadline for bounty submissions. Currently not enforced by program but used for frontend filtering.
Bounty lifecycle status:
0= Open (accepting submissions)1= Matched (submission linked, pending approval)2= Fulfilled (submission approved, payout complete)3= Closed (refunded, no longer active)
Address of the BountySubmission PDA if status is Matched/Fulfilled. Set to
Pubkey::default() (all zeros) when Open or Closed.Unix timestamp of bounty creation. Set via
Clock::get()?.unix_timestamp in create_bounty:94.PDA bump seed for the vault token account. Used to derive signer seeds for CPI transfers.
PDA bump seed for this NullBounty account.
Code Reference
BountySubmission
Junction account linking a researcher’s NullResult to a specific NullBounty. Location:lib.rs:517-526
PDA Seeds: ["bounty_submission", bounty.key().as_ref(), null_result.key().as_ref()]
Space: 8 + BountySubmission::INIT_SPACE (8-byte discriminator + 106 bytes)
Fields
Wallet address of the researcher submitting their NKA. Copied from the linked NullResult account.
Address of the NullResult PDA being submitted. Must be owned by the submitting researcher.
Address of the NullBounty PDA this submission is for. Must have status Open when created.
Submission approval status:
0= Pending (awaiting creator review)1= Approved (accepted, payout executed)2= Rejected (declined by creator - not currently used)
Unix timestamp of submission. Set via
Clock::get()?.unix_timestamp in submit_to_bounty:131.PDA bump seed for this BountySubmission account.
Code Reference
Account Size Summary
| Account | Discriminator | Data | Total |
|---|---|---|---|
| ProtocolState | 8 | 83 | 91 bytes |
| NullResult | 8 | 601 | 609 bytes |
| NullBounty | 8 | 419 | 427 bytes |
| BountySubmission | 8 | 106 | 114 bytes |
All accounts use Anchor’s
#[derive(InitSpace)] macro to automatically calculate the correct space allocation.