ABI смарт-контракта¶
ABI (Application Binary Interface) — JSON-схема соответствия между текстовым/JSON-представлением аргументов действий и структур таблиц с бинарной сериализацией в транзакции. Узел исполняет WASM независимо от ABI; последний критичен для клиентов, кошельков и индексаторов. Генерация ABI в CDT снижает расхождения с кодом, однако контроль совместимости остаётся на разработчике.
Соответствие типов C++ контрактного API полям ABI и низкоуровневые детали сериализации — в документации CDT (Doxygen).
ABI не является «входным фильтром»
Транзакция может содержать данные, не совпадающие с ABI: узел исполняет WASM. ABI нужен кошелькам, обозревателям и SDK для удобства и безопасности на стороне клиента.
Генерация и ручное редактирование¶
Утилита cdt-cpp с флагом -abigen (и корректными атрибутами в коде) создаёт ABI автоматически. Ручное редактирование нужно, если:
- генератор «спотыкается» о сложные шаблоны C++;
- используются нестандартные типы;
- требуются расширения ABI (variants, optional-поля через
$и т.д.).
Пустой каркас:
{
"version": "eosio::abi/1.1",
"types": [],
"structs": [],
"actions": [],
"tables": [],
"ricardian_clauses": [],
"abi_extensions": []
}
Секция types¶
Описывает псевдонимы типов. Встроенные типы цепочки в ABI дублировать не нужно (их набор определяется сериализатором узла; список смотрите в исходниках abi_serializer вашей версии узла).
Пример псевдонима:
Секции structs и fields¶
Каждая структура:
{
"name": "transfer",
"base": "",
"fields": [
{ "name": "from", "type": "name" },
{ "name": "to", "type": "name" },
{ "name": "quantity", "type": "asset" },
{ "name": "memo", "type": "string" }
]
}
- Неявные структуры соответствуют параметрам публичных действий, для которых нет отдельного
structв C++. - Явные структуры описывают строки таблиц
[[eosio::table]].
Поле base задаёт наследование от другой структуры в том же ABI (редко; должно соответствовать логике C++).
Секция actions¶
name— имя действия в цепочке.type— имя struct с полями параметров (часто совпадает сname, но это не обязательно).ricardian_contract— текст Ricardian или пустая строка, если подключается из внешнего файла при сборке.
Секция tables¶
{
"name": "accounts",
"type": "account",
"index_type": "i64",
"key_names": ["currency"],
"key_types": ["uint64"]
}
Имена ключей могут совпадать между таблицами — это лишь подсказка для клиентов; важно соответствие типов и struct.
Векторы¶
Тип массива записывается как тип[], например permission_level[].
Ricardian: файлы и разметка¶
Генератор подхватывает:
- договоры действий — файл
<имя_контракта>.contracts.md; - общие клаузы —
<имя_контракта>.clauses.md.
Для каждого действия в markdown используйте заголовок:
Для клаузы:
Чтобы ABI-генератор нашёл файлы в произвольных каталогах, передайте -R<путь> в cdt-cpp (аналогично -I для include). Пример из upstream: examples/hello/ricardian/hello.contracts.md.
Атрибуты C++ для генератора ABI¶
[[eosio::action]]¶
Помечает метод как действие. Альтернатива в стиле GNU: __attribute__((eosio_action)).
Если имя функции не является допустимым именем цепочки:
[[eosio::action("validname")]]
Можно объявлять действие как struct с EOSLIB_SERIALIZE.
[[eosio::table]]¶
Описание строки таблицы; для явного имени таблицы: [[eosio::table("tablename")]].
[[eosio::contract("name")]]¶
Привязывает класс к имени контракта для генерации, чтобы заголовки чужих контрактов не попадали в ваш ABI.
[[eosio::on_notify("acct::action")]]¶
Обработчик уведомлений о чужом действии; шаблон *::transfer — любой контракт.
[[eosio::wasm_entry]] / eosio_wasm_import¶
Расширенные сценарии сборки WASM для других окружений.
[[eosio::action, eosio::read-only]]¶
Действие только чтения; ограничения см. Действия и авторизация.
Обслуживание ABI¶
При каждом изменении:
- параметров действий;
- полей таблиц;
- имён таблиц;
обновляйте ABI. Ошибки при этом часто не возникают, а клиенты начинают слать неверный JSON — отлаживайте через сравнение с cdt-abidiff (см. Справочник команд).
Таблица «пустая» в клиенте¶
Проверьте, что секция tables и type указывают на существующий struct с верными полями. cleos может не ругаться на плохой ABI, но вернёт пустой результат.
abi_extensions и прочее¶
abi_extensions зарезервировано под будущие расширения формата; сейчас обычно пусто. Ricardian-тексты описывают намерение действия для пользователя.
Где углубиться¶
- Практика обновления полей без поломки строк — Обновление схемы данных.
- Сборка с ABI — Сборка контрактов.