Solidity-by-example(第二天)

76 阅读3分钟

第二天进入Application编码环节,对于每个Application的整体架构我通过5W2H分析法研究:

  1. Who:项目对象,项目中涉及到了哪些对象(人、客户端、服务端、合约、EVM等等)
  2. Why:项目价值,为什么会出现该应用,解决了哪些痛点,发展历史是什么样?
  3. What:项目需求,该项目通过哪些功能实现了项目价值?
  4. When:项目时序,项目中各个对象的写作时序是什么样?
  5. Where:项目运行在哪个位置,比如你的代码是运行在Java虚拟机还是EVM虚拟机,具体如何运行,如何部署
  6. How:项目如何实现,这部分涉及到具体编码,需要输出详细的方案设计
  7. How much:项目成本,依赖成本,开发成本,测试成本,部署成本,运维成本,运营成本

ERC20规范

ERC20标准 从文档的概要中我找到了这个标准出现的原因,以及ERC20提供的两个核心能力。 1.支持自己转账 2.支持授权给第三方平台转账 image.png

项目对象

  1. 代币合约开发者
  2. 以太链
  3. 拥有代币的账户

项目价值

为直接转账和授权转账制定规范,有助于生态建立。

我们可以设想一个场景,如果没有ERC20规范,智能合约转账都是合约开发者开发各自的转账接口,相对应的,客户端都需要独立开发。有了ERC20规范,一个客户端比如Metamask可以直接接入所有ERC20规范的Token。

项目需求

既然是转账功能,下面是我思考的几个问题,以及我在ERC20遍准文档中找到的答案:

  1. Token从哪里产生? 规范中没有提及Token的产生,但我从案例中找到一个方法:
function mint(uint amount) external {

        balanceOf[msg.sender] += amount;

        totalSupply += amount;

        emit Transfer(address(0), msg.sender, amount);

    }

看样子是无中生有?这个问题暂时没有找到一个合理的答案。

  1. Token的价值值几个ETH? 这个暂时也没找到答案。 有个相关的参数是decimals。我从solidity-by-example看到:

image.png

是不是Token合约将 decimals =18,就表示1token=1eth = 10 ** 18 wei?

  1. 如果我有10个Token,我该如何转2个Token给另外一个地址? 转Eth可以使用call、transform、send。ERC20定义了接口

function transfer(address _to, uint256 _value) public returns (bool success)

用于主动转账,既然是主动转账,发送者就是msg.sender,_to表示接收者,具体逻辑由ERC20实现者实现,比如从addresA抓给addressB 10个token,逻辑是给 address A 的amout-10,给 address B的amout + 10,并且还需要机制保证转账的ACID性质。

  1. 我如何查询转账的历史记录? ERC20规范中定义了事件可以用于记录

event Transfer(address indexed _from, address indexed _to, uint256 _value)

  1. 授权第三方转账,是第三方能够使用我所有的Token还是在授权时指定数量? ERC20中定义了授权接口进行授权,msg.sender是授权方,_spender参数表示第三方平台,_value表示第三方平台能够转移token的最大数量。

function approve(address _spender, uint256 _value) public returns (bool success)

  1. 授权后,第三方平台应该如何使用我的账户进行转账? ERC20中规定了使用

function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)

接口进行转账。from指授权方,to指收款方,value表示转账数量。该转账逻辑还必须要校验_from是否授权了msg.sender进行转账,并且授权数量>=value

  1. 如何查询授权的历史记录? ERC20中也定义了接口进行查询。

function allowance(address _owner, address _spender) public view returns (uint256 remaining)