geth容器里提供了一个智能合约的例子greeter合约,在/home/geth目录下有一个greeter.js文件和一个greeter.sol文件,命令如下:
由于在greeter.js中已经写好了部署合约的代码,所以按照官方文档指引直接调用greeter.js代码即可部署greeter合约。在console中使用loadScript函数调用greeter.js,代码如下:
但是,运行greeter.js文件时发生了错误,提示eth_compileSolidity函数不存在,原来这个geth版本已经被移除了。
由于在console中编译不了greeter.sol文件的Solidity代码,我们可以使用Remix工具来编译greeter合约。
在Remix中新建一个greeter.sol文件,并把docker中greeter.sol的源码复制到Remix中。当把代码里的注释都删除后,我们发现greeter.sol源码里没有声明版本的信息,需要在源码里补充Solidity 0.4.16版本的信息,不然编译就会出错,代码如下:
从构造函数看,只要编译没有出错,补充声明一个Solidity 0.4范围内的版本应该都是可以的。这里说明一下为什么补充的Solidity版本是0.4.16。因为在geth容器里solc命令的版本是0.4.16,因此猜想它们应该是对应的,查看版本的命令如下:
选择Solidity的版本为0.4.16的编译器,单击“Compile greeter.sol”按钮开始编译,若没有报错则表示编译成功,如图4.3所示。
分别单击“ABI”按钮和“Bytecode”按钮复制出ABI和Bytecode(字节码),如图4.4所示。
复制出的ABI是包含合约变量和函数信息的一个数组,内容如下:
图4.3
图4.4
复制出的Bytecode是一组json类型的数据,不过在部署合约时,只需要object对应的那段十六进制数据,内容如下:
获得ABI和Bytecode的数据后,修改greeter.js部署脚本,内容如下:
修改greeter.js脚本后,回到console中。执行greeter.js部署合约之前需要先解锁账户,如果没有解锁账户,执行时将会抛出报错,代码如下:
执行personal.unlockAccount函数来解锁账户,代码如下:
再次调用loadScript函数执行greeter.js脚本,若返回状态为true,则表示执行成功,代码如下:
使用txpool.status查看交易池的状态,pending结果为1,说明执行greeter.js提交部署合约的交易已经成功,接着进行挖矿确认交易,代码如下:
至此,greeter部署合约已完成。现在执行greet(),可正确返回字符串“Hello World!”,如图4.5所示。
图4.5
因为在部署合约时已经实例了greeter对象,所以这里可直接通过greeter对象来调用greet函数。那么,假设其他人部署了一个合约,我们应该通过什么方式去调用函数呢?