第3节:世界杯竞猜(标准ERC20协议)
本次课程主要讲解Token协议:ERC20,这就是我们最常见的token,例如USDT,后续我们会介绍NFT 本文收录于我的开源项目, 欢迎star转发,文末加V入群。
## 内容概述
本次课程主要讲解Token协议:ERC20,这就是我们最常见的token,例如USDT,后续我们会介绍NFT,具体如下:
- [点击获取代码](https://github.com/dukedaily/solidity-expert/blob/main/08_项目实战-世界杯竞猜/)
| | ERC20 | ERC721 | ERC1155 |
| ------ | ----------------- | -------------------- | ----------------------------------- |
| 定义 | 同质化Token(FT) | 非同质化Token(NFT) | 半同质化Token(SFT |
| 特点 | 每个Token都一样 | 每个Token都不一样 | TokenID不一样,但同ID下都单位都一样 |
| 分割性 | 可分割 | 不可分割 | ID下数量可分割 |
| 转移性 | 但目标限量转移 | 单目标单个转移 | 可批量转移 |
## ERC20
ERC20协议是标准的以太坊Token协议,它也是一个合约代码,只要在该合约内部实现了特定的6个方法,就会被系统判定为代币合约,**具体总结为:6个必要接口,2个必要事件,3个可选接口**,详情如下:
6个必要接口:
```JavaScript
// 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个必要事件
```js
// 在tranfer 和transferFrom内部使用
event Transfer(address indexed _from, address indexed _to, uint256 _value)
// 在approve方法中使用
event Approval(address indexed _owner, address indexed _spender, uint256 _value)
```
3个可选接口
```js
// 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,其关系如下图:
![image.png](https://img.learnblockchain.cn/attachments/2022/10/uCOBJ8X963420b9bada27.png)
其中关系为:
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,填写内容如下:
```JavaScript
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,需要手动安装一下这个包, 这是个标准的三方包,包含很多基础的合约,代码安全,可以放心使用。
```sh
npm i @openzeppelin/contracts
```
下图为openzeppeline/cntracts包里面支持的合约,涉及到:标准合约,准入控制,代理合约,工具合约等,后续我们会专门讲解里面的功能。
![image.png](https://img.learnblockchain.cn/attachments/2022/10/JEy9bgov63420baff26bb.png)
编写部署脚本:
```js
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;
});
```
编译部署合约:
```sh
# 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方法:
```sh
npx hardhat verify --contract contracts/tokens/WorldCupToken.sol:WorldCupToken 0xB500D338D6cd608D867015295483E38758CC7711 "World Cup Token" "WCT" "10000000000000000000000000" --network goerli
```
在浏览器查看,效果如下:
![image.png](https://img.learnblockchain.cn/attachments/2022/10/GHV4ePGA63420bbf400e4.png)
## 小结
至此,我们发行了一个自己的Token,与我们正常使用USDT等在技术上没有任何区别,从技术上看这个没有任何技术含量,真正让Token有价值的是它会应用到哪些场景中去,与业务结合,才会让Token有流动的意义。
为了能够将Token作为激励发放到我们的世界杯玩家中,我们需要先学习扫块技术,即subgraph,通过扫块,我们可以统计到有哪些参与用户,金额对真实贡献者提供奖励。
好了,本节就到这里,下回见!!
## 参考链接
- Goerli ETH faucet: https://goerlifaucet.com/
- 本文代码托管在github:https://github.com/dukedaily/solidity-expert, 欢迎start,谢谢支持!
> 本文收录于我的开源项目:https://github.com/dukedaily/solidity-expert , 欢迎star转发,文末加V入群。
![image.png](https://img.learnblockchain.cn/attachments/2022/10/OjFV1MrF634246a22b298.png)
加V入群:Adugii,公众号:阿杜在新加坡,一起抱团拥抱web3,下期见!
> 关于作者:国内第一批区块链布道者;2017年开始专注于区块链教育(btc, eth, fabric),目前base新加坡,专注海外defi,dex,元宇宙等业务方向。
内容概述
本次课程主要讲解Token协议:ERC20,这就是我们最常见的token,例如USDT,后续我们会介绍NFT,具体如下:
- 点击获取代码
ERC20 | ERC721 | ERC1155 | |
---|---|---|---|
定义 | 同质化Token(FT) | 非同质化Token(NFT) | 半同质化Token(SFT |
特点 | 每个Token都一样 | 每个Token都不一样 | TokenID不一样,但同ID下都单位都一样 |
分割性 | 可分割 | 不可分割 | ID下数量可分割 |
转移性 | 但目标限量转移 | 单目标单个转移 | 可批量转移 |
ERC20
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,其关系如下图:
其中关系为:
- 张三为Token持有人,李四为张三的委托人(被授权),王五是收款人;
- 张三调用USDT的Approve方法,授权李四可以支配50w Token,调用格式为:USDT.Approve(李四, 50w)
- 此时在USDT合约内部,会通过allowance进行记录:allowance[张三][李四] += 50w
- 此时李四便可以支配张三的50w USDT,并调用transferFrom给王五转转,调用形式为:USDT.transferFrom(张三, 王五, 1w)
- 转账过后,张三的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包里面支持的合约,涉及到:标准合约,准入控制,代理合约,工具合约等,后续我们会专门讲解里面的功能。
编写部署脚本:
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,通过扫块,我们可以统计到有哪些参与用户,金额对真实贡献者提供奖励。
好了,本节就到这里,下回见!!
参考链接
- Goerli ETH faucet: https://goerlifaucet.com/
- 本文代码托管在github:https://github.com/dukedaily/solidity-expert, 欢迎start,谢谢支持!
本文收录于我的开源项目:https://github.com/dukedaily/solidity-expert , 欢迎star转发,文末加V入群。
加V入群:Adugii,公众号:阿杜在新加坡,一起抱团拥抱web3,下期见!
关于作者:国内第一批区块链布道者;2017年开始专注于区块链教育(btc, eth, fabric),目前base新加坡,专注海外defi,dex,元宇宙等业务方向。
本文参与区块链技术网 ,好文好收益,欢迎正在阅读的你也加入。
- 发表于 2022-10-09 07:46
- 阅读 ( 376 )
- 学分 ( 7 )
- 分类:智能合约
评论