简介:
ERC-1155是ERC-20和ERC-721的升级规范,用于多种代币管理的合约标准接口。 单个部署的合约可以包括同质化代币、非同质化代币或其他配置(如半同质化代币)的任何组合,即可以使用一个智能合约同时代表多个代币。
功能和特点:
批量转移:一次调用即可转移多个资产。
批次余额:一次调用即可获取多个资产的余额。
批量批准:批准所有令牌到一个地址。
EIP-165支持:声明支持的接口。
钩子接口:提供代币接受钩子接口。
NFT支持:如果供应量仅为1,则将其视为NFT。
安全转移规则:安全转移的规则集
ERC1155的显着特点是它有一个额外的id参数,作为多种代币的唯一标识符。也就是说,多了一个key-value,多了一个键值对,映射着TokenId->Token。
实现:
同质化代币,类似ERC20
,一个合约中包含一种或多种ERC20代币,例子
非同质化代币,类似ERC721
,一个合约中包含一种或多种ERC721代币,例子
半同质化代币,代币含ERC20
+ERC721
的属性,ERC721代币同一个ID有多个数量,例子
同质化代币+非同质化代币,一个合约中包含ERC20
、ERC721
两种类型的代币,例子
ERC1155部署在opensea上:
通过ERC1155协议,模仿实现一个半同质化代币,一个项目有4种NFT会员卡,每个NFT会员卡有多个数量。
测试的合约源码 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 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 ("" ) {} mapping (uint256 => string) public _baseURI; function setBaseURI (uint256 _tokenId, string memory newuri ) public onlyOwner { _baseURI[_tokenId] = newuri; } 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); } 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); } }
部署脚本:
合约部署在测试网上,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 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
这样就实现了一个简单demo,一个项目方有4种NFT会员卡,每种会员卡NFT的数量有多个。
refs: