Курс разработчика EOS. Часть 7. Пишем смарт-контракт. Визитка. Расширяем функционал

avatar igorart 6 months ago

Назад Содержание Вперед

В прошлой статье мы рассмотрели и запустили наш смарт-контракт "визитку". В нашем смарт-контракте присутствовало всего лишь одно 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

Резюме

Мы приобрели достоаточное количество знаний и теперь можем самостоятельно писать контракты.

Назад Содержание Вперед