主页 > imtoken钱包苹果版下载 > 如何在以太坊上发行自己的代币

如何在以太坊上发行自己的代币

imtoken钱包苹果版下载 2023-01-16 22:11:31

简单代币开发

代币:

代币,如果单纯从名字上理解,是一种可以替代一般货币,充当交换媒介的东西。 可以是商城积分,也可以是游戏币,也可以是筹码。但在区块链中,不完全是这样。 区块链中的代币或通证通常是指加密数字权益的流通,如比特币、以太坊等数字货币。 代币

从上面的定义,我们可以知道token的三个要素:

综上所述,简而言之,代币的概念大致是基于基于区块链的加密货币或其他类似的东西。 通常大多数人或团队在开发区块链项目时都会考虑发行自己的代币。 一开始,如果我们要发行自己的加密货币,就得从比特币的源代码进行改造。 但是现在通过以太坊平台,我们可以很方便的开发和发行自己的代币,所以本文将介绍如何基于以太坊开发自己的代币。

本文将使用到两个工具,分别是 Remix 和 MetaMask。 如果你对这两个工具不是很了解,可以参考我另外两篇文章:

首先,我们使用solidity开发一个最基本功能的“token”demo,以了解token最基本的外观。 代码如下:

pragma solidity ^0.4.20;
contract SimpleToken {
    // 保存每个地址所拥有的代币数量
    mapping (address => uint256) public balanceOf; 
    // 参数为代币的初始供应量或者说发行数量
    constructor (uint256 initSupply) public {
        // 创建者拥有所有的代币
        balanceOf[msg.sender] = initSupply;
    }
    /**
     * 转移代币
     * 
     * @param _to     接收方的账户地址
     * @param _value  转移的代币数量
     */
    function transfer (address _to, uint256 _value) public {
        // 发送方的账户余额需大于等于转移的代币数量
        require(balanceOf[msg.sender] >= _value);
        // 检查有没有发生溢出,因为数量有可能超过uint256可存储的范围
        require(balanceOf[_to] + _value >= balanceOf[_to]);
        // 减少发送方账户的代币数量
        balanceOf[msg.sender] -= _value;
        // 增加接收方账户的代币数量
        balanceOf[_to] += _value;
    }
}

1. 代码写好后,在remix上部署合约,首先初始化token supply:

如何在以太坊上发行自己的代币

以太坊总共发行多少枚_以太坊现在有多少枚_以太坊总共有多少枚

2.查看指定账户拥有的代币数量:

如何在以太坊上发行自己的代币

3.转币到另一个账户地址:

如何在以太坊上发行自己的代币

4、此时账户地址中的代币数量只有100个:

如何在以太坊上发行自己的代币

ERC-20标准简介

在上一节中,我们实现了一个简单的通证,但由于其简单性以太坊总共发行多少枚,通证极其不完整,例如没有通证名称、通证符号,也没有办法控制通证交易。

因此,以太坊定义了 ERC20。 ERC20是以太坊定义的统一代币标准。 该标准描述了我们在实现代币时必须遵守的协议,如指定代币名称、总量、实现代币交易功能等。 ,只有实现该协议的代币才能被以太坊钱包支持。

下图是实现ERC20协议的代币:

如何在以太坊上发行自己的代币

事实上,ERC20协议定义了一套标准接口,使得在以太坊上开发的任何代币都可以被其他应用复用,比如钱包到去中心化交易所等,如下:

contract ERC20Interface {
    // 代币名称
    string public constant name = "Token Name";
    // 代币符号或者说简写
    string public constant symbol = "SYM";
    // 代币小数点位数,代币的最小单位, 18表示我们可以拥有 0.0000000000000000001单位个代币
    uint8 public constant decimals = 18;  // 18 is the most common number of decimal places
    // 查询代币的发行总量
    function totalSupply() public constant returns (uint);
    // 查询地址的代币余额
    function balanceOf(address tokenOwner) public constant returns (uint balance);
    // 查询spender允许从tokenOwner上花费的代币数量
    function allowance(address tokenOwner, address spender) public constant returns (uint remaining);
    // 实现代币交易,用于从本账户给某个地址转移代币
    function transfer(address to, uint tokens) public returns (bool success);
    // 允许spender多次从你的账户取款,并且最多可取tokens个,主要用于某些场景下授权委托其他用户从你的账户上花费代币
    function approve(address spender, uint tokens) public returns (bool success);
    // 实现代币用户之间的交易,从一个地址转移代币到另一个地址
    function transferFrom(address from, address to, uint tokens) public returns (bool success);
    // 代币交易时触发的事件,即调用transfer方法时触发
    event Transfer(address indexed from, address indexed to, uint tokens);
    // 允许其他用户从你的账户上花费代币时触发的事件,即调用approve方法时触发
    event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}

ERC-20标准代币的实施

代码如下:

以太坊现在有多少枚_以太坊总共发行多少枚_以太坊总共有多少枚

pragma solidity ^0.4.20;
// 定义ERC-20标准接口
contract ERC20Interface {
    // 代币名称
    string public name;
    // 代币符号或者说简写
    string public symbol;
    // 代币小数点位数,代币的最小单位
    uint8 public decimals;
    // 代币的发行总量
    uint public totalSupply;
    // 实现代币交易,用于给某个地址转移代币
    function transfer(address to, uint tokens) public returns (bool success);
    // 实现代币用户之间的交易,从一个地址转移代币到另一个地址
    function transferFrom(address from, address to, uint tokens) public returns (bool success);
    // 允许spender多次从你的账户取款,并且最多可取tokens个,主要用于某些场景下授权委托其他用户从你的账户上花费代币
    function approve(address spender, uint tokens) public returns (bool success);
    // 查询spender允许从tokenOwner上花费的代币数量
    function allowance(address tokenOwner, address spender) public view returns (uint remaining);
    // 代币交易时触发的事件,即调用transfer方法时触发
    event Transfer(address indexed from, address indexed to, uint tokens);
    // 允许其他用户从你的账户上花费代币时触发的事件,即调用approve方法时触发
    event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}
// 实现ERC-20标准接口
contract ERC20Impl is ERC20Interface {
    // 存储每个地址的余额(因为是public的所以会自动生成balanceOf方法)
    mapping (address => uint256) public balanceOf;
    // 存储每个地址可操作的地址及其可操作的金额
    mapping (address => mapping (address => uint256)) internal allowed;
    // 初始化属性
    constructor() public {
        name = "Test Token";
        symbol = "TEST"; 
        decimals = 18;

以太坊现在有多少枚_以太坊总共有多少枚_以太坊总共发行多少枚

totalSupply = 100000000; // 初始化该代币的账户会拥有所有的代币 balanceOf[msg.sender] = totalSupply; } function transfer(address to, uint tokens) public returns (bool success) { // 检验接收者地址是否合法 require(to != address(0)); // 检验发送者账户余额是否足够 require(balanceOf[msg.sender] >= tokens); // 检验是否会发生溢出 require(balanceOf[to] + tokens >= balanceOf[to]); // 扣除发送者账户余额 balanceOf[msg.sender] -= tokens; // 增加接收者账户余额 balanceOf[to] += tokens; // 触发相应的事件 emit Transfer(msg.sender, to, tokens); success = true; } function transferFrom(address from, address to, uint tokens) public returns (bool success) { // 检验地址是否合法 require(to != address(0) && from != address(0)); // 检验发送者账户余额是否足够 require(balanceOf[from] >= tokens); // 检验操作的金额是否是被允许的 require(allowed[from][msg.sender] <= tokens); // 检验是否会发生溢出 require(balanceOf[to] + tokens >= balanceOf[to]); // 扣除发送者账户余额 balanceOf[from] -= tokens; // 增加接收者账户余额 balanceOf[to] += tokens; // 触发相应的事件

以太坊总共有多少枚_以太坊总共发行多少枚_以太坊现在有多少枚

emit Transfer(from, to, tokens); success = true; } function approve(address spender, uint tokens) public returns (bool success) { allowed[msg.sender][spender] = tokens; // 触发相应的事件 emit Approval(msg.sender, spender, tokens); success = true; } function allowance(address tokenOwner, address spender) public view returns (uint remaining) { return allowed[tokenOwner][spender]; } }

将上述代码复制到Remix并编译合约代码:

如何在以太坊上发行自己的代币

部署合同:

如何在以太坊上发行自己的代币

部署成功:

如何在以太坊上发行自己的代币

测试 balanceOf 方法:

如何在以太坊上发行自己的代币

测试传输方法:

如何在以太坊上发行自己的代币

在 Remix 上测试基本方法后,我们通过 MetaMask 在以太坊的测试网上发行了我们的代币。 打开MetaMask,选择Ropsten测试网络,如下:

如何在以太坊上发行自己的代币

注意:如果您没有余额,请点击DEPOSIT按钮,然后点击GET ETHER按钮,您将进入一个网站,点击网站中的request 1 ether from faucet,您可以发送一些测试网络的以太币给您:

如何在以太坊上发行自己的代币

然后转到 Remix IDE 刷新它。 这时,Remix 会自动选择对应的测试网络。 注意MetaMask和Remix需要在同一个浏览器上,Environment和Account要和MetaMask保持一致,如下:

如何在以太坊上发行自己的代币

点击Deploy后,MetaMask会弹出交易确认框,点击CONFIRM:

如何在以太坊上发行自己的代币

合约部署交易确认后,复制合约地址:

如何在以太坊上发行自己的代币

打开Metamask界面,打开菜单(Menu),点击ADD TOKEN:

如何在以太坊上发行自己的代币

出现如下对话框,选择Custom Token,然后将合约地址粘贴进去:

以太坊总共发行多少枚_以太坊现在有多少枚_以太坊总共有多少枚

如何在以太坊上发行自己的代币

单击添加令牌:

如何在以太坊上发行自己的代币

这时我们可以在MetaMask中看到我们创建的token,如下:

如何在以太坊上发行自己的代币

接下来我们来测试代币转账功能,选择我们刚刚部署的代币,点击SEND:

如何在以太坊上发行自己的代币

填写转账相关信息:

如何在以太坊上发行自己的代币

确认转移:

如何在以太坊上发行自己的代币

成功后会生成相应的交易记录:

如何在以太坊上发行自己的代币

这样我们就完成了token的创建和部署(正式网和测试网的部署方法是一样的),现在我们可以在Etherscan中查询刚才发行的token了:

如何在以太坊上发行自己的代币

点击合约地址查看代币详情:

如何在以太坊上发行自己的代币

关于发行总量为0的问题

上一节以太坊总共发行多少枚,我们在以太坊上成功发行了自己的代币,但是很多同学应该已经有疑问了,为什么token里面明明设置了发行数量,但是发行数量还是0呢? 其实这也是新手在开发代币时可能遇到的一个坑。 之所以看到发行总量为0,是因为代币发行总量的整数位表示不是totalSupply的值,而是totalSupply除以10的小数次方。

例如,如果我们将 decimals 设置为 8,那么我们需要将令牌的总供应量(totalSupply)除以 100000000 以获得整数。 上一节合约代码中设置的decimals的值为18,即token使用的小数位数为18位,totalSupply的值为1亿。 自然是按小于1的小数来计算,而且还是比较小的小数。 MetaMask 只显示小数点后 3 位,因此我们认为发行的代币总数为 0。

既然知道是什么原因造成的,那么解决起来就很容易了。 修改合约的constructor token如下:

// 初始化属性
constructor() public {
    decimals = 18;
    totalSupply = 100000000 * 10 ** uint256(decimals);
    name = "Test Token";
    symbol = "TEST"; 
    // 初始化该代币的账户会拥有所有的代币
    balanceOf[msg.sender] = totalSupply;
}

修改完成后,仍然按照上一节描述的流程发行代币,并将代币添加到MetaMask钱包中。 这时候代币发行总量应该就是我们期望的值,如下:

如何在以太坊上发行自己的代币

我们也可以尝试使用代币进行转账:

如何在以太坊上发行自己的代币

转账成功,账户余额也正常扣除:

如何在以太坊上发行自己的代币

另一个账户也正常收到了这100个代币:

如何在以太坊上发行自己的代币

然后让我们检查令牌详细信息:

如何在以太坊上发行自己的代币