Skip to main contentA-REX Foundation

Whitepaper · 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до изменения балансов, для каждого затронутого id, хуки в порядке регистрации, остановка на первом ненулевом значениибыть view-функцией; никогда не откатываться из-за политики
onExecutedпосле изменения балансов, для каждого id, по порядкуне вызывать функции токена, изменяющие баланс (токен заблокирован)
canSend / canReceiveпри каждом переводе и для view-функций ERC-7943 токенабыть view-функциями

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): платформа, финансирующая до уборки урожая, устанавливает флаг так, чтобы разрешать их; спотовая торговая площадка — так, чтобы блокировать. Этот единственный хук покрывает блокирующую часть скоропортящести; кривые порчи становятся вспомогательной view-функцией или офчейн-оценкой.

AttestationHook — регуляторные ограничения по товарам

Сопоставляет код товара с обязательной темой аттестации. Перед переводом читает партию, находит требование, запрашивает у реестра аттестаций isAttested и в противном случае возвращает ATTESTATION_MISSING. Правила «кофе нужна ссылка на должную осмотрительность по EUDR», «партиям с маркировкой органической продукции нужен действующий сертификат органической продукции», «скоту нужен санитарный сертификат» — это по одному вызову setRequirement каждое.

PerishabilityHook — модели порчи

Конфигурация порчи по коду товара с переопределением для отдельной партии; модели NONE, LINEAR (до нижнего порога к моменту истечения срока), EXPONENTIAL (период полураспада) и STEP (ступенчатое снижение через каждый интервал). View-функции 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 — эталонный модуль для нескольких окон на товар и на операцию.

Практические правила:

  1. Символы OK и OP_FORCED_TRANSFER определены в нормативном тексте.
  2. Поведение сжигания определено в нормативном тексте.
  3. Обратный вызов check определён в нормативном тексте.
  4. Имена кодов, такие как ARexCodes.code("MYNS", "NAME"), определены в нормативном тексте.
  5. Значения флагов определены в нормативном тексте.
  6. Обратные вызовы onExecuted и check определены в нормативном тексте.

Регистрация и порядок

Дешёвые правила с высокой долей отказов следует ставить первыми. HOOK_ADMIN_ROLE следует размещать за мультиподписью или таймлоком: тот, кто контролирует конвейер, контролирует, какие переводы возможны.

Тестирование

test/standard/helpers.js развёртывает эталонный стек. RecordingHook записывает каждый обратный вызов и может получить указание отклонять с любым кодом; ReentrantHook пытается повторно войти в токен из onExecuted и подтверждает работу блокировки. DomainHooks.test.js и Extensions.test.js покрывают перенесённые хуки и сопутствующие контракты; Invariants.test.js выполняет случайную последовательность операций с зафиксированным seed и проверяет сохранение предложения, терминальность статуса и то, что canTransfer предсказывает каждый исход.

Взаимодействие с комплаенсом ERC-3643

Модуль комплаенса ERC-3643 предоставляет moduleCheck(from, to, value, compliance). Хук, который вызывает его для OP_TRANSFER и сопоставляет false с кодом, делает ограничения по странам, лимиты баланса и временные блокировки, написанные для токенов-ценных бумаг, пригодными для повторного использования на токенах партий. Обратное — предоставление хука A-REX токену ERC-3643 — столь же механично. Chainlink Automated Compliance Engine интегрируется по тому же шаблону: его движок политик становится одним хуком.