# 一个 Mimic Shhans 公共合约转独立合约的方案

By [issmall](https://paragraph.com/@icatsay) · 2022-08-31

---

最近由于工作上各种突发事件，导致本应该上周发的小作文拖到了这周。。。

* * *

当前 Mimic Shhans（以下简称 MS） 使用 OpenSea（Shared Storefront）公共合约发行，对于没有技术团队支持、没有背景的艺术家们来说，无疑是一个比较好的选择，只需要上传图片并进行一些配置就可以发行自己的 NFT。但当项目发展到一定的程度，则会成为制约项目发展的不利因素。

使用 OpenSea 公共合约发行的 NFT 本质上都是“中心化”的。这些 NFT 只能在 OpenSea 进行交易，倒不是说其他交易平台或分析平台存在技术或商务方面的问题，而是部分关键信息是基于中心化数据库维护的，例如：NFT 所属的专辑（collection）、各 NFT 的属性等等，其他平台显然是无法获取到的，获取不到自然也就无法计算各个项目的地板价、持仓用户数等信息。同时，也导致各 NFT 的知名度相对较低，价格自然也就上不去。（如果你觉得知名度很高，可能是因为你关注的圈子和社区的一致性太强了。。。）

所以，当项目使用 OpenSea 公共合约起步，并且发展到一定程度时，可以考虑切换到独立的 ERC-721 标准的合约，以便项目更健康、良性发展。

以下是我针对 MS 项目转换合约的方案，但同样适用于其他基于 OpenSea 公共合约的项目，仅供参考。

之前社区关于 MS 转换合约也进行过一些讨论，有一些方案，但都不太可行，原因如下：

1.  保留原公共合约项目如同分叉，发行量翻倍，而且可能造成社区分裂
    
2.  实际操作有难度，具体表现在如何获取持仓用户列表，是按时快照还是根据当时持仓情况加白名单？如何保证领取过的 NFT 不会被重复利用？如何阻止挂单成交或如何保证新购买用户的利益等等
    
3.  增加新元素对部分用户不公平，虽然都是黑猫，但各种元素之间是存在价差的，比如皇冠、鲨鱼等系列价格较高，而黄毛则留守地板等。新加入的元素可能导致部分用户损失
    
4.  NFT 中各种元素包括编号对于持有者可能具有特殊的意义，如果不保留也会带来问题
    

所以，比较合理的方案应该是在发行新 ERC-721 NFT 的同时应该销毁旧的公共合约 NFT，新的 NFT 会继承原 NFT 的所有属性包括编号。

具体来说，需要两个合约来完成转换的操作：ERC-721 合约和转换合约。其中，ERC-721 合约就是新的 NFT 合约；而转换合约相当于一个 DEX，用户通过转入旧的 NFT 置换新的 NFT。

用户操作步骤如下：

1.  用户登录合约转换网站，点击授权按钮，授权转换合约操作 OpenSea 公共合约所有资产
    
2.  网站列出用户持有的 MS NFT
    
3.  用户选择 NFT 进行转换
    
4.  完成所有的 NFT 转换后，点击取消授权按钮，解除授权
    

而转换合约的逻辑如下：

1.  转换合约将用户指定的 NFT 转到指定的地址（0xdead 或者作者发行地址），失败则回滚
    
2.  转换合约调用 ERC-721 合约铸造方法，铸造新的 NFT 并转到用户地址，失败则回滚
    

如果将所有旧的 NFT 转到作者发行的地址，待所有用户均完成转换后，作者可在 OpenSea 上删除该专辑（collection），但实际情况应该没有那么理想，毕竟之前有些被盗的 NFT 被冻结了。

实际操作中有个问题，OpenSea 公共合约的 token id 跟 MS 的编号并不是对应的，而在 ERC-721 合约里面，一般 token id 就是编号，需要维护一个公共合约 token id 与 MS 编号的映射关系表，而这个表最好是放在合约里面。但是，这将增加 ERC-721 合约的部署费用。

为了省去这部分费用，需要将映射关系放在合约外面，那么就会带来伪造的问题，即，我本来持有的是编号 1122 的 NFT，但是编号 8888 的 NFT 更贵，所以我通过伪造映射关系来铸造别人的 NFT。即便是网站调用合约时输入的都是正确的映射关系，也不能阻拦科学家直接调用合约，即便是合约不开源。为了解决这个问题，网站后端在向前端输出用户持有的 NFT 数据时，应该使用一个独立的私钥对用户地址、token id 及编号这三者进行签名并作为参数传递给合约，合约验证签名后执行转换操作。该私钥仅用于签名，对应的地址无需存有资产。

以上就是我的换合约方案，已经在 [Goerli](https://goerli.etherscan.io/tx/0x70b0bfe700f2c8a2d3c3bb0aa634fd8a106d3c1186799095f8b84877fa9cf26e) 测试网测试通过，相关合约及 DEMO 网站本周晚些时候会开源到 [Github](https://github.com/issmall/OpenSeaToERC721)。DEMO 网站和相关合约也将重新部署，之后大家可以在测试网测试该方案的可行性。（我不会前端，所以网站异常的糙）

当然，这个方案也有“缺陷”，转换操作需要用户将 OpenSea 公共合约授权给转换合约，可能会引来一批钓鱼网站围猎 MS 用户。

当前由于 OpenSea API 的特性，没有输出 OpenSea 公共合约的地址，所以，虽然有些用户经历了几次利用授权的钓鱼事件，但是 MS 系列 NFT 并没有被盗。有些同学认为是因为 ERC-1155 更安全，而实际是因为黑客为了利益最大化，会优先授权更值钱的 NFT 合约，而 OpenSea 公共合约因为接口没有输出合约地址，而成为漏网之鱼，并不是 ERC-1155 更安全或者不能盗。但在转换合约的时候，大家可能就没有那么幸运了，可能会有很多钓鱼网站来蹭热点；而转换之后，随着价格的提升，钓鱼事件可能就是家常便饭了。

* * *

**广告 & 吐槽**

最近跟几个小伙伴搞了个业余的项目，本来应该已经上线了，但是工作上突发事件太多，占用了太多业余时间，所以 delay 了，应该很快就会上线，敬请期待+关注+支持。。。

本来想加几个图来描述一下，但是。。。发现理解成本更高了，就去掉了。。。

牛市没出金，加上牛市买的期车在熊市兑现了。。。导致流动性危机。。。

最近工作原因错过了不少金狗，希望小伙伴们发财的时候记得带上我。。。嘤嘤嘤。。。

![](https://storage.googleapis.com/papyrus_images/415984161c1a89cdd9dd0b38ece84ae35ba60bc145b41f8dfaaa50657b9ab0ca.jpg)

---

*Originally published on [issmall](https://paragraph.com/@icatsay/mimic-shhans-2)*
