Solidity学习笔记(5) — 使用Web3.js实现与Smart Contract的交互
作者:孔令坤,转载请注明出处
Web3官方API:https://github.com/ethereum/wiki/wiki/JavaScript-API
Youtube环境搭配视频:https://coursetro.com/courses/20/Developing-Ethereum-Smart-Contracts-for-Beginners
在本文中,我写了一个很简单的存取钱的智能合约,并借助web3.js提供的接口写了一个非常简单 的网页,来实现用户通过网页与smart contract的交互。
1.环境配置
首先,用户需要在google chrome中配置MetaMask。
之后,用户需要安装web3.js,具体安装方式见官方安装文档。
接下来,为了能在本地端实现web3.js与metamask中的账号以及smart contract的交互,我们需要在本地为网页文件创造一个虚拟的服务器环境。这里,我们使用lite-server来帮助我们实现这个需求。具体安装方法如下:
- 在装好web.js的文件夹目录下输入command line code:
1 | >> npm install lite-server --save-dev |
如果用户之前是全局安装web.js的话,需要先输入npm init
。
- 打开目录中的 package.json文件,在其中的
scripts
中添加:
1 | "scripts": { |
- 在目录中已有index.html文件的前提下,输入如下语句即可正常运行网页中的js脚本:
1 | >> npm run dev |
可能这里我讲得有点粗糙,但是不用担心。有人已经在youtube上提供了非常详细的安装流程,见Youtube环境搭配视频。
2.smart contract开发
如果大家已经看过了我之前的博客,相信这一部分对于大家而言将不存在任何理解上的困难。
所以这里我简单的直接放上代码:
1 | pragma solidity ^0.4.21; |
3.网页开发与js脚本编写
首先,我放出网页的主体框架与css文件,其中大量借鉴了Developing-Ethereum-Smart-Contracts-for-Beginners中的框架。整体比较粗糙,但是非常便于大家理解代码。
main.css文件:
1 | body { |
index.html框架
1 |
|
下面,我将分布挑重点来介绍一下我的js代码。
首先,我们在代码中放入:
1 | if (typeof web3 !== 'undefined') { |
这一段是官方提供的初始化连接web3的代码。如果你使用了metamask,那么currentProvider就会是来自你的metamask的网络以及账号。这个时候,在remix上,你的smart contract创建方式应当选择Injected Web3。
若你没有使用metamask,那么你可以在remix上使用Web3 Provider的方式来创建smart contract。这里"http://localhost:8545"
其实来自另一个好用的eth smart contract开发应用,其安装方式如下:
1 | >> npm install -g ethereumjs-testrpc |
通过>> testrpc
来启动这个provider并通过"http://localhost:8545"
来进行数据的发送。
接下来,我们选择web3应用中的账户。
1 | web3.eth.defaultAccount = web3.eth.accounts[0]; |
接下来,我们建立网页与合约之间的直接关联:
1 | var saveMoney = web3.eth.contract(ABI OF THE CONTRACT); |
ABI即smart contract编译后产生的一个文件,在remix中点击Start to compile按钮,然后点击Details按钮,即可复制smart contract的ABI,大致格式如下:
1 | [ |
然后smart contract的address的获取就比较简单了,就是创建好smart contract后,copy地址即可,e.g. 0x8f7e0a306b1a1f1205fa47b2bf2fefabaf056dae
。
之后,设置点击save money和 withdraw按钮的触发事件:
1 | $("#button1").click(function() { |
其中需要注意的是initAccount函数中参数的设定。由于这个函数是一个带value的payable的函数,我们需要在编程时不仅传递函数的参数,还得传递一定数量的以太币。在查阅了官方的api文件后,可以用如上的方式传递value,即
1 | function(param1, param2, ..., paramk, {value: # of eth}) |
这里我在设置value时使用了$("#money").val()+100000
,这是因为提交函数需要消耗一定量的gas,+100000wei是为了防止由于gas的消耗,用户无法在账户中存入数量为$("#money").val()
的金额,导致交易失败。
最后,我们通过监听smart contract中的event来在网页上输出数据,代码如下:
1 | var saveEvent = saveMoneyContract.accountInited({}, 'latest'); |
最后,我附上了index.html文件的完整代码,供大家参考:
1 |
|