【许晓笛】开发第一个 EOS 智能合约

开发第一个 EOS 智能合约

Hello World!

稍微了解 EOS 系统,你就会知道 EOS 的智能合约基于 WebAssembly(WASM) 技术,这种技术在性能和跨平台兼容性之间取得了很好的平衡,通过将原始代码编译成字节码,使得代码可以在多种平台的 WASM 虚拟机(或者叫解释器)中执行。得到了苹果和谷歌等科技巨头的支持,被誉为下一代互联网前端技术。目前的 WebAssembly 技术支持 C/C++ 语言,并开发了 JavaScript 接口,并被 Chrome、Edge、Safari、Firefox 等几乎所有的主流浏览器支持。

因为使用了 WebAssembly,目前的 EOS 智能合约只支持 C/C++ 语言,简单的智能合约由 3 种文件组成:.hpp文件、.cpp文件、.abi 文件。其中 hpp 为 C++ 头文件,一般用来定义类及其成员变量与成员函数。cpp 为 C++ 文件,用来实现 hpp 中声明的成员函数,实现智能合约的业务逻辑。abi(Application Binary Interface) 文件为二进制接口文件,文件格式类似 JSON,用来定义智能合约与 EOS 系统外部交互的数据接口。

如果智能合约的非常简单,只有一个 cpp 文件,可以省略 hpp 文件,将类与成员定义在 cpp 文件中。abi 文件应该由 C++ 程序需要的数据库空间和外部接口生成,不过 EOS 开发了 abi 自动生成工具,可以根据智能合约代码自动生成 abi 文件,减轻了开发工作量。所以最简单的智能合约只需实现 cpp 文件。

image.png

Hello 智能合约

一般的操作系统上手时,惯例是编写一个 Hello World 程序,是主动输出一句话。但我们不一样,我们编写的是一个智能合约,智能合约强调的是互动,在 EOS 里叫做 Action,Action 表示别人可以对合约做什么动作,所有智能合约代码都是对 Action 的回应,是被动的。下面就是第一个 Hello 智能合约:

hello.cpp:

#include <eosiolib/eosio.hpp>
#include <eosiolib/print.hpp>
using namespace eosio;

class hello : public eosio::contract {
  public:
      using contract::contract;

      /// @abi action 
      void hi( account_name user ) {
         print( "Hello, ", name{user} );
      }
};

EOSIO_ABI( hello, (hi) )

我们在代码中定义了一个类:hello,这个类名与合约的账户名没关系,类中只有一个简单的方法:

void hi( account_name user ) {
         print( "Hello, ", name{user} );
      }

这就是 EOS 智能合约里所谓的 Action,我们定义了一个叫 hi 的 Action,参数是另一个账户名,函数体是打印一句话,回应 hello。 也就是说别的账户可以调用这个合约的 hi Action,这个 hello 合约就会打印一句 hello 来回应。

最后一行代码:

EOSIO_ABI( hello, (hi) )

EOSIO_ABI 是一个宏,将特定类的特定方法暴漏给系统,成为别的账户可以调用的 Action。

编译智能合约

我们使用 eosiocpp 工具将写好的 hello.cpp 编译成为字节码文件(.wast):

$ eosiocpp -o hello.wast hello.cpp

然后使用 eosiocpp 工具自动生成 abi 文件:

$ eosiocpp -g hello.abi hello.cpp
Generated hello.abi

看一下生成的 abi 文件内容:

{
  "____comment": "This file was generated by eosio-abigen. DO NOT EDIT - 2018-04-16T13:37:55",
  "types": [],
  "structs": [{
      "name": "hi",
      "base": "",
      "fields": [{
          "name": "user",
          "type": "account_name"
        }
      ]
    }
  ],
  "actions": [{
      "name": "hi",
      "type": "hi",
      "ricardian_contract": "# CONTRACT FOR hello::hi## ACTION NAME: hi\n 
      ### Parameters### Parameters\nInput paramters:Input paramters:\n 
      \n 
      * `user` (string to include in the output)* `user` (string to include in the output)\n
      \n 
      Implied parameters: Implied parameters: \n 
      \n 
      * `account_name` (name of the party invoking and signing the contract)* `account_name` (name of the party invoking and signing the contract)\n 
      \n 
      ### Intent### Intent\n 
      INTENT. The intention of the author and the invoker of this contract is to print output. It shall have no other effect.INTENT. The intention of the author and the invoker of this contract is to print output. It shall have no other effect.\n 
      \n 
      ### Term### Term\n 
      TERM. This Contract expires at the conclusion of code execution.TERM. This Contract expires at the conclusion of code execution.\n" 
    }
  ],
  "tables": [],
  "ricardian_clauses": [

   ...
   ...
   ...

  ]
}

我们省略了 ricardian_clauses ,也就是李嘉图条款部分(李嘉图合约指的是人与机器都能读懂的合同,EOS 最近才将其加入智能合约中)。我们看到 abi 文件中已经声明了 hi 这个 Action,并说明了这个 Action 的李嘉图合约,大概意思是本合约的输入为一串字符(user),本合约意图是打印输出,没有其他效果。

上传智能合约

上传智能合约之前,我们要先给智能合约建立一个账户 EOS 里账户和智能合约是一一对应的。使用 EOS 的 cleos 命令行工具创建账户:

$ cleos create account eosio hello.code EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4

命令中,hello.code 就是这个智能合约的账户名,EOS系统的账户名要求 12 字符以内。后面两个公钥是在本地测试网络中有建立账户权限的公钥(对应本地测试网络中的 eosio 账户)。

然后就可以上传智能合约了:

$ cleos set contract hello.code ../hello -p hello.code

使用智能合约

我们使用 user 账户调用 hello.codehi Action:

$ cleos push action hello.code hi '["user"]' -p user

hello.code 表示执行 hello.code 合约,hi 表示执行合约里的 hi Action,'["user"]' 是根据 abi 写的传入参数, -p 参数表示使用哪个账户的权限 (permission)。

以下是系统回应:

executed transaction: 4c10c1426c16b1656e802f3302677594731b380b18a44851d38e8b5275072857  244 bytes  1000 cycles
#    hello.code <= hello.code::hi               {"user":"user"}
>> Hello, user

说明执行了 hello.code 合约的 hi Action,并且系统输出为 Hello, user,智能合约成功对 Action 进行了回应。


相关文章和视频推荐

【许晓笛】EOS 新增的 WebAssembly 解释器,是什么鬼?
https://www.jianshu.com/p/06f86dd434ad

圆方圆学院汇集大批区块链名师,打造精品的区块链技术课程。 在各大平台都长期有优质免费公开课,欢迎报名收看。

公开课地址:https://ke.qq.com/course/345101

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容