Действия и транзакции
Действия¶
Для изменения состояния блокчейна в EOSIO используются действия. Действие — это атомарная операция, выполняемая в контексте определённого аккаунта и смарт-контракта. Она представляет минимальную единицу изменения состояния блокчейна. Все действия передаются и исполняются строго в порядке их указания в транзакции.
Действие - это атомарная операция по изменению состояния блокчейна
Каждое действие всегда связано с аккаунтом, который его выполняет, и системным смарт-контрактом, в котором действие выполняется. Действия при своём выполнении могут передавать данные в контракт.
Основные свойства действия:
-
Имя аккаунта контракта: Указывает, в рамках какого контракта выполняется действие.
-
Имя аккаунта пользователя: Указывает, какой аккаунт инициировал действие.
-
Имя действия: Определяет, какую операцию необходимо выполнить в рамках контракта.
-
Ипользуемое разрешение: Указывает уровень разрешения (например, active), необходимый для выполнения действия.
-
Параметры действия: содержит полезную нагрузку, на основании которой смарт-контракты изменяют состояние блокчейна;
Каждое действие может передавать данные в смарт-контракт в виде параметров. Эти данные часто включают идентификаторы пользователей, суммы транзакций, указания на файлы или другие метаданные, необходимые для выполнения операции.
mindmap
root((Действие))
ИмяКонтракта["Имя аккаунта контракта"]
ИмяПользователя["Имя аккаунта пользователя"]
ИмяДействия["Имя действия"]
Разрешение["Используемое разрешение"]
Данные["Полезная нагрузка"]
Транзакции¶
Транзакция представляет собой последовательность одного или нескольких действий, которые объединяются в одно целое и обрабатываются блокчейном как одна-единая атомарная операция. В случае, если хотя бы одно из действий в транзакции не проходит какой-либо проверки или вызывает ошибку при своём исполнении - то вся транзакция отклоняется.
Транзакция - последовательность одного или нескольких действий, которые группируются вместе и обрабатываются как единое целое.
Транзакциями изменяется состояние блокчейна. Для того, чтобы транзакция была принята блокчейном и смарт-контрактами, на ней должна быть цифровая подпись. На одной транзакции может быть одновременно несколько подписей, что делает возможным использование гибких мультисиг-сценариев авторизации.
Для того чтобы транзакция была принята блокчейном, она должна быть подписана приватным ключом, который связан с аккаунтом и обладает достаточными правами. После подписания транзакция проходит проверку протоколом и валидацию смарт-контракта перед записью изменений в блокчейн.
flowchart TB
subgraph Транзакция["Транзакция"]
Действие1["Действие 1"]
Действие2["Действие 2"]
Действие3["Действие 3"]
end
Подпись["Подпись приватным ключом"] --> Транзакция
Валидация¶
Все транзакции проверяются блокчейном в два этапа:
-
Валидация протоколом - здесь блокчейн сверяет подпись на соответствие к публичному ключу и имени аккаунта, который совершает действие. Если подпись на транзакции криптографически верна, соответствует аккаунту, и указанному им разрешению доступа, то поток управления валидацией передается на уровень смарт-контракта.
-
Валидация смарт-контрактом - здесь происходит сверка требований аудентификации на каждом действии в отдельности. Блокчейн применяет каждое действие, исполняя программный код и проверяя, что для каждой из представленных в нём строк есть достаточные права аудентификации. Требование аудентификации устанавливается и проверяется в программном коде системных смарт-контрактов.
sequenceDiagram
participant Пайщик as Пайщик
participant Блокчейн as Блокчейн
participant СмартКонтракт as Смарт-контракт
Пайщик->>Блокчейн: Подписанная транзакция
Блокчейн->>Блокчейн: Валидация протоколом
Блокчейн-->>Пайщик: Подпись верна
Блокчейн->>СмартКонтракт: Передача действий для проверки
СмартКонтракт->>Блокчейн: Валидация смарт-контрактом
Блокчейн-->>Пайщик: Транзакция принята
Таким образом, для изменения состояния блокчейна необходимо отправить подписанную транзакцию, которая содержит как минимум одно действие с информацией о том, какой аккаунт вызывает его, на каком аккаунте вызывает, как называется действие, которое вызывается, какие данные передаются.
Кооперативные транзакции¶
В текущей архитектуре пайщики самостоятельно транзакции по блокчейну не проводят. Во всех действиях, которые требуют изменения состояния блокчейна, подпись транзакции осуществляет сервисный приватный ключ кооператива, который хранится на сервере провайдера в зашифрованном виде.
Это в первую очередь необходимо для разделения ответственности между компонентами программного обеспечения, где пайщик взаимодействует только с программным обеспечением провайдера, а провайдер организует цифровую подпись транзакций и действий со своего сервера от имени и по заданию кооператива.
sequenceDiagram
participant Разработчик as Разработчики ПО
participant Провайдер as Провайдеры
participant ПО as Программное обеспечение провайдера
participant Транзакции as Транзакции
participant Контракты as Смарт-контракты
participant Блокчейн as Блокчейн
Разработчик->>Провайдер: Запрос через API с JWT
Провайдер-->>Разработчик: Ответ с результатом (JSON)
Провайдер->>ПО: Формирование запросов
ПО-->>Провайдер: Успешная обработка запроса
ПО->>Транзакции: Создание транзакции
Транзакции-->>ПО: Транзакция сформирована
Транзакции->>Контракты: Вызов действий
Контракты-->>Транзакции: Выполнение действий завершено
Контракты->>Блокчейн: Изменение состояния
Блокчейн-->>Контракты: Состояние обновлено
Так, разработчики прикладного программного обеспечения получают возможность использовать сервисы провайдеров и их API без избыточной сложности, связанной с организацией транзакций в блокчейн и извлечения информации из него. Эта зона остается ответственностью провайдеров на низком архитектурном уровне взаимодействия с платформой, т.к. разработчикам прикладного программного обеспечения в большинстве случаев будет достаточно обладать информацией и возможностями, которые предоставят ему провайдеры через свои API.
Спецификация¶
Транзакции формируются с использованием библиотеки coopjs. В дальнейших разделах будут представлены инструкции как именно создавать транзакции и где брать информацию о параметрах действий. Ниже же представлена спецификация транзакции с действиями в десериализованном виде:
{
"expiration": "2023-11-25T23:59:59", // Время истечения транзакции. Транзакция должна быть обработана до этого момента.
"ref_block_num": 12345, // Номер блока, на который ссылается транзакция (облегчает поиск).
"ref_block_prefix": 67890, // Префикс блока для проверки транзакции.
"max_net_usage_words": 0, // Максимальное использование сетевого ресурса в "словах".
"max_cpu_usage_ms": 0, // Максимальное использование CPU в миллисекундах.
"delay_sec": 0, // Задержка выполнения транзакции в секундах.
"context_free_actions": [], // Массив действий, не связанных с авторизацией. Обычно пуст.
"actions": [ // Массив действий, входящих в транзакцию.
{
"account": "eosio.token", // Имя аккаунта контракта, в котором вызывается действие.
"name": "transfer", // Имя действия, которое вызывается (например, "transfer").
"authorization": [ // Авторизация, необходимая для выполнения действия.
{
"actor": "useraccount1", // Имя аккаунта, который авторизует действие.
"permission": "active" // Разрешение, используемое для авторизации (active, owner и т.д.).
}
],
"data": { // Данные, передаваемые в смарт-контракт.
"from": "useraccount1", // Отправитель средств.
"to": "useraccount2", // Получатель средств.
"quantity": "10.0000 AXON", // Сумма перевода в формате количества и символа токена.
"memo": "Payment for services" // Заметка, описывающая транзакцию.
}
},
{
"account": "somecontract", // Имя другого контракта, если транзакция включает несколько действий.
"name": "someaction", // Имя действия (например, вызов кастомного действия в контракте).
"authorization": [
{
"actor": "useraccount3",
"permission": "owner"
}
],
"data": {
"key": "value" // Поля, специфичные для конкретного контракта и действия.
}
}
],
"transaction_extensions": [], // Расширения транзакции. Пока всегда пустой массив.
"signatures": [ // Массив цифровых подписей, подтверждающих транзакцию.
"SIG_K1_JyFhEj5f...etc" // Пример одной из подписей.
],
"context_free_data": [] // Дополнительные данные, не связанные с авторизацией (не используется).
}