Web3学习之 ERC20

Web3学习之 ERC20Web3 学习之 ERC20ERC20ER 是以太坊上的一种代币标准 它定义了一组接口 方法和事件 使得代币可以在不同的应用程序 钱包和交易所之间进行互操作

大家好,欢迎来到IT知识分享网。

Web3学习之 ERC20

ERC20

ERC20 是以太坊上的一种代币标准,它定义了一组接口(方法和事件),使得代币可以在不同的应用程序、钱包和交易所之间进行互操作。ERC20 标准使得创建和使用代币变得简单和一致,是最广泛采用的代币标准之一。

image-20240708151046000.png

EIP / ERC 标准

  • 标准:降低沟通协作成本、增强互操作性
  • EIP: Ethereum Improvement Proposal 以太坊改进提案
    • 不是所有的 EIP 都是标准
    • 提交改进 Issue (编号)、社区的讨论(实现及验证) 、形成共识、作为标准
      • ERC20:ERC-20: Token Standard
      • ERC1155:ERC-1155: Multi Token Standard
      • ERC4626:ERC-4626: Tokenized Vaults

EIP(Ethereum Improvement Proposal,以太坊改进提案)是以太坊社区提出和讨论对以太坊平台进行改进和变更的正式流程。EIP 分为几个主要分类,每个分类有不同的目的和用途。以下是 EIP 的主要分类:

  1. 核心(Core)
    • 这些是影响以太坊核心协议的改进提案,包括共识协议更改、网络升级和硬分叉。
    • Core EIP 是对以太坊的底层协议和运行机制的改进,需要进行广泛的测试和社区共识。
  2. 接口(Interface,ERC)
    • 这些提案用于标准化以太坊上的应用程序接口(API)和智能合约标准。
    • 最著名的例子是 ERC-20 标准,它定义了代币的接口,使代币在不同的应用程序和交易所之间具有互操作性。
  3. 网络(Networking)
    • 涉及以太坊网络协议的改进提案,包括对节点间通信的更改。
    • Networking EIP 包括对以太坊网络消息传递协议和数据传输的改进。
  4. 元(Meta)
    • Meta EIP 涉及以太坊改进提案流程本身的改进,包括对 EIP 模板、格式和流程的更改。
    • 这些提案不直接涉及以太坊代码或协议的更改,而是关于管理和协调改进提案的流程。
  5. 信息(Informational)
    • 提供与以太坊设计和使用相关的指导和信息。
    • 这些提案不提议任何新的功能或标准,只是为开发者和用户提供信息和最佳实践。

示例

  • EIP-1:描述了 EIP 的流程和指南,属于 Meta 分类。
  • EIP-20(ERC-20):定义了标准的代币接口,属于 Interface 分类。
  • EIP-1559:对以太坊的交易费用结构进行改进,属于 Core 分类。
ERC20 标准提供了一组基础接口,使得代币可以在以太坊生态系统中方便地创建、管理和交换。

区分原生币(Coin)和代币(Token)

你所提到的区别是区分原生币(Coin)和代币(Token)的关键概念。以下是更详细的解释:

以太币(Coin)
  • 原生币: 以太币(Ether,ETH)是以太坊区块链的原生加密货币。它直接由区块链协议生成和管理。
  • 用途: 主要用于支付网络上的交易费用(Gas)以及奖励矿工(现在是验证者)。
  • 特性: 原生币的交易是直接在区块链上进行的,不需要任何智能合约。
  • 地址: 以太币的交易地址是由以太坊协议生成的。
ERC20 代币(Token)
  • 智能合约币: ERC20 代币是通过智能合约创建和管理的加密货币。它们不是区块链的原生币,而是构建在区块链之上的。
  • 用途: 可以代表各种资产或功能,如稳定币、权益证明、治理代币等。
  • 特性: ERC20 代币遵循以太坊改进提案 20(EIP-20)的标准,实现了一组基本的接口和功能,使其能够在去中心化应用(DApps)之间互操作。
  • 地址: ERC20 代币的合约地址是由智能合约生成的。
WETH(Wrapped Ether)
  • 包装以太币: WETH(Wrapped Ether)是将 ETH 包装成 ERC20 代币的形式,使其能够在需要 ERC20 标准的去中心化应用中使用。
  • 用途: 由于 ETH 不是 ERC20 代币,有些 DApps 需要使用 ERC20 标准,因此 WETH 充当桥梁,使 ETH 可以像其他 ERC20 代币一样使用。
  • 特性: 1 WETH 始终等于 1 ETH,用户可以随时在 WETH 和 ETH 之间转换。
  • 合约地址: WETH 有自己的智能合约地址,用户通过该地址进行 WETH 与 ETH 的转换。

代码示例

以下是一个简单的将 ETH 转换为 WETH 的合约示例:

// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IWETH { function deposit() external payable; function withdraw(uint256 wad) external; } contract ETHToWETH { IWETH public weth; constructor(address _weth) { weth = IWETH(_weth); } function convertEthToWeth() external payable { require(msg.value > 0, "Must send ETH to convert to WETH"); weth.deposit{value: msg.value}(); } function convertWethToEth(uint256 amount) external { require(amount > 0, "Must specify WETH amount to convert to ETH"); weth.withdraw(amount); payable(msg.sender).transfer(amount); } receive() external payable { revert("Send ETH directly to this contract is not allowed"); } } 

ERC-20: Token Standard

image-20240707140033040.png

标准接口允许以太坊上的任何代币被其他应用程序重复使用:从钱包到去中心化交易所。

必备技能:不适用任何库的情况下,纯手撸ERC20

不要死记硬背

第一性原理

从区块链的角度出发实现一个数字货币一个链上的数字货币

思考:在技术层面需要什么接口

任何一个货币系统都有一个余额表,知道用户名是谁、余额是多少,在ERC20里面叫 balanceOf

它接收一个地址作为参数,返回这个地址的余额

知道总量是多少,在ERC20里面叫 total supply

用户之间需要转账,在ERC20里面叫 transfer

还有approveallowance 可以用于:

两个普通用户之间的一个约定,也可以用于一个普通用户和一个合约用户之间的一个约定。

例如 A 和 B ,其中A有1万元,但是它不想经常使用,因为没有很好的管理习惯,使用的越多,风险越大。所以A 新建了一个 B 账户,B 账户最多可以使用 A 账户中1万元的100块钱。

这就是 approveallowance 、transferFrom 所服务的一个场景

6 + 3 + 2

6 个必备的方法

3个可选的方法

2个必备的事件

思考:获取 USDT 合约的所有地址和地址的持币数量

通过事件获取合约的所有持币地址

https://etherscan.io/token/0xdac17f958d2ee523a97c13d831ec7#balances

image-20240707141841054.png

ERC20 还有很多插件:mint 、burn …

openzeppelin-contracts/contracts/token/ERC20 at master · OpenZeppelin/openzeppelin-contracts · GitHub

image-20240707142322006.png

USDT的合约的坑

以太坊 USDT 没有完全遵循 ERC20 标准,它transfer没有返回值

ERC20标准

image-20240707144547522.png

USDT 的实现

image-20240707144850385.png

USDT合约代码

image-20240707144455181.png

参考:

  • 大坑!以太坊 USDT 没有完全遵循 ERC20 标准 | 登链社区 | 区块链技术社区
  • Unable to use usdt token inside contract – Ethereum Stack Exchange
解决:

1 安装USDT 修改你的 interface

2 使用 SafeERC20

openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol at master · OpenZeppelin/openzeppelin-contracts · GitHub

实现一个简单的ERC20

// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract BaseERC20 { string public name; string public symbol; uint8 public decimals; uint256 public totalSupply; mapping(address => uint256) balances; mapping(address => mapping(address => uint256)) allowances; event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); constructor() { // 设置代币的名称、符号、小数位数和总供应量 name = "BaseERC20"; symbol = "BERC20"; decimals = 18; totalSupply =  * (10 uint256(decimals)); // 初始供应量分配给合约部署者 balances[msg.sender] = totalSupply; } function balanceOf(address _owner) public view returns (uint256 balance) { return balances[_owner]; } function transfer(address _to, uint256 _value) public returns (bool success) { require(balances[msg.sender] >= _value && _value > 0, "ERC20: transfer amount exceeds balance"); require(_to != address(0), "ERC20: transfer to the zero address"); unchecked { balances[msg.sender] -= _value; } unchecked { balances[_to] += _value; } emit Transfer(msg.sender, _to, _value); return true; } function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) { require(balances[_from] >= _value && _value > 0, "ERC20: transfer amount exceeds balance"); require(_to != address(0), "ERC20: transfer to the zero address"); require(allowances[_from][msg.sender] >= _value, "ERC20: transfer amount exceeds allowance"); unchecked { balances[_from] -= _value; } unchecked { balances[_to] += _value; } unchecked { allowances[_from][msg.sender] -= _value; } emit Transfer(_from, _to, _value); return true; } function approve(address _spender, uint256 _value) public returns (bool success) { require(_spender != address(0), "ERC20: approve to the zero address"); allowances[msg.sender][_spender] = _value; emit Approval(msg.sender, _spender, _value); return true; } function allowance(address _owner, address _spender) public view returns (uint256 remaining) { return allowances[_owner][_spender]; } } 
注意:实际一般不自己实现,使用[OpenZeppelin]OpenZeppelin | Solidity Contracts
来实现。

OpenZeppelin 是一个开源的区块链开发工具和智能合约库,旨在帮助开发者安全地构建和部署智能合约。它提供了一系列经过审核和验证的智能合约实现,包括代币标准、访问控制、支付通道等,极大地简化了以太坊和其他区块链平台上的开发工作。

OpenZeppelin 的主要功能和特点
  1. 安全性: OpenZeppelin 合约经过广泛的审计和验证,确保代码的安全性和可靠性。
  2. 模块化: 提供可重用的模块化合约,使得开发者可以轻松组合和扩展功能。
  3. 标准化: 实现了广泛接受的标准,如 ERC20、ERC721 和 ERC1155 等。
  4. 文档和支持: 提供详尽的文档和活跃的社区支持,帮助开发者快速上手。
使用 OpenZeppelin 的好处
  • 节省时间: 提供了常用合约的实现,减少了从零开始编写合约的时间。
  • 提高安全性: 经过审核的合约减少了安全漏洞的风险。
  • 社区支持: OpenZeppelin 拥有一个庞大且活跃的开发者社区,可以提供支持和帮助。

OpenZeppelin 是区块链开发中不可或缺的工具,提供了安全、可靠和高效的智能合约实现。通过使用 OpenZeppelin,开发者可以更专注于业务逻辑的实现,而不必担心底层合约的安全和稳定性。

参考

  • https://etherscan.io/tokens
  • openzeppelin-contracts/contracts/token/ERC20 at master · OpenZeppelin/openzeppelin-contracts · GitHub
  • OpenZeppelin | Solidity Contracts
  • https://ethernaut.openzeppelin.com/
  • https://cryptozombies.io/en/course/
  • ERC-20: Token Standard
  • Solidity by Example
  • ERC20 代币标准 | Decert.me

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/115564.html

(0)
上一篇 2025-12-02 18:00
下一篇 2025-12-02 18:15

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信