主页 > imtoken官方版 > 关于以太坊 ERC-20 代币智能合约协议

关于以太坊 ERC-20 代币智能合约协议

imtoken官方版 2023-03-12 05:41:00

文章目录

ERC-20协议是什么意思?

ERC 代表“Etuereum Request for Comment”。 为了创建以太坊平台的标准,以太坊社区提交了一份以太坊改进提案(EIP),其中包括协议规范和合约标准。 最终确定的 EIP 为以太坊开发者提供了一套可实施的标准。 这允许按照这些通用接口标准构建智能合约。 可以在此处检索所有 EIP 提案。

ERC-20 是以太坊上最重要的智能合约标准之一。 它已经成为用于发行基于以太坊公链的可替换代币的智能合约的技术标准。 ERC-20 定义了所有可替代以太坊代币应遵守的一般规则列表。 这简化了开发人员的任务erc20可以转以太坊地址吗,他们知道他们不需要在每次发布新令牌时重新实施每个新项目,只要令牌遵循标准中的规则即可。

知识点:什么是fungible Ethereum token,有没有non-fungible Ethereum token?

可更换的以太坊代币是指代币完全相同,可以更换,通常遵循ERC-20标准。 例如,钱包A中的一个ERC-20代币和钱包B中一个合约地址相同的ERC-20代币在区块链上是完全一样的,可以互相替换。

不可替代的以太坊代币也称为不可替代代币(Non-Fungible Token),简称NFT。 即使AB的两个钱包中有两个合约地址相同的token,它们的属性值也不一致。 它们是不同的。 因此,它们在区块链上似乎无法相互替代。 此类代币通常遵循 ERC-721 标准。

下面是一段ERC-20接口代码,定义了符合ERC-20标准代币必须实现的功能:

pragma solidity ^0.8.0;
interface IERC20 {
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function allowance(address owner, address spender)
        external
        view
        returns (uint256);
    function transfer(address to, uint256 amount) external returns (bool);
    function approve(address spender, uint256 amount) external returns (bool);
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);
}

这些功能的用途解释如下

价值函数总供给

该函数返回现有代币数量,显示代币当前总流通量erc20可以转以太坊地址吗,所有函数均可调用。 这个函数是一个价值函数,不会修改合约的状态。 重要提示:Solidity 中没有浮点数。 因此,大多数代币将保留 18 位小数,并将返回总供应量和其他结果,如下所示:1 个代币 = 100000000000000000。这在处理代币数量时需要格外小心,尽管并非每个代币都有 18 位小数。

function totalSupply() external view returns (uint256);

余额

此函数返回一个地址拥有的令牌(帐户)的数量。 这个函数也是一个价值函数,不会修改合约的状态。

function balanceOf(address account) external view returns (uint256);

津贴

此功能用于检查所有者给予消费者的代币数量。 该函数是一个值函数,不会修改合约的状态,默认返回0。

function allowance(address owner, address spender)
        external
        view
        returns (uint256);

操作功能转移

将一定数量(amount)的代币从函数调用者地址(msg.sender)移动到接收者(to)地址。 此函数发出稍后定义的 Transfer 事件。 如果转账是可能的,它会返回真,并且转账操作会消耗gas。

function transfer(address to, uint256 amount) external returns (bool);

批准

函数调用者(msg.sender)可以调用该函数授权消费者代其使用代币数量,即设置允许消费者从函数调用者(msg)的余额中转出的津贴数量.发件人)。 此函数发出批准事件。 此函数返回是否成功设置边距。

function approve(address spender, uint256 amount) external returns (bool);

从转移

使用保证金机制将令牌数量从从移动到到。 然后从呼叫者的余额中扣除该金额。 此函数发出一个 Transfer 事件。

function transferFrom(
    address from,
    address to,
    uint256 amount
) external returns (bool);

事件转移

当令牌的值从 from 地址发送到 to 地址时,例如调用 transfer 或 transferFrom 函数时,会发出此事件。

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

在铸造新代币的情况下,转账通常从 0x00…0000 地址开始,在销毁代币的情况下,转账到 0x00…0000。

赞同

当所有者批准消费者花费的代币数量(价值)时,会发出此事件。 例如在调用批准功能时。

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

ERC-20代币的基本实现

以下是 ERC-20 代币的最简单代码:

pragma solidity ^0.8.0;
interface IERC20 {
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function allowance(address owner, address spender)
        external
        view
        returns (uint256);
    function transfer(address to, uint256 amount) external returns (bool);
    function approve(address spender, uint256 amount) external returns (bool);
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);
}
contract ERC20Basic is IERC20 {
    string public constant name = "ERC20Basic";
    string public constant symbol = "ERC";
    uint8 public constant decimals = 18;
    mapping(address => uint256) balances;
    mapping(address => mapping(address => uint256)) allowed;
    uint256 totalSupply_ = 10 ether;
    constructor() {
        balances[msg.sender] = totalSupply_;
    }
    function totalSupply() public view override returns (uint256) {
        return totalSupply_;
    }
    function balanceOf(address tokenOwner)
        public
        view
        override
        returns (uint256)
    {
        return balances[tokenOwner];
    }
    function transfer(address receiver, uint256 numTokens)
        public
        override
        returns (bool)
    {
        require(numTokens <= balances[msg.sender]);
        balances[msg.sender] = balances[msg.sender] - numTokens;
        balances[receiver] = balances[receiver] + numTokens;
        emit Transfer(msg.sender, receiver, numTokens);
        return true;
    }
    function approve(address delegate, uint256 numTokens)
        public
        override
        returns (bool)
    {
        allowed[msg.sender][delegate] = numTokens;
        emit Approval(msg.sender, delegate, numTokens);
        return true;
    }
    function allowance(address owner, address delegate)
        public
        view
        override
        returns (uint256)
    {
        return allowed[owner][delegate];
    }
    function transferFrom(
        address owner,
        address buyer,
        uint256 numTokens
    ) public override returns (bool) {
        require(numTokens <= balances[owner]);
        require(numTokens <= allowed[owner][msg.sender]);
        balances[owner] = balances[owner] - numTokens;
        allowed[owner][msg.sender] = allowed[owner][msg.sender] - numTokens;
        balances[buyer] = balances[buyer] + numTokens;
        emit Transfer(owner, buyer, numTokens);
        return true;
    }
}