一个等效ping的EOS智能合约
这篇文章是为帮助EOS智能合约开发人员从初级到生产而发布的一系列帖子中的第一篇。有关本教程的完整代码,可以访问github存储库。
随着对EOS的所有兴奋而来的,对于大多数希望参与其中的开发人员仍然充满挑战的领域是开始使用智能合约。新开发人员通常需要克服两个障碍:获取工具和设置,并了解如何编写智能合约本身。
EOS智能合约是用C++编写的,并编译成Web Assembly。Dan Larimer选择C++来利用其类型和模板系统,这使得更安全的合约,并补充说,因为智能合约的运行时间很短,大多数内存问题都会消失。
配置
使用EOS的部分挑战是设置本地区块链。幸运的是,EOS为设置本地EOS环境提供了一些基础。对于本指南,我们将使用EOSIO Dawn 3.0。
该指南的摘要可以压缩为几个关键命令:
$ git clone https://github.com/EOSIO/eos --recursive $ cd eos $ ./eosio_build.sh $ cd build && make install $ cd programs/nodeos $ ./nodeos -e -p eosio --plugin eosio::wallet_api_plugin --plugin eosio::chain_api_plugin --plugin eosio::account_history_api_plugin --access-control-allow-origin=*
安装需要一些时间,但很简单。一旦在本地启动并运行本地EOS区块链,就可以开始了工作了。在整个指南中,我们将引用一些实用程序,如cleos和eosiocpp。 你可以在eos/programs文件夹中找到这些内容。
建立ping智能合约
在本教程中,我们将创建和部署分布式系统的“Hello World”:ping/pong。对于没有经验的人,我们将向服务器发送一个“ping”命令,它将以“pong”响应。 智能合约由以下几个部分组成:C++代码,ABI(应用程序二进制接口)和基于C++代码的WAST(Web程序集文本文件)。这是看起来像:
实现ping
在我们完成工具环境设置之后,让我们进入合约!要编写ping智能合约,我们只需要一个实现一个操作的合约:ping。所有这些方法需要做的就是打印“Pong”作为响应。
在contract中创建一个名为ping的文件夹,并在ping/ping.cpp文件中创建一个文件:
#include <eosiolib/eosio.hpp> #include <eosiolib/print.hpp> class ping_contract : public eosio::contract { public: using eosio::contract::contract; void ping(account_name receiver) { eosio::print("Pong"); } }; EOSIO_ABI( ping_contract, (ping) )
这里有一个简单的小例子,你可以测试,以便更熟悉。让我们分解这里发生的事情:
- 我们包含一些定义来写我们的合同。
- 我们创建了一个继承自eos::contract的新合约类。
- 我们创建了一个打印“Pong”的方法。
- 最后一行是最近添加的宏,它通过基于我们传递给第二个参数的方法生成一个来节省我们维护自己的手写ABI的工作量。
构建合约
EOS块生成器在执行智能合约时不运行C++代码,他们期望web-assembly。EOS提供了一个名为eosiocpp的工具,用于将C++代码转换为Web Assembly Text。我们现在就这样做eosiocpp -o ping.wast ping.cpp。这一步将产生一些警告,但我们现在可以忽略这些警告。
接下来,我们需要应用程序二进制接口。基本上,你的智能合约的ABI将描述方法及其相应的签名。由于我们在文件的末尾添加了EOSIO_ABI宏,而不手动编写,我们可以使用以下命令生成它:eosiocpp -g ping.abi ping.cpp。
此时,您的文件夹应如下所示:
├── ping.abi ├── ping.cpp └── ping.wast
部署到本地网络
现在我们拥有了智能合约所需的所有资源,让我们来部署它。确保你有一个钱包创建了cleos wallet create并确保它通过运行cleos wallet unlock并在提示时键入你的钱包密码来解锁。我们将在另一个帐户下部署我们的智能合约。
为此,我们需要创建一个新的密钥对,让我们通过运行:cleos create key来实现。这将为你生成随机的公钥和私钥。在本教程的其余部分中,请务必使用你刚刚收到的值替换文中的[public_key]/[private_key]。
将私钥导入当前未锁定的帐户钱包:cleos wallet import [private_key],使用公钥设置合约帐户:cleos create account eosio ping.ctr [owner_key:public_key] [active_key:public_key]。
将合约与新创建的帐户链接,ping.ctr ../ping -p ping.ctr。
与ping交互
一旦部署了新合约,就可以与它进行交互了!让我们使用相同的密钥创建一个测试人员帐户来运行交易:cleos create account eosio tester [public_key] [public_key]
现在我们可以在命令行上测试它:
$ cleos push action ping.ctr ping '["tester"]' -p tester executed transaction: e89ebeaad8f3623e42d966f62d4d0adbf6a7412b6bb4d7be61f04a22d3cd485e 232 bytes 102400 cycles # ping.ctr <= ping.ctr::ping {"account":"tester"} >> Received ping
应该可以了!
这对我们的程序员来说是令人兴奋的,但是大多数用户都不会设置他们的命令行来与你的智能合约进行交互。因此,让我们将这种互动带到他们更熟悉的界面:他们的浏览器。
通过浏览器进行交互
要从前端与EOS交互,我们将使用EOS.js. 由于我们在EOS支持上使用dawn3,我们需要确保在安装时使用dawn3分支:npm install eosjs @ dawn3。
我们从配置开始:
Eos = require('eosjs') eos = EOS.Localnet({ keyProvider: ['{replace_with_your_private_key}'], httpEndpoint: 'http://127.0.0.1:8888' })
配置完成后,我们必须指定一些细节:
eos.contract('ping.ctr').then((contract) => { contract.ping("tester", { authorization: ['tester'] }).then((res) => { console.log(res) }) })
请注意ping.ctr,它与我们之前部署的合约的名称相匹配。一旦我们获取了合约接口(或ABI),我们就可以与它进行交互,就好像它是本机Javascript一样。合约返回一个promise,其中包含resolve函数中包含的交易详细信息。这是从前端与我们的ping智能合约进行交互的核心思想。