具体来说,一个Solidity程序代码写完之后,必须先将它编译成bytecode才能部署至链上,变成智能合约。在部署时,编译后的bytecode被分为三个部分:Creation、Runtime和Constructor Parameters。其中Creation部分用来执行合约里的constructor,不会储存在区块内;Runtime部分是合约的主体,存储在链上;Constructor Parameters部分则是存储constructor的参数。
在使用合约内的函数时,Runtime部分的bytecode负责处理流程。其中最常用到的是function selector,用于比对要呼叫的function signature是否存在bytecode中。若存在,则执行相应的函数;否则就会执行fallback function。若合约甚至没有实作fallback function,则交易就会被Revert。
本文还以EtherDice.sol合约为例,介绍了其存在的安全漏洞。该合约的一个重要随机数来源居然是使用区块的timestamp,而只需写个攻击合约,即可透过合约来呼叫EtherDice的bet,预先计算出block.timestamp%6的结果,实现每赌必赢。对此,本文提供了防御措施:通过判断发出交易的address是否为contract address或externally owned account(EOA),即可挡下由攻击合约发出的交易。
然而,本文还提到了另一种攻击方式,即在合约的constructor中写入攻击程序代码,绕过侦测机制,实现攻击。对此,作者没有给出具体的防御措施,而是希望读者通过自己的方式找出答案。
总之,Solidity合约的安全是非常重要的,需要开发者深入理解其原理,加强安全意识,才能编写出安全可靠的合约。