ERC20合约审计初学者指南

在区块链世界中,代币被视为资产。这些资产必须得到安全地保护。在开发人员创建完智能合约之后,审计员有责任测试智能合约的漏洞。代币是使用智能合约创建的,而智能合约又使用 ERC20 标准。

那么,你如何审计 ERC20 合约呢?

请按照以下文章中的说明进行操作。但在此之前,让我们先定义 ERC20。

什么是 ERC20?

ERC20是使用以太坊区块链创建的可互换代币的标准。可互换代币是一种可与另一个代币互换的代币——而众所周知的非可互换代币(NFT)则不可互换。
在这里插入图片描述

ERC20 标准的功能:

如果合约实现了以下一些功能,则可以说该合约使用了 ERC20 标准。

  • 将代币从一个账户转移到另一个账户
  • 获取账户的当前代币余额
  • 获取网络上可用代币的总供应量
  • 批准某个账户是否可以由第三方账户花费一定数量的代币

审计 ERC20 合约时需要检查的事项:

  1. 当将代币从一个账户转移到另一个账户时,请检查值是否被正确更新。

  2. 类似地,当转移 ETH 时,请检查是否在转移之前发生状态更改。例如,在将 ETH 转移到接收方之前,应该先从发送方的账户中减少余额。这样可以防止诸如重入攻击之类的攻击。

  3. 检查所有外部调用。因为外部函数是任何人都可以调用的函数。如果有任何错误,攻击者将会清空合约中的余额。

  4. 如果合约具有多个用户角色,请检查所有角色,并检查是否正确应用了访问控制。

  5. 检查父合约(ERC20、Ownable)是否是标准合约(例如由 OpenZeppelin 编写),还是由开发者编写的自定义合约。

Gas燃气优化问题:

在这里插入图片描述

在审计阶段,审计员还将寻找gas优化问题。这将为客户降低成本。gas优化可以应用于所有合约,不仅仅是 ERC20 合约。

  • 检查合约中声明的所有函数是否都被使用(未使用函数)。
  • 检查是否存在多个功能相同的函数,有时开发人员会编写自己的逻辑。
  • 写入区块链存储是昂贵的。因此搜索“storage”关键字并分析是否应将其写入区块链。建议使用“memory”关键字。

找到所有问题后,重要的是再次验证这些问题。

  • 17
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
我可以为您提供一个erc20 合约的范例,您可以根据您的需求进行修改:pragma solidity ^0.5.11;contract ERC20 { mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowed; string public name; string public symbol; uint8 public decimals; uint256 public totalSupply; event Transfer(address indexed _from, address indexed _to, uint256 _value); constructor( uint256 initialSupply, string memory tokenName, uint8 decimalUnits, string memory tokenSymbol ) public { _balances[msg.sender] = initialSupply; totalSupply = initialSupply; name = tokenName; symbol = tokenSymbol; decimals = decimalUnits; } function balanceOf(address tokenOwner) public view returns (uint256 balance) { return _balances[tokenOwner]; } function transfer(address to, uint256 tokens) public returns (bool success) { _balances[msg.sender] = _balances[msg.sender].sub(tokens); _balances[to] = _balances[to].add(tokens); emit Transfer(msg.sender, to, tokens); return true; } function approve(address spender, uint256 tokens) public returns (bool success) { _allowed[msg.sender][spender] = tokens; return true; } function transferFrom(address from, address to, uint256 tokens) public returns (bool success) { _balances[from] = _balances[from].sub(tokens); _balances[to] = _balances[to].add(tokens); _allowed[from][msg.sender] = _allowed[from][msg.sender].sub(tokens); emit Transfer(from, to, tokens); return true; } function allowance(address tokenOwner, address spender) public view returns (uint256 remaining) { return _allowed[tokenOwner][spender]; } }

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值