Конверт транзакции
Каждая транзакция ZooBC, какого бы она ни была типа, — одна строка байтов с одинаковой структурой, которая называется конвертом. Собственные данные типа находятся в одном поле, теле; всё остальное (кто отправляет, кто получает, комиссия, время, необязательное сообщение) общее для всех 73 типов. Знания конверта достаточно, чтобы прочитать, оценить и проверить любую транзакцию.
Поля по порядку
| Поле | Размер | Примечания | |
|---|---|---|---|
| тип | 4 байта, little-endian | номер [[transactions | типа транзакции]] |
| версия | 1 байт | 1, 2 или 3 | |
| метка времени | 8 байт | секунды Unix | |
| отправитель | адрес | ||
| получатель | адрес | или 4-байтовый пустой маркер 02 00 00 00 | |
| комиссия | 8 байт | в атомарных единицах | |
| survival | 8 байт | версии 2 и 3 | |
| срок действия | 4 байта | версия 3 | |
| тело | 4-байтовая длина, затем тело | не более 65 536 байт | |
| часть эскроу | переменный | или 4-байтовый пустой маркер | |
| сообщение | 4-байтовая длина, затем сообщение | необязательно | |
| подпись | переменный | всегда последняя |
Адрес — это 4-байтовый номер типа, за которым следуют данные: всего 36 байт для нативного аккаунта ZBC_ и 24 для аккаунта Ethereum (см. Аккаунты и адреса). Каждая сумма — целое число атомарных единиц, и 1 ZBC равен 100 000 000 таких единиц.
Чего здесь нет
Нет лимита газа, потому что нет виртуальной машины, которую нужно было бы измерять: каждый тип — фиксированное правило, и его цена известна до подписания. Нет поля идентификатора цепочки: вместо него подпись охватывает хеш генезис-блока цепочки (см. Подписание транзакции). И нет поля nonce: цепочка хранит nonce каждого отправителя в собственном состоянии.
Версии
- Версия 1 не имеет поля survival.
- Версия 2 добавляет поле survival.
- Версия 3 добавляет ещё и поле срока действия, которое задаёт, как долго транзакция остаётся действительной (см. Срок действия и метки времени).
Транзакция версии 1, указывающая депозит survival, отклоняется, как и транзакция версии 1 или 2, указывающая срок действия: в их байтах для этого нет места.
Survival, тело, часть эскроу и сообщение
- Survival — либо 0, либо не меньше 10 000 000 атомарных единиц (0,1 ZBC). Это поле открывает запись долговечности, которая сохраняет транзакцию после обычной обрезки истории, и никогда не возвращается (см. Плата за сохранение данных (долговечность)). Транзакция, несущая в сообщении подписанную транзакцию чужой цепочки, такой депозит платить не может.
- Тело содержит не более 65 536 байт со структурой, определённой его типом.
- Часть эскроу могут нести только SendZBC и TransferToken; она превращает платёж в эскроу.
- Сообщение содержит не более 256 байт, если оно открытое, без нулевого байта; не более 320 байт, если зашифрованное (зашифрованное сообщение начинается с «ZBE1»); и не более 4 096 байт, если несёт нативную транзакцию чужой цепочки из Ethereum, Solana или Bitcoin.
Поле комиссии
Комиссия объявляется в атомарных единицах и должна быть не меньше минимальной комиссии транзакции: базовой комиссии за действие 0,025 ZBC, умноженной на шкалу комиссий, по которой голосуют зарегистрированные узлы, плюс платы за байты тела и сообщения, которые хранит каждый зарегистрированный узел. Поскольку минимальная комиссия зависит только от транзакции и параметров цепочки, кошелёк может запросить её у любого узла до подписания через GET /api/v1/blockchain/estimate-fee.
Комиссия ниже минимальной отклоняется, а блок, содержащий такую транзакцию, недействителен. Всё, что объявлено сверх минимальной комиссии, возвращается плательщику в том же блоке, поэтому переплата по ошибке ничего не стоит. Тип Empty, который ничего не перемещает, всё равно должен платить комиссию больше нуля, а несколько обязанностей, которые зарегистрированные узлы выполняют для сети, например доказательства хранения и аттестации событий, должны объявлять комиссию ровно 0. Статья комиссии объясняет формулу, возврат и то, куда уходят комиссии.