• 以太坊上发行ERC20代币


    ERC20 代币生成

    环境

    虚拟主机: ubuntu 18虚拟机

    宿主主机: win10; ip:192.168.0.160

    1.部署以太坊

    1.1 安装GO

    安装go,并编译geth

    将下载好的golang包上传到root目录。

    sudo apt-get install -y build-essential golang
    

    1.2 下载源代码编译

    git clone https://github.com/ethereum/go-ethereum
    cd go-ethereum
    make geth
    # 添加快捷访问
    cp build/bin/geth /usr/bin/geth
    

    1.3 部署节点

    1.3.1 创建节点目录

    创建数据存储目录,分别为8001-8002以此类推

    mkdir -p /node/node8001
    mkdir -p /node/node8002
    

    1.3.2 创建账号

    geth  account  new - -datadir  "/node/node8001"  
    

    执行后会要求设置账户的unlock口令,请记住配置的口令. 会生成一个密码保存文件夹(keystore), 内含一个密码保存文件,名字如下

    UTC--2018-12-13T02-58-07.160085261Z--f8c5cad127f7053e143204450c18b6bc1f353c9b

    1.3.3 生成创世文件

    生成文件名为genesis.json的文件, 内容如下:

    {
    "config": {
    	"chainId": 115,
    	"homesteadBlock": 0,
    	"byzantiumBlock": 12,
    	"eip155Block": 0,
    	"eip158Block": 0
    },
    "nonce":"0x0000000000000042",
    "mixhash":"0x0000000000000000000000000000000000000000000000000000000000000000",
    "difficulty":"0x0001",
    "alloc":{"f8c5cad127f7053e143204450c18b6bc1f353c9b":{"balance":"990000000000000000000000000000"}},
    "timestamp":"0x5b3bcd2f",
    "parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
    "extraData":"",
    "gasLimit":"0xffffffff"
    }
    

    1.3.4 根据创世文件信息,创建节点

    /usr/bin/gethfw --datadir /node/node8001 init ./genesis.json
    /usr/bin/gethfw --datadir /node/node8002 init ./genesis.json
    

    1.3.5 启动节点

    单独启一个终端来启动节点

    /usr/bin/geth --targetgaslimit 4294967295 --identity "node8001" --datadir /node/node8001  --port 8801 --rpc --rpcaddr "0.0.0.0" --rpcport 8145 --rpccorsdomain "http://192.168.0.160:8081" --rpcapi "admin,debug,eth,net,personal,shh,txpool,web3"  --networkid 115  --nodiscover --mine
    

    单独启一个终端来启动节点

    /usr/bin/geth --targetgaslimit 4294967295 --identity "node8002" --datadir /node/node8002  --port 8802 --rpc --rpcaddr "0.0.0.0" --rpcport 8546 --rpccorsdomain "http://192.168.0.160:8081" --rpcapi "admin,debug,eth,net,personal,shh,txpool,web3"  --networkid 115 --nodiscover
    

    此时,节点已经启动OK, 我们可以来查看一下节点状态了:

    先前的两个终端就让他们挂在那里执行程序,另外开启一个终端,执行如下命令:

    /usr/bin/gethfw attach ipc:/node/node8001/geth.ipc
    

    然后会自动进入控制台了, 输入admin命令,可以查看当前链的信息,输出类似如下:

    {
    datadir: "/node/node8001",
    nodeInfo: {
    ​ enode: "enode://9e7c5f604f49638524b3d95078bb4644e4e379f6fa532094ccd1bbd9c975e81a1e66fd602530c274240ee0f563f917fc4de0665e3e5abeaf021f3efaa0565eeb@[::]:8801?discport=0",
    ​ ip: "::",
    ​ listenAddr: "[::]:8801",
    ​ name: "Geth/node8001/v1.8.3-stable/linux-amd64/go1.10.4",
    ​ ports: {
    ​ discovery: 0,
    ​ listener: 8801
    ​ },
    ​ protocols: {
    ​ eth: {
    ​ config: {...},
    ​ difficulty: 78940001,
    ​ genesis: "0xa6ebc49109d376f9afc21fb6ab9d4b62da2442c6d81e6ab90633a03e851693d6",
    ​ head: "0xafe6c156e1920039334e4a470aa80c7d8ad9202fdf62a38ed2ec27e076685949",
    ​ network: 115

    ......

    至此, 以太坊私链算是启动完成了。

    2.部署Remix

    参考https://github.com/ethereum/remix-ide 文档, 开始部署。

    2.1 下载Remix-IDE源码

    git clone https://github.com/ethereum/remix-ide.git
    

    2.2 安装Remix-IDE

    cd remix-ide
    

    2.3 启动Remix-IDE

    npm start
    

    此时,就可以在localhost:8080访问RemixIDe了。

    3.部署ERC20代币

    通过在浏览器打开localhost:8080地址, 进入Remix-IDE.

    3.1 在新建智能合约

    加入如下代码

    pragma solidity ^0.4.16;
     
    interface tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData) public; }
     
    contract TokenERC20 {
        string public name;
        string public symbol;
        uint8 public decimals = 18;  // 18 是建议的默认值
        uint256 public totalSupply;
     
        mapping (address => uint256) public balanceOf;  // 
        mapping (address => mapping (address => uint256)) public allowance;
     
        event Transfer(address indexed from, address indexed to, uint256 value);
     
        event Burn(address indexed from, uint256 value);
     
     
        function TokenERC20(uint256 initialSupply, string tokenName, string tokenSymbol) public {
            totalSupply = initialSupply * 10 ** uint256(decimals);
            balanceOf[msg.sender] = totalSupply;
            name = tokenName;
            symbol = tokenSymbol;
        }
     
     
        function _transfer(address _from, address _to, uint _value) internal {
            require(_to != 0x0);
            require(balanceOf[_from] >= _value);
            require(balanceOf[_to] + _value > balanceOf[_to]);
            uint previousBalances = balanceOf[_from] + balanceOf[_to];
            balanceOf[_from] -= _value;
            balanceOf[_to] += _value;
            Transfer(_from, _to, _value);
            assert(balanceOf[_from] + balanceOf[_to] == previousBalances);
        }
     
        function transfer(address _to, uint256 _value) public {
            _transfer(msg.sender, _to, _value);
        }
     
        function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
            require(_value <= allowance[_from][msg.sender]);     // Check allowance
            allowance[_from][msg.sender] -= _value;
            _transfer(_from, _to, _value);
            return true;
        }
     
        function approve(address _spender, uint256 _value) public
            returns (bool success) {
            allowance[msg.sender][_spender] = _value;
            return true;
        }
     
        function approveAndCall(address _spender, uint256 _value, bytes _extraData) public returns (bool success) {
            tokenRecipient spender = tokenRecipient(_spender);
            if (approve(_spender, _value)) {
                spender.receiveApproval(msg.sender, _value, this, _extraData);
                return true;
            }
        }
     
        function burn(uint256 _value) public returns (bool success) {
            require(balanceOf[msg.sender] >= _value);
            balanceOf[msg.sender] -= _value;
            totalSupply -= _value;
            Burn(msg.sender, _value);
            return true;
        }
     
        function burnFrom(address _from, uint256 _value) public returns (bool success) {
            require(balanceOf[_from] >= _value);
            require(_value <= allowance[_from][msg.sender]);
            balanceOf[_from] -= _value;
            allowance[_from][msg.sender] -= _value;
            totalSupply -= _value;
            Burn(_from, _value);
            return true;
        }
    }
    

    3.2 编译智能合约

    在compile页中, 选中Auto Compile, 进行自动编译智能合约, (应用不会出现红色错误提示)

    3.3 部署合约

    在Run页中, Environment中,选中inject web3(前提是, 已经安装好了metamash插件,并且已经导入了账号,配置后账号环境)。

    在account项, 选择一个有币的账号

    最后通过点击deploy按钮来部署合约, 在部署前, 可填写构造函数的参数如 20000000, "TESTINT COIN", "TC"

    最终完成部署

  • 相关阅读:
    Mac MySql突然不好用了,说权限不够
    关闭Nginx的进程
    Mac 设置域名解析
    Docker的Yml文件
    Docker遇到的异常和注意点
    MySQL 查询时间段内的数据
    golang martini 源码阅读笔记之martini核心
    golang martini 源码阅读笔记之inject
    使用erlang实现简单的二进制通信协议
    使用 erlang OTP 模式编写非阻塞的 tcp 服务器(来自erlang wiki)
  • 原文地址:https://www.cnblogs.com/freebird92/p/10115274.html
Copyright © 2020-2023  润新知