既然你已经学完了我们的 solidity tutorial,接下来该做什么?
你现在已经具备了足够的知识来构建以下任何项目。知识来源于学习,但技能来自于实践。如果你想成为一名成功的 Solidity 开发者,知识和技能缺一不可!以下是一些建议,指导你可以构建哪些项目来应用迄今为止所学到的一切。
你已经掌握了所需了解的所有内容,所以如果你是认真想要成为一名 Solidity 工程师,那就动手实践吧!
这些项目大致按照从易到难的顺序排列,但你具备构建其中任何一个项目所需的全部背景知识。
1. 使用 ERC20 代币购买 NFT
构建一个经典的 NFT,规定只能通过支付特定的 ERC20 代币来进行铸造(mint)。
2. 时间解锁的 ERC20 / 归属(vesting)合约
付款人向合约存入一定数量的代币,而收款人在 n 天的时间里每天只能提取 1/n 的代币。
3. NFT 交换(Swap)合约
两个人希望以去信任(trustless)的方式交易他们的 NFT。用户在合约上创建一个交换记录,包含一个 address 和 id 的配对,其中 address 是 NFT 的智能合约地址,id 是 NFT 的 tokenId。只有当存放的 NFT 的 id 匹配所设置的 address 和 id 时,一方才能进行存入。同理,交易对手也只有在自己的 NFT 匹配该交换设置的 address 和 id 时才能存入。
一旦双方都完成了存入,任何一方都可以调用 swap 进行交换。
需要思考的一些边缘情况(corner cases):
- 交易者是否应该被强制将他们的 NFT 留在合约中?如果是,应该保留多长时间?
4. 众筹 ERC20 合约
你的合约应该包含一个 createFundraiser() 函数,接受目标金额和截止日期作为参数。捐赠者可以调用 donate() 向给定的 fundraiserId 进行捐赠。如果在截止日期前达到了目标金额,调用 createFundraiser() 的钱包就可以调用 withdraw() 提取与该活动相关的所有资金。否则,如果截止日期过后仍未达到目标,捐赠者可以撤回他们的捐款。构建一个支持 Ether 的合约,再构建另一个支持 ERC20 代币的合约。
需要思考的一些边缘情况:
- 如果同一个地址多次捐赠会怎样?
- 如果同一个地址向多个不同的活动捐赠会怎样?
5. 英式拍卖合约
卖家调用 deposit() 将一个 NFT 存入合约,同时设定截止日期和保留价格(reserve price)。买家可以在截止日期前对该 NFT 进行竞标,出价最高者获胜。如果没有达到保留价格,则不售出该 NFT。多个拍卖可以同时进行。未获胜的买家可以撤回他们的出价资金。获胜者无法撤回其出价,且必须完成交易以购买该 NFT。卖家也可以通过调用 sellerEndAuction() 来结束拍卖,该函数只能在过期后且达到保留价格的情况下才能生效。获胜者将被转入 NFT,而卖家将收到 ETH。
6. 简单的 NFT 市场
卖家可以调用 sell() 出售他们的 NFT,同时指定价格和过期时间。他们不需要将 NFT 存入合约中,而是授予合约将 NFT 从他们账户中划转的授权(approval)。如果买家出现并在过期前支付了指定的价格,那么该 NFT 将从卖家转移给买家,买家的 ether 将转移给卖家。
卖家可以随时调用 cancel() 取消出售。
边缘情况:
- 如果卖家将同一个 NFT 挂牌两次怎么办?由于他们并未将 NFT 实际转移至市场合约中,这在理论上是可能发生的。
7. 联合质押(Stake Together)
一个合约拥有 1,000,000 个 cloud coin。任何从 beginDate 开始将 cloud coin 质押到该合约并持有 7 天的人,将在到期时获得与其占总质押量比例成正比的奖励。例如,假设 Alice 质押了 5,000 个 cloud coin,而在到期时的总质押量为 25,000 个 cloud coin。那么 Alice 将有权获得 200,000 个奖励,因为她的质押量占了所有用户的 20%。
警告:很容易一不小心将奖励计算逻辑写错,从而让恶意攻击者有滥用系统的漏洞。请务必仔细思考其中的边缘情况!
8. 简单彩票
任何用户都可以调用 createLottery,从而创建一个彩票期数,其购票窗口期为接下来的 24 小时。一旦 24 小时结束,会有 1 小时的延迟,然后该彩票期数结束。在以太坊上安全地生成随机数非常棘手,但就本项目的目标而言,依赖于未来的 blockhash(玩家无法预测)就足够了。调用 createLottery 后,人们可以为特定的 lotteryId 执行 purchaseTicket。彩票必须包含一个停止售票的截止时间,以及随后的一个时间点,在该时间点由未来的 blockhash 来决定获胜者。获胜者随后必须在 256 个区块内(blockhash 函数的最大回溯限制)领取奖金,否则,所有人都可以退回他们买彩票的钱。
9. ERC1155 Bingo(宾果游戏)
使用 ERC1155 代币来模拟一副卡牌,其面值可以是 1 到 25(含边界值)之间的任何值。每个玩家初始拥有一个 5x5 的二维数组,其中 1-25 的数字随机排列。每隔 n 个区块,玩家就可以 mint 一张带有随机数字的新卡牌。最先将 5 个数字连成一条线(bingo)的玩家获胜。
10. 链上二十一点(Blackjack)
与常规的二十一点不同,在链上极难隐藏庄家(dealer)的底牌,因此应该让所有人的手牌完全公开。现实中的二十一点通常使用多副牌来降低算牌的有效性,所以你可以让随机数生成器产生一个介于 [2-10] 的随机数,但请记住 10、J、Q 和 K 的点数都是 10,因此你需要使概率成正比。同样,A 可以视为 1 或 11。庄家必须一直拿牌(hit),直到点数至少达到 21。
因为智能合约无法自行推进状态,所以如果是庄家的回合,任何人都可以调用 dealerNextMove() 来让游戏继续向前推进。在实际应用中,你需要一台链下计算机来维持庄家的自动操作,但我们目前暂不考虑这个问题。
你应该强制玩家在 10 个区块内做出操作,以防止任何人拖延游戏进度。
熟能生巧(Practice makes perfect)
我们的 learn solidity 资源之所以配备了 Solidity exercises,是因为纯粹通过看书学习编程是一个陷阱。动手写代码更重要!现在你可以做一些比解决碎片化小练习更具挑战性的事情了。
说真的,别再只盯着教程看了,开始创建项目吧!如果卡住了,请在我们的 discord 社区中求助,或者在 Google 上搜索,亦或是向现代的人工智能聊天机器人寻求帮助。
质量保证:编写单元测试并衡量 gas 成本
我们已经教过你如何使用 foundry framework for writing solidity unit tests(foundry 框架编写 Solidity 单元测试)。部署未经测试且用于处理他人资金的代码是绝对不可接受的。虽然这些只用于教学的合约,但你应该在学习过程的早期就养成编写测试的习惯。
试着像攻击者一样思考。如果攻击者试图破坏系统,他们会尝试输入哪些古怪的参数?
最后,请关注 foundry 报告的 gas 成本。你可以使用我们的 Ethereum gas price calculator 将 gas 单位转换为美元成本,并通过阅读关于如何将 ETH gas 转换为美元 的文章来了解该计算器的工作原理。
然后可以考虑学习 Solidity gas optimization tips(Solidity gas 优化技巧)并将其应用到你的项目中。
如果你想更进一步,可以构建一个简单的前端应用来连接这些合约。我们建议使用 wagmi js 库来实现这一点。
接下来做什么?
都完成了?我们建议你通过阅读我们的 gas optimization book(gas 优化书籍)并参加其中链接的课程,来学习如何对你的合约进行 gas 优化。然后尝试对你刚刚创建的合约进行 gas 优化!
通过 RareSkills 了解更多
如果你已经完成了上述所有内容,并希望加入社区结伴前行,或许可以考虑参加我们的进阶 Solidity bootcamp(Solidity 训练营)。
最初发布于 2023 年 9 月 10 日