最近在学习eth上的智能合约开发,本文主要是对Lil Nouns合约的学习总结。你将了解到Nouns拍卖的过程, 如何将NFT svg以节省gas的方式完全存放在链上,以及如何在下一轮拍卖前提前获取到Nouns的traits(并且我制作了一个可以实时获取下一个lil Nouns traits的工具)
参与过Lil Nouns 拍卖的朋友会知道,每一轮拍卖结束后需要有人手动去settle,当你点击官网上的Pick the next lil Noun按钮后,会唤起你的钱包去调用NounsAuctionHouse合约的settleCurrentAndCreateNewAuction(), 这个函数进行了两个操作,首先调用_settleAuction() settle上一轮拍卖,如果这一轮没有人出价那么会把这轮的lil noun销毁,如果有人出价,那么会把lil noun转到winner的钱包。最后会把bid资金转给lil nouns dao。

下面看一下createAuction的实现。创建auction时首先会mint一个新的noun(这里除了每第10和第11个lil noun,都会mint给auction合约), 并将返回的noun id作为参数更新当前的auction变量状态,同时会更新开始结束时间,将settled变量设置为false。

在用户进行出价时,必须大于等于前一个人的出价的105%(第四个require)。首先会把前一个出价人的eth还回去,然后会在auction变量中记录当前的出价人和出价。最后如果是在拍卖结束前90s出价,会让当前拍卖延长90s

下面说一下mint时nouns的traits是如何确定的。nouns是使用前一个区块的blockhash和前一个nounId作为seed生成伪随机数,然后使用把这个伪随机数对各个trait的总量取模作为该trait id的值。当然每次会把伪随机数进行右移,不然在不同trait总量相同时生成的trait id总是相同的

既然是伪随机数,那么我们就可以对下一个nouns的traits进行预测,只要遵守上面代码的算法,我们就能得到正确的traits。为了方便大家我制作了一个可以实时看到下一个lil noun的网站,只要输入上一个拍卖的lil noun的编号就能看到下一个lil noun的样子当然你要保证自己settle auction的交易被当前区块打包才行。
https://lil-nouns-predict.vercel.app
最后讲一个非常酷的trick,大家都知道eth上的存储是非常贵的,所以nft项目方大多选在将nft metadata存放在ipfs等平台上。Nouns 使用了@0xsequence的SSTORE2合约来优化gas。SSTORE2选择把数据编码成字节码部署成智能合约,在读取的时候直接读取合约的EXTCODECOPY(第一次知道这种骚操作),唯一的缺点是不能像状态变量一样修改,很适合存储静态的数据。这样写入和读取数据的gas都能得到可观的优化。
