0%

StudyRecord-ERC1155协议

简介:

ERC-1155是ERC-20和ERC-721的升级规范,用于多种代币管理的合约标准接口。 单个部署的合约可以包括同质化代币、非同质化代币或其他配置(如半同质化代币)的任何组合,即可以使用一个智能合约同时代表多个代币。

功能和特点:

  • 批量转移:一次调用即可转移多个资产。

  • 批次余额:一次调用即可获取多个资产的余额。

  • 批量批准:批准所有令牌到一个地址。

  • EIP-165支持:声明支持的接口。

  • 钩子接口:提供代币接受钩子接口。

  • NFT支持:如果供应量仅为1,则将其视为NFT。

  • 安全转移规则:安全转移的规则集

ERC1155的显着特点是它有一个额外的id参数,作为多种代币的唯一标识符。也就是说,多了一个key-value,多了一个键值对,映射着TokenId->Token。

实现:

  1. 同质化代币,类似ERC20,一个合约中包含一种或多种ERC20代币,例子

  2. 非同质化代币,类似ERC721,一个合约中包含一种或多种ERC721代币,例子

  3. 半同质化代币,代币含ERC20+ERC721的属性,ERC721代币同一个ID有多个数量,例子

  4. 同质化代币+非同质化代币,一个合约中包含ERC20ERC721两种类型的代币,例子

ERC1155部署在opensea上:

通过ERC1155协议,模仿实现一个半同质化代币,一个项目有4种NFT会员卡,每个NFT会员卡有多个数量。
20230111143048
20230111143120
测试的合约源码 github

合约源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// MyToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Supply.sol";
import "@openzeppelin/contracts/utils/Strings.sol";

contract MyToken is ERC1155, Ownable, ERC1155Supply {
using Strings for uint256;

constructor() ERC1155("") {}

/// @dev End token Id => URI that overrides `baseURI + tokenId` convention.
mapping(uint256 => string) public _baseURI;

function setBaseURI(uint256 _tokenId, string memory newuri) public onlyOwner {
_baseURI[_tokenId] = newuri;
}

/// @dev Returns the URI for a given tokenId.
function uri(uint256 _tokenId) public view override returns (string memory) {
return string(abi.encodePacked(_baseURI[_tokenId], _tokenId.toString()));
}

function mint(address account, uint256 id, uint256 amount, bytes memory data)
public
onlyOwner
{
_mint(account, id, amount, data);
}

function mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data)
public
onlyOwner
{
_mintBatch(to, ids, amounts, data);
}

// The following functions are overrides required by Solidity.

function _beforeTokenTransfer(address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data)
internal
override(ERC1155, ERC1155Supply)
{
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
}
}
  • 继承了ERC1155Supply,后续可查询多种Token的totalSupply

部署脚本:

合约部署在测试网上,https://goerli.etherscan.io/address/0x06983Ca838F76407436a36C1EB8FE5C4b44caFd0#code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// scripts/1.set_uri.ts
import {ethers, run, network} from "hardhat"

async function main() {

const TokenFactory = await ethers.getContractFactory("MyToken")
console.log("Deploying Token...")
const Token = await TokenFactory.deploy()
await Token.deployed()

console.log("Token Contract deployed at:", Token.address)

await Token.setBaseURI(0, "ipfs://QmavJyMNJiAz9hXTmZrEuFMi8yrpiNjUbFujHE57Z6avc3/");
let baseUri = await Token.uri(0);
console.log("baseUri:", baseUri.toString());

await Token.setBaseURI(1, "ipfs://QmTwC69n8hPzWYw1wHXT8Dc8h7PnjtAfzLFHPLz423DadA/");
let baseUri1 = await Token.uri(1);
console.log("baseUri1:", baseUri1.toString());

await Token.setBaseURI(2, "ipfs://QmTcwvsf1XXi5kKkBbk7iNX8svZD6iE4JE6NXioFiRTKbD/");
let baseUri2 = await Token.uri(2);
console.log("baseUri2:", baseUri2.toString());

await Token.setBaseURI(3, "ipfs://QmduXsTYa8NQ4xfFwXbLLpkkznwhwS9b1MMa25SENcvcRC/");
let baseUri3 = await Token.uri(1);
console.log("baseUri3:", baseUri3.toString());

await Token.mint("0xa48d2ed854effb7c4dafdb06931633699042c62a", 0, 100, "0x");
let balance = await Token.balanceOf("0xa48d2ed854effb7c4dafdb06931633699042c62a", 0);
console.log("balance:", balance.toString());
}

main().catch((error) => {
console.error(error)
process.exitCode = 1
})

先是给4个tokenId(0,1,2,3)分别设置不同的baseUri。

一般的ERC721协议的NFT,一个tokenId对应的数量只有一个。这里我们在调用铸造函数mint(address account, uint256 id, uint256 amount, bytes memory data)时,传参为mint("0xa48d2ed854effb7c4dafdb06931633699042c62a", 0, 100, "0x"),给tokenId为0的NFT代币铸造100个。

opensea查看:

看看效果:
https://testnets.opensea.io/zh-CN/collection/unidentified-contract-pkc1qecx1s
20230111144351
20230111144431
20230111144449
这样就实现了一个简单demo,一个项目方有4种NFT会员卡,每种会员卡NFT的数量有多个。

refs: