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))
```