学习如何使用Dune Analytics,适合完全的 Dune 和 SQL 初学者。
- 原文链接:https://web3edge.io/guides/dune-analytics-beginners-guide/
- 译文出自:登链翻译计划
- 译者:翻译小组 校对:Tiny 熊
- 本文永久链接:learnblockchain.cn/article…
Dune可能是目前向公众提供的最强大的区块链数据分析工具,而最棒的是:它还是免费的! 通过Dune,你可以通过一个公共数据库近乎实时地访问区块链数据,你可以通过Dune的网站使用SQL查询。
这是一个很大的能力。
Dune在将区块链数据添加到他们的数据库之前对其进行解码,这意味着你不需要自己弄清字节码通信。相反,你可以使用Dune的数据集浏览器来浏览数据集、特定的智能合约、事件或调用
随着Dune最近宣布他们的V2引擎,性能提高了10倍,现在是时候让你学习如何使用Dune了。
在本指南中,你将学习:
在这个手把手教程中,我们将为Pooly NFT系列建立以下仪表盘的查询,本文较长,做好准备,学习完收获很大。
通过 https://dune.com/phillan/pooly-nft-by-0xphillan 截图
让我们开始吧!
第一部分:Dune的概述和功能
第二部分:建立你的第一个查询
第三部分: 整理仪表板
结束
当你第一次在Dune.com上打开Dune网站时,迎接你的是下面的窗口。这个窗口的顶部有一个视图切换,可以让你循环浏览仪表盘(Dashboard)、查询(Queries)和向导(Wizards),然后是详细的视图区,在这里你可以看到左边的仪表盘、查询和向导(用户)列表,以及右边的一些搜索相关设置。
Dune.com登陆页
仪表盘是一个查询的集合,它被安排成一系列的图表、展示面板和其他信息,给用户提供关于特定兴趣领域的数据。下面,我打开了一个由传奇人物@hildobby制作的以太坊仪表盘。在这里,我们可以看到从Dune的数据库中提取的各种数据,以总和和时间序列图的形式显示。
截图来自:https://dune.com/hildobby/Ethereum-Overview
在Dune中,每个仪表板都是公开的。这意味着你或其他人建立的所有东西都可以被任何人查看和分叉(即复制)!这大大减少了仪表盘的数量。这大大减少了仪表板的创建时间,并让你从其他用户的查询中学习。
如果你还记得,我提到过仪表盘是查询的集合。如果你点击任何一个仪表盘元素的标题,你就会进入到该图表的SQL查询。
上面的以太坊 Dashboard的查询编辑器代码例子。
在这里,我们可以看到屏幕上的两个主要元素:查询(顶部;黑框)和输出图表(底部)。这就对了:无论你点击哪个区块或图表,你都可以看到用户是如何创建该图表的!
如果你想把整个仪表盘或者只把图表的查询保存到你自己的账户中,你可以点击右上方的 "分叉(Fork)",屏幕上的所有内容都会被复制到一个新的窗口中,在把视图保存到你的账户之前,你可以在其中进行编辑。
Ethereum价格查询,截图来自 https://dune.com/queries/663019/1231425
让我们分叉以太坊价格图表! 一旦你在一个查询上按下 "Fork",你就会进入到查询编辑器,前面的代码已经被复制进去了!
让我在这里向你介绍一下屏幕上的各种元素:
查询的位置和名称 -- 一旦你点击保存,名称就可以改变。
数据集浏览器 -- 搜索一个特定的数据集
查询窗口--在这里输入你的SQL查询
可视化选择器--选择是否查看查询结果、折线图或创建一个新的可视化视图。
运行 - 运行查询窗口中的查询
结果/可视化--看到查询结果或你用查询结果创建的可视化效果
保存--保存你的(分叉的)查询!
Dune查询编辑器的概述
让我们仔细看看数据集浏览器。在数据集浏览器中,有六个功能区:
Dune数据集浏览器的概述
在数据集选择中,你可以选择你要解析的链。选择 Dune Engine V2 (Beta)
可以让你使用Dune的最新改进,包括多链查询和10倍的性能提升。
数据集浏览器中的数据集选择选项
如果你选择了另一条链,你的类别选择(上图中的第3-6项)就会消失,取而代之的是你可以交互的合约调用和事件的列表。
选择 1. Ethereum
时的数据集浏览器
在搜索栏中,你可以输入你的搜索参数,Dune会在所有包含该关键词的表格中进行搜索。
注意:Dune Engine V2和旧的搜索功能以不同的方式返回结果。旧的搜索返回一个所有结果的列表,而Dune Engine V2返回一个嵌套的结果列表。我们将使用V2引擎!。
截图:
1. Ethereum
和7.Dune 引擎V2(测试版)
搜索结果的比较
如果你点击进入原始区块链数据,你可以很容易地找到Dune支持的各种区块链的查询,在一个嵌套的数据结构中,你可以首先挑选你的原始表,然后从那里挑选你想进一步调查的特定表列。在每个层次的嵌套中,你还可以选择过滤你要寻找的特定搜索结果。
Dune Engine V2 (beta) 原始区块链数据概述
这是一个非常快速和方便的方式来获得高水平的区块链数据。
在这里,你会发现已经被Dune解码的项目。解码的项目是指Dune团队将项目拆开,贴上标签,并放入表格,以便用户对某些数据有一个简单和标准化的参考。
你会注意到,同样,搜索结果是嵌套的。在最高层,有你可以搜索的项目,在较低层,你可以过滤该项目中的特定智能合约,最后我们得到了由该智能合约生成的各种表格。如果你点击任何一个表,你会看到一个列表,就像在原始区块链数据中一样。
Dune 引擎V2(测试版 )解码项目概述
抽象可以被认为是定制的表格,它连接和组合各种查询和数据片段,形成一个独特的表格。抽象帮助用户更容易地查询他们正在寻找的特定数据,而不需要手动组合各种数据片段的麻烦。
一般来说,抽象可以分为两个主要类别:
从抽象子菜单中,我们可以看到一个抽象列表,其中的标签说明了该抽象是针对领域还是针对项目的。
Dune引擎V2(测试版)的抽象概念概述
社区部分可以被认为是抽象部分的延伸,但数据的汇总是由Dune社区成员提供的。
你可能想知道为什么社区部分只有一个条目("flashbots")-- 那是因为Dune Engine V2刚刚发布,随着时间的推移,我们可以期待看到越来越多的由值得信赖的社区成员建立的社区数据集。
Dune引擎V2(测试版)社区概述
在下面的插图中,你可以看到截至Dune Engine V2发布时,Dune内部的数据汇总:四个主要的数据类别是原始区块链数据、解码项目、抽象和社区,它们以表格的形式保存了各种区块链的数据,可以保存各种数据类型。
Dune引擎V2(测试版)数据浏览器中的标签概览
让我们继续,先保存这个查询。在你点击保存后,有几件事会发生。首先,你会被要求给你的查询一个名字。
弹出保存查询对话框
一旦你选择了一个名字,你会注意到(1)查询的位置和名字已经更新为你选择的名字;(2)你的查询正在运行。这意味着Dune正在从他们的数据库中获取最新的数据,该数据库会定期更新各种区块链的最新数据。
一旦查询运行完毕,你会看到你的查询结果(3)。
分叉查询的概述
在这里,如果你点击(1) "查询结果(Query result)"、"折线图(Line Chart)" 或 ""新的可视化" 中的任何一个,(2)对你的选择的设置,结果/可视化框就会更新,同时出现在它下面的(3)。这里你还有一个 “添加到仪表盘(Add to dashboard) ”的按钮,可以快速将你的查询结果或可视化添加到新的或现有的仪表盘中--就像@hildobby之前的以太坊仪表盘一样!
查询结果和可视化部分
如果你点击(1)右上方的圆圈,然后点击(2) "我的查询",你将打开你的账户的查询列表。
导航到你的查询
查询列表包括你在账户中保存的所有查询。在下面的屏幕截图中,我们可以看到最新创建的查询。
我们的查询列表,顶部保存了最新的查询
恭喜你,你已经分叉并保存了你的第一个具有可视化的查询!。
分叉(fork)是一种Dune的超级能力,它可以帮助你基于之前建立查询向导(是的,你现在也是一个向导!)建立查询,轻松而快速地创建新的查询。你可以结合多个分叉的查询来建立你自己的仪表板
让我们亲自动手,从头开始建立一个仪表盘--查询和可视化的集合,而不通过分叉。这将教会我们为特定项目寻找正确的区块链细节,以及教你SQL基础知识。
本部分的目的是教你:
但首先,我们需要决定仪表盘要做什么。Pooly NFT by the Pool Together DeFi协议是很好的第一步。
Pooly NFT的铸币页面,来自:https://mint.pooltogether.com/
如果我们在Dune上搜索 "Pooly",肯定可以找到一些由社区创建的Pooly NFT追踪器。
在Dune.com上搜索Pooly的结果
我们可以点击由@0xbills创建的Pooly dashboard,点击 "Fork",然后从那里开始工作......
0xbills通过https://dune.com/0xbills/Pooly-NFT
然而,如果我们从头开始建立它,我们就可以学习如何成为一个区块链侦探并学习一些SQL! 因此,我们将从头开始建立我们自己的。
首先,让我们决定在仪表板上想要什么图表。让我们重建Pooly在他们的主页上建立的视图! 仔细看看下面两个截图,我们可以看到一些基于链上数据的指标。
Pooly NFT登陆页面,带有资金追踪器。来源:https://mint.pooltogether.com
Pooly NFT排行榜。来源: https://mint.pooltogether.com/
Pooly NFT铸造的选择和供应。来源:https://mint.pooltogether.com/
我们可以看到:
筹集的资金与和ETH计价的融资目标的对比
筹集的资金与以美元计价筹资目标的对比
支持者总数(购买Pooly的独立地址数)。
排行榜,包括地址、每个地址购买的NFT数量和花费的ETH总额,按降序排列
三种NFT类型的最大发行量和剩余发行量
厉害了! 但这些只是时间上的一个快照。让我们也给自己一个挑战:
就目前的情况来看,我们不能像Pooly网站那样建立视图,但我们可以捕获同样多的数据(甚至更多!)来建立我们的仪表板。
在我们开始研究Dune之前,我们需要找到正确的信息。从网站上我们可以知道PoolTogether正在销售三套NFT。
Pooly是通过一份合约,还是通过三份不同的合约出售这三套NFT?
让我们前往Etherscan,看看是否能找到与Pooly有关的智能合约。打开Etherscan.io后,输入 "Pooly",看看这些智能合约的所有者是否在Etherscan注册了它们。
在Etherscan上搜索Pooly
确实如此! 有三个智能合约,可能分别对应于三个NFT系列。此外,我们现在知道,每个Pooly都是一个ERC721代币。
打开这三个系列的每一个,点击悬停在地址上的复制图标,复制智能合约的地址。在页面的底部,我们也可以看到所有最近的交易,这对以后的bug排查会有帮助。
通过Etherscan找到Pooly合约地址, 来源:https://etherscan.io/token/0x90B3832e2F2aDe2FE382a911805B6933C056D6ed
我们将需要这些智能合约地址来从Dune中提取正确的数据,它们是我们所有查询的基础。
0.1ETH的Pooly支持者合约:
0x90B3832e2F2aDe2FE382a911805B6933C056D6ed
1.0 ETH Pooly律师合约:
0x3545192b340F50d77403DC0A64cf2b32F03d00A9
75 ETH Pooly 法官合约:
0x5663e3E096f1743e77B8F71b5DE0CF9Dfd058523
首先,导航到dune.com,点击屏幕右上方的 "新查询"。
创建一个新的查询
这将打开查询编辑器,然后就可以开始处理我们的查询了!
新的查询窗口
首先,在左上方将 7.Dune Engine V2(Beta)
切换到 1. Ethereum
。Pooly部署在以太坊上,因此我们只需要以太坊数据来进行这个查询。另外,1.Ethereum
中的表比Dune Engine V2更成熟,后者才刚刚进入测试阶段。
对于我们的第一个查询,我们将建立一个展示面板,显示以ETH计价的募集资金。要做到这一点,请将以下代码复制到Dune的查询字段中,并按 "运行"(或CTRL+Enter)。
select SUM("value"/1e18) from ethereum.transactions
where "to" = '\x90B3832e2F2aDe2FE382a911805B6933C056D6ed'
or "to" = '\x3545192b340F50d77403DC0A64cf2b32F03d00A9'
or "to" = '\x5663e3E096f1743e77B8F71b5DE0CF9Dfd058523'
上面的代码是一个SQL查询,它通过Dune的数据库解析,以获取我们要求的特定数据。你可以把Dune的数据库想象成各种表的集合,每个表都包含你可能想要提取的特定信息。使用SQL,你可以:
为了说明上述情况,让我们逐块运行上述代码。将下面的代码复制到Dune的查询编辑器中并运行它。
select * from ethereum.transactions
where "to" = '\x3545192b340F50d77403DC0A64cf2b32F03d00A9'
你会得到一个有很多信息的大表。
使用*命令返回表的所有列
现在让我们来浏览一下SQL代码:
SQL代码的分解
这段代码说的是 "从ethereum类别内的交易表中选择所有列,其中to列的值是\x3545192b340F50d77403DC0A64cf2b32F03d00A9"或者用白话说:给我看一张包含所有与Pooly2(1ETH)智能合约交互的表格。
你不需要运行查询来查看表内的列。数据浏览器可以让你通过其巧妙的搜索功能探索各种表头:
使用数据浏览器搜索 "以太坊" 中的表。
我们可以完全删除第3行,以去除过滤器,然而,这将返回一个巨大的表,查询将需要很长的时间来完成。你的查询越精确,运行速度就越快!
因为我们只想返回筹集的资金,我们不需要所有的列。因此,让我们调整代码,只抓取 value
列:
select "value" from ethereum.transactions
where "to" = '\x3545192b340F50d77403DC0A64cf2b32F03d00A9'
现在我们只有一个 value
列,而不是之前看到的许多列:
返回 "value"列中的所有条目
然而,你可能会注意到,这些值似乎相当大。这是因为它们是以Wei为单位,而不是以ETH为单位! 为了解决这个问题,我们可以简单地对 value
列应用一个算术运算。
select "value"/1e18 from ethereum.transactions
where "to" = '\x3545192b340F50d77403DC0A64cf2b32F03d00A9'
将 "value"列的面额从Wei转换为ETH
这看起来好多了! 1e18在SQL中与10^18相同,我们只是告诉Dune将这个数字除以1,000,000,000,000,000,这样我们就可以看到以ETH为单位的价值,而不是Wei。
因为我们只想得到总价值,而不是价值列表,所以我们可以用SUM()语句将 "value"/1e18包起来。
select SUM("value"/1e18) from ethereum.transactions
where "to" = '\x3545192b340F50d77403DC0A64cf2b32F03d00A9'
使用SUM()将
value
列中的所有条目合并为一个总和。
太棒了,我们现在可以看到在Pooly2上花费的ETH总数了, 由于我们想得到所有三个Pooly NFT智能合约的总花费,我们需要再增加两行来包括其他智能合约的细节。
select SUM("value"/1e18) from ethereum.transactions
where "to" = '\x90B3832e2F2aDe2FE382a911805B6933C056D6ed'
or "to" = '\x3545192b340F50d77403DC0A64cf2b32F03d00A9'
or "to" = '\x5663e3E096f1743e77B8F71b5DE0CF9Dfd058523'
最终输出,参考 https://dune.com/queries/882266
or
命令与 where
命令协同工作,指定在过滤 to
列中的值时,如果是或的关系应该考虑,或是第一个值或第二个值或第三个值。
我们现在看到,总共有773.7个ETH花在了所有三个Pooly合约上。棒极了,让我们去Pooly网站看看这是否正确。
将我们的成果与Pooly NFT页面上的官方数据进行比较。
在Pooly网站上,我们看到776.5个ETH--祝贺你实现了目标 但是,哦,不,还有2.8个ETH的差距! 嗯--这没什么可担心的。Dune会定期同步区块链数据。而由于他们同步到数据库的数据集非常庞大,所以需要一些时间。我们可以期待数据在未来一两个小时内被刷新。
现在我们的查询已经完成,我们需要设置一个展示面板(counter),以便稍后在我们的仪表板上显示这个。在查询结果框下面,点击新的可视化,在出现的下拉菜单中点击 "展示面板"。
为我们的查询添加一个展示面板
最后,点击 "添加可视化"。
在查询中添加可视化的展示面板
一个展示面板会出现,如果你向下滚动,你会看到各种设置。只需根据你的喜好调整设置即可。
可视化标签和标题设置
完成后,点击(1)添加到仪表盘(Add to dashboard)
,并选择(2)新仪表盘
。然后(3)给你的仪表板起个名字,(4)点击 保存仪表板
。你的新仪表板将出现在你的仪表板列表中。在这里,点击(5) 点add
添加你想要可视化的仪表板。一旦添加,标签将从 add
变为 added
。
在仪表盘上添加一个可视化信息
如果你在这个子菜单中点击你的仪表盘名称("Pooly NFT by 0xPhillan"),你会进入一个显示有跟踪器的仪表盘。
添加了可视化的仪表板
好极了!
一旦我们完成了所有查询的设置,我们将回到编辑仪表板。
我们有两种方法可以处理这个问题。
如果我们看一下Etherscan上的智能合约,我们可以看到776.5ETH中的很大一部分已经被移出了智能合约,截至发稿时,Pooly NFT智能合约中还剩下299.2ETH。
Pooly1/2/3智能合约在Etherscan.io上的ETH余额
如果我们看一下之前的Pooly网站截图,776.5个ETH的价值为1,411,249美元(1,817美元/ETH),暗示着可能Pooly智能合约的所有者将资金作为ETH保留,而不是兑换为美元。
最终,很难说Pooly采取的是哪种方法,但对美元价值的两种方法都很有趣。
所以......让我们同时创建这两个数据吧
对于这个问题,我们将使用之前的代码作为基础,并加入一些额外的行来获得当前的美元价值。
首先,分叉我们刚刚创建的查询:
分叉先前的查询
然后调整你的代码,使其看起来如下:
select SUM("value"/1e18) * (
SELECT "price" FROM prices.usd
WHERE "symbol" = 'WETH'
AND "minute" < now() - interval '1 hours'
ORDER BY "minute" DESC
LIMIT 1
)
from ethereum.transactions
where "to" = '\x90B3832e2F2aDe2FE382a911805B6933C056D6ed'
or "to" = '\x3545192b340F50d77403DC0A64cf2b32F03d00A9'
or "to" = '\x5663e3E096f1743e77B8F71b5DE0CF9Dfd058523'
你会注意到,我们在SUM("value"/1e18)命令之后添加了一个乘法运算符*
,以及一个大的代码块。
在Dune中,你可以高亮显示你的查询的特定部分,并通过点击 运行选择(Run selection)
只运行该部分。让我们(1)只选择括号内的行,(2)运行该选择。
基于你选择的查询的一部分,你可以只运行所选择的部分。 https://dune.com/queries/883725
在查询结果中,你会看到WETH的最新美元价格! 我们在这里将WETH的最新价格与筹集的ETH数量相乘,从而得到美元的价值。
让我们来分解一下这个代码块:
前面代码的分解
为了更好地理解这段代码,让我们对我们的查询做一些小调整。(1)将"price "替换为 *
(会返回所有列),(2)只选择第2至5行的代码,然后(3)运行选择。
对前一个查询进行小幅调整后再运行
在查询结果中,你将看到由五列组成的完整表格。首先,让我们检查一下Etherscan.io中的合约地址:
0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
在Etherscan.io上的ETH智能合约
这个智能合约控制着以太坊区块链上的WETH资产。很好! 现在我们知道了之前截图中显示WETH美元价格的表格的来源。
让我们把注意力转移到之前的表格上。
之前的查询结果表
在这里,我们有一个名为 minute
的列,跟踪每分钟的ETH兑美元的价值。由于我们将查询限制为 interval -'1 hours'
,我们只得到最近一小时的数据。因为就我们的目的而言,我们实际上只需要最新的数据条目,把这个查询限制在最后一个小时,可以大大加快查询的速度。例如,你也可以把它改为 1 days
、3 days
或 1 weeks
,以获得更多的历史数据。
这里重要的是,列的名称是 "minute",因此我们的查询指的是 minute
列,不能误认为是与时间有关的命令。
让我们把代码恢复到本部分开始时的样子,并运行查询:
结果是当前被转账到Pooly1、Pooly2和Pooly3智能合约的ETH 可换取美元价值。
为此我们将再次使用一个展示面板,所以向下滚动,(1)点击从我们之前的查询中分叉出来的展示面板,(2)调整数据源,(3)改变标签。
展示面板的视觉效果 https://dune.com/queries/883725
一旦完成,记得保存并添加到我们的仪表板。
保存查询并将可视化添加到我们以前的仪表板上
添加完毕后,它看起来就像下面的截图。别担心,在本指南的最后,我们会把它整理好。现在,不要担心它的外观!
添加了第二个查询面板
这个查询会比较复杂,因为我们必须查询两个表,并将结果结合起来。具体来说,我们将不得不获得单个交易,并使用交易时的ETH价格转换每个交易的ETH价值。
同样,让我们首先分叉之前的查询,为下一个查询做准备:
分叉之前的查询 https://dune.com/queries/883725
从分叉的代码中,我们要做以下工作:
with poolyTransactions as
(
select
block_time,
value/1e18 as value_eth
from ethereum.transactions
where "to" = '\x90B3832e2F2aDe2FE382a911805B6933C056D6ed'
or "to" = '\x3545192b340F50d77403DC0A64cf2b32F03d00A9'
or "to" = '\x5663e3E096f1743e77B8F71b5DE0CF9Dfd058523'
)
select
sum(value_eth * price)
from poolyTransactions tx
left join
(select minute, price from prices.usd
where symbol = 'WETH' and minute > '2022-05-01')
as prices on date_trunc('minute', block_time) = minute
使用购买NFT时的ETH-USD汇率进行查询 https://dune.com/queries/884492
如果我们在这里运行这段代码,我们会看到收到的美元价值是1,400万美金。
让我们把这段代码分解成三个部分:
将查询分解成三个部分
第1部分
在这里,我们建立了第一个表,在这里所做的是创建一个辅助表,以便后面引用它。我们称之为 "poolyTransactions",它将保存来自ethereum.transcations表中的block_time和value_eth(用wei除以10^18转换为ETH的值,我们给它一个自定义的名字)。对于这个表,我们过滤了三个Pooly地址。
这里逐行解释:
poolyTransaction
的辅助表,其属性如下第2部分
这就是我们创建输出表的地方。你会注意到,我们正在从 poolyTransactions(我们在第 1 部分中创建的辅助表)建立一个表,引用了一个我们还没有定义名称的 price
列。事实上,Price 是在第19行才定义的。这是有可能的,因为我们将poolyTransactions与第3 部分中prices.usd表中的某些输出相连接。因此,从本质上讲,我们正在使用我们的辅助表poolyTransactions以及我们在下一 部分中从price.usd建立的表来创建一个表。
第3部分
在这里,我们定义一个要与另一个表连接的表。通过 left join
关键字,我们可以做到这一点。
block_time
列,并将其截断为分钟,即删除所有非分钟的其他数据(例如,秒、毫秒等)。prices.usd 表已经被截断为分钟,所以这里不需要进一步转换。然后,price.usd中的分钟列与我们辅助表中的分钟列相匹配,因此正确的价格是从price.usd中分配到poolyTransactions中相应的分钟时间戳。在数据集浏览器中查看price.usd表的分钟列
为了更好地展示第三部分的内容,我重新组织了部分内容,使其更容易理解。
left join 命令的每一步的可视化
(1)创建poolyTransactions表,然后(2)告诉SQL将其与另一个表连接起来,(3) 从 price.usd表中 定义 minute和price 列 , (4)被连接到左边的表poolyTransactions上,使用分钟的时间作为映射变量。为了连接表,两个表必须有完全相同的条目,如果我们将block_time变量截断为分钟,我们就可以在两个表之间创建匹配的分钟。(5) poolyTransactions表被更新为包括price列,同时价格匹配到相应的日期。
从这里,我们简单地查询加入的poolyTransactions表,并将每一行的ETH的value_eth和价格相乘的结果相加。
现在添加一个展示面板,保存并添加到仪表盘上
在查询中添加一个可视化的展示面板
将展示面板可视化设置并添加到仪表板上
展示面板可视化添加到仪表板上
对于我们的下一个查询,我们要计算购买Pooly NFT的唯一地址(即支持者总数)。这意味着,即使一个地址在所有三种Pooly类型中购买了多个Pooly,也应该只被计算一次。
为此,让我们首先打开我们的第一个查询,分叉它,并记得也要保存它。
分叉第一个查询 https://dune.com/queries/882266
在这里,我们只需改变第一行。
select COUNT(DISTINCT "from") from ethereum.transactions
where "to" = '\x90B3832e2F2aDe2FE382a911805B6933C056D6ed'
or "to" = '\x3545192b340F50d77403DC0A64cf2b32F03d00A9'
or "to" = '\x5663e3E096f1743e77B8F71b5DE0CF9Dfd058523'
Unique Pooly 支持者查询 https://dune.com/queries/887079
COUNT变量计算所有的交易,而DISTINCT关键字确保每个独特的条目只被计算一次。我们得到的结果是4660个独特的支持者。如果我们将其与Pooly网站上的独特支持者进行比较,我们会发现它们非常接近。
Pooly实时支持者数字,来源:https://mint.pooltogether.com/
这表明我们的查询是正确的,因为Dune的数据库刷新和最新的区块链状态之间有一点滞后。
最后,改变展示面板的可视化,并再次添加到仪表板。
调整展示面板的可视化设置并添加到仪表板上
展示面板被添加到仪表板上
接下来,让我们建立一个排行榜,包括地址、每个地址购买的NFT数量和花费的ETH总量,按降序排列。
再次,让我们分叉之前的查询,这样我们就可以避免重新输入过滤的地址。记住在继续之前保存这个新的查询。
看一下排行榜,有三条信息是我们需要的。首先是购买者的地址,然后是购买的NFT数量,最后是购买所有NFT所花费的ETH金额。
Pooly排行榜上的栏目。来源:https://mint.pooltogether.com/
这里我们看的是购买的NFT,而不是持有的NFT。完全有可能有人购买了(铸币)NFT,然后把它转移到安全的钱包里,或者在后来转卖。我们只对首次购买(铸币)感兴趣。
我们使用下面的查询来实现这一点。
with poolyTransactions as
(
select
"from",
hash,
value/1e18 as value_eth
from ethereum.transactions
where "to" = '\x90B3832e2F2aDe2FE382a911805B6933C056D6ed'
or "to" = '\x3545192b340F50d77403DC0A64cf2b32F03d00A9'
or "to" = '\x5663e3E096f1743e77B8F71b5DE0CF9Dfd058523'
)
select
"from", nfts_purchased, value_eth
from poolyTransactions
left join
(Select evt_tx_hash, COUNT("tokenId") as nfts_purchased
From erc721."ERC721_evt_Transfer"
Where (contract_address = '\x90B3832e2F2aDe2FE382a911805B6933C056D6ed'
or contract_address = '\x3545192b340F50d77403DC0A64cf2b32F03d00A9'
or contract_address = '\x5663e3E096f1743e77B8F71b5DE0CF9Dfd058523')
and "from" = '\x0000000000000000000000000000000000000000'
group by 1)
as nfts
on evt_tx_hash = hash
ORDER BY 3 desc
Pooly排行榜表 通过 https://dune.com/queries/887141
你会注意到,这里与 以购买时ETH价值筹集的美元资金
中的查询非常相似,这是因为我们使用了相同的方法:我们首先在poolyTransactions表中收集交易数据,然后在其上留下一个具有共同映射值的第二个表。
在这里,对于第二个表,我们使用erc721. ERC721_evt_Transfer
表,这是Dune维护的一个抽象,跟踪以太坊上所有的NFT转移。如果我们使用数据集浏览器,输入 erc721
。并滚动到 "ERC721_evt_Transfer",我们可以看到包含在该特定表中的所有内容。我们也可以只选中显示第二个表的命令,看看输出结果会是什么。
运行选中的代码, https://dune.com/queries/887141
由于我们只想要智能合约铸造的NFT,我们必须指定 from
地址为空地址。在以太坊上,所有的NFT都是从空地址铸造的。通过计算每笔交易的 tokenId
的数量,我们可以计算每笔交易铸造的NFT的总数。
你还会注意到过滤的定义方式有一些特别的地方。前三个过滤器现在被括在括号里,而最后一个过滤器则在括号外。
大括号决定了执行和/或过滤命令的顺序,就像在SQL中执行算术命令时一样。如果我们不把前三条语句括起来,那么和条件就只适用于最后一个过滤设置。
没有使用圆括号的例子
由于我们希望from null address过滤器适用于前面过滤器的所有结果,所以我们需要加上括号。
最后,由于我们使用的是 COUNT
命令,需要指定用哪一列来计算这些结果(也就是说,用什么变量来计数)。为此,我们使用 group by
命令,表示我们要将 tokenId
的计数分组到表中的第一列,也就是 evt_tx_hash
。
先前我提到,我们需要一个共同的映射值来将这第二个表映射到交易表。在这里,我们使用交易哈希值将每笔交易购买的NFT数量映射到我们的poolyTransactions表中,这次我们也要求使用交易哈希值。所以最终,我们将erc721. ERC721_evt_Transfer
表(我们命名为 nfts
)的交易哈希值映射到我们的poolyTransactions表中,其中只包括用于购买poolys的交易。
输出结果是一个包括购买者地址、购买的NFT总数以及花费的ETH总价值的表格。
最后,我们告诉Dune "ORDER BY 3 desc",这意味着我们输出表的第三列应该以降序排列。
图示
ORDER BY 3 desc
命令, 通过 https://dune.com/queries/887141
棒极了! 我们的排行榜已经完成了。让我们把它与Pooly NFT网站上的排行榜进行比较。
比较Dune查询排行榜和Pooly网站的排行榜。
并非所有的数字都是相同的,但从这个列表中我们可以看到,一些地址、购买的NFT和花费的ETH总量的数字是相同的。这又是一个Dune和实时区块链数据之间的同步时间问题,没什么好担心的。
记得保存你的查询并将其添加到仪表板。
不使用erc721. ERC721_evt_Transfer
表,我们也可以使用Dune团队整理的poolysupporter. PoolyNFT_call_mintNFT
解码表。
with poolyTransactions as
(
select
"from",
hash,
value/1e18 as value_eth
from ethereum.transactions
where "to" = '\x90B3832e2F2aDe2FE382a911805B6933C056D6ed'
or "to" = '\x3545192b340F50d77403DC0A64cf2b32F03d00A9'
or "to" = '\x5663e3E096f1743e77B8F71b5DE0CF9Dfd058523'
)
select
"from", nfts_purchased, value_eth
from poolyTransactions
left join
(Select call_tx_hash, `_numberOfTokens` as nfts_purchased
From poolysupporters.`PoolyNFT_call_mintNFT`
where contract_address = '\x90B3832e2F2aDe2FE382a911805B6933C056D6ed'
or contract_address = '\x3545192b340F50d77403DC0A64cf2b32F03d00A9'
or contract_address = '\x5663e3E096f1743e77B8F71b5DE0CF9Dfd058523'
)
as nfts
on call_tx_hash = hash
ORDER BY 3 desc
方法和上面一样,只是通过这个表我们可以直接返回所有调用mintNFT函数的交易哈希值,而不是用空地址来确定哪些交易来自erc721。"ERC721_evt_Transfer "表是mint交易。
使用 poolysupporters.而不是erc721, https://dune.com/queries/887280
poolysupporter数据集允许我们做更具体和详细的查询,因为我们可以参考具体的合约调用。
让我们比较一下我们两个表的结果,以确保没有什么不妥。
使用erc721.和poolysupporter.数据集的查询结果比较
输出结果完全一样。很好!
记得保存你的查询,并把它添加到仪表盘上。
在查询4的替代版本中,我们使用了poolysupporter函数。你可能已经看到,当你在数据集浏览器中搜索pooly时,你也看到一个名为 PoolyNFT_call_maxNFT
的函数。
poolysupporters.PoolyNFT_call_maxNFT函数
你可以得出结论,你可以使用这个函数调用来直接检索最大的铸币NFT。
使用 poolysupporters.PoolyNFT_call_maxNFT 查询没有结果
不幸的是,这是不可能的:这个函数是一个 read
函数,因此,当这个函数被调用时,没有链上记录。请看下面的Etherscan。
maxNFT是一个读函数,它没有在区块链上留下记录
maxNFT变量是在deployer合约部署Pooly Supporter智能合约时设置的,但不幸的是,在写这篇文章时,部署智能合约还没有被解码,所以我们无法从链上数据中获得最大的铸造数量--至少在没有大量努力的情况下。
相反,我们将不得不为每个智能合约手动插入maxNFT的数字。
with poolyContracts as
(
Select contract_address,
COUNT("tokenId") as nfts_purchased
From erc721."ERC721_evt_Transfer"
Where (contract_address = '\x90B3832e2F2aDe2FE382a911805B6933C056D6ed'
or contract_address = '\x3545192b340F50d77403DC0A64cf2b32F03d00A9'
or contract_address = '\x5663e3E096f1743e77B8F71b5DE0CF9Dfd058523')
and "from" = '\x0000000000000000000000000000000000000000'
group by 1
)
select
CASE contract_address
WHEN '\x90B3832e2F2aDe2FE382a911805B6933C056D6ed' then 'Pooly_Supporter'
WHEN '\x3545192b340F50d77403DC0A64cf2b32F03d00A9' then 'Pooly_Lawyer'
WHEN '\x5663e3E096f1743e77B8F71b5DE0CF9Dfd058523' then 'Pooly_Judge'
END as NFT_name,
nfts_purchased,
CASE maxNFT_Supply
WHEN '\x90B3832e2F2aDe2FE382a911805B6933C056D6ed' then 10000
WHEN '\x3545192b340F50d77403DC0A64cf2b32F03d00A9' then 100
WHEN '\x5663e3E096f1743e77B8F71b5DE0CF9Dfd058523' then 10
END as NFT_Supply,
CASE maxNFT_Supply
WHEN '\x90B3832e2F2aDe2FE382a911805B6933C056D6ed' then 100-(nfts_purchased/10000.0*100)
WHEN '\x3545192b340F50d77403DC0A64cf2b32F03d00A9' then 100-(nfts_purchased/1000.0*100)
WHEN '\x5663e3E096f1743e77B8F71b5DE0CF9Dfd058523' then 100-(nfts_purchased/10.0*100)
END as percent_supply_remaining
from poolyContracts
left join
(
Select contract_address as maxNFT_Supply
From erc721."ERC721_evt_Transfer"
Where (contract_address = '\x90B3832e2F2aDe2FE382a911805B6933C056D6ed'
or contract_address = '\x3545192b340F50d77403DC0A64cf2b32F03d00A9'
or contract_address = '\x5663e3E096f1743e77B8F71b5DE0CF9Dfd058523')
and "from" = '\x0000000000000000000000000000000000000000'
group by 1
)
as maxNFT
on maxNFT_Supply = contract_address
ORDER BY 3 desc
Pooly NFT供应查询 , https://dune.com/queries/887355
这里是我不得不发挥一点创造力的地方。在SQL中手动添加数字到特定的表项是一项困难的工作,我不得不应用一些技巧来让这留下一个容易阅读的表。
在这里,我们将再次使用left join
连接来合并两个表,但我们也将在四列中的三列上使用CASE WHEN语句来输出我们想要显示的特定信息。我们要做的是首先创建基本表,然后创建第二个表,并将第二个表与第一个表进行左连接,并对表的输入进行转换,使其可以被人类阅读,并为我们做一些简单的运算。
建立第二个表的原因是,在一个查询中,SQL不允许你两次调用一个列。事实上,我们需要多次调用一个列,并对每个列的调用进行单独转换。然而,一个连接的表允许我们多次调用第二个表中的列,从而使我们能够为需要的列中的特定行创建需要的输出。
上述查询的分解
让我们把这个查询分解成四个部分,以便于消化。
请注意章节的顺序! 1, 3, 2, 4!
第1部分
在这一部分中,我们定义了一个名为 poolyContracts
的表,在该表中,我们统计了来自三个Pooly合约地址中的空地址的所有单个tokenIds,因此只包括通过使用erc721. ERC721_evt_Transfer
表铸造的NFT。然后我们通过第一列对这些进行分组,从而返回每个Pooly智能合约的已铸币NFT。
poolyContracts表
第2部分
在这个代码块中,我们强制查询只显示三个合约地址中的一个。我们通过使用 group by 1
命令来做到这一点,也就是说,通过第一列的唯一条目来分组结果。
用
group by 1
命令返回每个合约地址的第二张表
如果没有group by命令,查询将返回与这些合约地址有关的所有转账事件,但我们只需要每个合约出现一次。你会在下一部分看到原因。
第二张表返回一个没有
group by 1
命令的合约地址的长列表
此外,我们将contract_address列重命名为maxNFT_Supply,这样我们就可以定义用哪一列来连接这个表和poolyContracts表。
第3部分
这就是奇迹发生的地方, 在这一部分中,现在可以从我们连接的表中调用列。
我们调用:
你会注意到,我们基本上是通过列1、列3和列4三次检索相同的数据,而且列3和列4甚至是同一个相同的列! 这是有可能的,因为我们连接了两个表。如果你在表连接之前两次调用contract_address,查询编辑器会返回错误信息。
接下来你还会注意到,第1、3、4列都嵌入了一个CASE WHEN子句。因为我们之前创建的两个表,每个智能合约只有一个唯一的行,所以我们不能用CASE WHEN语句来指定是否出现一个特定的智能合约地址(三个选项之一),要返回其他东西来代替它。
不按nft_supply对结果排序的完整表格
你会看到这里的第一列,我们告诉查询编辑器,用各自的NFT名称替换每个智能合约地址
在第三列中,我们用Pooly网站上上架的已知的最大NFT数量来代替它。
而在第四列,我们使用一个公式来计算剩余NFT供应的百分比。在这些语句中,至少有一个算术运算的数字需要包括一个小数位。如果没有小数位,SQL查询将被认为想要返回整数,这意味着我们将不会在这些计算中得到任何小数。通过包括 ".0",我们向服务器表示,我们希望这个计算能够返回一个小数。
第4部分
最后,我们表示我们希望输出结果按第三列的降序排列(从大到小)。
按nft_supply降序排序后的全表
这个表也完成了。保存你的查询,对该表进行任何需要的修改,并将其添加到你的仪表板。
将表格添加到仪表板中
在我们的最后一个查询中,我们将创建一个随时间变化的NFT销售筹集的ETH数量的时间序列图。
select
block_time as time,
sum(value/1e18) over (order by date_trunc('minute', block_time) asc) as cumu_value_eth
from ethereum.transactions
where ("to" = '\x90B3832e2F2aDe2FE382a911805B6933C056D6ed'
or "to" = '\x3545192b340F50d77403DC0A64cf2b32F03d00A9'
or "to" = '\x5663e3E096f1743e77B8F71b5DE0CF9Dfd058523')
and date_trunc('day', block_time) < '2022-06-25’
随着时间的推移,以ETH为单位的累计NFT销售 https://dune.com/queries/887727
这是一段较短的代码,但是它包括over命令,这是一个汇总累积值的重要命令。
在这个查询中,我们首先选择block_time,然后将ETH值(即value/1e18)在block_time上以分钟为单位相加,我们直接以升序排序,并将该列命名为cumu_value_eth。
sum(value/1e18) over (order by date_trunc('minute', block_time) asc) as cumu_value_eth
此外,我们还在结尾处添加了另一个过滤器,规定对于这个查询,区块时间不应超过2022-06-25,根据Pooly网站,这大概是筹款活动结束的时间。这样,我们的区域图将只显示活动的数据。
为了创建区域图,(1)点击 新可视化(New visualization)
,然后在(2)下拉菜单中选择 区域图(Area chart)
,最后(3)点击 添加可视化(Add visualization)
。
创建一个区域图的可视化
区域图(Area chart)应该自动出现,Dune 会预设相关设置。
区域图的可视化设置,并添加到仪表板上
如果图表没有被预设,你可以在图表下面尝试设置,直到它看起来合适。
最后,保存你的查询,再按一次 "添加到仪表盘"。
我们建立了很多查询,并直接将这些查询添加到我们的仪表盘上。让我们来看看它是什么样子的。在将最后一个图表添加到仪表盘后,点击仪表盘名称即可。
可视化添加完毕后,点击仪表盘的名称打开它
然后,让我们看看效果...
整理前的仪表板
是的! 这肯定需要整理一下才行。
在你的仪表板屏幕的右上方,点击 编辑(Edit)
开始编辑。
点击右上角的编辑按钮来编辑仪表盘的格式
从这里,你可以在一个网格上拖放各个元素,当你移动元素时,背景中的红框会显示出来,你可以通过拖动左下角的图标调整每个元素的大小。简单!
可视化和其他元素支持拖放和悬垂来调整大小
要添加文本和图片到你的仪表板,请在仪表板编辑界面的右上方按 "添加文本部件"。
点击
添加文本小部件
来添加文本小部件
在 整理的时候,你可能会注意到这两个查询看起来是一样的,拥有这两个查询其实并没有提供任何有价值的信息.....:
两个展示面板显示了计算ETH的美元价值的不同方法
因为我们不知道PoolTogether在智能合约中提取ETH的时间和方式,我这里就把右边的删除,用另一个查询来代替。
到了,最后的仪表板。
这看起来比以前漂亮多了,而且还遵循了Pooly网站的相同格式!
Dune Analytics是一个强大的平台,在合适的人手中可以提供深入的区块链数据能力。我希望通过这篇文章,你能够学习到一些基本知识。从这里开始,就看你如何迎接更大的挑战,做出更好的仪表盘。
特别感谢 @superamscom审查我的代码,并告知我一个错误,现在已经修复了!
本翻译由 Duet Protocol 赞助支持。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!