Skip to main contentA-REX Foundation

Whitepaper · 07

Hooks und Referenzmodule

Wie einem konformen Token Funktionalität hinzugefügt wird, ohne den Standard anzutasten: die Hook-Schnittstelle, die Referenz-Hooks, die Begleiterweiterungen und wie eigene Hooks geschrieben, getestet und registriert werden.

Module sind Demonstrationen, nicht der Standard

Das Verhältnis zwischen A-REX Core und seinen Modulen entspricht dem zwischen ERC-3643 und den Compliance-Modulen von T-REX: Die Schnittstelle, über die Module angebunden werden, ist standardisiert; die Module sind es nicht. Ein konformer Token ohne Hooks ist ein gültiger A-REX-Token. Ein von beliebiger Seite geschriebener Hook ist mit jedem konformen Token kompatibel. Dadurch wächst das Ökosystem, ohne dass sich der Standard ändert.

graph LR
    T["ARexToken<br/>konformer Token"] -->|"check / onExecuted / canSend / canReceive"| H1[EligibilityHook]
    T --> H2[ExpiryHook]
    T --> H3[AttestationHook]
    T --> H4["Eigener Hook"]
    H3 --> A[ARexAttestations]

Die Hook-Schnittstelle

CallbackWannMuss
checkbevor sich Salden ändern, je betroffener ID, Hooks in Registrierungsreihenfolge, Abbruch beim ersten Wert ungleich nulleine View sein; aus Richtliniengründen nie revertieren
onExecutednachdem sich Salden geändert haben, je ID, der Reihe nachkeine saldenändernden Funktionen des Tokens aufrufen (der Token ist gesperrt)
canSend / canReceivebei jedem Transfer und für die ERC-7943-Views des TokensViews sein

op ist einer von OP_MINT (1), OP_TRANSFER (2), OP_BURN (3), OP_FORCED_TRANSFER (4), OP_TRANSFORM (5). Bei einer Transformation kommen Eingaben mit to == 0 und Ausgaben mit from == 0 an. data sind die ERC-1155-Transferdaten, bei Transformationen abi.encode(processRef), bei erzwungenen Transfers leer.

Der aufrufende Token ist msg.sender. Ein Hook, der die Charge benötigt, liest IARexBatch(msg.sender).batchOf(id). Ein bei der Bereitstellung an einen Token gebundener Hook (ADR-025, Vorgeschlagen) gibt ihn als token() an und lehnt Aufrufe von jeder anderen Adresse ab.

Lesen mehrere Regeln data, macht ADR-023 (Vorgeschlagen) daraus einen markierten Umschlag: bis zu 8 Einträge (bytes32 key, bytes32 value), Schlüssel in Namensräumen wie bei den Codes (keccak256("AREX:DELIVERY_ID"), keccak256("AREX:DOCUMENT_REF")), und jede Regel liest nur ihren eigenen Schlüssel. data von 32 Bytes behält die eine Bedeutung, die es zuvor für jede Regel hatte; alles andere ergibt keinen Wert, und das Lesen revertiert nie. Eine vor dem Umschlag geschriebene Regel liest ihn als keinen Wert; ein Absender baut deshalb nur dann einen Umschlag, wenn jede Regel des Tokens, die data liest, Umschläge liest. Die Referenz-Hooks DeliveryHook und TraceabilityHook tun das ab Release 2.0.0-alpha.7.

Referenz-Hooks

EligibilityHook – Zulassen, Sperren, Sanktionieren

Demonstriert HOOK_ELIGIBILITY. Führt eine optionale Zulassungsliste, eine Sperrliste und eine Sanktionsliste; canSend/canReceive geben deren Konjunktion zurück; check liefert SANCTIONED, SENDER_INELIGIBLE oder RECEIVER_INELIGIBLE, damit Benutzeroberflächen die Ablehnung erklären können. Erzwungene Transfers sind stets erlaubt: Güter von einem sanktionierten Konto zu beschlagnahmen, ist der Zweck der Durchsetzung. Im Produktivbetrieb werden die Listen von einem Identitätsregister (ONCHAINID, EAS, Verifiable Credentials) oder einem Sanktions-Oracle gespeist; dem Hook ist gleichgültig, welches.

ExpiryHook – Verderblichkeit ohne Modul

Zustandslos. Liest expiresAt und producedAt aus der Charge. Blockiert Mints und Transfers abgelaufener Chargen (BATCH_EXPIRED), nicht aber Burns (Abschreibung) oder erzwungene Transfers (Durchsetzung). Blockiert optional Transfers von Chargen, die noch nicht produziert sind (BATCH_NOT_PRODUCED) – eine Plattform, die Vorernte finanziert, setzt das Flag so, dass sie erlaubt sind; ein Spot-Marktplatz setzt es so, dass sie blockiert werden. Dieser eine Hook deckt den blockierenden Teil der Verderblichkeit ab; Verfallskurven werden zu einem View-Helfer oder einer Off-Chain-Bewertung.

AttestationHook – regulatorische Freigabesteuerung je Rohstoff

Ordnet einem Rohstoffcode ein erforderliches Attestierungsthema zu. Vor einem Transfer liest er die Charge, schlägt die Anforderung nach, fragt das Attestierungsregister mit isAttested und liefert andernfalls ATTESTATION_MISSING. „Kaffee benötigt eine EUDR-Sorgfaltsreferenz“, „als Bio gekennzeichnete Chargen benötigen ein gültiges Bio-Zertifikat“, „Rinder benötigen ein Tiergesundheitszeugnis“ sind jeweils ein Aufruf von setRequirement. Ab dem Referenz-Release 2.0.0-alpha.7 kann sein Eigentümer checksTransform einschalten (standardmäßig aus): Dann benötigen auch die Eingangschargen eines transform ihr Zertifikat, sodass ein Inhaber mit TRANSFORMER_ROLE eine nicht zertifizierte Charge nicht als neue Charge einem anderen Konto übergeben kann. Die Ausgaben sind neue Chargen und werden nicht geprüft.

PerishabilityHook – Verfallsmodelle

Verfallskonfiguration je Rohstoffcode mit Überschreibung je Charge; Modelle NONE, LINEAR (bis zu einer Untergrenze bei Ablauf), EXPONENTIAL (Halbwertszeit) und STEP (Abfall in jedem Intervall). Views valueBps, secondsRemaining, isExpired. Blockiert Mints und Transfers abgelaufener Chargen (BATCH_EXPIRED) sowie Transfers von Chargen, deren Restwert null beträgt (PERISH:NO_VALUE); blockiert nie Burns oder Durchsetzung.

SeasonalHook – Ernte- und Handelsfenster

Absolute Fenster [start, end] je Rohstoff und Operation (höchstens 16 je Schlüssel). Eine Kombination aus Rohstoff und Operation ohne Fenster ist unbeschränkt. Typische Verwendung: OP_MINT auf das Erntefenster beschränkt, OP_TRANSFER auf das Handelsfenster; andernfalls SEASON_CLOSED. Ab dem Referenz-Release 2.0.0-alpha.7 entfernt ein Manager ein Fenster anhand seiner Grenzen (removeWindow), nie anhand seiner Position, und abgelaufene Fenster machen Platz: Ist ein Schlüssel voll, verwirft das Hinzufügen eines Fensters zuerst dessen abgelaufene Fenster. Jede Entfernung emittiert WindowRemoved, sodass ein Indexer die Fenster aus den Ereignissen wiederherstellen kann.

DeliveryHook – Verwahrung und Abwicklung

Ein Absender plant die Lieferung von amount Einheiten über einen Frachtführer an einen Empfänger; die Einheiten werden gesperrt (ein O(1)-Zähler, sodass check nie über die Historie iteriert). Frachtführer und Sensoren erfassen Abholung, Transport und Temperaturmesswerte (Verstoß-Flag); der Empfänger bestätigt die Lieferung; Streitfälle gehen an einen Schlichter. Die Abwicklung ist der ERC-1155-Transfer selbst: Absender → Empfänger, exakter Betrag, mit der Nummer der Lieferung in data (32 Bytes, abi.encode(deliveryId), oder ab Release 2.0.0-alpha.7 der Eintrag AREX:DELIVERY_ID eines Umschlags); check erlaubt ihn nur, wenn die Lieferung DELIVERED ist, und onExecuted markiert sie als SETTLED und hebt die Sperre auf. Freie (nicht gesperrte) Einheiten bewegen sich weiter. Gesperrte Einheiten können weder transferiert noch verbrannt noch als Eingaben eines transform verwendet werden: check gibt IN_TRANSIT für jede Operation zurück, die den Saldo des Inhabers unter die gesperrte Menge senken würde, ausgenommen den Abwicklungstransfer, Mints und erzwungene Transfers. Nachdem ein erzwungener Transfer gesperrte Einheiten beschlagnahmt hat, gibt check weiterhin einen Code zurück, statt zu revertieren. Ab dem Referenz-Release 2.0.0-alpha.7 sind vom Token eingefrorene Einheiten (ERC-7943 getFrozenTokens) nicht frei für eine Lieferplanung (freeUnits gibt an, wie viele es sind); eine Lieferung, deren Einheiten ein erzwungener Transfer genommen hat, kann nicht als geliefert bestätigt oder angenommen werden (LockedUnitsMoved), da ihre Abwicklung nie stattfinden könnte, sie kann aber weiterhin angefochten und zurückgegeben werden; und ein Temperaturbereich, dessen Minimum nicht unter seinem Maximum liegt, wird abgelehnt (InvalidRange).

TraceabilityHook – EPCIS-förmiges Ereignisprotokoll

Beobachtet jede Token-Operation und klassifiziert sie mit CBV-Geschäftsschritten (commissioning, shipping, destroying, transforming) und Dispositionen (active, in_transit, destroyed, seized); RECORDER_ROLE erfasst kritische Verfolgungsereignisse, die keine Token-Operationen sind (Kühlung, Verpackung, Wareneingang), mit readPoint und bizLocation. Zwei Modi: nur emittieren (etwa +17 k Gas pro Transfer; ein Indexer baut das Protokoll neu auf) oder persistieren (etwa +184 k; getEvents antwortet On-Chain, paginiert). Version 2 des Hooks, im Referenz-Release 2.0.0-alpha.7, ist bei der Bereitstellung an einen einzigen Token gebunden: Nur dieser Token meldet Operationen, und recordEvent nimmt nur Chargen an, die es auf ihm gibt, sodass niemand Einträge im Namen des Tokens schreiben kann. Sein EPCISEvent enthält jedes Feld eines Eintrags (Operation, Lesepunkt, Ort und Erfasser), sodass der Modus „nur emittieren“ nichts verliert. Die Dokumentreferenz einer Bewegung stammt aus data von 32 Bytes oder aus dem Eintrag AREX:DOCUMENT_REF eines Umschlags, nie aus dem Eintrag einer anderen Regel. Der Hook ist nicht upgradefähig: Instanzen der Version 1 und ihre Ereignisse bleiben, wie sie waren, und Version 2 ist eine neue Bereitstellung.

CompanyFactsHook — die eigenen Aufzeichnungen eines Unternehmens

Demonstriert nur HOOK_EXECUTED: Er lehnt nie eine Operation ab, sein onExecuted revertiert nie, und er ist an genau einen Token gebunden. Er hält die eigenen Aufzeichnungen eines Unternehmens so fest, wie der Vokabular-Deskriptor des Standards sie beschreibt (interop/VOCABULARY.md, „Records on the ledger“): Fakten zu einer Charge, einem Standort oder dem Unternehmen (ein recordHash plus höchstens 8 öffentliche Werte), Stufenmarken (gesalzene Stufenreferenzen auf den Bit-Indizes 0–255, eine oder bis zu 50 pro Transaktion), von einem anderen Unternehmens-Token empfangene Stufen, tägliche Anker (eine Merkle-Wurzel und eine Anzahl) und Stornierungen. Jeder Schreibvorgang trägt einen approvalHash, den Hash des Unternehmensdatensatzes darüber, wer ihn freigegeben hat. Der Safe des Unternehmens registriert Definitionen und Stufen; ein Erfassungsschlüssel, der delegiert werden kann, schreibt die Aufzeichnungen. Bei einem transform überträgt er die Stufen, die jede Ausgangscharge durchlaufen hat, auf die Ergebnisse. Die Stufe eines Prozesstyps fügt er nur für einen im selben Block festgelegten processRef hinzu (commitRun), und jede Festlegung wird nur einmal eingelöst. Ebenso überträgt er das Rückverfolgbarkeitsmodell (cocModel, das niedrigste der Ausgangschargen) und die EUDR-Abdeckung (eudrCovered, das UND der Ausgangschargen). Events: FactRecorded, StageRecorded, ReceivedStageRecorded, Anchored, FactVoided, RunCommitted, StagesCarried, CustodyDeclared. Referenz-Release 2.0.0-alpha.9.

RequireStageHook — keine Lieferung ohne die geforderten Stufen

Demonstriert HOOK_CHECK auf Basis von CompanyFactsHook. Bis zu 16 Anforderungen, jede mit den Operationen, die sie abdeckt (Lieferungen und optional die Eingänge eines transform), den Rohstoffen und den Stufen, die eine Charge durchlaufen haben muss. Eine Charge, der eine fehlt, wird mit REQUIRE_STAGE:MISSING abgelehnt; eine Charge oder ein Stufenmodul, das er nicht lesen kann, mit REQUIRE_STAGE:UNREADABLE, nie mit einem Revert. Mints, Burns und Bewegungen auf rechtliche Anordnung werden nie abgelehnt. Jede Anforderung trägt ihr eigenes appliesFrom: Chargen, die davor erstellt wurden, werden nicht geprüft. Der Safe des Unternehmens legt die Anforderungen mit configure fest, sodass sich der Startpunkt ändern kann, wenn die Anforderungen ersetzt werden; jede Änderung emittiert Configured. Referenz-Release 2.0.0-alpha.9.

Begleiterweiterungen

Drei Belange mussten nie Transferregeln sein; es sind einfache Contracts, die Attestierungen lesen oder schreiben:

ErweiterungWas sie tut
CommodityPriceOracleMelder übermitteln Preise je Rohstoff; Runden sind nummeriert und werden per Quorum mit dem Median finalisiert oder manuell, sobald ein Minimum erreicht ist; latestAnswer, isStale
CarbonImmobilizationWrappererfasst in einem Register immobilisierte Gutschriften (Register, Seriennummernbereich, Vintage, Tonnen, Nachweis), verknüpft Tonnen mit Chargen, bildet Stilllegung und Freigabe nach, schreibt die Attestierung AREX:CARBON:IMMOBILIZED; mintet niemals Gutschriften
ParametricInsuranceERC-20-Pool; Police je Charge mit einem Auslöserthema; die Auszahlung erfolgt, wenn der Auslöser vor Ablauf attestiert ist

Alte und neue Chargen

Eine Regel, die für einen Token eingeschaltet wird, der bereits Chargen hält, gilt entweder für jede Charge oder nur für die Chargen, die ab einem bestimmten Zeitpunkt erstellt werden. Die Referenz-Hooks ExpiryHook, AttestationHook, SeasonalHook und PerishabilityHook erhalten diesen Zeitpunkt (appliesFrom, 0 für jede Charge) beim Deployment. Er lässt sich danach nicht ändern, sodass niemand später weitere Chargen ausnehmen kann; eine andere Wahl erfordert ein neues Deployment der Regel. RequireStageHook ist die Ausnahme: Jede seiner Anforderungen trägt ihr eigenes appliesFrom, und der Safe des Unternehmens kann die Anforderungen mit configure ersetzen.

Eine Regel den Systemen beschreiben, die sie nutzen

Eine Regel oder ein Add-on kann neben ihrem Code einen Deskriptor arex.module/1 veröffentlichen. Er ist ein versioniertes JSON-Dokument, das die Parameter und Einstellungen des Contracts nennt, die Chargenfelder, die er liest, die erwarteten Zertifikatstypen, seine Ereignisse und Ablehnungscodes und wie sein Zustand in eine neue Version übergeht. Eine Plattform, eine Wallet, ein Indexer oder ein Auditor liest ihn, um die Regel anzuzeigen, sie zu konfigurieren und eine Ablehnung zu erklären, ohne für diese Regel eigens Code zu schreiben. Seit Revision 1.1 kann der Deskriptor auch die Operationen angeben, die die Regel steuert (ops: mint, transfer, burn, forced_transfer, transform). Das Feld ist informativ: Fehlt es, sind die Operationen unbekannt, und kein Verbraucher darf sich zur Durchsetzung darauf verlassen, denn es entscheiden die Prüfungen des Hooks selbst. Revision 1.2 ergänzt zweierlei. Eine Einstellung kann einen Ort nennen (ref:site): Gespeichert wird die originRef, die dort erzeugte Chargen tragen, oder der Verweis auf den Herkunftsnachweis außerhalb der Chain, den sie stattdessen tragen (zum Beispiel eine EUDR-Sorgfaltserklärung), nie eine Adresse oder Koordinaten. Und das deklarierte Gas von check und onExecuted wird mit gefüllten Einstellungen gemessen: Vor der Messung ruft ein Validator jede Operation, die einen Wert setzt oder hinzufügt, setup-mal je Schlüssel mit Testwerten auf (8, sofern der Deskriptor nichts anderes angibt, höchstens 32), sodass eine Regel, die eine konfigurierbare Liste durchläuft, angibt, was sie mit voller Liste kostet. Revision 1.3 hält fest, was der erste Nutzer des Deskriptors bereits verwendet, damit seine Deskriptoren gegen das veröffentlichte Schema bestehen: die Aktionen, die Personen über eine Freigabe erfassen (die Einträge eines Add-ons, jeweils mit der Rolle, die sie aufrufen darf), die eigenen Fehler des Vertrags in Worten, Kennzahlen über seine Einträge, die Angabe je Lieferung, die eine Regel liest, eine vollständige Form seiner Ereignisse mit ihren Feldern und Texten sowie weitere Werttypen (eine Charge, ein Eintrag des Moduls, ein kurzer Text, ein nur über seinen Fingerabdruck gespeicherter Text). Jedes neue Feld ist optional, sodass jeder frühere Deskriptor gültig bleibt. Revision 1.4 beschreibt jeden Wert so genau, dass sich daraus ein Formular bauen lässt: neue Werttypen (ein Betrag mit Währung, Datum und Uhrzeit, ein über seinen Fingerabdruck gespeichertes Dokument, ein Code mit Format wie eine GTIN, ein Land oder eine Region, eine Einheit, eine Person oder eine Partei des Verzeichnisses), was ins Register gelangt (der Wert, nur sein Fingerabdruck oder nichts; nie personenbezogene Daten), Titel, Hilfe, Beispiel, Abschnitt und Bedingungen jedes Felds, feldübergreifende Prüfungen aus einer geschlossenen Liste, berechnete Werte, außerhalb des Registers gehaltene Angaben, schreibgeschützte Ansichten neben einer Charge und wie ein Eintrag gezeigt wird: immer als Erklärung der Organisation, die ihn erfasst hat, nie als geprüft. Revision 1.5 versieht jeden Fingerabdruck mit Salt: Ein Deskriptor, der fingerprint: { "scheme": "salted-jcs/1" } angibt, speichert den Hash jedes Werts zusammen mit einem eigenen 32-Byte-Salt, sodass kurze Texte, Zahlen oder Flurstücksumrisse nicht durch Ausprobieren gefunden werden können. Revision 1.6 ergänzt Kennzahlen, die keine Summen sind: Neben count und sum kann eine Kennzahl der Durchschnitt, der niedrigste oder der höchste Wert (avg, min, max) eines Zahlenfelds der Datensätze sein. Sie brauchen dieses Zahlenfeld und werden nie über Gruppen oder Unternehmen hinweg addiert: Der Durchschnitt zweier Unternehmen ist der Mittelwert ihrer Datensätze, nicht der Mittelwert ihrer Durchschnitte. Kennzahlen lassen sich außerdem nach der Partei gruppieren, die die Charge angelegt hat (party), und nach ihrem Standort (site). Die Vorlage des Feuchte-Add-ons in Referenz-Release 2.0.0-alpha.10 deklariert eine: die durchschnittliche Feuchte bei der Annahme je Produkt und Standort. Eine Kennzahl über einen in Basispunkten erfassten Wert deklariert unit: "bp", und ein nutzendes System zeigt sie durch 100 geteilt als Prozentsatz an. Revision 1.7 lässt das visibleWhen eines Felds den Bedingungsbaum des Vokabular-Deskriptors über die anderen Felder desselben Formulars verwenden: Blätter { field, op, value }, verknüpft mit all, any und not, höchstens 3 Ebenen und 12 Blätter, nie ein Ausdruck und nie der Kontext des Datensatzes. Die einzelne Bedingung aus Revision 1.4 bleibt gültig, ist veraltet und wird als das entsprechende Blatt gelesen.

Der Deskriptor ist informativ und hat den Status Vorgeschlagen: Eingebracht hat ihn die A-REX Platform, sein erster Nutzer, und er wird zu einem empfohlenen Format, sobald ein zweiter, unabhängiger Implementierer ihn nutzt. Felder, die eine Regel dem Metadatendokument einer Charge hinzufügt, lägen unter extensions.<key> und würden durch das Schemafragment des Deskriptors validiert (ADR-017, Vorgeschlagen, für das Metadatenschema 1.3.0).

Eine Organisation kann auch ihr eigenes Vokabular als arex.vocab/1-Definitionen veröffentlichen: Arten von Feldarbeit (Rückschnitt, Bodenprobenahme), Prozessarten (eine 72-stündige Fermentation, eine Sortierung nach Siebgröße) und Stufenlisten je Produkt (Ernte, Trocknung, Schälen, Sortierung, Export). Es sind Daten, kein Code. Jede verwendet das Feldobjekt des Deskriptors, nennt ihre Version und ist einer Referenzstufenklasse und einem GS1-CBV-Geschäftsschritt zugeordnet, sodass auch ein Leser, der die Organisation nicht kennt, sie versteht. Eine Prozessart ist ein transform mit einem Typ, niemals eine neue Operation: Ihr processRef trägt ein 4-Byte-Kennzeichen des Typs und einen Fingerabdruck der Werte des Durchlaufs, sodass eine Regel nach dem Typ handeln und jeder den Durchlauf prüfen kann. Einträge erreichen das Ledger einzeln oder als tägliche Merkle-Wurzel, jeder Wert mit eigenem Salt festgelegt, sodass eine Organisation einige Felder offenlegen und andere zurückhalten kann. Ein übereinstimmender Fingerabdruck zeigt, dass sich ein Eintrag seit seiner Aufzeichnung nicht geändert hat, nie, dass die Arbeit wie angegeben ausgeführt wurde. Das Format ist informativ und Vorgeschlagen (Revision 1.5 des Vokabular-Deskriptors). Revision 1.1 fügt ein optionales form hinzu, das die Felder in Abschnitte und Breiten gliedert und festlegt, wie sich jedes Feld verhält (Bedingungen, Standardwerte, schreibgeschützte und berechnete Werte, Masken und Muster); es schränkt nur ein, was die Felder annehmen, sodass ein Leser, der es ignoriert, jeden Datensatz wie bisher liest. Revision 1.2 gibt Bedingungen eine kleine Sprache, die sie mit dem Regeldeskriptor teilen: not, bis zu 3 Ebenen und 12 Blätter sowie Blätter, die lesen, was die Plattform über den Datensatz weiß, in Codes, die in jeder Sprache gleich lauten (die Kultur als EPPO-Code, die Tage seit der Pflanzung, die Art des Standorts, das Land, die HS-Position des Produkts der Charge, ihre letzte Stufe). Unbekannter Kontext gilt als leer, und jede Bedingung aus Revision 1.1 bleibt so gültig, wie sie geschrieben ist. Revision 1.3 lässt eine Stufenliste ihre Reihenfolge (order) angeben: Unter strict, der Vorgabe, wird eine Charge nicht auf einer Stufe erfasst, solange ihr eine erforderliche frühere Stufe fehlt, gezählt ab dem Punkt, an dem sie in die Liste eingetreten ist; unter flexible werden Stufen in beliebiger Reihenfolge erfasst und Lücken den Berichten überlassen. Eine Stufe, die aus der eigenen Geschichte der Charge folgt (ihre Registrierung, eine Transformation, eine Annahme), wird nie abgelehnt, und jede frühere Liste gilt als strict. Revision 1.4 lässt einen Prozesstyp angeben, welche Kaffee-Aufbereitungsmethode seine Ergebnisse tragen (washed, natural, honey mit den Varianten gelb, rot und schwarz, pulped_natural, wet_hulled, anaerobic, other), aus einem Feld des Laufs oder fest vom Typ vorgegeben, und die process-Metadaten einer Charge können die Methode (method) tragen (mixed nur für eine Charge). Es ist eine Erklärung der Organisation, keine Zertifizierung, und sie reist mit der Charge, auch wo die Werte der Schritte privat bleiben. Revision 1.5 lässt eine Zuordnung zu einer der breiten Klassen separating, conditioning, sorting_grading oder heat_treating eine subclass aus einer geschlossenen Liste je Klasse ergänzen (etwa hulling, curing, screen, roasting), und ein Leser ordnet den Schritt einer anderen Organisation in einer breiten Klasse nur über seine Unterklasse oder eine ausdrückliche Zuordnung je Absender zu. Revision 1.6 ergänzt to_processor, eine Unterklasse von transporting: Ware, die an einen Verarbeiter geht, der sie für ihren Eigentümer bearbeitet (Lohnverarbeitung), sodass der Besitz wechselt, das Eigentum aber nicht.

Einen eigenen Hook schreiben

Das Beispiel contracts/examples/SeasonHook.sol bleibt im Repository. test/standard/ImplementationGuide.test.js führt es für Leser mit Zugang aus. SeasonalHook ist das Referenzmodul für mehrere Fenster je Rohstoff und je Operation.

Faustregeln:

  1. Die Symbole OK und OP_FORCED_TRANSFER sind im normativen Text definiert.
  2. Das Verhalten von Burns ist im normativen Text definiert.
  3. Der Rückruf check ist im normativen Text definiert.
  4. Codenamen wie ARexCodes.code("MYNS", "NAME") sind im normativen Text definiert.
  5. Flag-Werte sind im normativen Text definiert.
  6. Die Rückrufe onExecuted und check sind im normativen Text definiert.

Registrieren und Reihenfolge

Günstige Regeln mit hoher Ablehnungsquote gehören an den Anfang. HOOK_ADMIN_ROLE sollte hinter einem Multisig oder Timelock liegen: Wer die Pipeline kontrolliert, kontrolliert, welche Transfers möglich sind.

Tests

test/standard/helpers.js rollt den Referenz-Stack aus. RecordingHook zeichnet jeden Callback auf und kann angewiesen werden, mit einem beliebigen Code abzulehnen; ReentrantHook versucht, den Token aus onExecuted erneut zu betreten, und belegt damit die Sperre. DomainHooks.test.js und Extensions.test.js decken die portierten Hooks und Begleiter ab; Invariants.test.js führt eine mit festem Seed erzeugte zufällige Operationsfolge aus und prüft Mengenerhaltung, terminalen Status und dass canTransfer jedes Ergebnis vorhersagt. Ab Referenz-Release 2.0.0-alpha.8 liefert die Referenzimplementierung außerdem ein Hook-Kit (conformance/hooks/), Foundry-Suites, die jede Regel bestehen muss, und eine Modulvorlage (templates/module/). Release 2.0.0-alpha.9 ergänzt ein Add-on-Kit (conformance/addons/) und drei darauf getestete Add-on-Vorlagen: Feuchte bei der Annahme (GrainMoisture), ein Fairtrade-Zertifikat, erfasst als deklarierte Tatsache des Unternehmens (FairTradeCertificate), und eine an einen Erzeuger gezahlte Prämie, deren Betrag und Empfänger nur als gesalzene Fingerabdrücke erfasst werden (PremiumPayments).

Zusammenspiel mit ERC-3643-Compliance

Ein ERC-3643-Compliance-Modul stellt moduleCheck(from, to, value, compliance) bereit. Ein Hook, der es für OP_TRANSFER aufruft und false auf einen Code abbildet, macht für Security-Token geschriebene Länderbeschränkungen, Saldenobergrenzen und Zeitsperren für Chargen-Token wiederverwendbar. Der umgekehrte Weg – einen A-REX-Hook einem ERC-3643-Token zugänglich zu machen – ist ebenso mechanisch. Die Automated Compliance Engine von Chainlink lässt sich nach demselben Muster integrieren: Deren Policy-Engine wird zu einem Hook. Diese beiden Richtungen sind nicht implementierte Entwürfe. Der vorhandene Referenzadapter geht den umgekehrten Weg und liest nur: Er lässt ERC-3643-Wallets und Compliance-Werkzeuge jede Charge als ERC-3643-Token sehen, über einen reinen Benachrichtigungs-Hook, der einen Transfer weder erlauben noch verweigern kann (ADR-020, Vorgeschlagen).