智能合约编程/Dapp漏洞 -- 浮点数精度Floating Points and Precision

到Solidity v0.4.24为止,Solidity并不支持定点数和浮点数。这意味着浮点数的表示必须要用Solidity的整数来表示。如果实现不正确的话,会导致合约漏洞。

攻击原理

由于Solidity里并没有浮点数,程序员需要用标准的整型来自己实现浮点类型。在这个过程中,有一系列的陷阱,这里会介绍其中几个。

下面是程序示例 (简单起见,请忽略其中可能的over/under flow 问题)

contract FunWithNumbers {

    uint constant public tokensPerEth = 10;

    uint constant public weiPerEth = 1e18;

    mapping(address => uint) public balances;

    function buyTokens() public payable {

        uint tokens = msg.value/weiPerEth*tokensPerEth; // convert wei to eth, then multiply by token rate

        balances[msg.sender] += tokens;

    }

    function sellTokens(uint tokens) public {

        require(balances[msg.sender] >= tokens);

        uint eth = tokens/tokensPerEth;

        balances[msg.sender] -= tokens;

        msg.sender.transfer(eth*weiPerEth); //

    }

}

 

这个简单的token买卖合约有几个明显的问题。尽管计算公式是对的,但是由于Solidity缺乏浮点数支持会导致错误的结果。比如在第7行买tokens on line [7], 如果买的数额小于1 ether的话,最初的除法结果是0,导致最后的结果也是0。同样的,在卖tokens的时候小于10最后结果也会是0。实际上,取整一直是向下取整,所以卖29tokens,最终结果是2 token.

这个合约的问题在于精度在最接近的ether (i.e. 1e18 wei)。如果在ERC20合约里需要高精度的话,情况会很复杂。

防护方式

保持正确的精度在智能合约编程中是非常重要的,特别是在处理比率和兑换率的场合。你必须尽量保证分子比较大。比如在例子中,我们使用了兑换率tokensPerEth。此处最好使用weiPerTokens以保证分子是个比较大的数。在想获取token的数量的时候使用msg.value/weiPerTokens.这样会保证高精度

另外一个要注意的是关于操作的次序问题。在上面的例子中,在计算购买tokens的数额时,使用了msg.value/weiPerEth*tokenPerEth。必须注意这里除法在乘法之前。最好把乘法放在除法之前比如msg.value*tokenPerEth/weiPerEth.

最后,为了执行数学运算,最好定义一个虚拟的精度数,把所有的变量都变换成一个高精度数,只有在输出的时候在把他们变换回来。一般,我们会使用uint256类型(可以省Gas费),范围大致有大概60位其中有些位可以用来保持精度。在Solidity合约中最好把所有的变量都变换成一个高精度数,在外部的app中的时候在把他们变换回来。 这也是ERC20中Decimal类型工作的方式。建议去学习Maker DAO合约的DSMath库看看是如何实现的。

转载于:https://my.oschina.net/gavinzheng731/blog/3019752

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
区块链智能合约是一种基于区块链技术的智能化合约,它通过编写智能合约代码,实现了自动化执行、验证和执行合约条件的功能。区块链智能合约具有去中心化、透明、安全等特点,可以用于各种领域的应用。 DApp(去中心化应用)是构建在区块链上的应用程序,与传统的中心化应用不同,DApp使用智能合约来管理和执行应用逻辑,数据存储在区块链上,确保信息的可靠性和安全性。 实战电子版指的是对区块链智能合约与DApp应用进行实际操作和开发的电子版本。通过实战电子版,用户可以学习如何编写智能合约代码,了解区块链技术的应用场景,以及如何开发DApp应用。 实战电子版可以提供一系列的案例和示例代码,提供操作指南和开发工具,帮助用户深入理解区块链智能合约与DApp应用的原理和使用方法。用户可以通过实践和模拟操作来学习,并将所学知识应用到实际的区块链项目中。 通过实战电子版,用户可以学习到智能合约的编写和部署、DApp应用的开发和测试、区块链节点的搭建和管理等相关知识。同时,实战电子版还可以提供实时更新和维护,以适应区块链技术的不断发展和更新。 总而言之,区块链智能合约与DApp应用实战电子版是一种通过实践和模拟操作来学习和探索区块链技术的电子学习资源,对于理解、应用和开发区块链相关项目具有重要意义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值