• 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岁突然醒悟,错全在自己身上,跟社会没有任何关系,故开始随时保持学习状态,向梦想冲刺。
  • 相关阅读:
    KnockoutJS 3.X API 第五章 高级应用(4) 自定义处理逻辑
    KnockoutJS 3.X API 第五章 高级应用(3) 虚拟元素绑定
    KnockoutJS 3.X API 第五章 高级应用(2) 控制后代绑定
    KnockoutJS 3.X API 第五章 高级应用(1) 创建自定义绑定
    KnockoutJS 3.X API 第四章(14) 绑定语法细节
    KnockoutJS 3.X API 第四章(13) template绑定
    KnockoutJS 3.X API 第四章 表单绑定(12) selectedOptions、uniqueName绑定
    KnockoutJS 3.X API 第四章 表单绑定(11) options绑定
    KnockoutJS 3.X API 第四章 表单绑定(10) textInput、hasFocus、checked绑定
    KnockoutJS 3.X API 第四章 表单绑定(9) value绑定
  • 原文地址:https://www.cnblogs.com/hushuning/p/14768303.html
Copyright © 2020-2023  润新知