Целочисленное ядро и ABI
Все контракты используют одну схему блока v2. ABI 3 фиксирует программу из
16 инструкций, два постоянных беззнаковых 64-битных регистра (state0,
state1), неизменяемые правила авторизации и адреса получателей. Каждый вызов
начинается с нулевых временных регистров (scratch0, scratch1). Регистрация
приложения, собственная матрица и отдельное доказательство не нужны.
Инструкции
| Операция | Действие над регистром назначения |
|---|---|
keep |
Сохранить значение |
move |
Скопировать левый операнд |
add, subtract |
Беззнаковое сложение или вычитание с проверкой границ |
min, max |
Минимум или максимум операндов |
less_than, equal |
Записать логическое 0 или 1 |
assert_equal, assert_less_or_equal |
Отклонить неверное сравнение; сохранить регистр |
Нарушение утверждения, переполнение, выход ниже нуля или нелогический предикат отклоняют вызов. Арифметика не зацикливается по модулю. Инструкции выполняются последовательно и видят предыдущие записи. Итоговая постоянная пара становится новым состоянием при продолжении. Закрытие тоже исполняет программу, но не создаёт преемника.
Инструкция выбирает один из четырёх регистров назначения, два операнда и
предикат: always, before_deadline, terminal, has_payout, scratch0 или
scratch1. Поле inverted инвертирует выбранное логическое значение. Неактивная
инструкция не меняет регистр. Неиспользованные последние инструкции заполняются
каноническими операциями keep.
{
"opcode": "add",
"destination": "state0",
"left": "state0",
"right": "one",
"predicate": {"source": "terminal", "inverted": true},
"immediate": "0"
}
Этот пример считает продолжающие вызовы. Это одна инструкция, а не полная политика расходования. Обязательные явные поля политики описаны в интеграции API.
Операнды
| Группа | Имена |
|---|---|
| Регистры | state0, state1, scratch0, scratch1 |
| Константы | immediate, zero, one |
| Контекст | height, fee, payout, retained, input_amount |
| Флаги | before_deadline, after_deadline, terminal, has_payout |
| Владелец выхода 1 | payout_owner0, payout_owner1, payout_owner2, payout_owner3 |
| Точная инкарнация и слоты | input_creation_id, input_slot, retained_slot, payout_slot |
height — высота включения. before_deadline означает height < deadline;
after_deadline включает равенство. Отдельного операнда deadline нет: другую
границу задают константой инструкции. Слова владельца — четыре u64 в порядке
little-endian из канонического 32-байтного обязательства владельца.
Контекст программы следует физическим позициям выходов. retained и
retained_slot всегда относятся к выходу 0; payout, payout_slot и слова
владельца — к выходу 1. При закрытии выход 0 платит получателю закрытия, а
выход 1 отсутствует. Поэтому ядро видит сумму закрытия как retained и
payout = 0, тогда как смысловой результат RPC показывает выплату и нулевой
оставшийся баланс контракта. В собственной программе различайте эти случаи
через terminal.
Политика и обязательство
Неизменяемая политика содержит полномочия и получателей основной и возвратной ветвей, высоту границы, потолок комиссии, предел выплаты за вызов, минимальный остаток и пять флагов. Флаги отдельно разрешают продолжение и закрытие в каждой ветви и произвольного получателя продолжающей выплаты. Неявного администратора нет. Точные правила ветвей и сумм приведены в жизненном цикле.
Три обязательства с разными доменами связывают программу (CNTCODE_), политику
(CNTPOL__) и живое состояние (CNTOBJ__). Итоговые 32 байта кодируются как
адрес контракта. Изменение любого постоянного счётчика меняет этот адрес.
Кошелёк группирует состояния по неизменяемым условиям; это локальная группировка,
а не зарегистрированный глобальный аккаунт контракта.
Каноническое публичное раскрытие занимает 699 байт:
| Поле | Байт |
|---|---|
Маркер NOIDOBJ3 + версия ABI little-endian |
8 + 2 |
| 16 пар дескриптор/константа | 16 × 32 |
| Упакованное постоянное состояние | 16 |
| Два полномочия и два получателя | 4 × 32 |
| Высота границы | 8 |
| Потолок комиссии, резерв, предел выплаты и байт режимов | 8 + 8 + 8 + 1 |
Дескриптор и константа занимают по 128 бит little-endian. Дескриптор использует
20 бит: операция 4, назначение 2, левый операнд 5, правый 5, предикат 3,
инверсия 1. Остальные биты нулевые, константа должна помещаться в u64.
state0 занимает младшие 64 бита состояния, state1 — старшие.
Используйте штатный кодировщик/API, а не собственный формат.
В JSON счётчики и константы инструкций — канонические десятичные строки,
от "0" до "18446744073709551615". Ведущие нули, знаки и дробные значения
недопустимы. Остальные целочисленные поля API имеют документированный числовой
формат; клиент должен обрабатывать их без потери точности.
Область применения
Ядро поддерживает ограниченные независимо финансируемые права: бюджеты, делегирование расходов, отложенный доступ, регулярные требования и поэтапное освобождение. Циклов, неограниченного хранилища, межконтрактных вызовов, сетевого доступа и автоматического таймера нет. Нужна авторизованная транзакция. Каждый депозит имеет собственные счётчики: два депозита не образуют общий бюджет.
Программу и политику нельзя обновить на месте. Разрешённая выплата может перевести средства в новые условия. Приложения в пределах ABI не требуют новой матрицы; добавление операций консенсуса может потребовать обновления протокола. Проверяйте логику во всех разрешённых ветвях, включая возврат и закрытие.