zoukankan      html  css  js  c++  java
  • solidity代币实例详解

    端午节放假了,饱食终日,无所事事,用solidity写了个以太坊代币,于是离骚币诞生了,纪念屈原,今年不仅仅是读一遍离骚了。

    代码地址:https://etherscan.io/address/0x9a5dcd4348549d719813431f10fbb6d1c1758d83#code

    代币地址:https://etherscan.io/token/0x9a5dcd4348549d719813431f10fbb6d1c1758d83

    这里也贴一份:

    pragma solidity ^0.4.24;
    /**
    * @title SafeMath
    * @dev Math operations with safety checks that throw on error
    防止整数溢出问题
    */
    library SafeMath {
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a * b;
    assert(a == 0 || c / a == b);
    return c;
    }

    function div(uint256 a, uint256 b) internal pure returns (uint256) {
    // assert(b > 0); // Solidity automatically throws when dividing by 0
    uint256 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold
    return c;
    }

    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    assert(b <= a);
    return a - b;
    }

    function add(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a + b;
    assert(c >= a);
    return c;
    }
    }

    contract StandardToken {
    //使用SafeMath
    using SafeMath for uint256;

    //代币名称
    string public name;
    //代币缩写
    string public symbol;
    //代币小数位数(一个代币可以分为多少份)
    uint8 public decimals;
    //代币总数
    uint256 public totalSupply;

    //交易的发起方(谁调用这个方法,谁就是交易的发起方)把_value数量的代币发送到_to账户
    function transfer(address _to, uint256 _value) public returns (bool success);
    //从_from账户里转出_value数量的代币到_to账户
    function transferFrom(address _from, address _to, uint256 _value) public returns (bool success);
    //交易的发起方把_value数量的代币的使用权交给_spender,然后_spender才能调用transferFrom方法把我账户里的钱转给另外一个人
    function approve(address _spender, uint256 _value) public returns (bool success);
    //查询_spender目前还有多少_owner账户代币的使用权
    function allowance(address _owner, address _spender) public constant returns (uint256 remaining);
    //转账成功的事件
    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    //使用权委托成功的事件
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);
    }
    //设置代币控制合约的管理员
    contract Owned {

    // modifier(条件),表示必须是权力所有者才能do something,类似administrator的意思
    modifier onlyOwner() {
    require(msg.sender == owner);
    _;//do something
    }

    //权力所有者
    address public owner;

    //合约创建的时候执行,执行合约的人是第一个owner
    constructor() public {
    owner = msg.sender;
    }
    //新的owner,初始为空地址,类似null
    address newOwner=0x0;

    //更换owner成功的事件
    event OwnerUpdate(address _prevOwner, address _newOwner);

    //现任owner把所有权交给新的owner(需要新的owner调用acceptOwnership方法才会生效)
    function changeOwner(address _newOwner) public onlyOwner {
    require(_newOwner != owner);
    newOwner = _newOwner;
    }

    //新的owner接受所有权,权力交替正式生效
    function acceptOwnership() public{
    require(msg.sender == newOwner);
    emit OwnerUpdate(owner, newOwner);
    owner = newOwner;
    newOwner = 0x0;
    }
    }

    //代币的控制合约
    contract Controlled is Owned{

    //创世vip
    constructor() public {
    setExclude(msg.sender,true);
    }

    // 控制代币是否可以交易,true代表可以(exclude里的账户不受此限制,具体实现在下面的transferAllowed里)
    bool public transferEnabled = true;

    // 是否启用账户锁定功能,true代表启用
    bool lockFlag=true;
    // 锁定的账户集合,address账户,bool是否被锁,true:被锁定,当lockFlag=true时,恭喜,你转不了账了,哈哈
    mapping(address => bool) locked;
    // 拥有特权用户,不受transferEnabled和lockFlag的限制,vip啊,bool为true代表vip有效
    mapping(address => bool) exclude;

    //设置transferEnabled值
    function enableTransfer(bool _enable) public onlyOwner returns (bool success){
    transferEnabled=_enable;
    return true;
    }

    //设置lockFlag值
    function disableLock(bool _enable) public onlyOwner returns (bool success){
    lockFlag=_enable;
    return true;
    }

    // 把_addr加到锁定账户里,拉黑名单。。。
    function addLock(address _addr) public onlyOwner returns (bool success){
    require(_addr!=msg.sender);
    locked[_addr]=true;
    return true;
    }

    //设置vip用户
    function setExclude(address _addr,bool _enable) public onlyOwner returns (bool success){
    exclude[_addr]=_enable;
    return true;
    }

    //解锁_addr用户
    function removeLock(address _addr) public onlyOwner returns (bool success){
    locked[_addr]=false;
    return true;
    }
    //控制合约 核心实现
    modifier transferAllowed(address _addr) {
    if (!exclude[_addr]) {
    require(transferEnabled,"transfer is not enabeled now!");
    if(lockFlag){
    require(!locked[_addr],"you are locked!");
    }
    }
    _;
    }

    }

    //端午节,代币离骚
    contract LiSaoToken is StandardToken,Controlled {

    //账户集合
    mapping (address => uint256) public balanceOf;
    mapping (address => mapping (address => uint256)) internal allowed;

    constructor() public {
    totalSupply = 1000000000;//10亿
    name = "LiSao Token";
    symbol = "LS";
    decimals = 0;
    balanceOf[msg.sender] = totalSupply;
    }

    function transfer(address _to, uint256 _value) public transferAllowed(msg.sender) returns (bool success) {
    require(_to != address(0));
    require(_value <= balanceOf[msg.sender]);

    balanceOf[msg.sender] = balanceOf[msg.sender].sub(_value);
    balanceOf[_to] = balanceOf[_to].add(_value);
    emit Transfer(msg.sender, _to, _value);
    return true;
    }

    function transferFrom(address _from, address _to, uint256 _value) public transferAllowed(_from) returns (bool success) {
    require(_to != address(0));
    require(_value <= balanceOf[_from]);
    require(_value <= allowed[_from][msg.sender]);

    balanceOf[_from] = balanceOf[_from].sub(_value);
    balanceOf[_to] = balanceOf[_to].add(_value);
    allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
    emit Transfer(_from, _to, _value);
    return true;
    }

    function approve(address _spender, uint256 _value) public returns (bool success) {
    allowed[msg.sender][_spender] = _value;
    emit Approval(msg.sender, _spender, _value);
    return true;
    }

    function allowance(address _owner, address _spender) public view returns (uint256 remaining) {
    return allowed[_owner][_spender];
    }

    }

    1.代码介绍
    遵守ERC20协议
    具体代码体现:contract StandardToken
    ERC20协议的github地址:https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
    遵守协议就是统一状态变量的名称和方法的名称,大家看代码里StandardToken合约里就是了,可能会觉得奇怪,官方文档里明明写的是像这种方法
    function name() view returns (string name)
    你的代码里咋没写呢?因为我定义了 string public name,而public的公共变量name,会自动生成一个返回name的name()的方法,所以我不用重复写function name()了,其它几个变量也是一样的
    引入SafeMath,防止整数溢出漏洞(SMT,BEC)
    具体代码实现:library SafeMath
    官方介绍地址:https://ethereumdev.io/safemath-protect-overflows/
    设置一个控制合约
    具体代码体现:contract Controlled
    作用:
    1.有突发情况,可以暂停所有人的转账
    2.设置黑名单功能,可以冻结黑名单帐户,让它无法转账
    3.也可以设置vip帐户,不受前面两个的控制
    管理员
    具体代码体现:contract Owned
    既然有控制合约,各种转账控制,那么谁来设置这个东西,如果人人都有权限,那就乱套了,所以需要一个唯一管理员;管理员也可以把这个权力禅让给一个新的管理员
    具体实现代币功能
    具体代码体现:contract LiSaoToken
    功能点,通俗的讲就是 :
    1.自己转账给他人(transfer)
    2.自己帮别人转账给另外一个人(transferFrom)
    3.我委托你帮我管理我的代币,使用权给你,但是币还在我这(approve)
    4.查看一下我还有多少币委托你在管理(allowance)

    2.开发部署
    remix,开发和部署一体的
    solidity的开发工具,在线工具:http://remix.ethereum.org,浏览器直接打开就行,很省事,当然也可以安装本地版,remix官网的安装介绍看起来很简单,几行命令就ok了,但是实际上很坑,反正我放弃了
    metamask钱包
    chrome浏览器的一个钱包插件,官网地址:https://metamask.io/,安装方法也在首页有,但是安装的时候需要FQ,了解一下?
    发布流程

    设置gas价格,确认交易

    然后就可以看的remix的日志信息了

    点开连接等待挖矿完成就好了
    metamask钱包导入自己的代币
    拷贝合约地址

    增加代币管理

    10亿个代币:

    本博2017年4月开始自学,到20年2月已自学3年,不仅仅python,目前已经全栈WEB开发,全自动A股交易,深度学习也初步涉猎,这句话改于2020年2月16日。计划学习10年,40岁学成精英,如若不到,继续学习,终身保持学习状态。30岁之前看不惯社会天天抱怨,30岁突然醒悟,错全在自己身上,跟社会没有任何关系,故开始随时保持学习状态,向梦想冲刺。
  • 相关阅读:
    实验一 命令解释程序的编写
    试验二
    实验一 命令解释程序的编写(重交)
    Sqlserver数据库帮助类(EFTools)
    js验证
    sqlserver中从日期字段取得月份
    IIS不可用或者有问题解决方法
    professional email address collections
    从psd文件到html
    空白符对HTML结构的影响与解决方案
  • 原文地址:https://www.cnblogs.com/hushuning/p/14768303.html
Copyright © 2011-2022 走看看