Курс разработчика EOS. Часть 7. Пишем смарт-контракт. Визитка. Расширяем функционал
В прошлой статье мы рассмотрели и запустили наш смарт-контракт "визитку". В нашем смарт-контракте присутствовало всего лишь одно action - добавление пользователя.
В данной статье мы расширим функционал нашей визитки, добавив действия для обновления и просмотра данных.
Давайте изменим наш код в файле BusinessCard.cpp на следующий
#include "BusinessCard.hpp"
namespace BusinessCard {
using namespace eosio;
using std::string;
class Users : public contract {
using contract::contract;
public:
Users(account_name self) :contract(self) {}
//@abi action
void add(account_name account, string& username) {
/**
* We require that only the owner of an account can use this action
* or somebody with the account authorization
*/
require_auth(account);
/**
* We access the "user" table as creating an object of type "userIndex"
* As parameters we pass code & scope - _self from the parent contract
*/
userIndex users(_self, _self);
/**
* We must verify that the account doesn't exist yet
* If the account is not found the iterator variable should be users.end()
*/
auto iterator = users.find(account);
eosio_assert(iterator == users.end(), "Address for account already exists");
/**
* We add the new user in the table
* The first argument is the payer of the storage which will store the data
*/
users.emplace(account, [&](auto& user) {
user.account_name = account;
user.username = username;
user.age = 30;
user.address = "Minsk";
});
}
//@abi action
void update(account_name account, string& username, int64_t age, string& address) {
require_auth(account);
userIndex users(_self, _self);
auto iterator = users.find(account);
eosio_assert(iterator != users.end(), "Address for account not found");
/**
* We add the new user in the table
* The first argument is the payer of the storage which will store the data
*/
users.modify(iterator, account, [&](auto& user) {
user.username = username;
user.age = age;
user.address = address;
});
}
//@abi action
void getuser(const account_name account) {
userIndex users(_self, _self);
auto iterator = users.find(account);
eosio_assert(iterator != users.end(), "Address for account not found");
/**
* The "get" function returns a constant reference to the object
* containing the specified secondary key
*/
auto currentUser = users.get(account);
print("Username: ", currentUser.username.c_str(), " Age: ", currentUser.age, " Address: ", currentUser.address.c_str());
}
private:
//@abi table user i64
struct user {
uint64_t account_name;
string username;
uint64_t age;
string address;
uint64_t primary_key() const { return account_name; }
EOSLIB_SERIALIZE(user, (account_name)(username)(age)(address))
};
typedef multi_index<N(user), user> userIndex;
};
EOSIO_ABI(Users, (add)(update)(getuser))
}
Посмотрим, что же у нас изменилось? Мы добавили еще два action:
void getuser(const account_name account) {};
и
void update(account_name account, string& username, int64_t age, string& address) {}
Код обоих действий интуитивно понятен если вы читали предыдущие две статьи. В первом action getuser мы ищем пользователя и выводим все его данные функцией
print("Username: ", currentUser.username.c_str(), " Age: ", currentUser.age, " Address: ", currentUser.address.c_str());
Во втором action update мы также ищем пользователя и обновляем его данные (поля). Для обновления данных используем функцию modify
users.modify(iterator, account, [&](auto& user) {
user.username = username;
user.age = age;
user.address = address;
});
Также обратите внимание, что у нас в макрос EOSIO_ABI(Users, (add)(update)(getuser)) добавилось еще два action - update и getuser.
Пришло время запускать наш код. Перекомпилируем контракт (т.к. мы его изменили). В консоли вводим
eosiocpp -o BusinessCard.wast BusinessCard.cpp
eosiocpp -g BusinessCard.abi BusinessCard.cpp
и задеплоим
cleos set contract buscardacc BusinessCard BusinessCard.wast BusinessCard.abi
Добавим данные пользователя, как мы это делали в предыдущей статье
cleos push action buscardacc add '["buscardacc","Igor Artemenko"]' -p buscardacc@active
Данные успешно добавились. Теперь просмотрим данные пользователя
cleos push action buscardacc getuser '["buscardacc"]' -p buscardacc@active
обновим данные нашей визитки
cleos push action buscardacc update '["buscardacc","IgorArt",34,"Moscow"]' -p buscardacc@active
Резюме
Мы приобрели достоаточное количество знаний и теперь можем самостоятельно писать контракты.