2.1 Remix的使用
Remix是一款可以在线编写调试代码的编辑器,也支持部署代码和查询区块链数据,它的优势在于可以快速编写合约代码并找到语法错误,并且不需要很复杂的配置环境,我们在编写代码初期使用这款软件特别合适,工具地址: http://remix.ethereum.org。
2.1.1 编程界面
登录Remix首页,其中主界面的编译器分为3个部分,如图2.1所示。
图2.1 Remix编程环境
首先来简单熟悉一下Remix编程工具提供的功能,左侧提供的是文件管理能力,图中区域1中包含新增按钮,单击该按钮可以生成一个后缀为.solde的智能合约文件。将第1章中用到的第一个Solidity源代码复制到图2.1所示的中间的输入框中,文件名以合约的名称来命名:SimpleStorage.sol。
文件的内容相对简单,仅有12行代码,需要注意的是第1行代码,上一章曾经讲解过:该代码指明了该合约代码需要的编译器版本,该内容可以根据编译环境进行微调。在编译器的右侧,Compile这个标签页下面,最新版的Solidity编译器是0.5.2版本,为了使用最新版编译器,可以将代码调整为与该编译器一致。如果不修改代码,则可以从图2.1中区域7的下拉菜单中,选择适合自己合约版本的编译器,不同的编译器语法会有所不同。截至本书出版之时,最新的编译器版本号是0.5,距离成熟的1.0版本还有很长的路要走,由此可见区块链领域仍有广阔的开拓空间。
在版本选择器下方有3个选项,其中Auto compile表示可以将编译器设置为实时编译,这样在编写智能合约时,可以实时显示语法错误,这些错误信息会显示在图2.1的区域9中。如果存在语法错误,区域9会给出相应的语法错误及修改意见;如果显示绿色,则没有语法错误。当编写的智能合约文件过大或者智能合约依赖的文件过多时,可以关闭自动编译的功能,选择图2.1中的编译按钮来手动编译代码。因为在开启自动编译的情况下,当创建的文件过多时,每次切换文件都会产生一次编译动作,这会使浏览器的速度变慢,所以可以通过手动编译的方式来解决该问题。
图2.1中区域10涉及的Bytecode和ABI曾在第1章中解释过,Remix作为Solidity的编译器,也可以生成这些描述文件,开发者可以通过这些数据,方便快速地调试DAPP。除此之外,图2.1的区域3中的加号和减号可以改变编程区内文本的字体大小,同时Remix编译器还会在代码发生变化后的5s后开始自动保存文件。
2.1.2 运行环境
合约代码编译成功之后,操作者就可以将合约部署到以太坊公链上,在图2.1右侧的Run标签下,可以看到运行和部署智能合约的相关选项。图2.2中的区域2表示的是本智能合约运行的环境,其下拉选项目前有3个,分别是JavaScript VM、Injected Provider和Web3 Provider,这3个不同的运行环境表示本合约需要部署的目的不同。
图2.2 Remix合约运行环境
● JavaScript VM使用的是一个沙箱(或沙盒)运行环境,它并不会与以太坊公链发生交互。
● Injected Provider表示使用嵌入到浏览器的公链运行环境,往往使用MetaMask这个插件提供的运行环境间接与以太坊环境发生交互。
● Web3 Provider则表示直接与真实的以太坊网络环境进行交互。
为了简便起见,使用JavaScript VM来测试编写的程序,可以在无须任何配置的情况下,快速对代码的语法进行检查,这也是本节介绍Remix的目的,它非常适合快速地检查和测试智能合约。因为正式的开发环境或者与区块链系统发生交互时需要产生真实的交易,并支付一定的费用,并且需要矿工来挖矿打包,才能将合约真正地部署到区块链系统上,这些知识点曾在上一章中简单介绍过。而如果选用JavaScript VM运行环境,则可以直接在浏览器中检查和调试智能合约,调试通过之后再正式部署。
图2.2中的区域3、4和5是开发和部署智能合约必不可少的元素,本开发环境的智能合约必须通过一个外部账户来发起,其中的区域3表示账户地址,地址后面的数字表示账户的余额为99.9 ETH。图2.2中的区域4表示该智能合约需要消耗的成本,以太坊将其称为程序部署需要的燃料,图2.2中的区域5表示在生成智能合约的同时将一定的余额转移到新创建的智能合约账户下,具体内容将在以后的案例中讲解。
图2.2中的区域6的位置是一个下拉菜单,当维护和管理多个智能合约文件时,可以通过下拉菜单来选择需要部署的合约文件。图2.2中的区域7是部署按钮,单击之后可以执行部署操作。
当部署结束之后,图2.2中的区域8、9和10展示了部署后的结果,在JavaScript VM中部署会非常快速,因为这只是个简单的沙盒环境,可以省去很多底层的调用。区域8表示合约地址,区域9和10则表示该合约提供给外部的功能。
Remix为所有的对外合约接口提供调试界面,本例中提供了2个函数:一个是get函数,另一个是set函数。get函数可以通过合约读取区块链上的状态信息,set函数则可以设置区块链状态。Remix调用部署后的智能合约界面如图2.3所示。
图2.3 Remix调用部署后的智能合约界面
调用get函数,会产生一个Message Call,该操作不会修改区块链的状态,只是从区块链上查询数据,在默认情况下,可以看到调用get函数的结果是0,如图2.4所示。
调用set函数会产生一个交易,该交易修改了区块链的状态,并且需要矿机将交易打包到区块链中,set函数才能够调用成功,调用set函数之后,再一次通过get函数来查询合约中存储的数据,图2.4中的区域4显示修改已经生效。
图2.4 get函数操作产生的消息
图2.5所示为set函数操作产生的交易数据,第一次调用get函数和第一次调用set函数时,系统发送给区块链的参数,这些参数内容会在后面的章节中用到,此处读者仅仅需要注意两次调用的不同之处,即调用set函数时,有status状态栏,并且该栏有矿机挖矿成功的提示。
图2.5 set函数操作产生的交易数据
2.1.3 其他设置
Analysis标签页中的很多选项都是在以太坊发生了多起被攻击的事件之后,编译器做出的改进性检查,像其中ECR20的检查,在2018年就有很多故事,读者可以自行搜索代币攻击事件。在本书的第7章中,笔者也会以案例的形式讲解其中的一种区块链合约攻击,这里不再展开讨论。有兴趣的读者可以逐条搜索每个选项背后的含义,这里建议保留默认选项,不要轻易修改,除非读者深刻地理解每条选项的含义。智能合约自动检测选项如图2.6所示。
图2.6 智能合约自动检测选项
像其他的IDE环境一样,Remix也提供了单元测试脚本的运行环境,如图2.7所示,并且Remix可以帮助开发者生成Solidity版本的测试代码。在修改代码后,可以单击Run Tests按钮来测试代码修改之后业务逻辑上的准确性,如果单元测试失败,会有相应的提示。
图2.7 Remix单元测试
智能合约运行时环境的复杂性使得智能合约的单步调试成为一件非常烦琐的事情,而Remix提供的单步调试界面如图2.8所示,这是Remix与其他开发环境相比有优势的地方。
图2.8 单步调试界面