上一篇文章里,我们实现了一个每周博客挑战合约,但是该合约仍未调试和测试,并且经过思考,我认为还有一点功能还未完善。在这篇文章里,我将继续完成这些内容~
我们允许参与者自由地加入和退出,在第一篇文章里并没有实现该功能,这里我们就浅浅实现一下~
modifier onlyNotParticipant() {
bool isParticipant = false;
for (uint256 i = 0; i < currentChallenge.participants.length; i++) {
if (msg.sender == currentChallenge.participants[i]) {
isParticipant = true;
break;
}
}
require(msg.sender != currentChallenge.challenger && !isParticipant, "Already participant!");
_;
}
// 中途加入
function participate() public onlyNotParticipant onlyStarted {
currentChallenge.participants.push(msg.sender);
}
// 中途退出
function exit() public onlyStarted {
uint256 len = currentChallenge.participants.length;
for (uint256 i = 0; i < len; i++) {
if (msg.sender == currentChallenge.participants[i]) {
currentChallenge.participants[i] = currentChallenge.participants[len - 1];
currentChallenge.participants.pop();
break;
}
}
}
还记得我们需要限制最大参与人数吗?上面的代码并没有做这个限制,既然现在允许用户自行加入,我们就需要做一个最大参与人数的限制。实现起来很简单,给Challenge加一个maxParticipants的变量并加以维护即可
我们还需要给合约添加事件,帮助我们更好地掌握合约状态的变化,我们可以定义这几个事件:
// region events
event ChallengeStart(address indexed challenger);
event ChallengeEnd(address indexed challenger, bool indexed passed);
event SubmitBlog(address indexed challenger, uint256 indexed cycle, string blogUrl);
event CycleEnd(address indexed challenger, uint256 indexed cycle, bool indexed passed);
event Participate(address indexed challenger, address indexed participant);
event Exit(address indexed challenger, address indexed participant);
event Release(address indexed challenger, uint256 indexed cycle, uint256 amount);
// endregion
然后我们在合适的地方进行emit就可以了,代码比较简单就不赘述了,让我们进入下一part!
首先,打开Remix,创建新工程,把代码粘贴过去:

然后点击编译——发现一堆错误hhhh
没关系,编译错误一般都很好解决,根据编译器提示逐个击破即可~
一共大概有十几个错误吧,都是些低级错误,这里就不写出来献(shui)丑(wen)了(zhang),大家感兴趣可以自己拿过去编译一下。总之改了几分钟,终于编译通过了~

编译通过后我们就可以开始测试了,最简单的方式是直接在Remix的虚拟机上面部署并测试,虽然能完成我们的目的,但是步骤非常繁琐低效。我们需要使用到一些智能合约开发工具来提高我们的效率以及让我们的项目显得更正式一点~
我们使用Foundry来进行测试,对Foundry不熟悉的童鞋(比如我),可以看这里介绍 - Foundry 中文文档 (learnblockchain.cn)
是的,我也是第一次用哈哈哈哈
