# 4.5 ERC-20通证标准及其爆发性应用

## ERC-20通证标准

ERC-20（又常被写作ERC20）通证标准是在以太坊平台上通过智能合约制订的通证标准。

我们常常把以ERC-20通证标准发行出来的通证，叫做“代币”。但请注意，Bitcoin是代币，ETH也是代币，但在以太坊生态里首创的ERC-20是一个通证标准而非代币标准。区块链以通证（Token）取代代币（Coin）是一次伟大的飞跃！

ERC20让开发者能够基于智能合约执行以下操作：

1. 制定通证总供应量
2. 获得账户余额
3. 转帐通证
4. 批准转账通证

以下内容翻译自：<https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md>

1. **概述**

   ERC20是通证（token）的一种标准接口。
2. **摘要**

   本标准允许在智能合约中部署token的标准API。 该标准提供了转移token的基本功能，并允许token被批准，以便链上其它第三方可以使用它们。
3. **动机**

   这一标准接口可以让以太网上的任何token可以被其他应用程序再利用：从钱包到去中心化的交易所。
4. **技术参数**

   **1）Token**

   1.1. 方法

   **注意：**

   a. 请到原始提案中查询本标准所使用的语法的Solidity的最低版本号。

   b. 调用者必须处理returns（bool success）返回的false。调用者绝对不能假设永远不会返回false。

   **name**：返回令牌的名字，例如“MyToken”。\
   可选——这个方法可以用来提高可用性，但接口和其它合约不能依赖该值的存在。

   function name() public view returns (string)

   **symbol**：返回令牌的符号，例如“HIX”。\
   可选——这个方法可以用来提高可用性，但接口和其它合约不能依赖该值的存在。

   function symbol() public view returns (string)

   **decimals**：返回token使用的小数位数，比如 8，表示将记录在链上的token数除以100000000后显示给用户。\
   可选——这个方法可以用来提高可用性，但接口和其它合约不能依赖该值的存在。

   function decimals() public view returns (uint8)

   **totalSupply**：返回token的总供应量。

   function totalSupply() public view returns (uint256)

   **balanceOf**：返回另一个账户地址\_owner的账户余额。

   function balanceOf(address \_owner) public view returns (uint256 balance)

   **transfer**：转移\_value数量的token到地址\_to，并且必须触发Transfer事件。 如果\_from帐户余额没有足够的token来支出，该方法应该throw。\
   **注意**：\_value=0必须被视为正常转账并触发Transfer事件。

   function transfer(address \_to, uint256 \_value) public returns (bool success)

   **transferFrom**：从地址\_from发送\_value个token到地址\_to，必须触发Transfer事件。\
   transferFrom方法用于提现流程，允许合约为你转移token。这可以用于允许合约为你转让代币或收取费用。除非帐户\_from有意通过某种机制授权消息的发送者，否则该方法应该throw。

   **注意**：\_value=0必须被视为正常转账并触发Transfer事件。

   function transferFrom(address \_from, address \_to, uint256 \_value) public returns (bool success)

   **approve**：允许\_spender多次从你的帐户提现，最高数量是\_value。 如果再次调用此函数，它将以\_value覆盖当前的值。

   注意：为了防止向量攻击，客户端需要确认以这样的方式创建用户接口，即在为同一个花费者设置另一个值之前，先将它的值设置为0。虽然合约本身不应该强制执行，以前部署的合同允许向后兼容。

   function approve(address \_spender, uint256 \_value) public returns (bool success)

   **allowance**：返回被允许从\_owner提取到\_spender余额。

   function allowance(address \_owner, address \_spender) public view returns (uint256 remaining)

   **2）event**

   **Transfer**：当token被转移(即使是0值)时必须被触发。

   event Transfer(address indexed \_from, address indexed \_to, uint256 \_value)

   **Approval**：当成功调用approve(address \_spender, uint256 \_value)后必须被触发。

   event Approval(address indexed \_owner, address indexed \_spender, uint256 \_value)
5. **实施**

   在以太坊网络上已经部署了大量符合ERC20标准的代币（查询：<https://etherscan.io/tokens>）。从节省gas到提高安全性，不同权衡的团队已经编写了各种不同的合约方案。

   合约实例：

   [OpenZeppelin implementation](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/9b3710465583284b8c4c5d2245749246bb2e0094/contracts/token/ERC20/ERC20.sol)

   （[对照一个新版本](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol)）

   [ConsenSys implementation](https://github.com/ConsenSys/Tokens/blob/fdf687c69d998266a95f15216b1955a4965a0a6d/contracts/eip20/EIP20.sol)
6. **历史**

   本标准的相关历史链接：

   * [Vitalik Buterin的最初提议](https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs/499c882f3ec123537fc2fccd57eaa29e6032fe4a)
   * [Reddit讨论](https://www.reddit.com/r/ethereum/comments/3n8fkn/lets_talk_about_the_coin_standard/)
   * [原Issue #20](https://github.com/ethereum/EIPs/issues/20)
7. **版权**

   版权和相关权利通过[CC0](https://link.jianshu.com/?t=https%3A%2F%2Fcreativecommons.org%2Fpublicdomain%2Fzero%2F1.0%2F)许可协议放弃。

## OpenZeppelin的 ERC-20 智能合约扩展

OpenZeppelin 是构建在 EVM 之上的开源智能合约开发工具，让开发者可以安全地开发和管理智能合约和 Dapp。[OpenZeppelin ERC-20库](https://www.openzeppelin.com/contracts)提供了一系列的扩展，提高了其功能性和安全性。ERC-20通证创建者可以根据项目需求灵活地选用和组合这些扩展，从而实现具有丰富功能和更高安全性的 ERC-20 通证。这些扩展包括：

1. Mintable：允许特定账户（外部账户或合约账户）创建新的通证。
2. Burnable：允许通证持有者销毁一定数量的通证，从而减少总供应量。
3. Pausable：允许合约拥有者在紧急情况下暂停合约的所有交易和功能。
4. Permit：允许用户通过签名授权他人代表自己进行通证转移，而无需在链上执行 approve()。
5. Votes：为通证持有者提供投票功能，可用于事务决策。
6. Flash Minting：闪电造：允许用户临时铸造大量通证，用于闪电贷等金融应用。
7. Snapshots：快照：捕捉特定时间点的通证持有情况，用于分红、投票等应用。
8. Access control：通过角色和权限管理来限制特定功能的访问。
9. Ownable：将合约的所有权赋予某个地址，该地址可以管理合约的某些功能。
10. Roles：为合约中的功能分配不同的角色，每个角色可以拥有特定的权限。

OpenZeppelin的ERC-20扩展库大大丰富了ERC-20的功用，但他们没有直接抛弃ERC-20，构建成新的通证标准，有两个原因：&#x20;

其一是如果创建新的通证标准，与ERC-20割裂，就会给整个行业带来应用上的负担甚至打击。采用扩展库的优势是它只会推动整个行业的发展。

其二是扩展本身是可升级的。EIP因为升级后果复杂，则无升级机制。这样应用起来更灵活。

## ICO爆发：ERC-20通证标准的应用

ICO是Initial Coin Offering的简称，顾名思义，就是项目方以初始产生或者首批公开发行的通证（代币）作为回报的一种众筹资金的方式。

ICO在很大程度上借鉴了证券业的Initial Public Offering（首次公开发行，IPO）。之所以没有沿用IPO而改为ICO，主因是传统的IPO（首次公开募股，initial public offerings）的门槛非常高而且涉及到跨国就更是难上加难。区块链业界删繁就简，采用了新的概念及新的模式，在突破障碍的同时规避了法律风险。

用最简单的话说：ICO就是项目方发行一种自己的通证，投资者用ETH或其它通证来兑换该通证。

有个别通证+收益分红模式（不同于股权模式）的区块链项目的众筹，采用过ITO（Initial Token Offering）这一名称，但因为我们知道只有符合ERC-20的通证才用于众筹，大众又更熟悉Coin，所以现在约定俗成，都采用ICO（Initial Coin Offering）。

典型的ICO流程与特点为：

1. 核心团队通过专业会议等各种渠道发布ICO消息。
2. 核心团队发布ICO规则，包括ICO的时间安排和融资额的安排。譬如最低融资额，如果达不到该额度，该ICO即告失败，所有投资都会被退回。有的项目同时会设定最高投资额（硬顶），达到该投资额，则ICO提前结束。
3. ICO开启后，现在越来越多的项目只接受ETH，因为通过以太坊的智能合约，可以让ICO过程实现零人工、零差错。个别项目还像以前那样接受以太币、比特币等多种数字加密货币。
4. ICO结束后，代币就会开始上交易所。

2015年11月创建、2017年9月11日定稿的ERC20通证标准，2017年4月提前爆发于ICO。这里面有多重原因：

* 真正抗审查
* 真正实现了全球范围的投融资
* 极低的投融资成本
* 极高的投融资效率（超快的转账速度、超快的融资速度）
* 第一次实现了平等的投资权利
* 真实的市场估值
* 最高的流动性溢价
* 零差错、零人工

以下为各种投融资手段的对比：

|       | ICO  | IPO | 众筹 | VC风投 |
| ----- | ---- | --- | -- | ---- |
| 投融资门槛 | 非常低  | 极高  | 低  | 高    |
| 透明程度  | 高    | 高   | 高  | 低    |
| 资金退出  | 非常容易 | 容易  | 难  | 难    |
| 流动性   | 非常好  | 好   | 差  | 差    |
| 监 管   | 目前很低 | 极高  | 低  | 低    |

前面我们提过，以太坊早在2014年就通过ICO筹集了发展基金，为什么是2017年ICO才大爆发？

这里面有区块链知识传递和区块链项目发展的原因，还有一个很重要的原因就在于ETH和ERC20通证标准。2017年前ICO的主要币种为比特币，但比特币到账时间长达1小时，ETH一次确认只需要9秒，到帐通常不足2分钟。而且比特币网络堵塞，有很多转账无法完成；加上比特币2017年没有智能合约可用，通常还需要用户到官网注册，ERC20通证标准的出现，才实现了ICO的质变！

ICO的爆发，归功于ERC20通证标准，也是智能合约的第一个爆点！

## ERC-20通证标准带来的问题

1. 人人能自由发币听上去实现了哈耶克在《货币的非国家化》里提出的理想。但人人能自由发币与各国政府印钞有什么本质的区别吗？
2. 人人能自由发币加上中本聪带来的匿名性，造成了区块链欺诈（scam）成行！经过五六年的肆虐，这个行业已经完全无诚信可言！


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://u.naturaldao.io/be/chapter4/4.5-erc20-tong-zheng-biao-zhun-ji-qi-bao-fa-xing-ying-yong.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
