以太坊应用层提案之ERC-20

一 什么是Token? Token怎么分类?

1.1 什么是Token?

Token也叫做同质化代币(Fungible Token), 它可以表示区块链网络中任何虚拟的东西,比如虚拟货币、积分、金融资产、游戏技能、权益等等。在以太坊上,Token是通过智能合约创建和管理的。

1.2 Token怎么分类?

1.2.1 货币型代币

表示数字货币,比如BCH、DAI、USDT、LTC、TRX等

1.2.2 权益型代币

表示对某个项目或公司的股权或债权,比如:

BCAP: Blockchain Capital 是一家专注于区块链技术的风险投资公司。BCAP 代币代表对 Blockchain Capital 投资基金的部分所有权,持有者有权分享基金的收益。

SPICE:SpiceVC 是一个风险投资基金,专注于区块链和加密货币相关项目。SPICE 代币代表对基金资产和收益的部分所有权,持有者有权分享基金的利润。

SCI:Science Blockchain 是一个风险投资基金,投资于区块链技术和加密货币初创企业。SCI 代币持有者可以分享基金的收益,并对投资决策进行投票。

1.2.3 实用型代币

通常用于提供对某个特定服务或产品的访问权限,比如用于支付交易费用或访问一个平台。比如:

GNT (Obyte):Obyte是一个去中心化的支付网络,GNT代币用于支付网络中的交易费用。

BAT (Basic Attention Token):BAT是用于浏览器Brave的隐私保护广告平台的代币,用户可以通过观看广告获得BAT,然后使用它来支持他们喜欢的网站或内容创作者。

MATIC (Polygon):MATIC是Polygon网络的代币,用于支付交易费用和参与网络的治理,Polygon是一个以太坊的扩展解决方案。

1.2.4 治理型代币

允许持有者参与网络或平台的治理决策,比如投票权。比如:

LINK (Chainlink):Chainlink是一个去中心化的预言机网络,LINK代币持有者可以参与网络的治理,决定网络的发展方向。

AAVE (Aave):Aave是一个去中心化借贷平台,其治理代币AAVE允许持有者参与平台的治理决策。

UNI (Uniswap):Uniswap是一个流行的去中心化交易所(DEX),UNI代币持有者可以参与社区治理,对协议的更新和发展方向进行投票。

注意:

有些代币的分类可能同时属于几类,比如UNI属于治理型代币,代币持有者可以参与 Uniswap 协议的治理,投票决定协议的升级和调整。

但是他也可以作为实用型代币,比如流动性挖矿奖励,通过提供流动性,用户可以获得 UNI 代币作为奖励

同时UNI 代币可以在各种加密货币交易所进行交易,作为一种数字资产进行价值交换,因此也可以作为货币型货币

二 什么是ERC-20? 为什么需要ERC-20?

2.1 什么是ERC-20?

ERC-20是以太坊区块链上的一种同质化代币的标准或者协议,它定义了一组统一的接口和规则,使得代币在以太坊上可以互操作。ERC-20可以被用于创建和发行智能合约代币

2.2 为什么需要ERC-20?

2.2.1 互操作性问题

如果没有ERC-20标准,那么可能不同的代币需要使用不同的钱包,这样用户需要使用不同的代币下载和使用不同的钱包

另外,比如交易所,如果没有ERC-20标准,兼容比较差,可能需要为不同个的代币做不通的兼容逻辑

2.2.2 用户体验差

用户需要了解如何使用每个不同的代币和相关应用程序,因为每一个代币有不同的使用规则和接口,所以用户需要花费大量时间来学习如何使用这些代币。这会导致用户体验差,增加了使用的门槛。

2.2.3 缺乏标准

不同的代币可能在功能实现上有很大差异,导致代币在不同平台上的行为不一致。

应用程序和服务需要为每个代币实现不同的接口和交互方式,增加了开发和维护成本。

2.2.4 审计麻烦

每个代币的智能合约都需要单独审计,耗时耗力,还增加了安全风险。

2.2.5 提高安全性

由于ERC-20标准经过广泛的审查和测试,使用这一标准可以提高代币合约的安全性。开发者可以利用社区已经发现和修复的漏洞,从而减少智能合约中的潜在安全风险。

总结:

没有ERC-20标准会导致在以太坊上创建和使用代币变得复杂和不一致。标准化的重要性在于它简化了代币的开发、使用和集成提高了安全性和互操作性改善了用户体验,促进了生态系统的健康发展。

三 ERC-20规范

ERC-20标准定义了一组通用的规则,使不同的代币在以太坊网络上能够互操作,并且能够轻松地被各种应用(如钱包和交易所)集成和使用,这些规则包括必须实现的函数和事件。

3.1 函数

3.1.1 name

function name() external view returns (string memory);

返回代币的名字

3.1.2 symbol

function symbol() external view returns (string memory);

返回代币符号

3.1.3 decimals

function decimals() external view returns (uint8);

返回代币使用的小数位数或者说精度

3.1.4 balanceOf

function balanceOf(address _owner) external view returns (uint256 balance);

返回指定合约地址的代币余额

3.1.5 totalSupply

function totalSupply() external view returns (uint256);

返回已经供应的代币总量,mint的时候会增加totalSupply, burn的时候会减少totalSupply

3.1.6 transfer

function transfer(address _to, uint256 _value) external returns (bool success);

给指定的地址转指定数量的代币,可以是合约调用,也可以是外部调用,需要发送Transfer事件

3.1.7 transferFrom

function transferFrom(address _from, address _to, uint256 _value) external returns (bool success);

将_from地址中代币转_value数量给_to地址,需要发送Transfer事件

3.1.8 approve

function approve(address _spender, uint256 _value) external returns (bool success);

给_spender授权_value额度或者数量,需要发送Approval事件

3.1.9 allowance

function allowance(address _owner, address _spender) external view returns (uint256 remaining);

返回 _spender 仍被允许从 _owner 提取的代币数量。

3.2 事件

3.2.1 Transfer

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

当发生转账的时候,必须触发Transfer事件,哪怕转账的金额是0

3.2.2 Approval

event Approval(address indexed _owner, address indexed _spender, uint256 _value);

当批准授权成功的时候,必须触发Approval事件

四 手动实现ERC-20

contract BaseERC20 {

    // 代币名称

    string public name;

    // 代币符号

    string public symbol;

    // 返回token使用的小数点后几位

    uint8 public decimals;

    // 代币发行总量

    uint256 public totalSupply;

    // 保存着每个地址对应的余额

    mapping(address => uint256) balances;

    // 保存着某个地址A允许另一个地址B可操作的金额

    mapping (address => mapping (address => uint256)) allowances;



    // 定义Transfer转账事件

    event Transfer(address indexed from, address indexed to, uint256 amount);

    // 定义Approva批准事件

    event Approval(address indexed owner, address indexed spender, uint256 amount);



    error BaseERC20NotEnoughAllowance();



    constructor() public {

        name = "BaseERC20";

        symbol = "BERC20";

        // token小数位最多18位

        decimals = 18;

        // 供应总量 = 供应量 * 1 eth = 100000000 * 10^18

        totalSupply = 100000000 * 10 ** uint256(decimals);

        // 合约部署的时候,设置这个地址对应的代币供应量

        balances[msg.sender] = totalSupply;

    }



    // 获取指定owner地址对应的代币余额

    function balanceOf(address account) public view virtual returns (uint256) {

        return balances[account];

    }



    // 查询某个owner授权委托人允许的转账数量

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

        return allowances[_owner][_spender];

    }



    // 向指定地址转账

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

        // 校验地址是不是0, address如果没有传递地址就是默认就是0

        require(_to != address(0), "BaseERC20: invalid sender");

       

        // 检验发送者账户token数量是否足够

        require(balances[msg.sender] > _value, "ERC20: transfer amount exceeds balance");

       

        // 扣除发送者账户token余额

        balances[msg.sender] -= _value;

        // 增加接收者账户token余额

        balances[_to] += _value;



        // 向区块链发送一个转账事件

        emit Transfer(msg.sender, _to, _value);



        return true;  

    }



    // 委托人将from用户转移一定数量token到to账户

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

        // 校验地址是不是0, address如果没有传递地址就是默认就是0

        require((_from != address(0) && _to != address(0)), "BaseERC20: invalid sender or recepient address");

       

        // 检验发送者账户token数量是否足够

        require(balances[_from] >= _value, "ERC20: transfer amount exceeds balance");



        // 校验token委托方针对from用户剩余被批准的token数量

        uint256 allowance = allowance(_from, msg.sender);

        require(allowance >= _value, "ERC20: transfer amount exceeds allowance");

        // 转移之后from的token数量扣减

        balances[_from] -= _value;

        // 扣减spender剩余的可转账token数量

        allowances[_from][msg.sender] -= _value;

        // 转移之后token数量的余额增加

        balances[_to] += _value;

        // 向区块链发送一个转账事件

        emit Transfer(_from, _to, _value);

        return true;

    }



    // 是授权的approve的调用方,即为批准方,也就是消息发送者,更新spender剩余可转账余额

    function approve(address spender, uint256 value) public returns (bool success) {

        allowances[msg.sender][spender] = value;

        // 向区块链发送一个批准事件

        emit Approval(msg.sender, spender, value);

        return true;

    }

}

  • 23
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

莫言静好、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值