在编写智能合约的时候需要注意的一个主要的安全特性:防止溢出和下溢。为了防止这些情况,OpenZeppelin建立了一个叫做SafeMath的库(library),默认情况下可以防止这些问题。

什么是溢出(overflow)

假设我们有一个uint8, 只能存储8 bit数据。这意味着我们能存储的最大数字就是二进制11111111(或者说十进制的2^8-1 =255).

来看看下面的代码。最后 number 将会是什么值?

在这个例子中,我们导致了溢出---虽然我们加了1,但是number出乎意料地等于0了。

下溢(underflow)也类似,如果你从一个等于0的uint8减去1, 它将变成255 (因为uint是无符号的,其不能等于负数)。

分析 SafeMath源码

1.加法,仅限内部调用,返回 uint256

require(c>=a && c>=b); //验证结果: 两个正数相加,和一定大于每个加数

2.减法,仅限内部调用,返回 uint256

require(b <= a) 因为返回值需要是 正数,所以此处判断 b必须小于等于a

3.乘法,仅限内部调用,返回 uint256

uint256 c = a * b; 容易溢出,比如 a=2,b=2^255 乘积 2^256 刚好溢出。结果取后面的256位(全为0),导致 c=0。

所以使用 (a == 0 || c / a == b),验证结果的一致性。

4.除法,仅限内部调用,返回 uint256

require(b > 0), 确保被除数不能为0

require(a == b * c + a % b);防止溢出,验证结果的一致性

总结:

不要直接使用简单的 "+-*/" ,尽量使用 library SafeMath 中的函数,避免整数溢出的隐患。

附:完整源码

pragma solidity ^0.4.24;

library SafeMath {

/**

* @dev Returns the addition of two unsigned integers, reverting on

* overflow.

*

* Counterpart to Solidity's `+` operator.

*

* Requirements:

* - Addition cannot overflow.

*/

function safeAdd(uint256 a, uint256 b) internal pure returns (uint256) {

uint256 c = a + b;

require(c >= a, "SafeMath: addition overflow");

return c;

}

/**

* @dev Returns the subtraction of two unsigned integers, reverting on

* overflow (when the result is negative).

*

* Counterpart to Solidity's `-` operator.

*

* Requirements:

* - Subtraction cannot overflow.

*/

function safeSub(uint256 a, uint256 b) internal pure returns (uint256) {

return safeSub(a, b, "SafeMath: subtraction overflow");

}

/**

* @dev Returns the subtraction of two unsigned integers, reverting with custom message on

* overflow (when the result is negative).

*

* Counterpart to Solidity's `-` operator.

*

* Requirements:

* - Subtraction cannot overflow.

*

* NOTE: This is a feature of the next version of OpenZeppelin Contracts.

* @dev Get it via `npm install @openzeppelin/contracts@next`.

*/

function safeSub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {

require(b <= a, errorMessage);

uint256 c = a - b;

return c;

}

/**

* @dev Returns the multiplication of two unsigned integers, reverting on

* overflow.

*

* Counterpart to Solidity's `*` operator.

*

* Requirements:

* - Multiplication cannot overflow.

*/

function safeMul(uint256 a, uint256 b) internal pure returns (uint256) {

// Gas optimization: this is cheaper than requiring 'a' not being zero, but the

// benefit is lost if 'b' is also tested.

if (a == 0) {

return 0;

}

uint256 c = a * b;

require(c / a == b, "SafeMath: multiplication overflow");

return c;

}

/**

* @dev Returns the integer division of two unsigned integers. Reverts on

* division by zero. The result is rounded towards zero.

*

* Counterpart to Solidity's `/` operator. Note: this function uses a

* `revert` opcode (which leaves remaining gas untouched) while Solidity

* uses an invalid opcode to revert (consuming all remaining gas).

*

* Requirements:

* - The divisor cannot be zero.

*/

function safeDiv(uint256 a, uint256 b) internal pure returns (uint256) {

return safeDiv(a, b, "SafeMath: division by zero");

}

/**

* @dev Returns the integer division of two unsigned integers. Reverts with custom message on

* division by zero. The result is rounded towards zero.

*

* Counterpart to Solidity's `/` operator. Note: this function uses a

* `revert` opcode (which leaves remaining gas untouched) while Solidity

* uses an invalid opcode to revert (consuming all remaining gas).

*

* Requirements:

* - The divisor cannot be zero.

* NOTE: This is a feature of the next version of OpenZeppelin Contracts.

* @dev Get it via `npm install @openzeppelin/contracts@next`.

*/

function safeDiv(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {

// Solidity only automatically asserts when dividing by 0

require(b > 0, errorMessage);

uint256 c = a / b;

return c;

}

/**

* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),

* Reverts when dividing by zero.

*

* Counterpart to Solidity's `%` operator. This function uses a `revert`

* opcode (which leaves remaining gas untouched) while Solidity uses an

* invalid opcode to revert (consuming all remaining gas).

*

* Requirements:

* - The divisor cannot be zero.

*/

function safeMod(uint256 a, uint256 b) internal pure returns (uint256) {

return safeMod(a, b, "SafeMath: modulo by zero");

}

/**

* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),

* Reverts with custom message when dividing by zero.

*

* Counterpart to Solidity's `%` operator. This function uses a `revert`

* opcode (which leaves remaining gas untouched) while Solidity uses an

* invalid opcode to revert (consuming all remaining gas).

*

* Requirements:

* - The divisor cannot be zero.

*

* NOTE: This is a feature of the next version of OpenZeppelin Contracts.

* @dev Get it via `npm install @openzeppelin/contracts@next`.

*/

function safeMod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {

require(b != 0, errorMessage);

return a % b;

}

}

墨客科普 | MOAC BlockChain SafeMath库相关推荐

  1. 助记词创建以太坊钱包源码_墨客科普 | MOAC区块链钱包账号管理

    本文简单描述钱包账号管理的一些方法. 一.术语 1.1 gas,Gas Limit和Gas Price 在墨客区块链上,发送代币或调用智能合约.执行写入操作,需要支付矿工计算费用,计费是按照Gas计算 ...

  2. 墨客科普---MOAC分层分片技术

    MOAC公链通过对以太坊系统架构的革新,目前主网已更新至女娲1.0.9版本,能够同时解决区块链有效去中心化.安全性以及可扩展性的技术难点,具体做法如下: 采用分层结构实现分片 640?wx_fmt=p ...

  3. 执行修订 第十五篇 墨客区块链(MOAC BlockChain) 搭建自己的第一个DAPP

    原文链接:https://blog.csdn.net/lyq13573221675/article/details/81698014 本文是在测试网络里面进行应用大搭建: C:\Users\Admin ...

  4. 墨客开发者行动(上海站)

    墨客开发者在行动(上海站) MoacChain 墨客区块链 2018.6.20 墨客上海技术研讨会这就来啦! 墨客上海核心团队将在7月1日,在上海Wework(威海路)举办MOAC技术研讨会.墨客 ...

  5. 墨客FileStorm生态与四块科技生态联合发布会

    2018年12月15日下午,由四块科技和墨客联合主办的墨客子链+FileStorm+四块存储设备及其四块落地应用上线运营联合发布会在四块科技深圳总部顺利召开.本次发布会集合了墨客美国硅谷团队.IPFS ...

  6. Openzeppelin学习记录二:utils模块(SafeMath.sol+SafeCast.sol)

    Openzeppelin学习记录一:access模块(AccessControl.sol+Ownable.sol) Openzeppelin学习记录 2.Utils 2.1 Math 2.2 Safe ...

  7. NFT合约解析(3)——SafeMath.sol——2021.5.17

    NFT合约解析(3)--SafeMath.sol 一丶配置需求: 1.环境需求:WeBASE-Front 2.合约语言:Solidity >=0.6.0 <0.8.0 二丶SafeMath ...

  8. 【区块链】【智能合约】美链攻击分析以及安全库的使用

    1.美链攻击过程 美链代币BEC为发行在以太坊上的ERC20代币,其具体合约的代码在该链接中合约代码. 向美链发起攻击的交易链接为攻击交易hash. function batchTransfer(ad ...

  9. 数字货币 2018年市值排行榜前100币种简介

    区块链,对于很多朋友来说绝对是一个陌生的词语.甚至很多人会去百度,区块链怎么去买之类的笑话了.而对于绝大部分炒币的朋友而言,甚至连这个叫什么币,以及作用确是浑然不知.今天,小编在这里进行科普一下了,把 ...

最新文章

  1. Oracle中Scott账户常见表的样本查询编程与数据库
  2. 面试题-Category(分类)
  3. Jupyter notebook 运行环境创建和切换 (Win10+Anaconda)
  4. ​​​​​​​Git学习笔记与IntelliJ IDEA整合
  5. 软件测试 测试策略_测试策略| 软件工程
  6. Linux 工程师技术 系统服务管理进阶
  7. python scipy stats_Python Scipy stats.binned_statistic_dd()用法及代码示例
  8. MySQL中的调度器
  9. linux jar 运行 停止,[转] Linux中启动和停止jar包的运行
  10. ant+testng 搭建
  11. python实现的好玩的小程序--利用wxpy实现的微信可检测僵尸粉机器人
  12. NAS媒体库资源归集整理工具nas-tools
  13. c语言幂函数_C ++中的幂函数
  14. 阿里技术专家:一文教你高效画出技术架构图
  15. Matlab坐标修改 gca
  16. Altium Designer16 精心总结
  17. 显著性目标检测之Shifting More Attention to Video Salient Object Detection
  18. jrebel java.lang.ClassCastException: org.springframework.boot.actuate.endpoint.annotation
  19. 音频标准AES的一点理解
  20. 2020五四青年节 | 青年人在美团是怎样成长的?

热门文章

  1. 南开大学2012年考博微观经济学真题
  2. 项目实习(五)网络渗透实验
  3. 基于VPB的三维地形建模小结
  4. html怎么写分享代码,怎么写一个文件分享网页?百度一键分享按钮HTML代码
  5. CentOS7 yum方式安装MySQL 5.7
  6. python下载夏目友人帳
  7. 如何高效学习(斯科特·扬 )(含思维导图)
  8. 黑人太管用计算机来打出来的音乐,求欧美黑人饶舌歌曲,节奏感要很强劲的那种。。。 (在百度上搜了,对味的只有少数)...
  9. android 键盘 自动消失,Android 系统键盘怎么也不消失
  10. 好书推荐--《人生不设限》