श्वेतपत्र · 07
हुक और संदर्भ मॉड्यूल
मानक को छुए बिना किसी अनुरूप टोकन में कार्यक्षमता कैसे जोड़ी जाती है: हुक कॉन्ट्रैक्ट, संदर्भ हुक, सहायक एक्सटेंशन, और अपना हुक कैसे लिखें, परखें और पंजीकृत करें।
मॉड्यूल प्रदर्शन हैं, मानक नहीं
A-REX Core और उसके मॉड्यूल के बीच वही संबंध है जो ERC-3643 और T-REX के अनुपालन मॉड्यूल के बीच है: जिस इंटरफ़ेस से मॉड्यूल जुड़ते हैं वह मानकीकृत है; मॉड्यूल नहीं। शून्य हुक वाला अनुरूप टोकन एक वैध A-REX टोकन है। किसी के भी द्वारा लिखा गया हुक प्रत्येक अनुरूप टोकन के साथ संगत है। यही इकोसिस्टम को मानक बदले बिना बढ़ने देता है।
graph LR
T[ARexToken<br/>अनुरूप टोकन] -->|"check / onExecuted / canSend / canReceive"| H1[EligibilityHook]
T --> H2[ExpiryHook]
T --> H3[AttestationHook]
T --> H4["आपका हुक"]
H3 --> A[ARexAttestations]हुक कॉन्ट्रैक्ट
| कॉलबैक | कब | अनिवार्य अपेक्षा |
|---|---|---|
check | बैलेंस बदलने से पहले, प्रत्येक प्रभावित आईडी के लिए, हुक पंजीकरण क्रम में, पहले गैर-शून्य पर रुकें | व्यू हो; नीति के कारण कभी रिवर्ट न करे |
onExecuted | बैलेंस बदलने के बाद, प्रत्येक आईडी के लिए, क्रम से | टोकन के बैलेंस बदलने वाले फ़ंक्शन कॉल न करे (टोकन लॉक्ड है) |
canSend / canReceive | प्रत्येक ट्रांसफ़र पर और टोकन के ERC-7943 व्यू के लिए | व्यू हों |
op इनमें से एक है: OP_MINT (1), OP_TRANSFER (2), OP_BURN (3), OP_FORCED_TRANSFER (4), OP_TRANSFORM (5)। ट्रांसफ़ॉर्मेशन में इनपुट to == 0 के साथ और आउटपुट from == 0 के साथ आते हैं। data ERC-1155 ट्रांसफ़र डेटा है; ट्रांसफ़ॉर्म के लिए abi.encode(processRef), बलपूर्वक ट्रांसफ़र के लिए खाली।
कॉल करने वाला टोकन msg.sender है। जिस हुक को बैच की आवश्यकता हो वह IARexBatch(msg.sender).batchOf(id) पढ़ता है।
संदर्भ हुक
EligibilityHook — अनुमति, ब्लॉक, प्रतिबंध
HOOK_ELIGIBILITY का प्रदर्शन करता है। एक वैकल्पिक अनुमति सूची, एक ब्लॉक सूची और एक प्रतिबंध सूची रखता है; canSend/canReceive उनका संयोजन लौटाते हैं; check SANCTIONED, SENDER_INELIGIBLE या RECEIVER_INELIGIBLE लौटाता है ताकि इंटरफ़ेस इनकार का कारण समझा सकें। बलपूर्वक ट्रांसफ़र की हमेशा अनुमति है: किसी प्रतिबंधित खाते से माल ज़ब्त करना ही प्रवर्तन का उद्देश्य है। प्रोडक्शन में सूचियाँ किसी पहचान रजिस्ट्री (ONCHAINID, EAS, वेरिफ़ायबल क्रेडेंशियल) या प्रतिबंध ऑरेकल से भरी जाती हैं; हुक को इससे फ़र्क नहीं पड़ता कि कौन-सा।
ExpiryHook — मॉड्यूल के बिना नाशवानता
स्टेटलेस। बैच से expiresAt और producedAt पढ़ता है। समाप्त हो चुके बैच के मिंट और ट्रांसफ़र को ब्लॉक करता है (BATCH_EXPIRED), पर बर्न (बट्टे खाते) या बलपूर्वक ट्रांसफ़र (प्रवर्तन) को नहीं। वैकल्पिक रूप से उन बैच के ट्रांसफ़र ब्लॉक करता है जो अभी उत्पादित नहीं हुए (BATCH_NOT_PRODUCED) — कटाई-पूर्व वित्तपोषण करने वाला प्लेटफ़ॉर्म उन्हें अनुमति देने के लिए फ़्लैग सेट करता है; स्पॉट मार्केटप्लेस उन्हें ब्लॉक करने के लिए। यह एक हुक नाशवानता का ब्लॉक करने वाला भाग कवर करता है; क्षय वक्र एक व्यू हेल्पर या ऑफ़-चेन मूल्यांकन बन जाते हैं।
AttestationHook — प्रति कमोडिटी विनियामक गेटिंग
कमोडिटी कोड को आवश्यक एटेस्टेशन विषय से मैप करता है। ट्रांसफ़र से पहले बैच पढ़ता है, आवश्यकता खोजता है, एटेस्टेशन रजिस्ट्री से isAttested पूछता है और अन्यथा ATTESTATION_MISSING लौटाता है। "कॉफ़ी को EUDR ड्यू-डिलिजेंस संदर्भ चाहिए", "जैविक-लेबल वाले बैच को वैध जैविक प्रमाणपत्र चाहिए", "मवेशी को स्वास्थ्य प्रमाणपत्र चाहिए" में से प्रत्येक setRequirement की एक कॉल है।
PerishabilityHook — क्षय मॉडल
प्रति कमोडिटी कोड क्षय कॉन्फ़िगरेशन, प्रति बैच ओवरराइड के साथ; मॉडल NONE, LINEAR (समाप्ति पर एक न्यूनतम स्तर तक), EXPONENTIAL (अर्ध-आयु) और STEP (प्रत्येक अंतराल पर गिरावट)। व्यू valueBps, secondsRemaining, isExpired। समाप्त बैच के मिंट और ट्रांसफ़र (BATCH_EXPIRED) तथा उन बैच के ट्रांसफ़र को ब्लॉक करता है जिनका शेष मूल्य शून्य है (PERISH:NO_VALUE); बर्न या प्रवर्तन को कभी ब्लॉक नहीं करता।
SeasonalHook — कटाई और व्यापार विंडो
प्रति कमोडिटी और ऑपरेशन निरपेक्ष [start, end] विंडो (प्रति कुंजी अधिकतम 16)। बिना विंडो वाली कमोडिटी/ऑपरेशन निर्बंध-रहित है। सामान्य उपयोग: OP_MINT कटाई विंडो तक सीमित, OP_TRANSFER व्यापार विंडो तक; अन्यथा SEASON_CLOSED।
DeliveryHook — अभिरक्षा और निपटान
प्रेषक किसी वाहक के माध्यम से किसी प्राप्तकर्ता को amount इकाइयों की डिलीवरी शेड्यूल करता है; इकाइयाँ लॉक हो जाती हैं (एक O(1) काउंटर, इसलिए check इतिहास पर कभी इटरेट नहीं करता)। वाहक और सेंसर पिकअप, ट्रांज़िट और तापमान रीडिंग (उल्लंघन फ़्लैग) दर्ज करते हैं; प्राप्तकर्ता डिलीवरी की पुष्टि करता है; विवाद मध्यस्थ के पास जाते हैं। निपटान स्वयं ERC-1155 ट्रांसफ़र है: प्रेषक → प्राप्तकर्ता, सटीक मात्रा, data = abi.encode(deliveryId) के साथ; check इसे केवल तब अनुमति देता है जब डिलीवरी DELIVERED हो और onExecuted उसे SETTLED चिह्नित करके अनलॉक कर देता है। मुक्त (अनलॉक्ड) इकाइयाँ चलती रहती हैं।
TraceabilityHook — EPCIS-आकार का इवेंट लॉग
प्रत्येक टोकन ऑपरेशन का अवलोकन करता है और उसे CBV बिज़नेस स्टेप (commissioning, shipping, destroying, transforming) तथा डिस्पोज़िशन (active, in_transit, destroyed, seized) से वर्गीकृत करता है; RECORDER_ROLE टोकन से असंबद्ध क्रिटिकल ट्रैकिंग इवेंट (कूलिंग, पैकिंग, प्राप्ति) readPoint और bizLocation के साथ दर्ज करती है। दो मोड: केवल-इमिट (प्रति ट्रांसफ़र लगभग +17 k गैस; इंडेक्सर लॉग फिर से बनाता है) या पर्सिस्ट (लगभग +184 k; getEvents ऑन-चेन उत्तर देता है, पेज-वार)।
सहायक एक्सटेंशन
तीन चिंताओं को कभी ट्रांसफ़र नियम होने की आवश्यकता नहीं थी; वे सामान्य कॉन्ट्रैक्ट हैं जो एटेस्टेशन पढ़ते या लिखते हैं:
| एक्सटेंशन | यह क्या करता है |
|---|---|
CommodityPriceOracle | रिपोर्टर प्रति कमोडिटी मूल्य जमा करते हैं; राउंड क्रमांकित होते हैं, कोरम द्वारा माध्यिका के साथ अंतिम किए जाते हैं, या न्यूनतम संख्या पूरी होने पर मैन्युअल रूप से; latestAnswer, isStale |
CarbonImmobilizationWrapper | किसी रजिस्ट्री में इम्मोबिलाइज़्ड क्रेडिट दर्ज करता है (रजिस्ट्री, सीरियल रेंज, विंटेज, टन, प्रमाण), टन को बैच से जोड़ता है, रिटायरमेंट और रिलीज़ को प्रतिबिंबित करता है, एटेस्टेशन AREX:CARBON:IMMOBILIZED लिखता है; क्रेडिट कभी मिंट नहीं करता |
ParametricInsurance | ERC-20 पूल; प्रति बैच एक ट्रिगर विषय वाली पॉलिसी; दावा तब भुगतान करता है जब ट्रिगर समाप्ति से पहले एटेस्ट हो |
अपना हुक लिखना
उदाहरण contracts/examples/SeasonHook.sol रिपॉज़िटरी में रहता है। test/standard/ImplementationGuide.test.js उसे पहुँच वाले पाठकों के लिए चलाता है। SeasonalHook प्रति कमोडिटी और प्रति ऑपरेशन कई विंडो का संदर्भ मॉड्यूल है।
व्यावहारिक नियम:
- प्रतीक
OKऔरOP_FORCED_TRANSFERनॉर्मेटिव पाठ में परिभाषित हैं। - बर्न का व्यवहार नॉर्मेटिव पाठ में परिभाषित है।
- कॉलबैक
checkनॉर्मेटिव पाठ में परिभाषित है। ARexCodes.code("MYNS", "NAME")जैसे कोड नाम नॉर्मेटिव पाठ में परिभाषित हैं।- फ़्लैग मान नॉर्मेटिव पाठ में परिभाषित हैं।
- कॉलबैक
onExecutedऔरcheckनॉर्मेटिव पाठ में परिभाषित हैं।
पंजीकरण और क्रम
सस्ते, उच्च-अस्वीकृति वाले नियम पहले रखें। HOOK_ADMIN_ROLE को मल्टीसिग या टाइमलॉक के पीछे होना चाहिए: जो पाइपलाइन को नियंत्रित करता है वही यह नियंत्रित करता है कि कौन-से ट्रांसफ़र संभव हैं।
परीक्षण
test/standard/helpers.js संदर्भ स्टैक डिप्लॉय करता है। RecordingHook प्रत्येक कॉलबैक दर्ज करता है और उसे किसी भी कोड के साथ अस्वीकार करने को कहा जा सकता है; ReentrantHook onExecuted से टोकन में पुनः प्रवेश का प्रयास करता है और लॉक को सिद्ध करता है। DomainHooks.test.js और Extensions.test.js पोर्ट किए गए हुक और सहायक कॉन्ट्रैक्ट कवर करते हैं; Invariants.test.js ऑपरेशनों का एक सीडेड यादृच्छिक अनुक्रम चलाता है और सप्लाई संरक्षण, अंतिम स्टेटस, तथा यह जाँचता है कि canTransfer प्रत्येक परिणाम की भविष्यवाणी करता है।
ERC-3643 अनुपालन के साथ अंतरसंचालन
एक ERC-3643 अनुपालन मॉड्यूल moduleCheck(from, to, value, compliance) उपलब्ध कराता है। जो हुक OP_TRANSFER के लिए इसे कॉल करता है और false को किसी कोड में मैप करता है, वह प्रतिभूति टोकन के लिए लिखे गए देश-स्तरीय निर्बंध, बैलेंस सीमाएँ और टाइम लॉक को बैच टोकन पर पुनः उपयोग-योग्य बनाता है। इसका उलटा — किसी A-REX हुक को ERC-3643 टोकन के सामने उपलब्ध कराना — उतना ही यांत्रिक है। Chainlink का Automated Compliance Engine उसी पैटर्न से एकीकृत होता है: उसका पॉलिसी इंजन एक हुक बन जाता है।