Solidity学习笔记(2) — Auction
作者:孔令坤,转载请注明出处
今天用拍卖合约(Auction Contract)进行Smart Contract编程的学习。
环境的安装和使用方法这里不做过多的赘述,附上两个链接,大家可以用来参考:
MetaMask配置:https://karl.tech/learning-solidity-part-1-deploy-a-contract/
Solidity配置与运行案例:https://karl.tech/learning-solidity-part-2-voting/
另外附上官方的学习代码链接:https://solidity.readthedocs.io/en/latest/solidity-by-example.html#blind-auction
另外发现了一个不错的大纲型文档:https://medium.com/@mattcondon/getting-up-to-speed-on-ethereum-63ed28821bbe
1.SimpleAuction
通过智能合约,实现了拍卖中用户们的匿名化。具体而言,在拍卖中,用户们通过调用智能合约进行出价,由智能合约后台经过处理后选出出价最高的用户进行最后交易,并退回其它用户的钱。
首先,我们来看官方给出第一个例子,contract SimpleAuction{}
。在这个例子中,在拍卖结束后,这个合约需要被人为地操作auctionEnd()
函数,这样收益人beneficiary
才能获得来自出价最高的用户的钱。另外,这个合约中,如果一个用户的报价被接受了,并不意味着这个用户已经可以拍得这个商品,因为有可能只是他出的前是目前而言最高的。如果之后有更高的出价,他需要操作withdraw()
函数才能退回自己的金额。
代码分析:
payable
函数几乎是所有smart contract涉及到金额流动都会有的一个函数,因为涉及交易金额的信息都已经在以太坊的transaction中了,所以payable
函数并不需要参数输入。在这个函数中,合约先判断是否还在拍卖截止前,然后看用户提供的拍卖金额是不是当前最高的,如果不是直接退回,如果是的话则存储到pendingReturns
中,等待最后拍卖截止后再看是不是最高的价格。另外值得注意的是,由于require(msg.value > highestBid);
所以在用户价格相同的时候,会取先出价的用户。
另外在这段代码中,出现了对event的调用(HighestBidIncreased()
),通俗的来说event, i.e., 事件是以太坊EVM提供的一种日志基础设施。事件可以用来做操作记录,存储为日志。也可以用来实现一些交互功能,比如通知UI,返回函数调用结果等。(http://me.tryblockchain.org/blockchain-solidity-event.html)
1 | event HighestBidIncreased(address bidder, uint amount); |
withdraw()
函数可以说是simple auction中最笨的地方了,这里由于合约无法自动退回一些没有成功达成交易的用户的拍卖投标,用户需要在拍卖结束后自己去调用withdraw()
函数。
1 | function withdraw() public returns (bool) { |
在最后的auctionEnd()
函数中,合约将最高的金额转移给受益人。
1 | bool ended; |
2.Blind Auction
在官方提供的blind auction智能合约中,通过哈希函数的一系列特性,用户可以不直接把自己的拍卖投标放到合约中,而是只用提供自己的投标的哈希值。在拍卖结束后,用户通过提供未被哈希过的值作为依据,交给合约验证,从而判断之前提供的哈希值是有效的 — 确实由本人提交并且金额无误。
代码分析:
由于代码较长,这里我直接通过注释的方式对代码进行说明:
1 | contract BlindAuction { |
3.一些思考与改进
在看代码的过程中,我发现用户的钱在投标后其实是会把钱直接锁死在了智能合约中。根据本合约的逻辑,最终其实会有很多用户的钱被锁定(因为在用户调用withdraw()
函数之前,他们都认为自己下的标是最大的)这其实对用户而言非常的不友好。
这里,我重新修改了placeBid()
函数,当highestBid
发生变化时我直接把前一个highestBid
的钱退还给了相应的用户。我把我的代码放到了下面的链接里:https://github.com/Ohyoukillkenny/Learn-Solidity