环境依赖
以太坊的智能合约主要是 Solidity 实现,但是从零开始编写一个智能合约无疑是费时的(虽然本示例并不复杂),所以选择使用 Truffle 框架来帮助我们开发,所以我们首先需要安装 Node.js 、 npm 、 truffle1。智能合约需要运行在以太坊虚拟机上,我们不可能将未通过测试的智能合约直接部署在以太坊主链上————这会让你付出昂贵的代价,因此还需要一个测试链,而在通过Geth搭建私有以太坊网络中我们已经成功搭建了自己的测试网络,不过这次我们选择另一种更加便捷的方法,那就是 Ganache ,安装使用非常方便,只需官网下载一键安装即可。为了减少版本问题带来的未知Bug,可使本试验成功运行的主要软件版本为:
软件 | 版本 |
---|---|
Node.js | 14.16.0 |
npm | 6.14.11 |
truffle | 5.2.6 |
Ganache | 2.5.4 |
项目搭建
Ganache创建测试链
- 运行Ganache后选择 NEW WOEKSPACE
- 为你的测试链取一个响亮的名字并保存
- 记下网络参数
Truffle创建项目
- 创建文件夹 auction
- 进入文件夹执行
truffle init
初始化 - 创建智能合约
truffle create contract Auction
- 在 truffle-config.js 配置文件中配置测试链
- 项目架构如下
|
|
编写合约
拍卖流程如下:在拍卖合约部署时(构造)会绑定拍卖时长和最终受益人,每个用户可以通过公开渠道进行竞拍,合约会储存所有的竞拍记录;当出价高于已有记录时会更新最高出价人和最高出价,同时也会返还原/退回最高出价人的出价;拍卖时间结束后会将拍卖收益发送给最终受益人并关闭所有合约修改接口。完整代码如下2:
|
|
编译部署
- 创建部署文件
migrations/1_initial_migration.js
其中1 2 3 4
const Auction = artifacts.require("Auction"); module.exports = function (deployer) { deployer.deploy(Auction, 20000, "0xd136bE3960877709AC32fc6f5A3c299BFc9827Ac"); };
20000
是拍卖时长,也就是从部署的那一刻算起向后持续的时间,单位为秒,建议不要太小;0xd136bE3960877709AC32fc6f5A3c299BFc9827Ac
是最终受益人的钱包地址,可在Ganache
的默认十个账户中随便选一个,这里选择的是第0个账户。 - 编译合约
1 2 3 4 5 6 7 8
C:\Users\Fantasy\Desktop\auction>truffle compile Compiling your contracts... =========================== > Compiling .\contracts\Auction.sol > Artifacts written to C:\Users\Fantasy\Desktop\auction\build\contracts > Compiled successfully using: - solc: 0.5.16+commit.9c3226ce.Emscripten.clang
- 部署合约
提示信息中可以看到合约的地址为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
C:\Users\Fantasy\Desktop\auction>truffle migrate …… 1_initial_migration.js ====================== Replacing 'Auction' ------------------- > transaction hash: 0xc8395261413c662e00f3822b6647b0249fa6b789476b8efda680a7394d3491ac > Blocks: 0 Seconds: 0 > contract address: 0x4a9119E5b00b1Fd0681077C78688500637eAE629 > block number: 1 > block timestamp: 1628764710 > account: 0xd136bE3960877709AC32fc6f5A3c299BFc9827Ac > balance: 99.98959302 > gas used: 520349 (0x7f09d) > gas price: 20 gwei > value sent: 0 ETH > total cost: 0.01040698 ETH > Saving artifacts ------------------------------------- > Total cost: 0.01040698 ETH Summary ======= > Total deployments: 1 > Final cost: 0.01040698 ETH
0x4a9119E5b00b1Fd0681077C78688500637eAE629
,部署成功后可在 Ganache 的 BLOCKS 栏看见一个新的区块,并且第0个账户的以太币减少,这是因为部署智能合约会消耗以太币,而部署过程默认使用第0个账户部署。
测试交互
- 输入指令进入 console
进入 console 界面后可按两次 tab 建获取提示信息,可以看见我们刚部署的智能合约已经生效:
1 2
C:\Users\Fantasy\Desktop\auction>truffle console truffle(development)>
- 获取刚部署的智能合约实例
这里注意一定要加上await关键字,否则会获取失败。其它相关的方法为3:
1 2 3 4 5 6 7 8
truffle(development)> let app = await Auction.deployed() undefined truffle(development)> app. ...... app.AuctionEnded app.HighestBidIncreased app.abi app.address app.allEvents app.auctionEnd app.beneficiary app.bid app.constructor app.contract app.endAuction app.getPastEvents app.highestBid app.highestBidder app.methods app.send app.sendTransaction app.transactionHash app.withdraw
- 获取指定合约实例:
let app = await Auction.at("0xd136bE3960877709AC32fc6f5A3c299BFc9827Ac")
- 部署新的智能合约:
let app2 = await Auction.new(2000, "0xd136bE3960877709AC32fc6f5A3c299BFc9827Ac")
- 获取指定合约实例:
- 第1个账户发起2个以太币的竞拍
1
truffle(development)> app.bid({from:accounts[1], value:web3.utils.toWei("2")})
- 第5个账户发起4个以太币的竞拍
在竞拍后可以看见区块链上增加了两个新的块: 在竞拍后可以看见区块链上用户余额变化:
1
truffle(development)> app.bid({from:accounts[5], value:web3.utils.toWei("4")})
- 查看当前最高出价人和最高出价
需要注意的是,
1 2 3 4 5 6
truffle(development)> app.highestBidder() '0x898a007a57EDd1a37202D4F3781acB589Af1EDA3' truffle(development)> let highestBid = await app.highestBid() undefined truffle(development)> highestBid.toString() '4000000000000000000'
app.highestBid()
返回的是 BN(BigNumber)格式的数据无法直接查看,必须结合 await 关键字才能正常显示4。 - 账户1非最高出价可以赎回出价
此时可以看见链上增加了一个区块,并且账户1的2个以太币已退回:
1
truffle(development)> app.withdraw({from:accounts[1]})
- 拍卖时间结束后申请发放最终收益
此时可以看见最终拍卖价格4个以太币已经发送到账户0上:
1
truffle(development)> app.endAuction()
参考
-
朵耳. WIN10下node.js \ npm \ truffle的安装与配置. 简书. [2019-03-09] ↩︎
-
learnblockchain.cn. 秘密竞价(盲拍)合约. learnblockchain.cn. [2020-07-23] ↩︎
-
learnblockchain.cn. 与合约进行交互. learnblockchain.cn. [2019-05-21] ↩︎
-
Ofir Baruch. Convert BN to number. Stack overflow. [2020/07/23] ↩︎