# ERC1155 - NFT 和标准代币共存

By [un.Block](https://paragraph.com/@un-block) · 2021-10-09

---

> ERC721 做不到的，ERC1155 可以

### ERC1155 的独特之处

[ERC1155](https://docs.openzeppelin.com/contracts/3.x/erc1155) 的独特之处在于它使用一次性通过一个智能合约来代表多种代币。

ERC1155 的 `balanceOf` 函数和 ERC20 与 ERC777 的有所不同，他有一个独特的 `id` 参数来代表你想查询的代币，就像 ERC721 一样。

但实际上 ERC1155 又与 ERC 721 略有不同：

*   在 ERC721 中，每个 `id` 代表的代币供应量要么是 0 要么是 1。ERC721 的 `balanceOf` 函数会返回一个钱包里有多少个 `id` 不同的代币。
    
*   在 ERC1155 中， `id` 所代表代币的供应量可以为任意数字。并且我们可以知道 `id` 所代表代币的数量。NFT 也是一种特殊的 ERC1155 代币。
    

得益于这种设计思路，当我们需要多种代币的时候，能够大大的节省 Gas（例如你要做一个炉石传说的 NFT，里面有各种卡牌），借助 ERC1155，我们能够地轻易的搭建整个生态系统。

### 批量化操作

由于全部状态都存在一个合约中，因此我们可以在一笔交易中进行多项代币操作，这样效率可以大大提高。

*   `balanceOfBatch` 一次性查询多个代币的余额
    
*   `safeBatchTransferFrom` 一次性转账多种代币
    

### 实现 ERC1155 的 NFT 和标准代币共存

如开头所说，在 ERC1155 中，一切都以代币形式存在，NFT 就是存量为 1 的代币，独一无二；标准代币是存量大于 1 的代币。

要达成上述目标，我们只需要修改在调用 `_mint` 函数是传入不同的数量参数，NFT 传入 1，标准代币传入大于 1 的数字。

我们先来看下`_mint` 函数：

![](https://storage.googleapis.com/papyrus_images/814951e3efb39b9945d0606dd3ca197255a7c6ee0d90c7ed2afb88b2c4330bea.jpg)

*   `account`: 代币存放地址
    
*   `id`: 代币序号
    
*   `amount`: 代币数量（关键点）
    
*   `data`: 额外数据
    

然后我们来看看 OpenZepplin 给的示范代码：

![](https://storage.googleapis.com/papyrus_images/5f15de1b16d5ab758e6b292dafa5d24418bda9fb9ee12cbce4496f2c8b4155be.jpg)

在上述代码中，我们可以看到 `GOLD`、`SILVER` 并不唯一，属于标准代币，而 `THOR_HAMMER` 只有 1 把，属于 NFT 代币。通过控制存量，我们就能实现 NFT 和标准代币的共存。

还有一个值得注意的地方就是：在 ERC1155 中是不存在小数的，因此每一个代币都是独立不能分割的单位。

### 相关阅读：

*   [_EIPS-1155_](https://link.zhihu.com/?target=https%3A//www.notion.so/un-Block-2021-17-Hermez-ERC1155-35dfc122b2554ddd96824207fd17878d)
    
*   [_OpenZepplin: ERC1155_](https://link.zhihu.com/?target=https%3A//docs.openzeppelin.com/contracts/3.x/erc1155)
    
*   [_Token Standards: ERC20 vs ERC721 vs ERC1155_](https://link.zhihu.com/?target=https%3A//medium.com/coinmonks/token-standards-erc20-vserc721-vs-erc1155-3106f1e3f2f3)

---

*Originally published on [un.Block](https://paragraph.com/@un-block/erc1155-nft)*
