前段时间做了一个eth的dapp(http://freeeth.club),趁着现在闲了总结一下这次开发的心得。 当时fomo3d挺火的,我干的第一个事情是把fomo3d合约发布到了测试网,然后再开始开发这个天天抽eth的合约,智能合约用的是solidity, 后台用的是nodejs。
天天抽eth这款dapp的大致逻辑如下:
1. 主要操作有:管理员充值,设置当日抽奖金额, 用户参入抽奖, 用户邀请其他人抽奖(非dapp行为,用户分享链接), 开奖 (管理员操作,每天操作一次)
2. 奖池划分: 70%归当日中奖用户 , 30%归当日邀请用户最多的用户, 10%归中奖用户 (ps: ^_^ 这个奖池划分还是我这个coder想的)
整体来说,这个项目工作量还好,但初次自己从头做dapp的我,也是遇到这里一个坑那里一个坑。
第一坑编辑器:
最开始用的线上remix:http://remix.ethereum.org/,这个时常打不开,还有compile找不到等一些问题,很是无赖。
后来就用vscode下了solidity的插件做主编辑器,vscode有些语法报错检测不到,没办法就只能安装remix-ide(https://github.com/ethereum/remix-ide), 作为一些辅助检测。
第二坑搭建开发测试私链:
智能合约写好了,一般会选择发布到自己的私链上,最开始我选择是ganache,当时先跑的是fomo3d的合约,那个发布要800多万gas, ganache总是报out of gas, 我当时还啥逼逼的想是不是我用的ganache的姿势不对(⊙_⊙), 在google上搜索解决方法了半天,各种尝试就不管用。后来别人推荐说parity好,我立马用parity搭了个两节点的私链,fomo3d的合约发布在parity上妥妥的,parity带UI用户体验比较好,能看到每笔消耗的gas。至此我后面的自己的私链都是选择的parity.
第三坑调试:
eth的智能合约调试更像交易记录的回放,在remix下支持已完成的交易的debug,支持单步前进,单步回退等操作,能显示当前的local,全局变量,操作指令等信息。
但是与传统编程的调试而言:1.操作滞后,必须是已完成的交易,不能实时进行 2.进行复杂逻辑测试的时候,要先构造很多先决交易。
第四坑智能合约编写:
智能合约的编写与其他编程的很大不同是,细节要注意的更多,合约一旦发出去就没法修改。我总结了以下几点:
1. 前置条件判断,一定要考虑的周细,多用modifier, require, asset
2. 权限的管理,一般会有些操作智能合约拥有者,管理员操做
3. 合约和外界的交互,基本只能靠事件event
4. 针对只读函数,可以用 view,pure进行修饰
5. 多用一些验证的安全库,比如SafeMath
第五坑随机数选择:
现在随机数的方案有以下这几种:
solidity文档(solidity.readthedocs.io) 推荐的方案RANDAO(https://github.com/randao/randao),是个线上合约, 这个方案比较复杂,先要交纳保证金而且还要经历三个阶段才能得到最终的随机数(ps:细节比我描述的复杂多啦),所以不是一个经济和使用的方案。
fomo3d: 采用区块的特征作为随机的特征来进行随机数的种子,但是可以通过在另一个合约的构造函数内进行随机数逻辑的调用,从来达到刷空投的目的
vdice: 采用orcalize service+ random.org的方式, 此方案成本过高
dice2.win: 采用commit-reveal, 提交-揭示方法包括两个阶段,dice2.win第一阶段是玩家进行下注的时候提供存证信息(猜测服务器生成的),第二阶段是庄家进行结算根据存证+blockhash来作为随机种子,在进行判断玩家是否中奖,我做的dapp不适合按照这个方式来进行操作(参加抽奖有很多人,开奖只能是管理员,开奖时间间隔很长,dice.win开奖时间很短)。
在写这篇文章的时候,发现随机数选取写的相当好的一篇文章(http://www.freebuf.com/vuls/179173.html)
综上,最后我在做这个dapp的时候,用了一个取巧的办法,采用和fomo3d一样的随机数方案,当时只有管理员能够控制,虽然减少被风险,但也显得不那么去中心化。
第六坑定时触发:
当时遇到的问题是,想每天定时一个事件开奖。
在solidity文档中,找的方案是alarm clock(https://www.ethereum-alarm-clock.com/),大致方案是alarm clock提供一个定时触发的服务,有几个公共的智能合约代我们运行这个定时触发,但是也不保证完全能够定时触发。 更为详细的介绍可以看(https://ethereum-alarm-clock-service.readthedocs.io/)
操作繁琐,且不一定成功,后来我们修改的结算方案,改为开奖结束后的24小时为结束时间,由管理员自己发起交易来触发开奖操作(此操作不频繁)。本来想做一个服务器后台还跑了检测结束时间的服务,来自动触发开奖,后来时间仓促就没弄啦。
小结:
综上,这是我开发的Dapp的一些心得体会,文中有不正确的地方,欢迎大家指出。
合约工程地址:
合约代码在https://github.com/tiankonglan/DayDrawEth
技术交流:
区块链技术QQ群:532655612