接著,透過File > New Project來建立範例的hicontract
(hi_contract)。先來看看include/hicontrat.hpp
這份檔案:
#include <eosio/eosio.hpp>
using namespace std;
using namespace eosio;
CONTRACT hicontract : 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;
};
其中可以注意到CONTRACT
、ACTION
、TABLE
,這是最重要的部份,CONTRACT
是整個智能合約,剩下的在定義可執行的活動和儲存於合約內的資料結構。這點和在v1.4.1時仍然相同,實際上是數個巨集。在之前,我還更習慣寫class [[eosio::contract]]
、[[eosio::action]] void
、struct [[eosio::table]]
,替換看看:
class [[eosio::contract]]
hicontract : public contract {
public:
using contract::contract;
[[eosio::action]]
void hi(name from, string message);
[[eosio::action]]
void clear();
private:
struct [[eosio::table]]
messages {
name user;...
};
typedef multi_index<name("messages"), messages> messages_table;
};
multi_index
也很重要,不過有些複雜...以後在說。
再來看看實際實現的src/hicontract.cpp
#include <hicontract.hpp>
ACTION hicontract::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 hicontract::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(hicontract, (hi)(clear))
可以看到兩個ACTION
都有require_auth()
要求驗證身份(簽章)。此外,在EOS Studio生成的程式碼中,還有EOSIO_DISPATCH(hicontract, (hi)(clear))
。不過在v1.8.0rc版本中的eosio.token
合約中,並不存在這一行;但是在v1.4.1之中還有,不知道新版本是不是可以省略了。EOSIO_DISPATCH
同樣也是一個巨集。