本教程主要面向初阶开发人员,目的在于带领大家以最简单的示例合约,通过简单但不失完整的流程,体验整个合约的编译、发布与调用过程,从而让大家从直观角度有个清晰的概念认识。


版本说明
测试网公链版本: v1.7.0-dirty
EOSjS-SDK版本:16.0.9
开发组件包(CDT): 1.5.0


一、帐户管理

1. Register EOS Account

生成公私钥

在进行帐户注册时,需要事先提供一对公私钥地址,以便在注册帐号时进行绑定使用。可通过EOS Key Generation网站进行公私钥地址生成。

注册帐户

通过Jungle2.0 - EOS Test Network Monitor (CryptoLions.io)网站进行EOS帐户的创建

点击图中标红create account, 在弹出界面中,填写事先生成的公钥地址


见上图中,需要填写三个信息,其中account name主要用于填写我们易于记忆的帐户名称,但其帐户名称长度只允许12位长度,且其组成字符也只能从a-z, 1-5以及一个点符号组成。
至于owner public key和 active public key分别对应该帐户owner权限和active权限。如果从安全角度讲,两个权限所对应的公钥地址应该设置成不一样的,这样当active private key丢失的时候,可以使用ower权限对active权限对应的公钥地址进行更换。因为ower和active权限是有层次关系的,只允许低级权限对下次权限进行操作。在不丢失ower私钥的情况下,也可以实现对ower权限地址的更换操作。

点击create, 创建成功后,会显示如下信息

2. Claim EOS


Jungle2.0 - EOS Test Network Monitor (CryptoLions.io)页面,点击菜单栏中的Faucet按钮,会弹出如下界面

3. Balance Query


Jungle2.0 - EOS Test Network Monitor (CryptoLions.io)页面,点击菜单栏中的account info按钮,弹出如下界面:

填写帐号名称后,点击get按钮, 便可以查到该用户的EOS余额及公钥地址信息。

4. Install Chrome Plugin: Scatter

安装scatter

在chrome浏览器中安装Chrome 网上应用店 - scatter插件。

注: 如果Chrome插件商店无法打开,则可以使用Start | Chrome Extension Downloader进行下载。scatter插件地址: https://chrome.google.com/webstore/detail/scatter/ammjpmhgckkpcamddpolhchgomcojkle?hl=zh-CN

插件安装完成后,可以chrome浏览器中看到如下高亮图标。

使用scatter

  • 初始化scatter帐户
    填写密码,然后点击创建按钮

    点击创建操作后,会显示如下界面,提示保存12个助记词

    大家需要保存好这12个助词词,以便于在忘记密码时用助记词进行恢复。注:丢失此助记词则意味着你将永远丢失该帐户。

  • 添加测试网络
    首先、打开主界面后,点击右上解系统设置

    然后,选择网络,新建网络

    填入测试网络的参数信息,比如: http://jungle2.cryptolions.io:80、chainid: e70aaab8997e1dfce58fbfac80cbbb8fecec7b99cf982a9444273cbc64c41473
    chaind的获取方式,可以直接通过http://jungle2.cryptolions.io/v1/chain/get_info进行查询

  • 导入公私钥
    回到主界面,选择Key Pairs, 然后导入之前创建的私钥
  • 绑定EOS帐户

5. Buy(RAM、CPU、NET )

访问内存交易 - 钱包 - EOSX - Fastest EOS Block Explorer网站,绑定scatter帐号

购买RAM

购买CPU与NET资源

二、合约开发

1. 编写示例合约

在本地创建一个工程目录

1
2
3
4
5
~> mkdir -p mycontract/{utils, contracts}
~> tree
.
├── contracts
└── utils

在工程目录contracts文件下,创建hello.cpp,

1
~> touch contracts/hello.cpp

打开hello.cpp, 填写以下内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <eosiolib/eosio.hpp>

using namespace eosio;

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

[[eosio::action]]
void hi( name user ) {
print( "Hello, ", user);
}
};

EOSIO_DISPATCH(hello, (hi))

2. 编译合约

该步骤需要用到EOS合约开发所必需的cdt开发工具包, 来完成对示例合约的编译工作。

1)在本地安装eosio-cpp工具命令

1
2
brew tap eosio/eosio.cdt //增加仓库
brew install eosio.cdt //安装工具包

注: 可使用eosin-cpp –help命令来查看所有参数说明

2)进行合约编译,生成abi合约描述文件及wasm合约文件

1
eosio-cpp -abigen 'contracts/hello.cpp' -o 'contracts/hello.wasm' --contract 'hackdappcom1'

编译完成后,会在工程目录生成hello.abi、hello.wasm两个编译文件。hello.abi就好比webservice中的wsdl描述语言一样,主要用于对合约接口及数据结构进行结构性描述, wasm文件为合约编译后的二进制文件。

ABI文件详细说明: 剖析EOS合约编译ABI文件 | HackDApp

3. 发布合约

初始化项目工程,并安装eosjs-sdk

使用npm init命令对项目进行初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
~> npm init
package name: (mycontract)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to /Users/nolan/Desktop/mycontract/package.json:

{
"name": "mycontract",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}

然后,使用npm install eosjs@16.0.9命令进行eos sdk组件安装

1
~> npm install eosjs@16.0.9

安装完成后, 整个项目工程目录结构显示如下:

1
2
3
4
5
6
7
8
9
~> tree
.
├── contracts //合约文件
├── node_modules //依赖组件
├── package-lock.json
├── package.json //工程配置定义
└── utils //工具库

3 directories, 2 files

编辑合约发布文件: deploy.js

首先,在工程根目录下,创建deploy.js;
然后,打开该文件,并填下以下内容;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const eos = require('./utils/eossdk')({
chainId: "e70aaab8997e1dfce58fbfac80cbbb8fecec7b99cf982a9444273cbc64c41473",
httpEndpoint: "http://jungle2.cryptolions.io:80",
//更改处一: EOS合约Active权限权限
keyProvider: "5JxqGao9rzXWBUDnNzALyxaFdmZYXiZ46EzHL4sJkHkryzCFKxu",
// 更改处二: 改为要发布的合约帐户名称
authorization: 'hackdappcom1@active',
broadcast: true,
sign: true
})
const {deployContract} = require('./utils/common')

//更改处三:改为要发布的合约帐户名称
deployContract(eos, { account: "hackdappcom1", contractDir: "./contracts" }).then((result) => {
console.log(`Deployment successful`, JSON.stringify(result, null , 4))
})
.catch(err => {
console.error(`Deployment failed`, err)
})

最后,根据自己的帐户信息进行参数更改。

注:deploy.js文件头引入的两个文件eossdkcommon.js可直接点击链接下载,并放入工程目录utils文件夹中。

执行合约发布

编辑完成deploy.js相关参数数据, 通过node命令进行合约发布。

1
node deploy.js

运行命令之后,如果发布成功,会显示以下日志信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Deployment successful
[
{
"broadcast": true,
"transaction": {
"compression": "none",
"transaction": {
"expiration": "2019-04-03T06:50:55",
"ref_block_num": 25564,
"ref_block_prefix": 1344811314,
"max_net_usage_words": 0,
"max_cpu_usage_ms": 0,
"delay_sec": 0,
"context_free_actions": [],
......
"account_ram_deltas": [
{
"account": "hackdappcom1",
"delta": -27
}
],
"except": null,
"inline_traces": []
}
],
"except": null
}
}
]

4. 合约调用

在确保合约发布成功之后,开始编写合约调用文件 invoke.js

1
~> touch invoke.js

打开invoke.js, 填入以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const eos = require('./utils/eossdk')({
chainId: "e70aaab8997e1dfce58fbfac80cbbb8fecec7b99cf982a9444273cbc64c41473",
httpEndpoint: "http://jungle2.cryptolions.io:80",
keyProvider: "5JxqGao9rzXWBUDnNzALyxaFdmZYXiZ46EzHL4sJkHkryzCFKxu",
authorization: 'hackdappcom1@active',
broadcast: true,
sign: true
})

const data = {
actions: [
{
account: 'hackdappcom1',
name: 'hi',
authorization: [{
actor: 'hackdappcom1',
permission: 'active'
}],
data: {"user": "222"}
}
]
}
eos.transaction(data).then((result)=>{
console.log(JSON.stringify(result.processed.action_traces[0].console, null, 4))
}).catch((err)=>{
console.log(err)
})

执行调用命令

1
node invoke.js

如果能够正常运行,则会显示以下内容信息

1
"Hello, 222"

另外,针对教程中出现的代码,我提供了完整的工程代码示例及文字稿教程。大家可点击链接或者直接克隆到本地进行查看。项目地址: https://github.com/hackdapp/learn_eos


可能出现的问题

  1. 如果你没有事先购买RAM资源,可以会提示以下错误信息
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    {
    "code": 500,
    "message": "Internal Service Error",
    "error": {
    "code": 3080001,
    "name": "ram_usage_exceeded",
    "what": "Account using more than allotted RAM usage",
    "details": [
    {
    "message": "account hackdappcom1 has insufficient ram; needs 26318 bytes has 5471 bytes",
    "file": "resource_limits.cpp",
    "line_number": 213,
    "method": "verify_account_ram_usage"
    }
    ]
    }
    }

测试网帐号

帐户名 公钥 私钥
hackdappcom1 EOS6LTWfM5ffbmjUhvwFnrU5QEBrmkzsRo2eXogr2h9oP8DUuzgAi 5JxqGao9rzXWBUDnNzALyxaFdmZYXiZ46EzHL4sJkHkryzCFKxu
hackdappcom2 EOS6qCqbFLuYK5rGK9LDPzcboLqy4phrUxLXLrhLgXxVBpzLzsJke 5Jnw2anG8Zzy6MuCNxvwmaX5Hu4B6de1uzuae5QyRrUFtyfL2Wo
hackdappcom3 EOS57B3rxRBBUiTyZf9iBxsWyQnvEhq2H95wbBbjdzcLbV1gfJ4zy 5Ju2NNc24q3jQ2Yc2JcvwWjtGVeAyuWcNsaNVb37u7cmRW56zgc
hackdappcom4 EOS7i5Diz2uqXSpvutmV4DftBRrL1XASzxsSdWBGrgzngPoXhT2dk 5K6nyWMvpfYnQqLhS545dm53exduJgDBLHMYQ6SCNaPmeHjGZdr
hackdappcom5 EOS6NcaFvvoekuBjhZLsBVywiMcN7VTVmgvAdA5srgTvQMeDmdiAH 5JjN9efKokkgZYno2qjbE9C7WCGbVpPvgNArKDvcjbDic2pRGCS

参考资料

  1. https://nadejde.github.io/eos-token-sale/
  2. http://monitor.jungletestnet.io/#home
  3. https://jungle.eosx.io/tools/ram/buy?symbol=10
  4. https://github.com/hackdapp/learn_eos
  5. https://chrome-extension-downloader.com/f944f5bf7bc58292048aa5b9bf29dc48/scatter.crx.crx.crx

到此,整个EOS合约开发的流程就算介绍完毕。让我们再总结一下整体操作流程:

  1. 生成两对公私地址,并进行EOS帐户注册
  2. 通过jungle网站进行EOS币的领取,并对其进行余额查询
  3. 安装Scatter插件,导入私钥并绑定新身份
  4. 使用新注册的EOS帐户购买RAMCPUNET发布合约所需要的资源
  5. 创建合约测试示例并编译
  6. 编写发布合约脚本,替换合约帐户后进行合约发布
  7. 编写合约方法调用脚本,调用合约中的hi方法进行日志打印。
    通过七个步骤我们了解了整个EOS合约开发的最简化操作流程。

欢迎关注HackDApp博客或公众号, HackHook将持续为你分享IndieMaker成长路径、DAPP技术知识、高效Mac使用技巧、底层思维认知。

我的博客: https://www.hackdapp.com/
我的github: https://github.com/hackdapp
我的哔哩哔哩: https://space.bilibili.com/17360859
我的微信公众号: hackdapp

IndieMakers: https://www.indiemakers.cn

联系邮箱:55269778@qq.com