Skip to main contentA-REX Core

Livre blanc · 04

Vue d'ensemble de la solution

Architecture d'A-REX Core : trois niveaux avec un seul sens de dépendance, le pipeline de transfert, les acteurs et la manière dont les éléments sont déployés.

Trois niveaux, un seul sens de dépendance

A-REX sépare ce qui doit être standardisé de ce qui doit simplement fonctionner :

Les quatre couches du standard

flowchart TB
    L3["Couche 3 · IARexAttest<br/>attest · revokeAttestation · isAttested · émetteurs de confiance par thème"]
    L2["Couche 2 · IARexHook + IARexHookManager<br/>hookFlags · check → bytes32 · onExecuted · getHooks"]
    L1["Couche 1 · IARexBatch<br/>createBatch · batchOf · setBatchStatus · setBatchMetadata · transform · parentsOf"]
    L0["Couche 0 · ERC-1155 + ERC-165 + IERC7943MultiToken<br/>freeze · forcedTransfer · canSend · canReceive · canTransfer"]
    L3 --- L2 --- L1 --- L0
    classDef l3 fill:#edf5ff,stroke:#0f62fe,color:#161616
    classDef l2 fill:#d0e2ff,stroke:#0f62fe,color:#161616
    classDef l1 fill:#a6c8ff,stroke:#0f62fe,color:#161616
    classDef l0 fill:#78a9ff,stroke:#0043ce,color:#161616
    class L3 l3
    class L2 l2
    class L1 l1
    class L0 l0

Les deux niveaux du dépôt et le sens de la dépendance

flowchart LR
    STD["<b>Le standard</b><br/>standard/ · contracts/standard/<br/>normatif · CC0"]
    REF["<b>Implémentation de référence</b><br/>ARexToken · ARexAttestations<br/>MIT"]
    DEMO["<b>Démonstrations</b><br/>7 hooks · 3 extensions<br/>MIT · non normatif"]
    STD -->|implémenté par| REF -->|démontré par| DEMO
    DEMO -.->|dépendent uniquement des interfaces| STD

Le standard ne dépend jamais de la référence ; le jeton ne dépend jamais des hooks. Retirez tous les hooks et toutes les extensions, et un jeton conforme existe toujours. C'est la propriété qui permet à un tiers d'implémenter A-REX sans adopter quoi que ce soit de ce dépôt hormis six fichiers d'interface.

Ce qu'est un lot

Un lot est un identifiant de jeton ERC-1155 assorti d'un enregistrement :

struct Batch {
    address issuer;        // who created it (or performed the transformation)
    uint64  createdAt;
    uint8   status;        // 0 ACTIVE · 255 RETIRED (terminal) · 1..254 issuer-defined
    bytes32 commodity;     // keccak256("HS:100199"), keccak256("FAO:0111"), keccak256("GTIN:0779…")
    bytes32 unit;          // UN/CEFACT Rec. 20: "KGM", "TNE", "LTR", "BX"
    uint64  producedAt;    // 0 = not yet produced (pre-harvest)
    uint64  expiresAt;     // 0 = none
    bytes32 originRef;     // hash / reference to origin evidence — never coordinates
    bytes32 metadataHash;  // keccak256 of the off-chain document
    string  uri;           // where the document is
}

Tout ce qui est plus riche — classe de qualité, humidité, protéines, conditionnement, identifiants GS1, code de lot de traçabilité, référence de déclaration EUDR, rapports de laboratoire, table des statuts de l'émetteur — vit dans le document de métadonnées dont le hash est engagé on-chain. Le document suit un JSON Schema publié, aligné sur EPCIS 2.0 et sur les éléments de données clés de FSMA 204.

Le pipeline de transfert

Toute modification de solde — émission, transfert, destruction, transfert forcé, transformation — passe par un point de passage obligé unique dans le jeton de référence. L'ordre est fixe et auditable :

flowchart TD
    A[safeTransferFrom / createBatch / burn / forcedTransfer / transform] --> B["verrou de réentrance"]
    B --> C{"en pause ?"}
    C -- oui, hors transfert forcé --> X1[EnforcedPause]
    C -- non --> D{"canSend from / canReceive to<br/>conjonction des hooks ELIGIBILITY"}
    D -- false --> X2[ERC7943CannotSend / CannotReceive]
    D -- true --> E{"par identifiant : existe ? non retiré ?<br/>montant ≤ solde − gelé ?"}
    E -- échec --> X3[ARexBatchNotFound / ARexBatchRetired /<br/>ERC7943InsufficientUnfrozenBalance]
    E -- ok --> F{"par identifiant, pour chaque hook CHECK dans l'ordre :<br/>check → code"}
    F -- code ≠ 0 --> X4["ARexHookRejected(hook, code)"]
    F -- tous à 0 --> G["soldes mis à jour · offre totale suivie"]
    G --> H["par identifiant, pour chaque hook EXECUTED : onExecuted"]
    H --> I["déverrouillage"]

Deux vues rejouent la même logique sans modifier l'état : canTransfer (booléen, comme l'exige ERC-7943) et transferCheck (le premier code de rejet, afin qu'une interface puisse indiquer à l'utilisateur pourquoi).

Les transferts forcés contournent la pause et les vérifications d'éligibilité — la mise en application doit fonctionner quand tout le reste est gelé — mais exécutent tout de même les hooks avec OP_FORCED_TRANSFER, de sorte qu'un hook peut exiger, par exemple, une référence d'ordonnance judiciaire dans les données de transfert.

Filiation

transform est l'opération unique de fractionnement, de fusion et de traitement :

graph LR
    W1["blé #1<br/>250 t · agriculteur"] -- "transform (réorganisation)" --> W2["blé #2<br/>100 t · acheteur A"]
    W1 -- "transform (réorganisation)" --> W3["blé #3<br/>150 t · acheteur B"]
    W2 -- "transform (traitement, TRANSFORMER_ROLE)" --> F4["farine #4<br/>75 t · minoterie"]
  • La réorganisation de lots (même denrée, même unité, quantité conservée) est ouverte à tout détenteur ou opérateur approuvé : une coopérative répartissant un lot de silo entre ses membres, un exportateur fusionnant des livraisons.
  • Le traitement (tout le reste) exige en outre TRANSFORMER_ROLE.
  • parentsOf(4) == [2], parentsOf(2) == [1] ; un événement BatchTransformed par opération, ce qui constitue un TransformationEvent d'EPCIS par construction.

Mise en application

ENFORCER_ROLE peut geler n'importe quel montant pour n'importe quel compte (setFrozenTokens, pouvant dépasser le solde, comme le précise ERC-7943) et déplacer des jetons sans le consentement du détenteur (forcedTransfer). C'est ce qui rend un jeton de lot utilisable hors d'une démonstration : un prêteur exécutant un warrant, un tribunal ordonnant la saisie de grains stockés, un entrepôt récupérant un lot après qu'un client a perdu ses clés. Chaque action de mise en application est un événement.

Hooks

Un hook est un contrat doté de cinq fonctions et d'un bitmap de drapeaux constant. Le jeton met les drapeaux en cache à l'enregistrement, de sorte qu'un transfert coûte un appel externe par hook concerné, et non une sonde d'interface par capacité et par module. Un hook apprend quel jeton l'appelle via msg.sender ; un même déploiement peut servir de nombreux jetons.

Les hooks de référence démontrent les trois capacités :

HookCapacitéCe qu'il démontre
EligibilityHookCHECK + ELIGIBILITYles listes d'autorisation et de blocage ainsi que les sanctions alimentent canSend / canReceive et produisent des codes précis
ExpiryHookCHECKle filtrage de la périssabilité et de l'avant-récolte, dérivé uniquement de l'enregistrement du lot
AttestationHookCHECK« le café exige une déclaration EUDR attestée avant de pouvoir être vendu »
PerishabilityHookCHECKmodèles de décroissance et vues de valeur ; les lots expirés ou sans valeur ne circulent pas
SeasonalHookCHECKfenêtres de récolte et de négociation par denrée
DeliveryHookCHECK + EXECUTEDverrou de garde pendant la livraison ; le règlement est le transfert lui-même, identifié par data
TraceabilityHookEXECUTEDjournal d'événements calqué sur EPCIS pour chaque opération, plus des événements de suivi critique manuels

Extensions compagnons (pas des hooks) : CommodityPriceOracle, CarbonImmobilizationWrapper, ParametricInsurance.

Attestations

Un contrat compagnon enregistre (batch, topic) → (issuer, reference, validity). Seuls les émetteurs de confiance pour un thème peuvent attester ; la révocation, l'expiration et la perte de confiance rendent toutes isAttested faux. Les thèmes sont des bytes32, de sorte que les thèmes d'attestation d'ERC-735, les identifiants de schéma d'Ethereum Attestation Service et les hashes de noms de certification fonctionnent tous sans table dans le standard.

Acteurs et rôles

ActeurRôle typique dans le jeton de référenceAction typique
Plateforme d'origine, coopérative, silo collecteurISSUER_ROLEcreateBatch
Agriculteur / détenteuraucuntransfert, réorganisation de lots, destruction
Minoterie, conditionneur, transformateurTRANSFORMER_ROLEtransform de traitement
Entrepôt, inspecteur, plateformeSTATUS_ROLEsetBatchStatus, setBatchMetadata
Certificateur, laboratoire, autoritéémetteur de confiance pour un thèmeattest
Prêteur, dépositaire désigné par un tribunal, conformitéENFORCER_ROLEsetFrozenTokens, forcedTransfer
Gouvernance (multisig, timelock)DEFAULT_ADMIN_ROLE, HOOK_ADMIN_ROLE, UPGRADER_ROLE, PAUSER_ROLErôles, hooks, mises à niveau, pause

Rien dans le standard ne fixe ces rôles ; ils constituent la manière dont l'implémentation de référence met en œuvre les exigences DOIT (« réservé à un rôle autorisé »).

Formes de déploiement

  • L2 public (Polygon, Arbitrum, Base, Optimism) : le moins cher, le plus composable ; adapté au négoce et au financement de denrées lorsque les contreparties sont des entreprises.
  • Chaîne EVM à accès restreint : lorsque les autorités de protection des données ou l'institution d'ancrage l'exigent ; l'EDPB encourage expressément les conceptions à accès restreint. Le standard est indépendant de la chaîne.
  • Hybride : lots sur une chaîne publique, données restreintes (polygones de parcelles, identité du producteur) derrière un stockage à accès contrôlé référencé depuis les métadonnées.

La pile de référence se déploie avec un module Ignition ou un script : proxy du jeton, registre d'attestations, hooks d'éligibilité et d'expiration.

Décisions de conception et alternatives qu'elles remplacent

Alternative envisagéeA-REX CoreRaison
une large interface de cœur avec des énumérations pour la denrée, le grade et l'étatIARexBatch à 8 fonctions avec codes ouvertsrien à redéployer pour une nouvelle culture, un nouveau schéma de classement ou un nouveau cycle de vie
des interfaces de capacité sondées à chaque transfertune seule interface de hook, drapeaux mis en cachegaz linéaire en nombre de hooks, et non en ids × modules × sondes
motifs sous forme de chaînescodes bytes32 et erreurs typéeslisible par machine, indexable
état du cycle de vie modifiable par n'importe quel détenteurrôle uniquement ; RETIRED terminalsécurité
date de récolte obligatoirement passéeproducedAt == 0 autoriséfinancement avant récolte
ni fractionnement, ni fusion, ni traitementtransform + parentsOftraçabilité, rappels, EPCIS
ni gel ni transfert forcéERC-7943possibilité de mise en application
coordonnées stockées on-chainréférence d'origine uniquementGDPR / EDPB 02/2025
contrats de registre et d'identité obligatoiresrien d'obligatoireaucune pile d'identité imposée