Whitepaper · 13
Анализ производительности
Измеренный газ эталонной реализации с нулём, одним и двумя хуками; что определяет стоимость; и рекомендации по развёртыванию.
Метод
Приведённые ниже числа получены запуском scripts/gas-report-standard.js во встроенной (in-process) сети Hardhat на скомпилированной эталонной реализации (solc 0.8.22, viaIR, optimizer.runs = 1 для ARexToken), сентябрь 2026 г. «Тёплый» означает ту же пару отправитель/получатель/id, что и в предыдущем переводе (слоты хранилища уже затронуты в блоке). Хуки: EligibilityHook (CHECK + ELIGIBILITY) и ExpiryHook (CHECK). Воспроизвести можно командой:
npx hardhat run scripts/gas-report-standard.js
Результаты
xychart-beta
title "Газ тёплого перевода по числу хуков (тысячи)"
x-axis ["без хуков", "Eligibility", "Eligibility + Expiry"]
y-axis "газ (тыс.)" 0 --> 140
bar [66.8, 91.2, 119.6]Стоимость растёт линейно с числом хуков: каждый из них — это один внешний вызов check на каждый id, а для хука допуска ещё и canSend и canReceive. В таблице приведены все операции.
| Операция | 0 хуков | 1 хук | 2 хука |
|---|---|---|---|
createBatch (новый id, эмиссия 1000) | 264,096 | 283,831 | 299,396 |
safeTransferFrom (первый, «холодный») | 80,687 | 108,266 | 136,682 |
safeTransferFrom («тёплый») | 66,790 | 91,166 | 119,582 |
transform, разделение 1 → 2 (два новых id) | 564,422 | 595,707 | 636,858 |
setFrozenTokens | 54,188 | 54,188 | 54,188 |
forcedTransfer | 80,152 | 89,909 | 99,569 |
burn | 66,621 | 83,001 | 93,395 |
«Тёплый» перевод ровно с одним хуком каждого вида (предельная стоимость правила):
xychart-beta horizontal
title "Дополнительный газ одного хука при тёплом переводе (тысячи)"
x-axis ["DeliveryHook", "Traceability (события)", "EligibilityHook", "ExpiryHook", "SeasonalHook", "PerishabilityHook"]
y-axis "добавленный газ (тыс.)" 0 --> 35
bar [12.3, 17.4, 24.4, 25.2, 27.5, 31.0]TraceabilityHook в режиме сохранения добавляет 184.5k и не показан на диаграмме из-за масштаба.
| Хук | Газ | Δ относительно перевода без хуков |
|---|---|---|
| EligibilityHook | 91,166 | +24,376 |
| ExpiryHook | 92,023 | +25,233 |
| SeasonalHook | 94,324 | +27,534 |
| PerishabilityHook | 97,813 | +31,023 |
| DeliveryHook (нет активной доставки) | 79,076 | +12,286 |
| TraceabilityHook, только события | 84,152 | +17,362 |
| TraceabilityHook, с сохранением | 251,273 | +184,483 |
От чего зависит стоимость
- Перевод без хуков в «тёплом» состоянии стоит ~67k, то есть ERC-1155 плюс учёт предложения плюс чтение существования, статуса и замороженного количества партии и служебные операции конвейера (сохранение данных, блокировка). Это нижняя граница.
- Каждый хук добавляет примерно 25–30k к переводу: один вызов
check(view, между контрактами) плюс, для хуков допуска, вызовыcanSendиcanReceive. Стоимость линейна по числу хуков и по числу id в пакетном переводе. Опрос каждого контракта-правила на каждую возможность черезsupportsInterfaceперед вызовом добавил бы несколько статических вызовов на каждый id; такие накладные расходы отсутствуют, потому что флаги кэшируются при регистрации. - В
createBatchпреобладает стоимость хранилища: структураBatch(шесть слов плюс строка) и слоты баланса и предложения ERC-1155. Это единовременная стоимость на лот. transformсоздаёт новые id: разделение на две партии оплачивает две записи партий, две эмиссии и одно сжигание плюс вызовы хуков на каждом звене (OP_TRANSFORM). Разделение на n частей стоит примерноn × createBatchплюс сжигание; объединение n в одну — примерноnсжиганий плюс один createBatch.- Принудительное исполнение обходится дёшево: заморозка — один слот; принудительный перевод стоит столько же, сколько перевод, плюс запись разморозки и событие.
transferCheck/canTransfer— view-функции: бесплатны офчейн и проходят тот же путь кода, что и транзакция.
Что даёт такая архитектура
| Архитектура с опросом возможностей | A-REX Core (ARexToken) | |
|---|---|---|
| Перевод с n контрактами-правилами | id × модули × (опросы supportsInterface + вызов хука) до выполнения какой-либо логики | id × хуки × 1 вызов (+2 для хуков допуска); флаги кэшируются при регистрации |
| Отказ | откат со строкой (копируется в память, не индексируется) | пользовательская ошибка с адресом хука и кодом bytes32 |
| Родословная | недоступна | ~280k на каждую выходную партию |
| Заморозка / принудительный перевод | недоступны | 54k / 80k |
Левый столбец описывает архитектуру, которую заменяет A-REX Core (ADR-004, ADR-005); измерен только правый столбец.
Рекомендации по развёртыванию
- Стоимость в деньгах равна
gas × gas price × token price, и два последних множителя меняются на порядки между сетями и днями. Исключительно в качестве иллюстрации: при 0.01 gwei и 3,000 USD за ETH «тёплый» перевод с двумя хуками (119,582 газа) стоит около 0.0036 USD, аcreateBatch(264,096 газа) — около 0.008 USD; при 20 gwei в основной сети Ethereum те же операции стоят около 7.2 и 15.8 USD. Перед принятием модели юнит-экономики следует провести измерения в целевой сети. - Пакетные переводы:
safeBatchTransferFromраспределяет фиксированные расходы; стоимость хуков по-прежнему растёт с числом id. - Порядок хуков: дешёвые хуки с высокой долей отказов следует ставить первыми; отказ останавливает конвейер до выполнения более дорогих хуков.
- Число хуков: от трёх до пяти хватает большинству эмитентов; каждый дополнительный хук — это измеримая стоимость каждого перевода и дополнительная поверхность управления.
- Метаданные:
uriследует делать коротким (CID или Digital Link); строка хранится ончейн. - Офчейн-чтение: перед отправкой следует использовать
transferCheck; транзакция с откатом всё равно стоит газа.
Пропускная способность
Узким местом является не сам токен, а сеть. Один перевод — это одна транзакция; преобразование с n выходами — это одна транзакция с n эмиссиями. Индексация родословной требует чтения событий BatchTransformed, которые генерируются один раз на операцию с полными списками количеств, поэтому индексатору не нужно ничего восстанавливать из событий отдельных переводов.
Размер контракта
ARexToken развёртывается размером 24,136 байт (лимит 24,576), скомпилированный с optimizer.runs = 1. Остальные контракты невелики: ARexAttestations — 2,708; хуки — от 1,358 (ExpiryHook) до 6,215 (DeliveryHook), TraceabilityHook — 4,076; расширения — от 3,716 до 4,588. Добавление функциональности в сам токен ограничено размером по замыслу — именно для этого существуют хуки и сопутствующие контракты.