Платформа EOS все еще довольно новая, мы пытались найти любую информацию о платформе EOS, не говоря уже об API базы данных, который предоставляет платформа EOS.
На данный момент мы нашли только этот видеоурок и Справочник по API является наиболее информативным, но в остальном он был довольно скудным.
Это дало нам, Fueled, задачу и возможность просто разобраться в этом, покопавшись в фактическом исходном коде EOS. Мы изложили то, что узнали, читая, так что вам не нужно (надеюсь). Я лично не гарантирую, что все в этой статье полностью правильно или все еще актуально, поскольку разработка EOS продолжается, но это может дать вам лучшее представление о базе данных EOS и ее функциях.
Программное обеспечение EOS использует смарт-контракты для сохранения данных об использовании RAM и имеет несколько хороших примеров, которые вы можете использовать, мы просмотрели их все, прочитав построчно, и вот наш первый результат, наш введение в базу данных EOS.
Введение в базу данных EOS
База данных EOS - это специальная функция, которая позволяет хранить индексированные данные в цепочке блоков, отформатированные внутри определенных структур данных. Наличие базы данных в блокчейне не означает, что каждый имеет право выполнять запись / чтение в этой базе данных. База данных EOS в основном состоит из нескольких уровней, как описано в contracts/eosiolib/db.h
, имеет простую идею:
* EOS.IO organizes data according to the following broad structure: * * — **code** — the account name which has write permission * — **scope** — an account where the data is stored * — **table** — a name for the table that is being stored * — **record** — a row in the table
Есть некоторые используемые термины, которые отличаются от тех, что вы слышали раньше, здесь я изложил, что означают эти термины.
- code
- это число, которое соответствует коду вашего контракта. Вы, возможно, видели это раньше, создавая смарт-контракты на EOS, это «идентификатор» смарт-контракта.
- scope
Поскольку контракт может быть развернут несколько раз, идентификатор контракта равен не хватит. Область видимости может быть любой, но обычно это идентификатор учетной записи, с которой она развертывается.
- table
Имя таблицы.
- record
Надеюсь, это говорит само за себя.
Структурирование ваших таблиц
Таблицы базы данных EOS могут быть отформатированы по struct
типу данных, в этих структурах вы можете определить именование и определение типа ваших свойств этой таблицы.
Давайте посмотрим на пример:
Итак, давайте пройдемся по частям кода и выделим некоторые из требований, определенных EOS.
Аннотации ABI
// @abi table proposal i64
Для развертывания контракта вы запустите код с помощью команды eosiocpp
, компилятор смарт-контрактов EOS может считывать комментарии над вашими struct
и общедоступными функциями. есть 2 типа, которые вы можете пройти; action
и table
, что говорит само за себя. Эта аннотация комментария извлекается генератором abi (находится в библиотеках / abi_generator / abi_generator.cpp # 201) для добавления этого метода или определения таблицы в вывод ABI.
Второй аргумент, то есть «предложение», дает вам возможность указать другое имя таблицы. Последний - определить тип таблицы, которую вы хотите использовать, на данный момент кажется, что есть только версия для i64
, что означает 64-битную индексированную таблицу.
Другие типы, которые вы можете пройти, - это str
для запроса по строке. i64
, i64i64i64
и i128i128
, все относятся к типу целочисленного primary_key, который в основном увеличивает количество возможных индексных номеров.
Определение типа владельца учетной записи
account_name owner = 0
Пакет EOSIO поставляется с определением настраиваемого типа для хранения ссылки на имя учетной записи, это учетная запись, которую вы создаете в своем собственном локальном кошельке EOS.
Это определение настраиваемого типа, включенное в платформу EOS. Как бы он ни выглядел индивидуально, на самом деле он просто хранится как uint64_int
.
Списки в вашей таблице
Вы можете сохранять векторные объекты внутри определения вашей таблицы. Это означает, что вы можете легко создавать простые вложенные коллекции в своих схемах.
В этом примере у нас есть векторное отображение избирателя (account_name) и веса голоса (uint32_t).
std::vector<account_name, uint32_t> votes;
Первичные ключи uint64_t primary_key() const { return id; }
Класс eosio::multi_index
требует, чтобы ваша структура данных возвращала первичный ключ для вашей строки. Это необходимо, и это можно сделать, создав primary_key()
метод на вашем struct
. В этом примере показано, как мы приводим его к uint64_t
, но это также может быть account_name
, который, в свою очередь, является uint64_t
замаскированным.
Серализация потока данных
EOSLIB_SERIALIZE( <StructName>, (field1)(field2)(field3))
Мне всегда было интересно, что конкретно это означает в примерах контрактов EOS. Зная, что это определенно макрос, я начал изучать код и лучше разбираться в системе. Глубоко покопавшись, я прочитал contracts/eosiolib/serialize.hpp
и обнаружил, что он использует макрос `BOOST_PP_SEQ_FOR_EACH`
(вот что он делает). Он в основном предоставляет дополнительные операторы структуры для сериализации и десериализации данных в базу данных multi_index и из нее.
Запросы, изменение и создание
База данных EOS Multi Index имеет некоторые функции для получения информации. Хотя функции не так обширны, как что-то вроде SQL-запроса, но он делает свои основы:
- Запрос записи с помощью .find
- Создание новых записей с помощью .emplace
- Изменение существующих записей с помощью .modify
Получение предметов
Для получения записи по ее первичному ключу мы просто запускаем: auto itr = proposals.find(proposal_id)
Что возвращает вам итератор, который запросил элемент результата, кэшированный в частном порядке. Этот итератор предоставляет вам несколько весьма полезных функций для просмотра таблицы. Просматривая multi_index внутри EOS, мы видим, что у него есть несколько изящных методов оператора:
Итератор сам по себе может вернуть текущий объект путем разыменования объекта или как экземпляр объекта:
print(eosioitr->property) // reference print((*itr).property) // instance Proposal proposal = *itr // get object instance
Следующий и предыдущий объекты
Затем можно выполнить итерацию самого по себе, чтобы получить следующий или предыдущий объект внутри базы данных. Это может быть полезно во время итерации по объектам в этой таблице.
auto nextitr = itr++; auto previtr = itr--;
Под капотом. Для меня понимание предмета действительно помогает мне понять основные функции, а также обычно раскрывает их простоту. То же самое и с EOS: после рытья кода метод .find()
просто запускает std::find_if
function, которая проверяет, имеет ли зацикленный элемент правильный первичный ключ:
ptr._item->primary_key() == input_primary
Изменение предметов
Чтобы изменить объект, вы можете использовать метод .modify
. Этот метод принимает следующие аргументы: modify( const T& obj, uint64_t payer, Lambda&& updater )
Примером может быть:
auto iter = proposals.find(proposal_id); // assert basically checks if iteration is at the end, meaning there is // no value eosio_assert(iter != proposals.end(), “Could not find proposal”); proposals.modify( iter, _self, [&]( auto& proposal) { proposal.description = “New value” });
В нашей первой строке мы возвращаем объект-итератор, который затем проверяется, находится ли список в конце таблицы multi_index, что означает отсутствие элемента.
После этого мы передаем этот объект-итератор в наш modify
вызов, второй аргумент будет _self
. Эта ссылка унаследована от класса eosio::contract
, и обозначает account_name
, развернувшего этот контракт.
Как видите, второй аргумент метода modify
- это лямбда-функция, в которой вы получите ссылку на объект для обновления.
Создание новых предметов
Чтобы создать новый элемент, вы можете использовать метод .emplace
из класса multi_index
. Используются следующие аргументы:
emplace( uint64_t payer, Lambda&& constructor )
Как видите, первый аргумент - это снова payer
ссылка. При каждом взаимодействии с EOS, как и с транзакцией ETH, есть кто-то, кто «платит» за хранение, мы рассмотрим это в следующей статье.
Пример вставки может быть:
auto new_proposal = proposals.emplace( _self, [&]( auto& proposal) { proposal.id = proposals.available_primary_key(); proposal.owner = sender; proposal.description = description; });
Собираем все вместе
Если объединить все это в один контракт, это будет выглядеть примерно так:
Мы продолжим рассмотрение 45_ примера голосования в следующих публикациях, чтобы продолжить работу над EOS.
Обновление:
Как мне сказали другие читатели, они хотели поделиться своими ресурсами, с которыми они работали, вот некоторые ресурсы для продолжения обучения:
Посмотрите это видео о разработке EOS:
Я более чем открыт для отзывов и советов по этому сообщению, так как это новая тема для меня, дайте мне знать!