В смарт-контрактах используйте SafeMath
Причина, по которой библиотеки обрабатывают математические операции, заключается в первую очередь в предотвращении проблем целочисленного переполнения и опустошения. Эти проблемы находятся в Solidity очень важны, поскольку могут привести к уязвимостям безопасности или неожиданному поведению.
SafeMath
это Solidity Библиотека, предоставляющая набор безопасных функций для целочисленной арифметики и арифметики с фиксированной запятой. Эти функции проверяют, произойдет ли переполнение или опустошение при выполнении таких операций, как сложение, вычитание, умножение, деление и т. д., и выдают исключения при возникновении этих условий, избегая таким образом использования неверных результатов.
SafeMath
Проблемы с переполнением и опустошением автоматически проверяются при выполнении математических операций.SafeMath
Будет выброшено исключение, предотвращающее выполнение и откатывающее транзакцию.SafeMath
Предоставляет набор простых в использовании функций.,Может быть легко интегрирован виз В контракте。SafeMath
Библиотеки могут облегчить разработчикам задачу по написанию проверок переполнения вручную.SafeMath
Она получила широкое признание как стандартная библиотека, и многие разработчики и аудиторы с ней знакомы.SafeMath
Может улучшить читаемость и удобство сопровождения кода.SafeMath
библиотека это Solidity часть сообщества, поэтому он соединяется с другими SafeMath
проекты совместимы.SafeMath
Легко интегрируется с другими контрактами.SafeMath
Это также хорошая практика, поскольку она может предотвратить возможные проблемы в будущем.подэто Простойиз Пример,показывает, какиспользовать SafeMath
Библиотека для предотвращения целочисленного переполнения:
pragma solidity ^0.8.0;
// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.
/**
* @dev Wrappers over Solidity's arithmetic operations.
*
* NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
* now has built in overflow checking.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
/**
* @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 sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting 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 mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
/**
* @dev Returns the integer division of two unsigned integers, reverting 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.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* 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 mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}
using SafeMath for uint256;
contract SafeMathExample {
function safeAdd(uint256 a, uint256 b) public pure returns (uint256) {
// использовать SafeMath из add функция
return a.add(b);
}
function
safeSub(uint256 a, uint256 b) public pure returns (uint256) {
// использовать SafeMath из sub функция
return a.sub(b);
}
function safeMul(uint256 a, uint256 b) public pure returns (uint256) {
// использовать SafeMath из mul функция
return a.mul(b);
}
function safeDiv(uint256 a, uint256 b) public pure returns (uint256) {
// использовать SafeMath из div функция
return a.div(b);
}
}
SafeMath
Обычно нужно начинать с OpenZeppelin Или другая надежная библиотека импорта исходного кода.SafeMath
может немного увеличиться gas Стоимость, поскольку необходимо провести дополнительные проверки.использовать SafeMath
Библиотека может помочь написать более безопасные смарт-контракты и предотвратить уязвимости безопасности, вызванные проблемами переполнения и потери целых чисел. Хотя это может добавить немного больше gas Стоит дорого, но обычно оно того стоит, особенно когда имеешь дело с критической бизнес-логикой.