前 言随着区块链技术发展,网卓新闻网,更加多的企业与个人开始将区块链与自身业务结合。区块链所具备的独有优势,例如,数据公开发表半透明、不能伪造,可以为业务带给便捷。但与此同时,也不存在一些隐患。
数据的公开发表半透明,意味著任何人都可以加载;不能伪造,意味著信息一旦上链就无法移除,甚至合约代码都无法被变更。除此之外,合约的公开性、消息传递机制,每一个特点都可被利用,作为反击手法,稍有不慎,轻则合约形同虚设,轻则要面对企业机密泄漏的风险。
所以,在业务合约上链前,必须预先对合约的安全性、可维护性等方面不作充分考虑。幸运地的是,通过近些年Solidity语言的大量实践中,开发者们大大萃取和总结,早已构成了一些"设计模式",来指导应付日常研发少见的问题。智能合约设计模式阐述2019年,IEEE收录于了维也纳大学一篇为题《Design Patterns For Smart Contracts In the Ethereum Ecosystem》的论文。
这篇论文分析了那些火热的Solidity开源项目,融合以往的研究成果,整理出有了18种设计模式。这些设计模式涵括了安全性、可维护性、生命周期管理、鉴权等多个方面。
接下来,本文将从这18种设计模式中自由选择尤为标准化少见的展开讲解,这些设计模式在实际研发经历中获得了大量检验。安全性(Security)智能合约撰写,首要考虑到的就是安全性问题。在区块链世界中,恶意代码数不胜数。
如果你的合约包括了横跨合约调用,就要尤其当心,要证实外部调用否可靠,特别是在当其逻辑不为你所掌控的时候。如果缺少防人之心,那些“居心叵测”的外部代码就有可能将你的合约毁坏只剩。
比如,外部调用可通过蓄意消息传递,使代码被重复继续执行,从而毁坏合约状态,这种反击手法就是知名的Reentrance Attack(纠错反击)。这里,再行引进一个纠错反击的小实验,以便让读者理解为什么外部调用有可能造成合约被毁坏,同时协助更佳地解读将要讲解的两种提高合约安全性的设计模式。
关于纠错反击,这里荐个精简的例子。AddService合约是一个非常简单的计数器,每个外部合约可以调用AddService合约的addByOne来将字段_count特一,同时通过require来强迫拒绝每个外部合约最多不能调用一次该函数。
这样,_count字段就准确的反应出有AddService被多少合约调用过。在addByOne函数的末尾,AddService不会调用外部合约的消息传递函数notify。AddService的代码如下:contract AddService{uint private _count;mapping(address=bool) private _adders;function addByOne() public {//强迫拒绝每个地址不能调用一次require(_adders[msg.sender] == false, "You have added already");//计数_count++;//调用账户的消息传递函数AdderInterface adder = AdderInterface(msg.sender);adder.notify();//将地址重新加入已调用子集_adders[msg.sender] = true; }}contract AdderInterface{function notify() public;}如果AddService如此部署,蓄意攻击者可以只能掌控AddService中的_count数目,使该计数器几乎过热。
攻击者只必须部署一个合约BadAdder,就可通过它来调用AddService,就可以超过反击效果。BadAdder合约如下:contract BadAdder is AdderInterface{AddService private _addService = //...;uint private _calls;//消息传递function notify() public{if(_calls5){return;}_calls++;//Attention !!!!!!_addService.addByOne();}function doAdd() public{_addService.addByOne(); }}BadAdder在消息传递函数notify中,反过来之后调用AddService,由于AddService差劲的代码设计,require条件检测语句被精彩跨过,攻击者可以中出_count字段,使其被给定地反复加到。
本文来源:澳门威斯尼斯wns888入口-www.tzssjj.com