如果你觉得我说得不对,那就是你说得对:)


Share Dialog
Share Dialog
如果你觉得我说得不对,那就是你说得对:)

Subscribe to issmall

Subscribe to issmall
MimicShhans 是近期爆火的一款 NFT,由韩国的一位艺术家使用 OpenSea 的 ERC-1155 公共合约发行,计划发行总量为 10020,根据官网的铸造计划共分为三个阶段:
阶段一:共计铸造 700 个 Mimic Shhans NFT (已完成)
阶段二:每天铸造不定数量的 NFT,共计 9000 个,另外保留 1000 个 (已完成)
阶段三:20 个手绘版作为奖励(进行中)
由于 MimicShhans 使用的公共合约发行,所以目前市面上绝大多数的 NFT 分析平台都不支持分析其数据,所以对于 NFT 的持仓分布等情况一直是黑盒的。
项目起飞之前,我“零元购”了 80 个 MimicShhans NFT,由于担心成为一个冤种,我开始研究该 NFT 的链上数据及 Dune 清洗的数据,并通过 Dune 看板将其展示出来。
由于之前工作的原因,很早就接触了 Redash,而 Dune 正是基于 Redash 二次开发的,所以上手基本没有压力。但是由于 Dune 的数据表数量过于庞大并且相关资料并不详细,于是我开始通过关键词寻找可能满足我需求的数据表。
首先,通过 pg_tables 查询可能的模式(schema),关键词锁定为 opensea 和 nft:

幸运的是结果并不多,挨个看了一下模式名称,从中筛出 nft 和 opensea 两个模式。
然后,通过 pg_tables 查看这两个模式所包含的数据表,为什么用 pg_tables 查看呢?因为左侧的查询实在很不方便。

从结果可以看出 opensea 模式下的表基本是合约函数调用记录,而 nft 模式下只有 5 个表。“嫌疑人”范围锁定在了 opensea 模式下的某个函数调用表及 nft 模式下的 trades、trades_v2_beta 和 wyvern_data 表。
由于该 NFT 是从 OpenSea 发行的,于是我先从 opensea 模式下手。前文提到过,我“零元购”了一批 NFT,于是我翻看 OpenSea 的记录,此处以 MimicShhans #8320 为例。

共有 4 条动态,其中,Minted 和 List 是没有上链的,所以没有超链接;而 Transfer 和 Sale 其实对应了同一笔交易,点击超链接打开 Etherscan 查看交易详情。

点击 “Click to see More” 查看更多细节信息:

此处可以看到这笔交易调用了合约的 atomicMatch_ 函数,于是我回到 Dune 查找 opensea 模式下关于 atomicMatch_ 函数相关的数据表:

只查到了 opensea.WyvernExchange_call_atomicMatch_ 这个表,通过左侧查询框查询该表结构如下:

仅仅从表结构其实并不能很好的确定里面的内容,于是我查询了几条数据样本查看:

简单看了下数据,基本是没有解析的状态,如果不进行二次清洗、加工,不太可能拿来做看板的数据源。
于是我继续查看 nft 模式下的表,既然有 v2 那我就直接先拿 v2 版本下手了,于是我查看了 nft.trades_v2_beta 的数据结构:

单从数据结构上就觉得是它了,因为从字段名上可以看到 buyer、seller、nft_token_id 等解析后的数据。
查询了几条数据作为样本:

其中一笔的 tx_hash 为:\x0008512e06c1fd26a7484484400d07ee179fd95651ee9405c4d577828a50440c
打开 Etherscan 查看交易详情:

对照 Dune 的查询结果,可以确定:
seller 是 Tokens Transferred 对应的 From 地址;
buyer 是 To 地址;
nft_token_id 就是 Token ID;
original_amount 对应的是 Value,也就是转账的 Ether 数量,而 Ether 是 Ethereum 的主链币,并没有合约,所以 original_currency_contract 对应的 0x0;
nft_contract_address 对应的就是合约地址。
有了上述的调研之后,回过头来看我的购买记录,对应的数据如下:
seller:0xadf9e26e125d64dd1df6482d8f3a62f704122cc3
buyer:0xd89e373dc88503fdb3bbe34021fc13a6c9a2fcaa
nft_token_id:78691630486237452253407982334196552834116754498908990625475385096473963134977
nft_contract_address:0x495f947276749ce646f68ac8c248420045cb7b5e
根据以上信息构造查询:

查询到这条记录,说明之前的推测是正确的,使用 nft.trades_v2_beta 可以查到 Mimic Shhans NFT 的交易数据。
由于该 NFT 是通过公共合约(0x495f947276749ce646f68ac8c248420045cb7b5e)创建的,所以统计该合约的所有数据肯定是不准的。
于是我寄希望于通过 Token ID 获得一些线索,这里 Token ID 是个十进制的长整数(78691630486237452253407982334196552834116754498908990625475385096473963134977),我试着将其转换为十六进制:

从中可以看到前 42 位字符(去掉0x是40位字符)刚好跟 seller 的地址一致,应该是发行人地址, 而后面 0 隔开的两个数字可能跟编号、系列有关(仅仅是推测)。
于是构造查询:

获得 9040 条记录(其中有 32 条是重复数据),对 nft_token_id 进行去重后总计 9008 条记录:

这时由于还没有详尽的调研,所以对于 9008 这个数字我是持怀疑态度的,但是由于前几天刚刚发行了 10008 号 NFT,所以数据上似乎又有一丝的合理性。于是我翻看了官网,最终找到了铸造计划:

也就是证明了 9008 这个数字的合理性。
于是回过头去 OpenSea 查看 MimicShhans #9001 的动态:

没有链接,也就是没上链的状态,随后我又查看了 MimicShhans #10000 的动态:

也是没有上链的状态,随后我又用二分法查了一下,9001-9500 由 Shhan_Crowned 铸造,9501-10000 由 june0929 铸造。
这时我才意识到走了弯路,如果一开始就点开 MimicShhans #8320 动态里面 MimicShhans 的超链接就可以看到:

也就是说,初始 seller 就是艺术家的地址,而 Token ID 又是根据艺术家地址计算得出的。但是,如果作者有多个系列的作品,Token ID 就会混在一起。
不过在 MimicShhans 系列当前铸造的 NFT 里面暂时没有这个问题,因为这个地址只铸造了 MimicShhans 系列的 NFT。
至于 9001-10000 段的 NFT,我分析了几个 Token ID,没有发现如何跟作者的其他作品拆分开,也许就是中心化存储进行的归类吧。
通过上述调研,已经得到了当前已经上链的 NFT 的 Token ID,所以可以构造查询获得 MimicShhans 的所有交易数据:

为了方便使用,可以通过 with as 语句构造一个查询子句,减少重复查询和重复代码:

之后可以将 mimicshhans_trades 看作是一个数据表来使用,例如:交易额:

关于看板的其他 SQL 语句,可以在这里找到优化后的代码,此处就不一一列举了。
SQL 逻辑虽然写完了,但是运行效率是真的差,每个 SQL 的执行时间都在 1 分钟到 3 分钟,对于一个分析师来说是无法忍受的,于是我开始着手优化 SQL,首先查看 nft.trades_v2_beta 的索引有哪些:

从中可以看到:
nft_trades_v2_beta_platform_tx_hash_evt_index_trade_id_uniq_idx (platform, tx_hash, evt_index, trade_id)
nft_trades_v2_beta_platform_tx_hash_trace_address_trade_id_uniq (platform, tx_hash, trace_address, trade_id)
nft_trades_v2_beta_block_time_idx (block_time)
nft_trades_v2_beta_seller_idx (seller)
nft_trades_v2_beta_buyer_idx (buyer)
nft_trades_v2_beta_nft_project_name_nft_token_id_block_time_idx (nft_project_name, nft_token_id, block_time)
nft_trades_v2_beta_block_time_platform_seller_buyer_nft_project (block_time, platform, seller, buyer, nft_project_name, nft_token_id)
之前看板查询中使用到了 nft_contract_address、seller、nft_token_id 这些字段,其中,子句:

已经使用了索引 nft_trades_v2_beta_seller_idx,基本没有优化的空间了。
而外层的查询使用了 nft_contract_address、nft_token_id 字段,可以试着往索引 nft_trades_v2_beta_nft_project_name_nft_token_id_block_time_idx 上靠。根据之前的查询,可以获得 nft_project_name 为 OpenSea Collection,如果想使用索引就必须满足 nft_project_name = ‘OpenSea Collection’ 的合约地址只能是 0x495f947276749ce646f68ac8c248420045cb7b5e,于是,我花几分钟时间证明了自己的猜想:

更改后的代码及执行效果:

之前需要执行两分钟的代码,现在只需要两秒钟就可以达到同样的效果。
在使用 Dune 的过程中发现很多不方便的地方,于是我顺便做了一个工具看板。
上面的两个输入框(Schema Keyword、Table Keyword)用于模糊查找模式及表
下面的两个输入框(Schema Name、Table Name)用于精确查找表的结构及索引
通过这个看板可以快速的找到所需要的模式及表,以及翻看表结构及索引。
以上便是我制作看板的大致过程,如果你只想看数据,可以通过这个链接查看:
https://dune.com/issmall/mimicshhans
你可以通过这些方式找到我:https://linktr.ee/issmall
MimicShhans 是近期爆火的一款 NFT,由韩国的一位艺术家使用 OpenSea 的 ERC-1155 公共合约发行,计划发行总量为 10020,根据官网的铸造计划共分为三个阶段:
阶段一:共计铸造 700 个 Mimic Shhans NFT (已完成)
阶段二:每天铸造不定数量的 NFT,共计 9000 个,另外保留 1000 个 (已完成)
阶段三:20 个手绘版作为奖励(进行中)
由于 MimicShhans 使用的公共合约发行,所以目前市面上绝大多数的 NFT 分析平台都不支持分析其数据,所以对于 NFT 的持仓分布等情况一直是黑盒的。
项目起飞之前,我“零元购”了 80 个 MimicShhans NFT,由于担心成为一个冤种,我开始研究该 NFT 的链上数据及 Dune 清洗的数据,并通过 Dune 看板将其展示出来。
由于之前工作的原因,很早就接触了 Redash,而 Dune 正是基于 Redash 二次开发的,所以上手基本没有压力。但是由于 Dune 的数据表数量过于庞大并且相关资料并不详细,于是我开始通过关键词寻找可能满足我需求的数据表。
首先,通过 pg_tables 查询可能的模式(schema),关键词锁定为 opensea 和 nft:

幸运的是结果并不多,挨个看了一下模式名称,从中筛出 nft 和 opensea 两个模式。
然后,通过 pg_tables 查看这两个模式所包含的数据表,为什么用 pg_tables 查看呢?因为左侧的查询实在很不方便。

从结果可以看出 opensea 模式下的表基本是合约函数调用记录,而 nft 模式下只有 5 个表。“嫌疑人”范围锁定在了 opensea 模式下的某个函数调用表及 nft 模式下的 trades、trades_v2_beta 和 wyvern_data 表。
由于该 NFT 是从 OpenSea 发行的,于是我先从 opensea 模式下手。前文提到过,我“零元购”了一批 NFT,于是我翻看 OpenSea 的记录,此处以 MimicShhans #8320 为例。

共有 4 条动态,其中,Minted 和 List 是没有上链的,所以没有超链接;而 Transfer 和 Sale 其实对应了同一笔交易,点击超链接打开 Etherscan 查看交易详情。

点击 “Click to see More” 查看更多细节信息:

此处可以看到这笔交易调用了合约的 atomicMatch_ 函数,于是我回到 Dune 查找 opensea 模式下关于 atomicMatch_ 函数相关的数据表:

只查到了 opensea.WyvernExchange_call_atomicMatch_ 这个表,通过左侧查询框查询该表结构如下:

仅仅从表结构其实并不能很好的确定里面的内容,于是我查询了几条数据样本查看:

简单看了下数据,基本是没有解析的状态,如果不进行二次清洗、加工,不太可能拿来做看板的数据源。
于是我继续查看 nft 模式下的表,既然有 v2 那我就直接先拿 v2 版本下手了,于是我查看了 nft.trades_v2_beta 的数据结构:

单从数据结构上就觉得是它了,因为从字段名上可以看到 buyer、seller、nft_token_id 等解析后的数据。
查询了几条数据作为样本:

其中一笔的 tx_hash 为:\x0008512e06c1fd26a7484484400d07ee179fd95651ee9405c4d577828a50440c
打开 Etherscan 查看交易详情:

对照 Dune 的查询结果,可以确定:
seller 是 Tokens Transferred 对应的 From 地址;
buyer 是 To 地址;
nft_token_id 就是 Token ID;
original_amount 对应的是 Value,也就是转账的 Ether 数量,而 Ether 是 Ethereum 的主链币,并没有合约,所以 original_currency_contract 对应的 0x0;
nft_contract_address 对应的就是合约地址。
有了上述的调研之后,回过头来看我的购买记录,对应的数据如下:
seller:0xadf9e26e125d64dd1df6482d8f3a62f704122cc3
buyer:0xd89e373dc88503fdb3bbe34021fc13a6c9a2fcaa
nft_token_id:78691630486237452253407982334196552834116754498908990625475385096473963134977
nft_contract_address:0x495f947276749ce646f68ac8c248420045cb7b5e
根据以上信息构造查询:

查询到这条记录,说明之前的推测是正确的,使用 nft.trades_v2_beta 可以查到 Mimic Shhans NFT 的交易数据。
由于该 NFT 是通过公共合约(0x495f947276749ce646f68ac8c248420045cb7b5e)创建的,所以统计该合约的所有数据肯定是不准的。
于是我寄希望于通过 Token ID 获得一些线索,这里 Token ID 是个十进制的长整数(78691630486237452253407982334196552834116754498908990625475385096473963134977),我试着将其转换为十六进制:

从中可以看到前 42 位字符(去掉0x是40位字符)刚好跟 seller 的地址一致,应该是发行人地址, 而后面 0 隔开的两个数字可能跟编号、系列有关(仅仅是推测)。
于是构造查询:

获得 9040 条记录(其中有 32 条是重复数据),对 nft_token_id 进行去重后总计 9008 条记录:

这时由于还没有详尽的调研,所以对于 9008 这个数字我是持怀疑态度的,但是由于前几天刚刚发行了 10008 号 NFT,所以数据上似乎又有一丝的合理性。于是我翻看了官网,最终找到了铸造计划:

也就是证明了 9008 这个数字的合理性。
于是回过头去 OpenSea 查看 MimicShhans #9001 的动态:

没有链接,也就是没上链的状态,随后我又查看了 MimicShhans #10000 的动态:

也是没有上链的状态,随后我又用二分法查了一下,9001-9500 由 Shhan_Crowned 铸造,9501-10000 由 june0929 铸造。
这时我才意识到走了弯路,如果一开始就点开 MimicShhans #8320 动态里面 MimicShhans 的超链接就可以看到:

也就是说,初始 seller 就是艺术家的地址,而 Token ID 又是根据艺术家地址计算得出的。但是,如果作者有多个系列的作品,Token ID 就会混在一起。
不过在 MimicShhans 系列当前铸造的 NFT 里面暂时没有这个问题,因为这个地址只铸造了 MimicShhans 系列的 NFT。
至于 9001-10000 段的 NFT,我分析了几个 Token ID,没有发现如何跟作者的其他作品拆分开,也许就是中心化存储进行的归类吧。
通过上述调研,已经得到了当前已经上链的 NFT 的 Token ID,所以可以构造查询获得 MimicShhans 的所有交易数据:

为了方便使用,可以通过 with as 语句构造一个查询子句,减少重复查询和重复代码:

之后可以将 mimicshhans_trades 看作是一个数据表来使用,例如:交易额:

关于看板的其他 SQL 语句,可以在这里找到优化后的代码,此处就不一一列举了。
SQL 逻辑虽然写完了,但是运行效率是真的差,每个 SQL 的执行时间都在 1 分钟到 3 分钟,对于一个分析师来说是无法忍受的,于是我开始着手优化 SQL,首先查看 nft.trades_v2_beta 的索引有哪些:

从中可以看到:
nft_trades_v2_beta_platform_tx_hash_evt_index_trade_id_uniq_idx (platform, tx_hash, evt_index, trade_id)
nft_trades_v2_beta_platform_tx_hash_trace_address_trade_id_uniq (platform, tx_hash, trace_address, trade_id)
nft_trades_v2_beta_block_time_idx (block_time)
nft_trades_v2_beta_seller_idx (seller)
nft_trades_v2_beta_buyer_idx (buyer)
nft_trades_v2_beta_nft_project_name_nft_token_id_block_time_idx (nft_project_name, nft_token_id, block_time)
nft_trades_v2_beta_block_time_platform_seller_buyer_nft_project (block_time, platform, seller, buyer, nft_project_name, nft_token_id)
之前看板查询中使用到了 nft_contract_address、seller、nft_token_id 这些字段,其中,子句:

已经使用了索引 nft_trades_v2_beta_seller_idx,基本没有优化的空间了。
而外层的查询使用了 nft_contract_address、nft_token_id 字段,可以试着往索引 nft_trades_v2_beta_nft_project_name_nft_token_id_block_time_idx 上靠。根据之前的查询,可以获得 nft_project_name 为 OpenSea Collection,如果想使用索引就必须满足 nft_project_name = ‘OpenSea Collection’ 的合约地址只能是 0x495f947276749ce646f68ac8c248420045cb7b5e,于是,我花几分钟时间证明了自己的猜想:

更改后的代码及执行效果:

之前需要执行两分钟的代码,现在只需要两秒钟就可以达到同样的效果。
在使用 Dune 的过程中发现很多不方便的地方,于是我顺便做了一个工具看板。
上面的两个输入框(Schema Keyword、Table Keyword)用于模糊查找模式及表
下面的两个输入框(Schema Name、Table Name)用于精确查找表的结构及索引
通过这个看板可以快速的找到所需要的模式及表,以及翻看表结构及索引。
以上便是我制作看板的大致过程,如果你只想看数据,可以通过这个链接查看:
https://dune.com/issmall/mimicshhans
你可以通过这些方式找到我:https://linktr.ee/issmall
<100 subscribers
<100 subscribers
No activity yet