contract ERC20 {
 //**********9个函数*******
 //1.代币的名字
 function name() constant public returns (string name);
 //2.代币的简称,例如:HMB
 function symbol() public constant returns (string symbol);
 //3.代币的最小分割量 token使用的小数点后几位。比如如果设置为3,就是支持0.001表示
 function decimals() public constant returns (uint8 decimals);
 //4.token的总量
 function totalSupply() public  constant returns (uint totalSupply); 
 //5.余额 返回某个地址(账户)的账户余额
 function balanceOf(address _owner) public constant returns (uint balance);
 /*6.转账 交易代币 从消息发送者账户中往_to账户转数量为_value的token,
     从代币合约的调用者地址上转移 _value的数量token到的地址 _to
    【注意:并且必须触发Transfer事件】*/
 function transfer(address _to, uint _value) public returns (bool success);
 /*7.两个地址转账
    从账户_from中往账户_to转数量为_value的token,与approve方法配合使用
    从地址 _from发送数量为 _value的token到地址 _to
   【注意:并且必须触发Transfer事件】
    transferFrom方法用于允许合约代理某人转移token。条件是from账户必须经过了approve。*/
 function transferFrom(address _from, address _to, uint _value) public returns (bool success);
 //8.批准_spender能从合约调用账户中转出数量为_value的token
 function approve(address _spender, uint _value) public returns (bool success);
 //9.获取_spender可以从账户_owner中转出token的剩余数量
 function allowance(address _owner, address _spender) public constant returns (uint remaining);
 //**********2个事件*******
 //1.发生转账时必须要触发的事件,transfer 和 transferFrom 成功执行时必须触发的事件
 event Transfer(address indexed _from, address indexed _to, uint _value);
 //2.当函数 approve(address _spender, uint256 _value)成功执行时必须触发的事件
 event Approval(address indexed _owner, address indexed _spender, uint _value);
//10.存储(映射)对账号的控制:mapping(owner => mapping(spender => amount)) allowed
第一个address表示token拥有者
第二个address表示授权的spender,即spender代理消费owner的token
第三个amout表示代理的数量
这是一个map的嵌套使用

// 此合约实现不记得是哪看到后复制保存的......和官网案例类似
pragma solidity ^0.4.25;interface tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData) public; }contract TokenERC20 {string public name; // ERC20标准string public symbol; // ERC20标准uint8 public decimals = 2;  // ERC20标准,decimals 可以有的小数点个数,最小的代币单位。18 是建议的默认值uint256 public totalSupply; // ERC20标准 总供应量// 用mapping保存每个地址对应的余额 ERC20标准mapping (address => uint256) public balanceOf;// 存储对账号的控制 ERC20标准mapping (address => mapping (address => uint256)) public allowance;// 事件,用来通知客户端交易发生 ERC20标准event Transfer(address indexed from, address indexed to, uint256 value);// 事件,用来通知客户端代币被消费 ERC20标准event Burn(address indexed from, uint256 value);/*** 初始化构造*/function TokenERC20(uint256 initialSupply, string tokenName, string tokenSymbol) public {totalSupply = initialSupply * 10 ** uint256(decimals);  // 供应的份额,份额跟最小的代币单位有关,份额 = 币数 * 10 ** decimals。balanceOf[msg.sender] = totalSupply;                // 创建者拥有所有的代币name = tokenName;                                   // 代币名称symbol = tokenSymbol;                               // 代币符号}/*** 代币交易转移的内部实现*/function _transfer(address _from, address _to, uint _value) internal {// 确保目标地址不为0x0,因为0x0地址代表销毁require(_to != 0x0);// 检查发送者余额require(balanceOf[_from] >= _value);// 确保转移为正数个require(balanceOf[_to] + _value > balanceOf[_to]);// 以下用来检查交易,uint previousBalances = balanceOf[_from] + balanceOf[_to];// Subtract from the senderbalanceOf[_from] -= _value;// Add the same to the recipientbalanceOf[_to] += _value;Transfer(_from, _to, _value);// 用assert来检查代码逻辑。assert(balanceOf[_from] + balanceOf[_to] == previousBalances);}/***  代币交易转移*  从自己(创建交易者)账号发送`_value`个代币到 `_to`账号* ERC20标准* @param _to 接收者地址* @param _value 转移数额*/function transfer(address _to, uint256 _value) public {_transfer(msg.sender, _to, _value);}/*** 账号之间代币交易转移* ERC20标准* @param _from 发送者地址* @param _to 接收者地址* @param _value 转移数额*/function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {require(_value <= allowance[_from][msg.sender]);     // Check allowanceallowance[_from][msg.sender] -= _value;_transfer(_from, _to, _value);return true;}/*** 设置某个地址(合约)可以创建交易者名义花费的代币数。** 允许发送者`_spender` 花费不多于 `_value` 个代币* ERC20标准* @param _spender The address authorized to spend* @param _value the max amount they can spend*/function approve(address _spender, uint256 _value) publicreturns (bool success) {allowance[msg.sender][_spender] = _value;return true;}/*** 设置允许一个地址(合约)以我(创建交易者)的名义可最多花费的代币数。*-非ERC20标准* @param _spender 被授权的地址(合约)* @param _value 最大可花费代币数* @param _extraData 发送给合约的附加数据*/function approveAndCall(address _spender, uint256 _value, bytes _extraData)publicreturns (bool success) {tokenRecipient spender = tokenRecipient(_spender);if (approve(_spender, _value)) {// 通知合约spender.receiveApproval(msg.sender, _value, this, _extraData);return true;}}/*** 销毁我(创建交易者)账户中指定个代币*-非ERC20标准*/function burn(uint256 _value) public returns (bool success) {require(balanceOf[msg.sender] >= _value);   // Check if the sender has enoughbalanceOf[msg.sender] -= _value;            // Subtract from the sendertotalSupply -= _value;                      // Updates totalSupplyBurn(msg.sender, _value);return true;}/*** 销毁用户账户中指定个代币*-非ERC20标准* Remove `_value` tokens from the system irreversibly on behalf of `_from`.** @param _from the address of the sender* @param _value the amount of money to burn*/function burnFrom(address _from, uint256 _value) public returns (bool success) {require(balanceOf[_from] >= _value);                // Check if the targeted balance is enoughrequire(_value <= allowance[_from][msg.sender]);    // Check allowancebalanceOf[_from] -= _value;                         // Subtract from the targeted balanceallowance[_from][msg.sender] -= _value;             // Subtract from the sender's allowancetotalSupply -= _value;                              // Update totalSupplyBurn(_from, _value);return true;}
}

ERC20合约标准详解分析相关推荐

  1. PeckShield:DeFi平台Opyn智能合约漏洞详解——攻击者空手套白狼!

    北京时间2020年08月05日,DeFi 期权平台 Opyn 的看跌期权(Opyn ETH Put)智能合约遭到黑客攻击,损失约37万美元. Opyn 是一个通用期权协议,于今年2月份转型为保险平台, ...

  2. c语言菜单选择如何用字符形式,【创客天地】计算机二级C语言、VB考试详解分析...

    原标题:[创客天地]计算机二级C语言.VB考试详解分析 01 马上就要迎来计算机二级考试了,你准备好了吗?今天助手君准备了一点C语言干货,希望对即将考试的你有所帮助.(上期刚刚推了office,有需要 ...

  3. java线程的生命周期及wait(),notify(),notifyAll()的详解分析

    1.java线程的生命周期     线程是一个动态执行的过程,它也有一个从产生到死亡的过程. (1)生命周期的五种状态 新建(new Thread)     当创建Thread类的一个实例(对象)时, ...

  4. 5G移动通信系统设计与标准详解 个人整理(PDF和Word)

    5G移动通信系统设计与标准详解 个人整理(PDF和Word) 链接:https://pan.baidu.com/s/134YxiXyP1f7Ab4BD75bs8Q  提取码:1001 Word示例 P ...

  5. 详解分析MySQL8.0的内存消耗

    文章来源: 学习通http://www.bdgxy.com/ 普学网http://www.boxinghulanban.cn/ 智学网http://www.jaxp.net/ 目录 1.innodb_ ...

  6. php java集成_PHP和Java 集成开发详解分析 强强联合第1/4页

    PHP和Java 集成开发详解分析 强强联合第1/4页 更新时间:2008年11月14日 12:28:23   作者: 很久以前,有人从www上看到看到天空上一个很亮的亮点,它就是Java语言,与此同 ...

  7. 无线通信知识回顾(2) - 《5G移动通信系统设计与标准详解》

    Reference: <5G移动通信系统设计与标准详解>-- 王映民等 第10章 功率控制 10.1 概述 功率控制对基站或者终端发送信号功率进行调节,达到有效地实现路径损耗补偿.克服阴影 ...

  8. EcoVadis认证的评分标准详解

    [EcoVadis认证的评分标准详解] EcoVadis是一个帮助企业评估其供货商的环境和社会责任表现的平台,通过评估供应商的CSR表现提供改善指导,帮助企业提升业务水平,使供应商具备国际的企业竞争力 ...

  9. 好用的CAD看图软件功能详解分析

    CAD制图工作中,我们都知道需要查看编辑等很多操作,这里有CAD看图软件,好用的CAD功能详解分享,提供6种基本看图模式,3种三维看图方法,6种CAD图纸编辑功能,加上3种CAD转换功能,且完全免费. ...

最新文章

  1. SEL | 植物通过根系分泌物招募假单孢菌协助抵抗地上部病原菌侵染
  2. base64是哪个jar包的_如何通过一个类名找到它属于哪个jar包?
  3. 最长公共子序列(LCS问题)
  4. 图像识别最新赛事!总奖金31万,一起组队吗?
  5. 查看journalnode节点状态信息_OpenStack Cinder服务状态排错
  6. 文章和随笔的标题好像没有HtmlEnCode。
  7. 汇总jQuery的61种选择器及示例
  8. 现实世界的Windows Azure 视频:新南威尔士州教育部(DET)利用Windows Azure实现在线科学测验...
  9. Python深度学习:No handles with labels found to put in legend.
  10. Qt工作笔记-Qt文档阅读笔记-setMouseTracking(无需按下移动使得widget获取鼠标位置)
  11. linux中wait()系统调用的例子,linux进程管理之wait系统调用
  12. ModelAndView视图解析器小结
  13. 内蒙古2021年高考成绩查询系统入口,2021年内蒙古高考成绩查询网址,内蒙古高考成绩查询系统时间安排...
  14. 根据地理坐标查询地标 城市名称 街道名称 地标建筑
  15. vue3实现动态组件加载写法
  16. 【Nee】MMD镜头+动作打包下载.zip
  17. STM32的Flash
  18. hibernatexml方式和注解方式实现单实体映射和继承关系映射,eclipse实现
  19. 【深度学习】使用tensorflow实现AlexNet
  20. Visual Studio Code vs. Visual Studio:该怎么选?

热门文章

  1. Ubuntu16.04 LTS下apt安装WireShark
  2. 52)PHP,加了单例模式的数据库代码
  3. github 学习笔记【一】
  4. GridView实战一:自定义分页、排序、修改、插入、删除
  5. 大数据之-Hadoop3.x_MapReduce_区内排序案例---大数据之hadoop3.x工作笔记0117
  6. Vue打包发布项目---vue工作笔记0020
  7. java零碎要点013---java lambda 表达式中的双冒号的用法 ::
  8. Swagger工作笔记001---Swagger2的使用
  9. SpringBoot学习笔记001--创建第一个spring boot应用
  10. DataLoader, when num_worker 0, there is bug