AZ-002 — Data Structures and Canonical Validation Rules v1
Status
Acesta este primul document tehnic normativ pentru ATLAS ZERO. Definește structurile de date fundamentale, convențiile de serializare, hashing-ul canonic și regulile minime de validare.
Termeni:
- MUST = obligatoriu
- MUST NOT = interzis
- SHOULD = recomandat puternic
- MAY = opțional
1. Obiectiv
AZ-002 stabilește:
- identificatori canonici;
- structurile de date fundamentale;
- hashing și semnare;
- reguli generale de serializare;
- reguli minime de validare sintactică și semantică;
- compatibilitatea dintre Value Layer, Logic Layer și Witness Layer.
Acest document nu definește încă:
- algoritmii criptografici finali;
- consensul ENDC complet;
- mașina virtuală finală;
- economic model complet.
2. Convenții globale
2.1 Encoding
Toate structurile protocolului MUST avea o formă canonică de serializare numită AZ-CBOR:
- bazată pe CBOR canonical form;
- chei ordonate lexical;
- fără câmpuri duplicate;
- fără valori implicite omise dacă schema le cere explicit;
- fără spații semantice alternative pentru aceeași valoare.
Motiv: două noduri diferite MUST produce exact același hash pentru aceeași structură logică.
2.2 Byte order
Toate câmpurile numerice multi-byte MUST fi big-endian în reprezentarea binară internă când nu sunt codate direct prin AZ-CBOR.
2.3 Time
Timpul protocolului este exprimat în:
unix_mspentru timestamp exact;epoch_indexpentru ferestre de consens;slot_indexpentru subdiviziuni interne.
2.4 Versioning
Fiecare structură top-level MUST conține:
version_majorversion_minor
Compatibilitate:
- schimbările breaking cresc
version_major; - schimbările additive cresc
version_minor.
2.5 Domain separation
Toate hash-urile MUST folosi prefix de domeniu. Exemple:
AZ:CELL:AZ:TX:AZ:BLOCK:AZ:WITNESS:AZ:MACHINE:AZ:INTENT:
Motiv: se previne coliziunea semantică între obiecte serializate similar.
3. Tipuri primitive
3.1 Hash32
Hash32 = secvență fixă de 32 bytes.
3.2 SigBytes
SigBytes = secvență variabilă de bytes pentru semnături.
3.3 PubKeyBytes
PubKeyBytes = secvență variabilă de bytes pentru chei publice.
3.4 AssetAmount
AssetAmount = integer nesemnat pe 128 bits.
MUST NOT fi negativ.
MUST fit în intervalul [0, 2^128 - 1].
3.5 Ratio
Ratio = pereche (numerator:uint64, denominator:uint64).
denominator MUST NOT fi 0.
3.6 BoundedBytes
BoundedBytes(max_len) = blob binar cu limită fixată prin schemă.
3.7 PolicyRef
PolicyRef = referință canonicală la o politică de autorizare sau cheltuire.
Poate fi:
- hash de script/policy;
- hash de policy object;
- hash de multisig template.
4. Identificatori
4.1 cell_id
cell_id = H("AZ:CELL:" || canonical_cell_body)
canonical_cell_body MUST exclude:
- dovezi de cheltuire;
- semnături externe;
- metadata non-canonical.
4.2 machine_id
machine_id = H("AZ:MACHINE:" || canonical_machine_deploy_body)
4.3 witness_id
witness_id = H("AZ:WITNESS:" || canonical_witness_body)
4.4 intent_id
intent_id = H("AZ:INTENT:" || canonical_intent_body)
4.5 tx_id
tx_id = H("AZ:TX:" || canonical_transaction_body)
4.6 block_id
block_id = H("AZ:BLOCK:" || canonical_block_header_body)
Toți identificatorii MUST fi derivați doar din forma canonică. Nu se admit ID-uri arbitrare generate local.
5. Structura Cell
5.1 Schema
Cell {
version_major: uint16
version_minor: uint16
asset_id: Hash32
amount: uint128
owner_policy: PolicyRef
spend_policy: PolicyRef
expiry_policy: PolicyRef? // optional
nonce: uint64
created_at_epoch: uint64
metadata_hash: Hash32? // optional
origin_ref: Hash32? // optional
tags: [Tag] // bounded list
}
5.2 Semnificație
asset_ididentifică activul;amounteste cantitatea de activ;owner_policydescrie dreptul legitim de control economic;spend_policydescrie condițiile concrete de consum;expiry_policydescrie ce se întâmplă la expirare;nonceprevine ambiguități structurale;created_at_epochfixează epoca de origine;metadata_hashleagă context extern;origin_refleagă celula de o mașină, mint event sau alt obiect;tagspermit clasificare minimală, nu logică executabilă complexă.
5.3 Reguli
amountMUST be > 0.owner_policyMUST fi validă sintactic.spend_policyMUST fi validă sintactic.expiry_policy, dacă există, MUST fi validă sintactic.tagsMUST fi pure metadata; MUST NOT schimba semanticile de bază ale cheltuirii.nonceMUST fi tratat ca parte a identității cell.
5.4 Cell tags
Tag-urile sunt perechi:
Tag {
key: ascii_string(max=32)
value_hash: Hash32
}
Cheia MUST fi ASCII lower snake_case.
6. Input și Output de tranzacție
6.1 CellInput
CellInput {
referenced_cell_id: Hash32
unlock_bundle_ref: Hash32
}
unlock_bundle_ref indică dovezile și semnăturile necesare.
6.2 CellOutput
CellOutput {
cell: Cell
}
6.3 UnlockBundle
UnlockBundle {
version_major: uint16
version_minor: uint16
policy_ref: PolicyRef
signatures: [SignatureEnvelope]
witness_refs: [Hash32]
proof_refs: [Hash32]
machine_call_refs: [Hash32]
nonce: uint64
}
Reguli:
policy_refMUST corespunde politicii cerute de Cell;- semnăturile MUST acoperi exact payload-ul cerut de policy;
witness_refsMAY fi necesare pentru spend condiționat;proof_refsMAY referi date off-chain sau dovezi compacte;machine_call_refsMAY arăta că o mașină a autorizat consumul.
7. Structura Bounded Machine
7.1 MachineDeploy
MachineDeploy {
version_major: uint16
version_minor: uint16
code_hash: Hash32
abi_hash: Hash32
initial_state_root: Hash32
state_bound_bytes: uint64
effect_bound: EffectBound
loss_envelope: LossEnvelope
permission_surface: PermissionSurface
upgrade_policy: PolicyRef
halt_policy: PolicyRef
operator_policy: PolicyRef
storage_rent_prepaid_until_epoch: uint64
metadata_hash: Hash32?
}
7.2 EffectBound
EffectBound {
max_cells_consumed_per_call: uint32
max_cells_created_per_call: uint32
max_assets_touched_per_call: uint16
max_witness_emits_per_call: uint16
max_state_write_bytes_per_call: uint32
max_total_value_out_ratio: Ratio?
}
7.3 LossEnvelope
LossEnvelope {
envelope_type: enum
max_loss_abs_by_asset: [(asset_id: Hash32, amount: uint128)]
max_loss_ratio: Ratio?
max_locked_duration_epochs: uint64?
max_external_dependency_count: uint16
}
envelope_type poate fi:
STATICDYNAMIC_BOUNDEDNONE_DECLARED_FORBIDDEN
ATLAS ZERO v1 SHOULD interzice NONE_DECLARED_FORBIDDEN pentru mașinile ce pot custodia valoare.
7.4 PermissionSurface
PermissionSurface {
allowed_asset_ids: [Hash32]?
allowed_call_selectors: [Hash32]
allowed_witness_types: [ascii_string(max=32)]
allowed_counterparty_policy_roots: [Hash32]?
can_emit_cells: bool
can_emit_witnesses: bool
can_lock_value: bool
can_burn_value: bool
can_delegate_subroles: bool
}
7.5 MachineStateRef
MachineStateRef {
machine_id: Hash32
state_root: Hash32
state_size_bytes: uint64
state_epoch: uint64
}
7.6 Reguli
state_bound_bytesMUST be > 0.state_size_bytesMUST NOT depășistate_bound_bytes.effect_boundMUST fi non-zero și coerent.loss_envelopeMUST fi prezent și sintactic valid.permission_surfaceMUST limita explicit efectele.operator_policyMUST fi diferită dehalt_policyîn aplicațiile custodiale sensibile, dacă guvernanța locală o cere.storage_rent_prepaid_until_epochMUST fi >= current epoch la deploy.
8. Machine Call
8.1 Schema
MachineCall {
version_major: uint16
version_minor: uint16
machine_id: Hash32
selector: Hash32
args_hash: Hash32
prior_state_ref: MachineStateRef
max_exec_units: uint64
declared_effect_digest: Hash32
attached_cell_inputs: [CellInput]
attached_witness_refs: [Hash32]
attached_proof_refs: [Hash32]
caller_policy: PolicyRef
nonce: uint64
}
8.2 CallResult
MachineCallResult {
machine_call_id: Hash32
next_state_ref: MachineStateRef
emitted_cell_ids: [Hash32]
emitted_witness_ids: [Hash32]
consumed_cell_ids: [Hash32]
exec_units_used: uint64
status_code: uint32
result_hash: Hash32
}
8.3 Reguli
selectorMUST aparțineallowed_call_selectors.prior_state_ref.machine_idMUST matchmachine_id.exec_units_usedMUST NOT depășimax_exec_units.- Efectele reale MUST match
declared_effect_digest. - Rezultatul MUST fi determinist pentru același input, aceeași stare și aceleași witnessuri.
- Orice încălcare a
effect_boundinvalidează call-ul. - Orice încălcare a
loss_envelopeinvalidează call-ul.
9. Structura Witness Record
9.1 Schema
WitnessRecord {
version_major: uint16
version_minor: uint16
subject_ref: Hash32
issuer_policy: PolicyRef
statement_type: ascii_string(max=32)
statement_hash: Hash32
proof_bundle_ref: Hash32?
issued_at_unix_ms: uint64
ttl_unix_ms: uint64?
revocation_policy: PolicyRef?
visibility_class: enum
meta_hash: Hash32?
}
9.2 visibility_class
Valori:
PUBLICHASH_ONLYRESTRICTED
9.3 Reguli
statement_typeMUST fi canonical lower snake_case.ttl_unix_ms, dacă există, MUST be >issued_at_unix_ms.issuer_policyMUST fi validă.proof_bundle_refMAY lipsi doar dacă statement-ul nu cere dovadă externă.revocation_policyMAY lipsi pentru statement-uri ireversibile.- Un Witness expirat MUST NOT satisface o condiție care cere witness activ.
10. Structura Intent
10.1 Schema
Intent {
version_major: uint16
version_minor: uint16
creator_policy: PolicyRef
target_domain: ascii_string(max=32)
action_type: ascii_string(max=32)
constraint_blob_hash: Hash32
risk_limit: RiskLimit
time_window: TimeWindow
acceptable_routes_hash: Hash32?
required_witness_refs: [Hash32]
max_fee_by_asset: [(asset_id: Hash32, amount: uint128)]
cancel_policy: PolicyRef
priority_class: uint8
nonce: uint64
}
10.2 RiskLimit
RiskLimit {
max_slippage_ratio: Ratio?
max_notional_loss_by_asset: [(asset_id: Hash32, amount: uint128)]?
max_partial_fill_ratio: Ratio?
min_fill_ratio: Ratio?
external_dependency_limit: uint16
}
10.3 TimeWindow
TimeWindow {
valid_from_unix_ms: uint64
valid_until_unix_ms: uint64
}
10.4 Reguli
valid_until_unix_msMUST be >valid_from_unix_ms.priority_classMUST fi într-un interval protocol-limitat.risk_limitMUST fi valid sintactic.- Intentul expirat MUST NOT fi executat.
- Intentul MAY fi parțial executat doar dacă
min_fill_ratioșimax_partial_fill_ratiopermit. constraint_blob_hashMUST referi un format standardizat de restricții pentru aceltarget_domain.
11. SignatureEnvelope
11.1 Schema
SignatureEnvelope {
sig_scheme: enum
public_key: PubKeyBytes
signature: SigBytes
signed_message_hash: Hash32
signer_hint: Hash32?
}
11.2 Reguli
signed_message_hashMUST corespunde exact mesajului cerut de policy.sig_schemeMUST fi acceptată de versiunea de protocol.- Semnăturile MUST NOT fie malleable conform regulilor schemei.
- Două semnături diferite pentru același mesaj MAY fi acceptate doar dacă policy o permite.
12. ProofBundle
12.1 Schema
ProofBundle {
version_major: uint16
version_minor: uint16
proof_type: ascii_string(max=32)
payload_hash: Hash32
blob_ref: Hash32?
verifier_hint: Hash32?
expiry_unix_ms: uint64?
}
12.2 Utilizare
ProofBundle este container generic pentru:
- Merkle proof
- ZK proof
- committee attestation package
- oracle proof
- storage inclusion proof
12.3 Reguli
proof_typeMUST fi standardizat.- Dacă dovada expiră, aceasta MUST NOT satisface o condiție după expirare.
- Verificatorul MUST ști exact cum validează tipul respectiv.
- Nodurile MUST respinge
proof_typenecunoscut în contexte care îl cer explicit.
13. Transaction Envelope
13.1 Schema
Transaction {
version_major: uint16
version_minor: uint16
tx_type: enum
body_hash: Hash32
body_blob: bytes
fee_inputs: [CellInput]
fee_outputs: [CellOutput]
auth_bundle_refs: [Hash32]
memo_hash: Hash32?
nonce: uint64
}
13.2 tx_type
Valori inițiale:
TX_VALUE_TRANSFERTX_MACHINE_DEPLOYTX_MACHINE_CALLTX_WITNESS_EMITTX_INTENT_SUBMITTX_INTENT_CANCELTX_GUARD_HALTTX_EPOCH_NOTARIZE
13.3 Reguli
body_hashMUST matchbody_blob.tx_typeMUST corespunde structurii dinbody_blob.- Taxele MUST fi conservate corect.
auth_bundle_refsMUST conține toate bundle-urile cerute de corpul tranzacției.nonceMAY fi per-caller sau per-transaction, după schema body.
14. Block Header
14.1 Schema
BlockHeader {
version_major: uint16
version_minor: uint16
parent_refs: [Hash32]
epoch_index: uint64
slot_index: uint32
proposer_id: Hash32
tx_root: Hash32
witness_root: Hash32
machine_result_root: Hash32
state_commitment_root: Hash32
timestamp_unix_ms: uint64
protocol_flags: uint64
proposer_signature: SignatureEnvelope
}
14.2 Reguli
parent_refsMUST fi non-empty, except genesis.epoch_indexșislot_indexMUST respecta regulile ENDC.tx_root,witness_root,machine_result_root,state_commitment_rootMUST corespunde conținutului blocului.timestamp_unix_msMUST fi în toleranța protocolului față de ceasul local.proposer_signatureMUST valida header-ul canonic.
15. Epoch Notarization Record
15.1 Schema
EpochNotarization {
version_major: uint16
version_minor: uint16
epoch_index: uint64
selected_front_block_ids: [Hash32]
finalized_state_root: Hash32
finalized_tx_root: Hash32
finalized_witness_root: Hash32
notary_committee_root: Hash32
notary_signatures: [SignatureEnvelope]
conflict_set_hash: Hash32?
metadata_hash: Hash32?
}
15.2 Reguli
selected_front_block_idsMUST descrie un front compatibil.notary_signaturesMUST trece pragul de finalitate.finalized_state_rootMUST corespunde execuției deterministe a frontului.- O notarizare conflictuală pentru aceeași epocă MUST declanșa reguli de slashing.
16. Politici
16.1 Policy Object canonical
PolicyObject {
version_major: uint16
version_minor: uint16
policy_type: ascii_string(max=32)
rules_hash: Hash32
threshold: uint16?
participants: [Hash32]?
expiry_unix_ms: uint64?
fallback_policy_ref: PolicyRef?
}
16.2 Exemple
- single_sig
- m_of_n_multisig
- time_lock
- witness_guarded
- machine_authorized
- committee_approved
- rate_limited_delegate
16.3 Reguli
policy_typeMUST fi standardizat.- Obiectele policy MUST avea semantici clare, deterministe.
- O politică expirată MUST NOT autoriza noi acțiuni.
fallback_policy_refMAY fi folosit pentru recuperare sau rotație.
17. Erori canonice
17.1 Format
ProtocolError {
code: uint32
class: ascii_string(max=32)
detail_hash: Hash32?
}
17.2 Clase inițiale
syntax_errorhash_mismatchinvalid_signatureunknown_policypolicy_unsatisfiedexpired_objectdouble_spend_attemptstate_bound_exceededeffect_bound_exceededloss_envelope_exceededpermission_deniedinsufficient_feeinvalid_time_windowinvalid_notarizationunknown_proof_type
17.3 Reguli
Codurile MUST fi stabile între noduri pentru aceeași versiune de protocol.
18. Reguli generale de validare
18.1 Validare sintactică
Un nod MUST verifica:
- schema obiectului;
- tipurile câmpurilor;
- limitele de dimensiune;
- encoding canonic;
- hash-ul obiectului;
- semnăturile structurale de bază.
Dacă pică aici, obiectul este invalid fără execuție suplimentară.
18.2 Validare semantică
Un nod MUST verifica:
- referințele există;
- obiectele referite nu sunt expirate;
- politicile sunt satisfăcute;
- limitele de stare și efect sunt respectate;
- conservarea valorii;
- lipsa dublului consum în frontul local candidat.
18.3 Determinism
Pentru orice:
- MachineCall
- notarization candidate
- batch clearing
ieșirea MUST depinde doar de:
- inputurile canonice;
- starea anterioară canonicală;
- witnessurile și proof-urile valide atașate;
- parametrii de protocol activi pentru versiunea curentă.
Nimic din:
- ordinea locală a mempool-ului;
- timpul de sistem în afara toleranței;
- arhitectura hardware;
- concurența internă
nu MUST influența rezultatul final.
19. Reguli de mempool
19.1 Admitere
Un nod SHOULD accepta în mempool doar obiecte care trec:
- validarea sintactică completă;
- validarea semantică minimă;
- verificarea taxei minime;
- verificarea timpului.
19.2 Evicție
Un obiect MAY fi scos din mempool dacă:
- expiră;
- devine invalid prin consum concurent;
- taxa devine sub minimul curent;
- depinde de referințe evictate sau invalide.
19.3 Conflict tracking
Nodul SHOULD marca explicit conflictele:
- spend conflict
- nonce conflict
- machine state conflict
- intent exclusivity conflict
20. Reguli de compatibilitate între straturi
20.1 Value -> Logic
O Bounded Machine MAY consuma Cells doar dacă:
- policy o permite;
- permission surface o permite;
- efectul este declarat;
- envelope nu este încălcat.
20.2 Logic -> Witness
O mașină MAY emite Witness Records doar dacă:
can_emit_witnesses = true;- tipul de witness este permis;
- numărul și dimensiunea sunt în bound.
20.3 Witness -> Value
O Cell MAY cere witness valid în spend policy. Witnessul MUST:
- exista;
- fi neexpirat;
- satisface tipul și subject-ul cerut;
- fi validat de issuer policy.
20.4 Intent -> Logic/Value
Un intent executat MUST produce efecte care respectă toate constrângerile declarate. Dacă nu există execuție compatibilă, intentul MUST rămâne neexecutat, nu reinterpretat.
21. Canonical hash domains
Lista minimă de prefixe:
AZ:CELL:AZ:UNLOCK_BUNDLE:AZ:MACHINE_DEPLOY:AZ:MACHINE_CALL:AZ:MACHINE_CALL_RESULT:AZ:WITNESS:AZ:INTENT:AZ:PROOF_BUNDLE:AZ:POLICY_OBJECT:AZ:TX:AZ:BLOCK_HEADER:AZ:EPOCH_NOTARIZATION:AZ:ERROR:
Nodurile MUST respinge prefixe necunoscute în contexte canonice.
22. Limite inițiale recomandate pentru testnet
Aceste valori sunt de pornire, nu constituție:
- max tx size: 256 KiB
- max witness size: 64 KiB
- max proof bundle inline payload: 64 KiB
- max machine call args size via referenced blob: 1 MiB
- max cells consumed per simple tx: 256
- max cells created per simple tx: 256
- max witness emits per machine call: 32
- max tags per Cell: 16
- max required_witness_refs per Intent: 32
- max notary signatures per notarization object: 512
23. Invariants rezumate
- Orice obiect top-level are serializare canonică unică.
- Orice identificator este derivat, nu ales arbitrar.
- Orice referință critică este hash-addressed.
- Orice tranziție de stare este deterministă.
- Orice efect logic este bounded.
- Orice pierdere posibilă trebuie să fie envelope-bounded unde aplicația custodiază valoare.
- Orice witness utilizat normativ trebuie să fie valid, neexpirat și verificabil.
- Orice execuție a unui intent trebuie să respecte exact constrângerile declarate.
- Orice bloc și orice notarizare trebuie să fie reconstruibile independent de noduri diferite.
- Orice ambiguitate de encoding este interzisă.
24. Ce urmează
Acum că obiectele fundamentale sunt fixate, următorul document corect este:
AZ-003 — Transaction Validation and State Transition Rules
Acolo definim exact:
- cum se validează fiecare
tx_type; - ordinea validărilor;
- conservarea valorii per activ;
- conflict detection;
- compunerea efectelor de mașină;
- cum intră și ies obiectele din stare.
25. Formula de etapă
Dacă AZ-001 a spus „ce este protocolul” și Protocol Skeleton a spus „cum se împarte în straturi”, AZ-002 spune pentru prima dată:
din ce obiecte exacte este făcut protocolul și ce înseamnă ca ele să fie valide.
Închidere
ATLAS ZERO devine implementabil numai în momentul în care tipurile, hash-urile și regulile canonice sunt mai puternice decât interpretările locale.
Acest document fixează exact acest lucru.