embark是什么
embark是一款特定于Ethereum区块链平台的DApp开发环境,辅助开发者创建、构建编译、测试和部署DApp,可无缝集成计算(EVM)、存储(IPFS/Swarm)和网络(Whisper)资源。
embark的便捷之处
在尝试embark并和truffle框架进行对比之后,我总结以下几个方面的优势:功能全面,上手迅速,反馈快速,可视化程度高,合约可调试。
功能全面
正如embark概览所言,embark并不仅仅是一款只提供构建编译、测试部署功能的开发工具,还是一整套的开发环境。它包含了智能合约自动部署,客户端(UI)开发,测试,DApp分布式托管(IPFS/Swarm),点对点通信(Whipser)和组件监控、在线IDE及代码调试(Cockpit)等功能。
如果和truffle框架比较,embark几乎包含了它提供的所有功能。不过,embark缺失了truffle在migration方面的功能,基于对不可变基础设施的考量,embark有必要拥抱这项标准实践。
embark考虑了单独开发智能合约的可能性,所以允许开发者在创建项目时只创建智能合约项目结构,通过启用--contracts-only
选项。而且在构建编译时,也可以指定embark build --contracts
命令单独构建智能合约。
上手迅速
这个维度虽然有点主观,但是很值得拿出来说。一般学习新的工具,需要花很多时间看文档学习基本概念和操作流程,最恼火的就是熟悉各种配置项,当你左支右绌,手忙脚乱让工具程序跑起来,除了浪费时间,也侧面证明该工具不够成熟、对开发者不友好。
很意外的是,本来以为这么一个大而全的开发环境设置起来一定得耗费不少时间,结果却是除了用yarn global add embark
报出一个compiler和yarn不兼容后,改成了npm install -g embark
安装,就再没有特别恼人的问题出现了。
注意: 上面的安装错误其实是因为embark对于yarn的版本有一定的要求,从embark源码中可以得到如下前置条件。
代码语言:javascript复制"engines": {
"node": ">=8.12.0",
"npm": ">=6.4.1",
"yarn": ">=1.12.3"
},
我当前的yarn版本是1.6.0,使用brew upgrade yarn
升级到1.15.2就可以全局安装了。
yarn global add embark
...
embark version
4.0.2
embark run
会启动一个命令行中可视化界面,里面会告诉你当前Dapp的状态,包括智能合约是否部署,哪些组件服务可用,最最重要的是它会告诉你接下来你该做什么!在Logs视窗中,embark试图告诉你开发环境确实哪些依赖服务,比如geth节点没有启动(事实上,可以用gananche-cli代替),ipfs节点未侦测到,Cockpit Web UI所在端口还有Dapp服务的入口等等。而console视窗则是命令交互入口,一条help
命令就能展示很多有用信息。
Dashboard
以上这些信息都无需查看文档便可以获得,个人觉得从尝试中学习是特别有趣的事情。
我一般拿从零到写出第一行程序的时间作为上手快慢的标准。这行程序是用来试验,未必得手写,所以我选用了truffle自带的样例MetaCoin.sol
和ConvertLib.sol
。
// ConvertLib.sol
pragma solidity ^0.5.0;
library ConvertLib{
function convert(uint amount,uint conversionRate) public pure returns (uint convertedAmount) {
return amount * conversionRate;
}
}
代码语言:javascript复制// MetaCoin.sol
pragma solidity ^0.5.0;
import "./ConvertLib.sol";
contract MetaCoin {
mapping (address => uint) balances;
event Transfer(address indexed _from, address indexed _to, uint256 _value);
constructor() public {
balances[msg.sender] = 10001;
}
function sendCoin(address receiver, uint amount) public returns(bool sufficient) {
if (balances[msg.sender] < amount) return false;
balances[msg.sender] -= amount;
balances[receiver] = amount;
emit Transfer(msg.sender, receiver, amount);
return true;
}
function getBalanceInEth(address addr) public view returns(uint) {
return ConvertLib.convert(getBalance(addr), 4);
}
function getBalance(address addr) public view returns(uint) {
return balances[addr];
}
}
当把这两个智能合约文件放到项目根目录下contracts/目录中后,合约代码被自动编译,并在Contracts视窗中展示出来,状态为Deployed,这表明智能合约已经被部署到区块链网络里。之后,我进入Cockpit Web UI,惊喜地发现这个服务俨然就是一个高配版的etherscan.io,通过它不仅可以查看部署之后的合约,甚至还可以调用合约方法。
估算下来,我用embark写完第一行代码的时间基本可以忽略不计。
反馈快速
写程序都希望其可行性能被快速验证,因为只有这样才能方便快速地迭代出正确功能的程序。我所知道的前端开发者是把这个过程做到极致的群体,比如Liveloading;embark对于智能合约也提供了一致的功能。当修改合约文件并保存时,embark会自动检测变更同时重新编译再部署,这个过程非常快速(当然,embark对于哪些修改的合约需要重新部署是有一定限制的,而且据我观察,这里面有些潜在的bug,比如修改合约constructor中的内容就不会触发重新构建,即便用embark reset
也不行,这个和文档的描述有些出入,值得花时间研究下)。
自动重新构建和部署合约对程序员的效率提升很有帮助,但是无法快速验证同样达不到目的。所幸的是,embark不仅提供了Cockpit这样的可视化工具辅助验证合约的正确性,而且还提供embark console,在console中可以调用部署合约的实例,比如:输入Embark (Development) > MetaCoin <ENTER>
就能获取部署好的实例,有了合约实例就可以调用其上的方法进行数据校验。
同样重要的是,embark支持js和sol版本测试,我可以像使用truffle一样使用TDD的方式开发DApp了。
可视化程度高
当在终端中运行embark run
时,embark会自动进入可视化界面(dashboard)。这里面监控的信息会实时告诉你DApp开发的状态。除此之外,embark还提供了DApp的Web server,Cockpit Web UI页面,这些绝对是开发DApp极大的助力。
如果不想使用dashboard,可以通过embark run --nodashboard
禁用。不过,根据我的经验,禁用dashboard的结果是没法直接拿到进入Cockpit的访问token,还需要运行embark console
进入命令行单独获取。
从上面这点来看,embark在组件化方面做得相当出色,虽然功能大而全,但是并没有限制你删减不必要的组件、独立启用感兴趣的组件
合约可调试
调试合约在以前的开发过程中还是比较难的,不过借助于Cockpit,embark也提供了在线调试的能力。Cockpit内置一个编辑器,它和本地的开发目录保持一致,该编辑器就提供了debug功能。另外,进入Explorer页,我们甚至可以对某次的tx进行debug验证这次合约调用的真实数据流转情况。
Explorer & Debug
小结
总的来说,embark是一款优秀的区块链开发环境。相比较truffle的专注于合约工程化的努力,embark的功能更加丰富,而且各组件组合性很强。对于开发者而言,快速开发出DApp才是真的诉求,而embark显然在这一方面具备很大的优势。
怎么快速玩转embark
工具版本号
代码语言:javascript复制yarn --version
1.15.2
npm -v
6.4.1
node -v
v10.15.3
embark version
4.0.2
快速使用DApp
embark默认开发时都是 development 环境,为了对接正确的ganache-cli(模拟以太坊客户端)端口,我们需要修改config/contract.js
文件中development/port
到ganache-cli默认的8545端口。
先执行embark build --pipeline development
,然后启动embark run
,此时就可以在http://localhost:8000
查看DApp的界面了。
IPFS分布式托管
首先得安装IPFS的客户端,然后运行如下命令:
代码语言:javascript复制ipfs init
ipfs daemon
...
Daemon is ready
当ipfs启动完成后,embark的dashboard会显示ipfs节点已连接。此时执行embark upload
,构建出来的dist目录就会被分发到ipfs网络,然后就可以通过内容寻址(content-addressed)的方式访问这个静态网站了。
IPFS distribution of static pages
于 2019-05-07