本次课程主要讲解Token协议:ERC20,这就是我们最常见的token,例如USDT,后续我们会介绍NFT 本文收录于我的开源项目, 欢迎star转发,文末加V入群。
本次课程主要讲解Token协议:ERC20,这就是我们最常见的token,例如USDT,后续我们会介绍NFT,具体如下:
ERC20 | ERC721 | ERC1155 | |
---|---|---|---|
定义 | 同质化Token(FT) | 非同质化Token(NFT) | 半同质化Token(SFT |
特点 | 每个Token都一样 | 每个Token都不一样 | TokenID不一样,但同ID下都单位都一样 |
分割性 | 可分割 | 不可分割 | ID下数量可分割 |
转移性 | 但目标限量转移 | 单目标单个转移 | 可批量转移 |
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的时候,会在内部修改allownce,mapping
// 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,其关系如下图:
其中关系为:
我们发行一个worldCupToken,用于后续对参与竞猜的用户进行奖励,token信息如下:
在我们的项目中,创建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包里面支持的合约,涉及到:标准合约,准入控制,代理合约,工具合约等,后续我们会专门讲解里面的功能。
编写部署脚本:
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
在浏览器查看,效果如下:
至此,我们发行了一个自己的Token,与我们正常使用USDT等在技术上没有任何区别,从技术上看这个没有任何技术含量,真正让Token有价值的是它会应用到哪些场景中去,与业务结合,才会让Token有流动的意义。
为了能够将Token作为激励发放到我们的世界杯玩家中,我们需要先学习扫块技术,即subgraph,通过扫块,我们可以统计到有哪些参与用户,金额对真实贡献者提供奖励。
好了,本节就到这里,下回见!!
本文收录于我的开源项目:https://github.com/dukedaily/solidity-expert , 欢迎star转发,文末加V入群。
加V入群:Adugii,公众号:阿杜在新加坡,一起抱团拥抱web3,下期见!
关于作者:国内第一批区块链布道者;2017年开始专注于区块链教育(btc, eth, fabric),目前base新加坡,专注海外defi,dex,元宇宙等业务方向。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!