Lição: 084: Biblioteca SafeMath
Nesta aula, vamos explorar a biblioteca SafeMath em Solidity. A SafeMath é uma biblioteca utilizada para realizar operações aritméticas de forma segura, protegendo contra erros de transbordo (overflow) e subfluxo (underflow) que podem ocorrer em aritmética de inteiros.
Por que usar a SafeMath?
Em Solidity, operações aritméticas em inteiros não são verificadas quanto a transbordo ou subfluxo por padrão. Isso significa que quando uma operação excede o valor máximo do tipo de dado (transbordo) ou vai abaixo do seu mínimo (subfluxo), pode levar a resultados inesperados ou vulnerabilidades em seus contratos inteligentes.
Para evitar esses problemas, podemos usar a biblioteca SafeMath, que fornece funções seguras para adição, subtração, multiplicação e divisão.
Implementação da Biblioteca SafeMath
Aqui está como a biblioteca SafeMath é implementada em Solidity:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: transbordo na adição");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subfluxo na subtração");
return a - b;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: transbordo na multiplicação");
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: divisão por zero");
return a / b;
}
}
Explicação das Funções
-
Adição (
add
): Esta função retorna a soma de dois números e verifica se o resultado é maior que qualquer um dos números, garantindo que não haja transbordo. -
Subtração (
sub
): Esta função retorna o resultado da subtração deb
dea
, garantindo queb
não seja maior quea
para evitar subfluxo. -
Multiplicação (
mul
): Esta função retorna o produto de dois números e verifica o transbordo confirmando que a divisão do resultado por um dos operandos iguala o outro operando. -
Divisão (
div
): Esta função retorna o quociente de dois números e verifica se o divisor não é zero para evitar erros de divisão por zero.
Usando SafeMath em um Contrato Inteligente
Agora vamos ver como usar a biblioteca SafeMath em um contrato inteligente simples.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./SafeMath.sol";
contract Token {
using SafeMath for uint256;
string public name = "MeuToken";
string public symbol = "MTK";
uint8 public decimals = 18;
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
constructor(uint256 initialSupply) {
totalSupply = initialSupply * 10 ** uint256(decimals);
balanceOf[msg.sender] = totalSupply;
}
function transfer(address to, uint256 value) public returns (bool) {
require(to != address(0), "Endereço inválido");
require(balanceOf[msg.sender] >= value, "Saldo insuficiente");
// Usando SafeMath para adição e subtração
balanceOf[msg.sender] = balanceOf[msg.sender].sub(value);
balanceOf[to] = balanceOf[to].add(value);
return true;
}
}
Explicação do Contrato Inteligente
- O contrato
Token
representa um token simples semelhante ao ERC20. - Ele utiliza a biblioteca SafeMath ao invocar
using SafeMath for uint256;
, permitindo que chamemos diretamente as funções SafeMath em valoresuint256
. - No
construtor
, o fornecimento total de tokens é calculado e atribuído ao criador do contrato. - A função
transfer
permite que os usuários transfiram tokens para outro endereço. Ela garante que:- O endereço do destinatário não seja zero.
- O remetente tenha saldo suficiente para a transferência.
- A adição e subtração seguras são aplicadas usando a biblioteca SafeMath.
Conclusão
Usar a biblioteca SafeMath é uma boa prática ao desenvolver contratos inteligentes em Solidity. Ela ajuda a prevenir erros aritméticos comuns que podem levar a vulnerabilidades sérias. Com a versão 0.8.0 do Solidity, as verificações de transbordo e subfluxo estão integradas na linguagem, mas entender a SafeMath ainda é importante para trabalhar com versões anteriores ou para fins educacionais.