智能合约是1994年由尼克萨博首次提出的理念,是一种旨在以信息化方式传播、验证或执行合约的计算机协议。智能合约允许在没有第三方的情况下进行可信交易。这些交易可追踪且不可逆。
区块链技术给我们带来了一个去中心化的,不可篡改的,高可靠性的系统,在这种环境下,智能合约才大有用武之地。智能合约是区块链最重要的特性之一,也是区块链能够被称为颠覆性技术的主要原因。
本质上可以使用任何文本编辑器,最好支持C++语法高亮显示。流行的编辑器有Sublime Text和Atom。另一个选项是IDE,它提供更复杂的代码完成和更完整的开发体验。欢迎您使用您个人喜欢的软件,如果您不确定使用什么,我们提供了一些选项供您选择。
推荐uosio.cdt 的代码和你的编译源码一起看。uosio.cdt有例子,很容易做到举一反三。而且查询接口也很容易查。你自己的程序也可以放到 ~/uosio.cdt/examples 目录下,方便比较。
#include <uosiolib/uosio.hpp> //合约库的头文件
#include <uosiolib/print.hpp> //使用打印输出,调试时候用
using namespace uosio; //uos合约的命名空间,接口都是在这个命名空间内
class [[uosio::contract]] addressbook : public uosio::contract {
//[[uosio::contract]]表示这个是合约,名称为 addressbook,必须从uosio::contract 继承
public:
using contract::contract; //直接使用 contract::contract 类型
addressbook(name receiver, name code, datastream<const char*> ds): contract(receiver, code, ds) {} //构造函数
[[uosio::action]]
void upsert(name user, std::string first_name, std::string last_name, std::string street, std::string city, std::string state) {
require_auth(user); //需要 user用户的授权,即user用户发起的交易就可以执行。
address_index addresses(_code, _code.value);
auto iterator = addresses.find(user.value); //在表中查找user的对象
if( iterator == addresses.end() ) //没找到则插入
{
addresses.emplace(user, [&]( auto& row ){
row.key = user;
row.first_name = first_name;
row.last_name = last_name;
row.street = street;
row.city = city;
row.state = state;
send_summary(user, " successfully emplaced record to addressbook");
increment_counter(user, "emplace");
});
}
else { //找到记录则更新
std::string changes;
addresses.modify(iterator, user, [&]( auto& row ) {
if(row.first_name != first_name) { //如果新的名字和旧名字不一样
row.first_name = first_name; //使用新名字替换旧名字
changes += "first name "; //记载操作记录
}
if(row.last_name != last_name) {
row.last_name = last_name;
changes += "last name ";
}
if(row.state != state) {
row.state = state;
changes += "state ";
}
});
if(changes.length() > 0) {
send_summary(user, "successfully modified record in addressbook. Fields changed: " + changes); //发送通知信息
increment_counter(user, "modify"); //用于操作统计
} else {
send_summary(user, "called upsert, but request resulted in no changes.");
}
}
}
[[uosio::action]]
void erase(name user) { //删除操作
require_auth(user);
address_index addresses(_code, _code.value);
auto iterator = addresses.find(user.value);
uosio_assert(iterator != addresses.end(), "Record does not exist");
addresses.erase(iterator);
send_summary(user, " successfully erased record from addressbook");
increment_counter(user, "erase");
}
[[uosio::action]] //通知操作。合约本身有执行自己的权限
void notify(name user, std::string msg) {
require_auth(get_self()); //合约本身有执行自己的权限
require_recipient(user); //通知 user用户
}
private:
struct [[uosio::table]] person { //合约的数据结构
name key;
std::string first_name;
std::string last_name;
std::string street;
std::string city;
std::string state;
uint64_t primary_key() const { return key.value; }
};
void send_summary(name user, std::string message) { //发送通知信息
action(
permission_level{get_self(),"active"_n},
get_self(),
"notify"_n,
std::make_tuple(user, name{user}.to_string() + message)
).send();
};
void increment_counter(name user, std::string type) { //发送计数交易
action counter = action(
permission_level{get_self(),"active"_n}, //合约发布者的 active权限
"abcounter"_n, //合约发布者名称
"count"_n, //合约发布者发布的函数
std::make_tuple(user, type)
);
counter.send();
}
typedef uosio::multi_index<"people"_n, person> address_index; //合约表的索引结构
};
UOSIO_DISPATCH( addressbook, (upsert)(notify)(erase)) //申明合约可以被调用的接口
比如用户要做addressbook.cpp 合约转为在 UOS下可以使用的合约,那么只需要做一下替换, 以addressbook.cpp为例, 原有的addressbook.cpp 里面的eos 、 EOS 直接替换为uos、UOS 即可变为uos下面的合约。
uosio-cpp addressbook.cpp -o addressbook.wasm –abigen