Skip to main contentA-REX Core

الورقة البيضاء · 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_MINT1كميات جديدة (createBatch)
OP_TRANSFER2تحويل يبدؤه الحامل
OP_BURN3الاسترداد، أو التسليم، أو الشطب
OP_FORCED_TRANSFER4الإنفاذ
OP_TRANSFORM5مدخلات transform (to = 0) ومخرجاتها (from = 0)
HOOK_CHECK1الخطاف يطلب check
HOOK_EXECUTED2الخطاف يطلب onExecuted
HOOK_ELIGIBILITY4يجيب الخطاف عن canSend / canReceive
STATUS_ACTIVE0الافتراضي
STATUS_RETIRED255نهائي

كل ما عدا ذلك — أكواد السلع، وأكواد وحدات القياس، والحالات 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

  • يجب تقييدها بحسابات مخوّلة؛ ويجب ألا يُشتق التخويل من رصيد الرمز.
  • يجب أن تتراجع بالخطأ ARexInvalidBatch عندما تكون quantity == 0 أو commodity == 0 أو unit == 0 أو expiresAt != 0 && producedAt != 0 && expiresAt <= producedAt.
  • يجب قبول 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).

metadata

  • يجب أن يكون metadataHash هو keccak256 للمستند بصيغته القياسية الموجود في uri. وينبغي أن يتبع المستند 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.
  • يجب ألا تنجح التحويلات العامة حيث تكون canTransfer false.
  • يجب تقييد forcedTransfer بدور، ويجب أن تتجاوز الأهلية، ويجب أن تخفض المقدار المجمّد بحيث لا يتجاوز أبدًا الرصيد المتبقي (مع إصدار Frozen)، ويجب أن تشغّل الخطافات مع OP_FORCED_TRANSFER، ويجب أن تُصدر ForcedTransfer، وينبغي أن تعمل أثناء الإيقاف المؤقت.
  • canSend / canReceive هما الاقتران المنطقي لجميع خطافات HOOK_ELIGIBILITY.
  • ينبغي أن يتيح الرمز 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) عند أول كود غير صفري قبل أي تغيير في الأرصدة؛ واستدعاء onExecuted لكل معرّف ولكل خطاف EXECUTED بعد تحديث الأرصدة؛ ومنع إعادة الدخول أثناء التسلسل؛ وتمرير data؛ وإبقاء القائمة والأعلام عامة.

التزامات الخطاف: أعلام ثابتة؛ وcheck دالة عرض تُرجع الأكواد ولا تتراجع أبدًا لأسباب تتعلق بالسياسة؛ والرمز المستدعي هو msg.sender؛ وإرجاع 0 لـ OP_FORCED_TRANSFER ما لم تكن القاعدة تحكم الإنفاذ؛ ولا تستدعي 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 إذا كانت الإفادة غائبة أو مُبطَلة أو منتهية الصلاحية، أو إذا لم تعد جهة الإصدار موثوقة. وتبطل جهات الإصدار إفاداتها الخاصة؛ ويجوز للمسؤول إبطال أي إفادة.

أكواد الرفض (الموصى بها)

keccak256("AREX:" + NAME) لكل من 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("NAMESPACE:NAME").

حقائق التنفيذ المرجعي

الخاصيةالقيمة
الأساسOpenZeppelin 5.3.0 القابل للترقية: ERC1155 وERC1155Supply وAccessControl وPausable وUUPS
التخزينفضاء أسماء ERC-7201 arex.storage.token، والخانة 0x8ed599b6be05dec05297c009a1279a71df771ad996fe924d0b5a47326ff60900
المترجمsolc 0.8.22، وviaIR، وEVM paris؛ وoptimizer.runs = 1 لـ ARexToken (24,136 بايت بعد النشر)، و200 في غيره
الأدوارISSUER وTRANSFORMER وSTATUS وENFORCER وHOOK_ADMIN وPAUSER وUPGRADER وDEFAULT_ADMIN؛ وATTEST_ADMIN في ARexAttestations
إعادة الدخولقفل تخزين حول تسلسل _update بأكمله؛ يجري اختباره بواسطة اختبار ReentrantHook
تمرير البياناتتحفظ safeTransferFrom / safeBatchTransferFrom / createBatch القيمة data للخطافات؛ وتمرّر transform القيمة abi.encode(processRef)
البيانات الوصفيةتُرجع uri(id) عنوان URI الخاص بالدفعة إذا ضُبط، وإلا فعنوان URI الأساسي
الاختبارات46 اختبارًا في test/standard: دورة الحياة، والنسب، والتجميد والتحويل القسري، وترتيب الخطافات، والرفض، والبيانات وإعادة الدخول، والإفادات، ومعرّفات الواجهات، وتفويض الترقية، وخطافات المجال، والامتدادات، والثوابت العشوائية، ودليل التنفيذ منفَّذًا من البداية إلى النهاية

إصدارات المعيار

أي تغيير في توقيع دالة أو حدث أو بند MUST يمثل إصدارًا رئيسيًا مع ملاحظة ترحيل. أما التوصيات الإضافية (الأكواد وحقول المخطط) فتمثل إصدارًا ثانويًا. ولا تُقبل التغييرات إلا حين يؤكد منفّذان مستقلان تبنّيها. ولن تُرفع الواجهات بوصفها ERC قبل أن يعمل نشر إنتاجي واحد ستة أشهر، وتوجد ثلاثة تنفيذات مستقلة للخطافات، ويُنشر تدقيق من طرف ثالث.