第3节:世界杯竞猜(标准ERC20协议)

小白入门:https://github.com/dukedaily/solidity-expert ,欢迎star转发,文末加V入群。

职场进阶: https://dukeweb3.com

概述

本次课程主要讲解Token协议:ERC20,这就是我们最常见的token,例如USDT,后续我们会介绍NFT,具体如下:

  1. 点击获取代码
  2. 点击查看视频
ERC20 ERC721 ERC1155
定义 同质化Token(FT) 非同质化Token(NFT) 半同质化Token(SFT
特点 每个Token都一样 每个Token都不一样 TokenID不一样,但同ID下都单位都一样
分割性 可分割 不可分割 ID下数量可分割
转移性 但目标限量转移 单目标单个转移 可批量转移

ERC20

image-20221009070445434

ERC20协议是标准的以太坊Token协议,它也是一个合约代码,只要在该合约内部实现了特定的6个方法,就会被系统判定为代币合约,具体总结为:6个必要接口,2个必要事件,3个可选接口,详情如下:

6个必要接口:

// FHT Token: 总发行量:1000w,decimal:18

// 总发行量:10000000 * 10**18
function totalSupply() public view returns (uint256)

// 内部维护一个mapping, 返回余额
function balanceOf(address _owner) public view returns (uint256 balance)

// token持有人调用,进行转账(写操作,花钱)
// 张三 -> 李四, 100 * 10**18
function transfer(address _to, uint256 _value) public returns (bool success)

// 张三,李四,王五
// 张三是token持有人, owner, 1w
function approve(address _spender, uint256 _value) public returns (bool success)
// 张三调用approve的时候,会在内部修改allowncemapping
// allownace[张三][李四] += 1w

function allowance(address _owner, address _spender) public view returns (uint256 remaining)
// 李四是被授权人, spender
// 王五接受token的人, receiver

// 李四是张三的授权人,李四调用transferFrom来给王五转账
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)

2个必要事件

// 在tranfer 和transferFrom内部使用
event Transfer(address indexed _from, address indexed _to, uint256 _value)

// 在approve方法中使用
event Approval(address indexed _owner, address indexed _spender, uint256 _value)

3个可选接口

// FHT Token
function name() public view returns (string)

// FHT
function symbol() public view returns (string) 

// USDT:  6, 10000000 * 10**6
// WBTC:  8, 10000000 * 10**8
// 其他Token:18, 10000000 * 10**18
function decimals() public view returns (uint8)

其中,approve逻辑是我们最常使用的,与之配合的方法是transferFrom,其关系如下图:

approve流程图

其中关系为:

  1. 张三为Token持有人,李四为张三的委托人(被授权),王五是收款人;
  2. 张三调用USDT的Approve方法,授权李四可以支配50w Token,调用格式为:USDT.Approve(李四, 50w)
  3. 此时在USDT合约内部,会通过allowance进行记录:allowance[张三][李四] += 50w
  4. 此时李四便可以支配张三的50w USDT,并调用transferFrom给王五转转,调用形式为:USDT.transferFrom(张三, 王五, 1w)
  5. 转账过后,张三的Token减少1w,王五点Token增加1w,李四被授权的额度减少1w。

发行ERC20 Token

我们发行一个worldCupToken,用于后续对参与竞猜的用户进行奖励,token信息如下:

  • 名称Name:World Cup Token
  • 简称Symbol:WCT
  • 精度decimals:18
  • 发行量Total Amounts:10,000,000

在我们的项目中,创建tokens/WorldCupToken.sol,填写内容如下:

pragma solidity ^0.8.10;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

//合约继承,使用 is
contract FHTToken is ERC20 {
    // 2. 一次性mint出来,不允许后续mint
    constructor(
        string memory name_,
        string memory symbol_,
        uint256 totalSupply_
    ) ERC20(name_, symbol_) {
        _mint(msg.sender, totalSupply_);
    }
}

我们使用了标准openzeppeline包来创建token,需要手动安装一下这个包, 这是个标准的三方包,包含很多基础的合约,代码安全,可以放心使用。

npm i @openzeppelin/contracts

下图为openzeppeline/cntracts包里面支持的合约,涉及到:标准合约,准入控制,代理合约,工具合约等,后续我们会专门讲解里面的功能。

image-20221008155705857

编写部署脚本:

import { ethers } from "hardhat";

async function main() {

  const totalSupply = ethers.utils.parseUnits('10000000', 18)
  console.log('totalSupply:', totalSupply);

  const FHTToken = await ethers.getContractFactory('WorldCupToken');
  const fht = await FHTToken.deploy("World Cup Token", "WCT", totalSupply);

  await fht.deployed();

  console.log(`new World Cup Token deployed to ${fht.address}`);
}

// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

编译部署合约:

# new World Cup Token deployed to 0xB500D338D6cd608D867015295483E38758CC7711
npx hardhat run scripts/deployMockERc20.ts --network goerli

# 常规verify方法
#npx hardhat verify 0x27716a01Ef4eBd9001dE035A89d86593588D92BC "World Cup Token" "WCT" "10000000000000000000000000" --network goerli

当有多个代码相同时,verify方法:

 npx hardhat verify --contract contracts/tokens/WorldCupToken.sol:WorldCupToken 0xB500D338D6cd608D867015295483E38758CC7711 "World Cup Token" "WCT" "10000000000000000000000000" --network goerli

在浏览器查看,效果如下:

image-20221008163326175

小结

至此,我们发行了一个自己的Token,与我们正常使用USDT等在技术上没有任何区别,从技术上看这个没有任何技术含量,真正让Token有价值的是它会应用到哪些场景中去,与业务结合,才会让Token有流动的意义。

为了能够将Token作为激励发放到我们的世界杯玩家中,我们需要先学习扫块技术,即subgraph,通过扫块,我们可以统计到有哪些参与用户,金额对真实贡献者提供奖励。

好了,本节就到这里,下回见!!

参考链接


加V入群:dukeweb3,公众号:阿杜在新加坡,一起抱团拥抱web3,下期见!

关于作者:国内第一批区块链布道者;2017年开始专注于区块链教育(btc, eth, fabric),目前base新加坡,专注海外defi,dex,元宇宙等业务方向。