श्वेतपत्र · 05
तकनीकी विनिर्देश
A-REX Core का नॉर्मेटिव सारांश: अनुरूपता, इंटरफ़ेस, ऑपरेशन शब्दार्थ, हुक कॉन्ट्रैक्ट, एटेस्टेशन, स्टोरेज और अपग्रेड नियम। प्रामाणिक पाठ standard/AREX-CORE.md है; यह अध्याय श्वेतपत्र के पाठकों के लिए उसे दोहराता है।
अनुरूपता
एक अनुरूप टोकन के लिए ERC-1155, ERC-165, IERC7943MultiToken (0x41c4fbad) और IARexBatch (0xe22639e0) को लागू करना तथा अपनी पाइपलाइन को IARexHookManager.getHooks() (0x964f4861) के माध्यम से उपलब्ध कराना अनिवार्य है। उसे IARexAttest (0xad603a6c) को सीधे या किसी सहायक कॉन्ट्रैक्ट के माध्यम से लागू करना चाहिए। एक अनुरूप हुक के लिए IARexHook (0x332afcbb) और ERC-165 को लागू करना अनिवार्य है। सभी आईडी npm run interface-ids द्वारा पुनः उत्पन्न की जाती हैं।
निश्चित स्थिरांक
| स्थिरांक | मान | अर्थ |
|---|---|---|
OP_MINT | 1 | नई इकाइयाँ (createBatch) |
OP_TRANSFER | 2 | धारक द्वारा आरंभ किया गया ट्रांसफ़र |
OP_BURN | 3 | मोचन, डिलीवरी, बट्टे खाते में डालना |
OP_FORCED_TRANSFER | 4 | प्रवर्तन |
OP_TRANSFORM | 5 | transform के इनपुट (to = 0) और आउटपुट (from = 0) |
HOOK_CHECK | 1 | हुक check चाहता है |
HOOK_EXECUTED | 2 | हुक onExecuted चाहता है |
HOOK_ELIGIBILITY | 4 | हुक canSend / canReceive का उत्तर देता है |
STATUS_ACTIVE | 0 | डिफ़ॉल्ट |
STATUS_RETIRED | 255 | अंतिम |
इसके अलावा सब कुछ — कमोडिटी कोड, इकाई कोड, 1..254 स्टेटस, अस्वीकृति कोड, एटेस्टेशन विषय — खुला है। अनुशंसित परंपराएँ ARexCodes में हैं।
परत 1 — IARexBatch
interface IARexBatch is IERC165 {
struct BatchInit { bytes32 commodity; bytes32 unit; uint64 producedAt; uint64 expiresAt; bytes32 originRef; bytes32 metadataHash; string uri; }
struct Batch { address issuer; uint64 createdAt; uint8 status; bytes32 commodity; bytes32 unit; uint64 producedAt; uint64 expiresAt; bytes32 originRef; bytes32 metadataHash; string uri; }
event BatchCreated(uint256 indexed id, address indexed issuer, bytes32 indexed commodity, bytes32 unit, uint256 quantity, address to);
event BatchStatusChanged(uint256 indexed id, uint8 previousStatus, uint8 newStatus, bytes32 reason);
event BatchMetadataUpdated(uint256 indexed id, bytes32 metadataHash, string uri);
event BatchTransformed(address indexed operator, uint256[] inputIds, uint256[] inputAmounts, uint256[] outputIds, uint256[] outputAmounts, bytes32 processRef);
error ARexBatchNotFound(uint256 id);
error ARexBatchRetired(uint256 id);
error ARexInvalidBatch(bytes32 reason);
error ARexInvalidStatusTransition(uint256 id, uint8 from, uint8 to);
error ARexLengthMismatch();
function createBatch(BatchInit calldata init, uint256 quantity, address to, bytes calldata data) external returns (uint256 id);
function batchOf(uint256 id) external view returns (Batch memory);
function batchExists(uint256 id) external view returns (bool);
function totalSupply(uint256 id) external view returns (uint256);
function setBatchStatus(uint256 id, uint8 status, bytes32 reason) external;
function setBatchMetadata(uint256 id, bytes32 metadataHash, string calldata uri) external;
function transform(address from, address to, uint256[] calldata inputIds, uint256[] calldata inputAmounts, BatchInit[] calldata outputs, uint256[] calldata outputAmounts, bytes32 processRef) external returns (uint256[] memory outputIds);
function parentsOf(uint256 id) external view returns (uint256[] memory);
}
शब्दार्थ
createBatch
- अधिकृत खातों तक सीमित होना अनिवार्य है; प्राधिकार का टोकन बैलेंस से व्युत्पन्न होना वर्जित है।
- जब
quantity == 0,commodity == 0,unit == 0, याexpiresAt != 0 && producedAt != 0 && expiresAt <= producedAtहो, तबARexInvalidBatchके साथ रिवर्ट करना अनिवार्य है। producedAt == 0को स्वीकार करना अनिवार्य है (कटाई-पूर्व)।- पाइपलाइन को
OP_MINTके साथ चलाना अनिवार्य है; पहलेBatchCreatedऔर फिरTransferSingleइमिट करना अनिवार्य है।
setBatchStatus
- भूमिका-सीमित होना अनिवार्य है।
255अंतिम है। रिटायर किए गए बैच: कोई मिंट नहीं, कोई ट्रांसफ़र नहीं (ARexBatchRetired), बर्न की अनुमति है।
transform
msg.senderकाfromहोना याfromद्वारा सभी के लिए अनुमोदित होना अनिवार्य है।- असंगत लंबाइयों पर
ARexLengthMismatchके साथ रिवर्ट करना अनिवार्य है, और खाली इनपुट या आउटपुट सूचियों पर रिवर्ट करना अनिवार्य है। - इनपुट बर्न करना, आउटपुट मिंट करना,
parentsOf(output) = inputIdsसेट करना, और आउटपुट परissuer = msg.senderसेट करना अनिवार्य है। - प्रत्येक बर्न और प्रत्येक मिंट के लिए पाइपलाइन को
OP_TRANSFORMके साथ,data = abi.encode(processRef)के साथ, चलाना अनिवार्य है। - प्रति आउटपुट
BatchCreated, ERC-1155 इवेंट और एकBatchTransformedइमिट करना अनिवार्य है। - मात्रा संरक्षण अनिवार्य नहीं है। संदर्भ कार्यान्वयन री-बैचिंग (समान कमोडिटी और इकाई,
Σin == Σout; कोई भी धारक) को प्रसंस्करण (TRANSFORMER_ROLE) से अलग करता है।
मेटाडेटा
metadataHashकाuriपर स्थित कैनोनिकल दस्तावेज़ काkeccak256होना अनिवार्य है। दस्तावेज़ कोstandard/schema/batch-metadata.schema.jsonका पालन करना चाहिए।originRefमें कच्चे निर्देशांक या प्राकृतिक व्यक्तियों के आइडेंटिफ़ायर होना वर्जित है।
परत 0 — IERC7943MultiToken
ERC-7943 से शब्दशः (forcedTransfer, setFrozenTokens, canSend, canReceive, getFrozenTokens, canTransfer; इवेंट ForcedTransfer, Frozen; एरर ERC7943CannotSend, ERC7943CannotReceive, ERC7943CannotTransfer, ERC7943InsufficientUnfrozenBalance)। A-REX ये स्पष्टीकरण जोड़ता है:
canTransferका false होना अनिवार्य है जब पॉज़ हो, जब बैच मौजूद न हो या रिटायर हो, जब पात्रता विफल हो, जबamount > balance − frozenहो, या जब कोई CHECK हुकOP_TRANSFERको अस्वीकार करे।- जहाँ
canTransferfalse है वहाँ सार्वजनिक ट्रांसफ़र का सफल होना वर्जित है। forcedTransferका भूमिका-सीमित होना, पात्रता को बायपास करना, फ़्रीज़ की गई राशि को इतना घटाना कि वह शेष बैलेंस से कभी अधिक न हो (Frozenइमिट करते हुए), हुक कोOP_FORCED_TRANSFERके साथ चलाना, औरForcedTransferइमिट करना अनिवार्य है; और उसे पॉज़ की स्थिति में भी काम करना चाहिए।canSend/canReceiveसभीHOOK_ELIGIBILITYहुक का संयोजन (AND) हैं।- टोकन को
transferCheck(from, to, id, amount) → bytes32उपलब्ध कराना चाहिए।
परत 2 — हुक
interface IARexHook is IERC165 {
error ARexHookRejected(address hook, bytes32 code);
function hookFlags() external view returns (uint8);
function check(uint8 op, address operator, address from, address to, uint256 id, uint256 amount, bytes calldata data) external view returns (bytes32 code);
function onExecuted(uint8 op, address operator, address from, address to, uint256 id, uint256 amount, bytes calldata data) external;
function canSend(address account) external view returns (bool);
function canReceive(address account) external view returns (bool);
}
interface IARexHookManager {
event HookRegistered(address indexed hook, uint8 flags, uint256 position);
event HookRemoved(address indexed hook);
error ARexHookAlreadyRegistered(address hook);
error ARexHookNotRegistered(address hook);
error ARexInvalidHook(address hook);
function getHooks() external view returns (address[] memory);
function hookFlagsOf(address hook) external view returns (uint8);
function registerHook(address hook) external;
function removeHook(address hook) external;
}
टोकन के दायित्व: क्रमबद्ध सूची; पंजीकरण के समय supportsInterface(0x332afcbb) सत्यापित करना और गैर-शून्य फ़्लैग कैश करना; प्रत्येक आईडी के लिए प्रत्येक CHECK हुक पर check कॉल करना और किसी भी बैलेंस परिवर्तन से पहले पहले गैर-शून्य कोड पर ARexHookRejected(hook, code) के साथ रिवर्ट करना; बैलेंस के बाद प्रत्येक आईडी के लिए प्रत्येक EXECUTED हुक पर onExecuted कॉल करना; अनुक्रम के दौरान रीएंट्रेंसी रोकना; data अग्रेषित करना; सूची और फ़्लैग सार्वजनिक रखना।
हुक के दायित्व: स्थिर फ़्लैग; check एक व्यू है जो कोड लौटाता है और नीति के कारण कभी रिवर्ट नहीं करता; कॉल करने वाला टोकन msg.sender है; जब तक नियम प्रवर्तन को शासित न करता हो, OP_FORCED_TRANSFER के लिए 0 लौटाएँ; onExecuted बैलेंस बदलने वाले फ़ंक्शन को कभी कॉल नहीं करता।
परत 3 — IARexAttest
interface IARexAttest is IERC165 {
struct Attestation { address issuer; bytes32 ref; uint64 issuedAt; uint64 expiresAt; bool revoked; }
event Attested(uint256 indexed id, bytes32 indexed topic, address indexed issuer, bytes32 ref, uint64 expiresAt);
event AttestationRevoked(uint256 indexed id, bytes32 indexed topic, address indexed issuer, bytes32 reason);
event TrustedIssuerUpdated(bytes32 indexed topic, address indexed issuer, bool trusted);
error ARexUntrustedIssuer(bytes32 topic, address issuer);
error ARexAttestationNotFound(uint256 id, bytes32 topic);
function attest(uint256 id, bytes32 topic, bytes32 ref, uint64 expiresAt) external;
function revokeAttestation(uint256 id, bytes32 topic, bytes32 reason) external;
function getAttestation(uint256 id, bytes32 topic) external view returns (Attestation memory);
function isAttested(uint256 id, bytes32 topic) external view returns (bool);
function isTrustedIssuer(bytes32 topic, address issuer) external view returns (bool);
}
attest के लिए उस विषय का विश्वसनीय जारीकर्ता और एक मौजूदा बैच आवश्यक है। isAttested तब false है जब एटेस्टेशन अनुपस्थित, निरस्त या समाप्त हो, या जारीकर्ता अब विश्वसनीय न रहा हो। जारीकर्ता अपने स्वयं के एटेस्टेशन निरस्त करते हैं; प्रशासक किसी भी एटेस्टेशन को निरस्त कर सकता है।
अस्वीकृति कोड (अनुशंसित)
PAUSED, FROZEN, SENDER_INELIGIBLE, RECEIVER_INELIGIBLE, SANCTIONED, BATCH_NOT_FOUND, BATCH_RETIRED, BATCH_INACTIVE, BATCH_EXPIRED, BATCH_NOT_PRODUCED, LIMIT_EXCEEDED, DOCUMENT_MISSING, SEASON_CLOSED, IN_TRANSIT, ATTESTATION_MISSING के लिए keccak256("AREX:" + NAME)। कस्टम कोड: keccak256("NAMESPACE:NAME")।
संदर्भ कार्यान्वयन के तथ्य
| गुण | मान |
|---|---|
| आधार | OpenZeppelin 5.3.0 अपग्रेड-योग्य: ERC1155, ERC1155Supply, AccessControl, Pausable, UUPS |
| स्टोरेज | ERC-7201 नेमस्पेस arex.storage.token, स्लॉट 0x8ed599b6be05dec05297c009a1279a71df771ad996fe924d0b5a47326ff60900 |
| कंपाइलर | solc 0.8.22, viaIR, EVM paris; ARexToken के लिए optimizer.runs = 1 (24,136 बाइट डिप्लॉय किए गए), अन्यत्र 200 |
| भूमिकाएँ | ISSUER, TRANSFORMER, STATUS, ENFORCER, HOOK_ADMIN, PAUSER, UPGRADER, DEFAULT_ADMIN; ARexAttestations पर ATTEST_ADMIN |
| रीएंट्रेंसी | पूरे _update अनुक्रम के चारों ओर स्टोरेज लॉक; ReentrantHook टेस्ट द्वारा परखा गया |
| डेटा अग्रेषण | safeTransferFrom / safeBatchTransferFrom / createBatch हुक के लिए data सहेजते हैं; transform abi.encode(processRef) पास करता है |
| मेटाडेटा | uri(id) सेट होने पर बैच URI लौटाता है, अन्यथा बेस URI |
| टेस्ट | test/standard में 46: जीवनचक्र, वंशावली, फ़्रीज़ और बलपूर्वक ट्रांसफ़र, हुक क्रम, अस्वीकृति, डेटा और रीएंट्रेंसी, एटेस्टेशन, इंटरफ़ेस आईडी, अपग्रेड प्राधिकरण, डोमेन हुक, एक्सटेंशन, यादृच्छिक इनवेरिएंट, और आरंभ से अंत तक निष्पादित कार्यान्वयन मार्गदर्शिका |
मानक का संस्करण-निर्धारण
सिग्नेचर, इवेंट या किसी अनिवार्य आवश्यकता में कोई भी परिवर्तन माइग्रेशन नोट सहित मेजर संस्करण होता है। जोड़ने वाली अनुशंसाएँ (कोड, स्कीमा फ़ील्ड) माइनर होती हैं। परिवर्तन केवल तभी स्वीकार किए जाते हैं जब दो स्वतंत्र कार्यान्वयनकर्ता अपनाए जाने की पुष्टि करें। इंटरफ़ेस को ERC के रूप में तब तक सबमिट नहीं किया जाएगा जब तक एक प्रोडक्शन डिप्लॉयमेंट छह महीने न चल ले, तीन स्वतंत्र हुक कार्यान्वयन मौजूद न हों और तृतीय-पक्ष ऑडिट प्रकाशित न हो जाए।