tier 1 ```c++ #include <eosio/eosio.hpp> using namespace std; using namespace eosio; CONTRACT test : public contract { public: using contract::contract; ACTION hi(name from, string message); ACTION clear(); private: TABLE messages { name user; string text; auto primary_key() const { return user.value; } }; typedef multi_index<name("messages"), messages> messages_table; }; ``` ```c++ #include <test.hpp> ACTION test::hi(name from, string message) { require_auth(from); // Init the _message table messages_table _messages(get_self(), get_self().value); // Find the record from _messages table auto msg_itr = _messages.find(from.value); if (msg_itr == _messages.end()) { // Create a message record if it does not exist _messages.emplace(from, [&](auto& msg) { msg.user = from; msg.text = message; }); } else { // Modify a message record if it exists _messages.modify(msg_itr, from, [&](auto& msg) { msg.text = message; }); } } ACTION test::clear() { require_auth(get_self()); messages_table _messages(get_self(), get_self().value); // Delete all records in _messages table auto msg_itr = _messages.begin(); while (msg_itr != _messages.end()) { msg_itr = _messages.erase(msg_itr); } } EOSIO_DISPATCH(test, (hi)(clear)) ``` tier 2 ```c++ #include <eosio/eosio.hpp> using namespace std; using namespace eosio; CONTRACT test : public contract { public: using contract::contract; ACTION hi(name from, name to, string message); ACTION clear(name from); private: TABLE messages { name user_to; string text; auto primary_key() const { return user_to.value; } }; typedef multi_index<name("messages"), messages> messages_table; }; ``` ```c++ #include <test.hpp> ACTION test::hi(name from, name to, string message) { require_auth(from); // Init the _message table messages_table _messages(get_self(), from.value); // Find the record from _messages table auto msg_itr = _messages.find(to.value); if (msg_itr == _messages.end()) { // Create a message record if it does not exist _messages.emplace(to, [&](auto& msg) { msg.user_to = to; msg.text = message; }); } else { // Modify a message record if it exists _messages.modify(msg_itr, from, [&](auto& msg) { msg.text = message; }); } } ACTION test::clear(name from) { require_auth(from); messages_table _messages(get_self(), from.value); // Delete all records in _messages table auto msg_itr = _messages.begin(); while (msg_itr != _messages.end()) { msg_itr = _messages.erase(msg_itr); } } EOSIO_DISPATCH(test, (hi)(clear)) ``` ```c++ #include <eosio/eosio.hpp> #include <eosio/asset.hpp> using namespace std; using namespace eosio; CONTRACT test : public contract { public: using contract::contract; ACTION hi(name from, name to, string message); ACTION clear(name from); ACTION clear2(name from, uint32_t limit); [[eosio::on_notify("eosio.token::transfer")]] void deposit(name from, name to, eosio::asset quantity, std::string memo); private: TABLE messages { name user_to; string text; auto primary_key() const { return user_to.value; } }; typedef multi_index<name("messages"), messages> messages_table; TABLE payments { name user; asset amount; auto primary_key() const { return user.value; } }; typedef multi_index<name("payments"), payments> payments_table; }; ``` tier 3 ```c++ #include <test.hpp> ACTION test::hi(name from, name to, string message) { require_auth(from); payments_table payments(get_self(), get_self().value); const auto &payment = payments.get(from.value); check(payment.amount >= asset(10, symbol("EOS", 4)), "fail"); payments.modify(payment, get_self(), [&](auto& row) { row.amount -= asset(10, symbol("EOS", 4)); }); // Init the _message table messages_table _messages(get_self(), from.value); // Find the record from _messages table auto msg_itr = _messages.find(to.value); if (msg_itr == _messages.end()) { // Create a message record if it does not exist _messages.emplace(to, [&](auto& msg) { msg.user_to = to; msg.text = message; }); } else { // Modify a message record if it exists _messages.modify(msg_itr, from, [&](auto& msg) { msg.text = message; }); } } ACTION test::clear(name from) { require_auth(from); messages_table _messages(get_self(), from.value); // Delete all records in _messages table auto msg_itr = _messages.begin(); while (msg_itr != _messages.end()) { msg_itr = _messages.erase(msg_itr); } } ACTION test::clear2(name from, uint32_t limit) { require_auth(from); messages_table _messages(get_self(), from.value); // Delete all records in _messages table auto msg_itr = _messages.begin(); while (msg_itr != _messages.end() && limit > 0) { msg_itr = _messages.erase(msg_itr); --limit; } } void test::deposit(name from, name to, eosio::asset quantity, std::string memo) { if (to == get_self()) { return; } payments_table payment(get_self(), get_self().value); auto payment_itr = payment.find(from.value); if (payment_itr != payment.end()) payment.modify(payment_itr, get_self(), [&](auto &row) { row.amount += quantity; }); else payment.emplace(get_self(), [&](auto &row) { row.amount = quantity; }); } EOSIO_DISPATCH(test, (hi)(clear)(clear2)) ```