From 3f35f627b9151de7111b094314c13985843e173c Mon Sep 17 00:00:00 2001
From: jh <0xroll.onchain@gmail.com>
Date: Sat, 9 Dec 2023 23:56:40 +0800
Subject: [PATCH 01/11] add sample query
---
docs/resources/index.md | 6 ++
docs/resources/sample-queries.md | 115 +++++++++++++++++++++++++++++++
2 files changed, 121 insertions(+)
create mode 100644 docs/resources/sample-queries.md
diff --git a/docs/resources/index.md b/docs/resources/index.md
index 7e32e1dc..c971572f 100644
--- a/docs/resources/index.md
+++ b/docs/resources/index.md
@@ -13,6 +13,12 @@ A collection of resources for the Dune community.
[→ Citing Dune](citing-dune.md)
+- #### Exploring frequently used queries on Dune
+
+ Walkthrough of commonly used queries
+
+ [→ Sample Queries](sample-queries.md)
+
- #### Find a Wizard
Discover and connect with skilled builders and researchers in the Ethereum ecosystem.
diff --git a/docs/resources/sample-queries.md b/docs/resources/sample-queries.md
new file mode 100644
index 00000000..25ab69c5
--- /dev/null
+++ b/docs/resources/sample-queries.md
@@ -0,0 +1,115 @@
+---
+title: Sample Queries
+description: Learn how to make use of popular tables and spells on Dune
+---
+
+# Sample Queries
+
+Dune is a platform that provides tools for querying, visualizing, and analyzing data from various chains. However, this can be difficult for new users that are not familiar with SQL/on chain data! Hence this guide will help you on your journey becoming a Dune wizard.
+
+Refer to [this dashboard](https://dune.com/resident_wizards/sample-queries){:target="_blank"}, which is a collection of commonly requested queries over time, and this list will continue to grow! Don't find the query that you need? Check out the [Dune AI](https://dune.com/ai){:target="_blank"} or head down to our [Discord](https://discord.gg/dunecom).
+
+
+
+### Getting Total Supply Of ERC20 Token
+
+[Getting Total Supply of ERC20 Token Query](https://dune.com/queries/3265730){:target="_blank"}
+
+To get the total supply of ERC20 token, we can make use of the erc20's Transfer event that is emitted on every transfers.
+
+For every token that are minted, there will be an event emitted from these transfers from the blackhole address(`0x0000000000000000000000000000000000000000`), and when tokens are burned, they will usually get sent to the similar address as well.
+
+```
+SELECT SUM(case when "from" = 0x0000000000000000000000000000000000000000 THEN (value/1e18) ELSE -(value/1e18) END) as lp_supply
+from erc20_ethereum.evt_transfer
+where contract_address = 0x046eee2cc3188071c02bfc1745a6b17c656e3f3d -- erc20 token address
+and ("from" = 0x0000000000000000000000000000000000000000 or "to" = 0x0000000000000000000000000000000000000000)
+-- to filter transfers that are sent from or receiving from the blackhole address
+```
+
+From the query above, we can make use of the `erc20_ethereum.evt_transfer` table, to get the total supply. As the `erc20_ethereum.evt_transfer` table contains all erc20 tokens' transfer, you have to filter by `contract_address`,sender(`from`) and recipient(`to`).
+
+
+Next, you'll need to sum up all the transfer events, adding when token is minted `"from" = 0x0000000000000000000000000000000000000000` and subtracting when token is burned(sent to blackhole address(`to = 0x0000000000000000000000000000000000000000`))
+
+This is done here, using `CASE` function to get the aggregated amount.
+
+```
+SELECT SUM(case when "from" = 0x0000000000000000000000000000000000000000 THEN (value/1e18) ELSE -(value/1e18) END)
+```
+
+You can then verify the token supply on blockchain explorer!
+
+### Getting All Token Holders Of ERC20 Token
+
+[Getting All ERC20 Token Holders' Balance](https://dune.com/queries/2753189){:target="_blank"}
+
+Similarly to getting total supply of ERC20 token, we will make use of the erc20's Transfer event table to achieve this.
+
+For every erc20 transfers that each wallet received / sent out, we can just aggregate them up and grouping by the wallet address.
+
+```
+SELECT address,
+ symbol,
+ SUM(amount) as balance
+FROM (
+-- transactions that address having token outflows
+SELECT tr."from" AS address,
+ symbol,
+ contract_address,
+ -(tr.value/POW(10,decimals)) AS amount
+FROM erc20_ethereum.evt_transfer tr JOIN tokens.erc20 USING (contract_address)
+WHERE "from" != 0x0000000000000000000000000000000000000000 -- exclude mint/burn addresses
+AND contract_address = 0x046eee2cc3188071c02bfc1745a6b17c656e3f3d -- contract_address of the erc20 token
+UNION ALL
+-- transactions that address having token inflows
+SELECT tr."to" AS address,
+ symbol,
+ contract_address,
+ (tr.value/POW(10,decimals)) AS amount
+FROM erc20_ethereum.evt_transfer tr JOIN tokens.erc20 USING (contract_address)
+ WHERE "to" != 0x0000000000000000000000000000000000000000 -- exclude mint/burn addresses
+ AND contract_address = 0x046eee2cc3188071c02bfc1745a6b17c656e3f3d -- contract_address of the erc20 token
+ ) x
+ GROUP BY address,symbol
+ HAVING SUM(amount) > 0.1 -- having more than 0.1 balance
+ ORDER BY 3 DESC
+```
+
+```
+FROM erc20_ethereum.evt_transfer tr JOIN tokens.erc20 USING (contract_address)
+```
+
+As token decimals varies, we can make use of the `tokens.erc20` table, which contains the token mapping to get the `symbol` and `decimals`.
+We then divide the value by the token decimals(`tr.value/POW(10,decimals)`) to get the amount.
+
+To get the balance of each user, you'll need to get to sum up inflows(`"to"`) and subtracting outflows(`"from"`) to get the current balance.
+We then aggregate all the values from the events,to get the current balance of each holder(`GROUP BY address,symbol`).
+
+- You can also add in a filter to remove holders that are holding dust amount (` HAVING SUM(amount) > 0.1`)
+- You can also add in a filter to get the top X holders (`LIMIT 100`) at the end of query
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From d4dc3e56e5f8741e55a0d2ff2b876c79acc80653 Mon Sep 17 00:00:00 2001
From: jh <0xroll.onchain@gmail.com>
Date: Sun, 10 Dec 2023 02:22:18 +0800
Subject: [PATCH 02/11] update more sample queries
---
docs/data-tables/decoded/.pages | 1 -
docs/resources/sample-queries.md | 154 ++++++++++++++++++++++++++++++-
2 files changed, 153 insertions(+), 2 deletions(-)
diff --git a/docs/data-tables/decoded/.pages b/docs/data-tables/decoded/.pages
index b3ef187c..34f00678 100644
--- a/docs/data-tables/decoded/.pages
+++ b/docs/data-tables/decoded/.pages
@@ -1,6 +1,5 @@
title: Decoded Tables
nav:
- index.md
-- new_guide.md
- EVM: evm
- Solana: solana
\ No newline at end of file
diff --git a/docs/resources/sample-queries.md b/docs/resources/sample-queries.md
index 25ab69c5..794bd6e1 100644
--- a/docs/resources/sample-queries.md
+++ b/docs/resources/sample-queries.md
@@ -7,7 +7,7 @@ description: Learn how to make use of popular tables and spells on Dune
Dune is a platform that provides tools for querying, visualizing, and analyzing data from various chains. However, this can be difficult for new users that are not familiar with SQL/on chain data! Hence this guide will help you on your journey becoming a Dune wizard.
-Refer to [this dashboard](https://dune.com/resident_wizards/sample-queries){:target="_blank"}, which is a collection of commonly requested queries over time, and this list will continue to grow! Don't find the query that you need? Check out the [Dune AI](https://dune.com/ai){:target="_blank"} or head down to our [Discord](https://discord.gg/dunecom).
+Refer to this [dashboard](https://dune.com/resident_wizards/sample-queries){:target="_blank"}, a collection of commonly requested queries over time, and this list will continue to grow! Don't find the query that you need? Check out the [Dune AI](https://dune.com/ai){:target="_blank"} or head down to our [Discord](https://discord.gg/dunecom).
@@ -40,6 +40,8 @@ SELECT SUM(case when "from" = 0x0000000000000000000000000000000000000000 THEN (v
You can then verify the token supply on blockchain explorer!
+
+
### Getting All Token Holders Of ERC20 Token
[Getting All ERC20 Token Holders' Balance](https://dune.com/queries/2753189){:target="_blank"}
@@ -89,6 +91,156 @@ We then aggregate all the values from the events,to get the current balance of e
- You can also add in a filter to remove holders that are holding dust amount (` HAVING SUM(amount) > 0.1`)
- You can also add in a filter to get the top X holders (`LIMIT 100`) at the end of query
+### Getting Number Of ERC20 Token Holders Over Time
+
+[Getting Number Of ERC20 Token Holders Over Time](https://dune.com/queries/2749329){:target="_blank"}
+
+Getting the number of holders over time will require you to modify [the previous example](#current-erc20-holder). From the transfer events, you will only get records of addresses that have transfer events on the particular day. To ensure that there will be no gaps in between, you will need to generate a date series and backfill with the previous date's data.
+
+```
+WITH user_balance AS (
+SELECT date,
+ address,
+ SUM(SUM(amount)) OVER (PARTITION BY address ORDER BY date) as daily_cumulative_balance -- get the cumulative balance of the holders
+FROM (
+SELECT date_trunc('day',evt_block_time) as date,
+ tr."from" AS address,
+ -(tr.value/1e18) AS amount
+FROM erc20_ethereum.evt_transfer tr
+WHERE "from" != 0x0000000000000000000000000000000000000000 -- exclude mint/burn addresses
+AND contract_address = 0x046eee2cc3188071c02bfc1745a6b17c656e3f3d -- contract_address of the erc20 token
+UNION ALL
+SELECT date_trunc('day',evt_block_time) as date,
+tr."to" AS address,
+(tr.value/1e18) AS amount
+FROM erc20_ethereum.evt_transfer tr
+ WHERE "to" != 0x0000000000000000000000000000000000000000 -- exclude mint/burn addresses
+ AND contract_address = 0x046eee2cc3188071c02bfc1745a6b17c656e3f3d -- contract_address of the erc20 token
+ ) x
+ GROUP BY date,address
+),
+
+setLeadData as (
+SELECT *,lead(date,1,NOW()) OVER (PARTITION BY address ORDER BY date) as latest_day FROM user_balance
+),
+
+gs as (
+SELECT date FROM UNNEST(sequence(CAST('2023-06-28' AS TIMESTAMP),CAST(NOW() AS TIMESTAMP),interval '1' day)) as tbl(date)
+),
+
+getUserDailyBalance as (
+SELECT gs.date,
+ address,
+ daily_cumulative_balance
+FROM setLeadData g
+INNER JOIN gs ON g.date <= gs.date AND gs.date < g.latest_day
+WHERE daily_cumulative_balance > 1/1e12
+)
+
+SELECT date,
+ COUNT(address) as holders,
+ COUNT(address) - LAG(COUNT(address)) OVER (ORDER BY date) as change
+FROM getUserDailyBalance
+GROUP BY 1
+ORDER BY 1 DESC
+```
+
+```
+SUM(SUM(amount)) OVER (PARTITION BY address ORDER BY date) as daily_cumulative_balance
+```
+
+This windows function will sum up all the amount(`token transfer amount`) cumulatively, to get the token balance of each address on that particular day, which you have to aggregate them by date and address (`GROUP BY date,address`)
+
+```
+setLeadData as (
+SELECT *,lead(date,1,NOW()) OVER (PARTITION BY address ORDER BY date) as latest_day FROM user_balance
+),
+
+gs as (
+SELECT date FROM UNNEST(sequence(CAST('2023-06-28' AS TIMESTAMP),CAST(NOW() AS TIMESTAMP),interval '1' day)) as tbl(date)
+),
+```
+
+- `setLeadData`: This will get the next available date of the address (`PARTITION BY address`), in an ascending date order (`ORDER BY date`)
+- `gs`: This will help you to generate a date series, which you can set the start and end date of the timeframe, in the above example its `2023-06-28` as start date and `NOW()` as current date
+
+```
+getUserDailyBalance as (
+SELECT gs.date,
+ address,
+ daily_cumulative_balance
+FROM setLeadData g
+INNER JOIN gs ON g.date <= gs.date AND gs.date < g.latest_day
+WHERE daily_cumulative_balance > 0.01
+)
+```
+With the generated date series(`gs` CTE), you will just have to join it with the `setLeadData` CTE to get the daily balance of each address since inception!
+
+- You can also add in a filter to remove dusts (`WHERE daily_cumulative_balance > 0.01`)
+
+Once you have the daily balance of each user, you can now get the daily number of holders by simply aggregating the number of addresses on each day. You can also get the daily change in token holders by taking each day's holder count and subtracting previous day's holder count (`COUNT(address) - LAG(COUNT(address)) OVER (ORDER BY date) as change `)
+
+### Getting ERC20 Token Transaction Value In USD
+
+[Top 100 Transfers In USD Into Binance](https://dune.com/queries/3269085){:target="_blank"}
+
+You are able to get the token amount for transfers from the `erc20 evt transfer` table, to get the usd amount, you will need to join with the prices table (`prices.usd`)
+
+```
+select "from" as sender,
+ symbol,
+ value/POW(10,decimals) as token_amount,
+ value/POW(10,decimals) * price as token_usd
+from erc20_ethereum.evt_transfer a
+LEFT JOIN prices.usd b ON date_trunc('minute',a.evt_block_time) = b.minute AND a.contract_address = b.contract_address
+where "to" = 0x28c6c06298d514db089934071355e5743bf21d60
+and evt_block_time >= NOW() - interval '24' hour
+ORDER BY 4 DESC
+LIMIT 1000
+```
+
+The above query shows you the top 1000 deposits in the past 24 hours (`evt_block_time >= NOW() - interval '24' hour`). You can simply just do a JOIN with the `prices.usd` table, with the erc20 token contract address (`contract_address`) and datetime of the transaction (`date_trunc('day',evt_block_time)`).
+
+- The `date_trunc` here is required as there are milliseconds in the `evt_block_time`, to match the minute-level data in `prices.usd`
+
+
+### Getting Current NFT Holders For A Specific Collection
+
+[Getting Current NFT Holders](https://dune.com/queries/2858082){:target="_blank"}
+
+You can make use of the `erc721_ethereum.evt_trasnfer` table to get the holders of a NFT collection. The example below identifies the current holders of Bored Ape Yacht Club(BAYC) collection.
+
+```
+SELECT "to" as address,
+ COUNT(*) as nft_count,
+ ARRAY_AGG(tokenId) as nft_list
+FROM (
+select contract_address,
+ to,
+ tokenId,
+ ROW_NUMBER() OVER (PARTITION BY tokenId ORDER BY evt_block_time DESC,evt_index DESC) as rn
+from erc721_ethereum.evt_transfer
+where contract_address = 0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D -- bayc address
+) x
+WHERE rn = 1
+GROUP BY 1
+```
+
+For ERC721 nft token, each of them have a unique token number (`tokenId`).
+
+From the query above, what it does is:
+- get the recipients (`to`)
+- get the token number (`tokenId`)
+- create a sequential numbering of rows to rank the deposits using `ROW_NUMBER()` windows function
+- to get the latest transfer of each token (`PARTITION BY tokenId ORDER BY evt_block_time DESC,evt_index DESC`)
+
+We will just need to identify the latest recipient of each NFT token and we will just remove all other transactions (`WHERE rn = 1`).
+Aggregate by address will get you the current holder of BAYC collection!
+
+
+
+
+
From 44bb41cea5e7e5fe9d6a2049a0b618257bd8ae48 Mon Sep 17 00:00:00 2001
From: jh <0xroll.onchain@gmail.com>
Date: Sun, 10 Dec 2023 02:41:09 +0800
Subject: [PATCH 03/11] update query overview for each
---
docs/resources/sample-queries.md | 52 ++++++++++++++++++++++++++------
1 file changed, 43 insertions(+), 9 deletions(-)
diff --git a/docs/resources/sample-queries.md b/docs/resources/sample-queries.md
index 794bd6e1..f84cf624 100644
--- a/docs/resources/sample-queries.md
+++ b/docs/resources/sample-queries.md
@@ -27,7 +27,13 @@ and ("from" = 0x0000000000000000000000000000000000000000 or "to" = 0x00000000000
-- to filter transfers that are sent from or receiving from the blackhole address
```
-From the query above, we can make use of the `erc20_ethereum.evt_transfer` table, to get the total supply. As the `erc20_ethereum.evt_transfer` table contains all erc20 tokens' transfer, you have to filter by `contract_address`,sender(`from`) and recipient(`to`).
+What this query does:
+
+- Get all erc20 token transfer that originates and received by the blackhole address
+
+- Check if it is minted from blackhole address, sum them up, if not subtract them
+
+We can make use of the `erc20_ethereum.evt_transfer` table, to get the total supply. As the `erc20_ethereum.evt_transfer` table contains all erc20 tokens' transfer, you have to filter by `contract_address`,sender(`from`) and recipient(`to`).
Next, you'll need to sum up all the transfer events, adding when token is minted `"from" = 0x0000000000000000000000000000000000000000` and subtracting when token is burned(sent to blackhole address(`to = 0x0000000000000000000000000000000000000000`))
@@ -78,6 +84,14 @@ FROM erc20_ethereum.evt_transfer tr JOIN tokens.erc20 USING (contract_address)
ORDER BY 3 DESC
```
+What this query does:
+
+- Get all erc20 token transfer but exclude blackhole address
+
+- Get the token decimals from tokens.erc20 table
+
+- Get the sum inflows and subtract outflows
+
```
FROM erc20_ethereum.evt_transfer tr JOIN tokens.erc20 USING (contract_address)
```
@@ -145,6 +159,14 @@ GROUP BY 1
ORDER BY 1 DESC
```
+What this query does:
+
+- Get addresses' balance of available dates
+
+- Generate date series to ensure no gaps in between
+
+- Subtract previous day data to get the daily change
+
```
SUM(SUM(amount)) OVER (PARTITION BY address ORDER BY date) as daily_cumulative_balance
```
@@ -174,6 +196,7 @@ INNER JOIN gs ON g.date <= gs.date AND gs.date < g.latest_day
WHERE daily_cumulative_balance > 0.01
)
```
+
With the generated date series(`gs` CTE), you will just have to join it with the `setLeadData` CTE to get the daily balance of each address since inception!
- You can also add in a filter to remove dusts (`WHERE daily_cumulative_balance > 0.01`)
@@ -199,6 +222,14 @@ ORDER BY 4 DESC
LIMIT 1000
```
+What this query does:
+
+- Get token transfers into Binance 14 Hot Wallet
+
+- Join the prices table to get token price
+
+- Filter to only get latest 24 hour data and limiting to 1000 records
+
The above query shows you the top 1000 deposits in the past 24 hours (`evt_block_time >= NOW() - interval '24' hour`). You can simply just do a JOIN with the `prices.usd` table, with the erc20 token contract address (`contract_address`) and datetime of the transaction (`date_trunc('day',evt_block_time)`).
- The `date_trunc` here is required as there are milliseconds in the `evt_block_time`, to match the minute-level data in `prices.usd`
@@ -208,7 +239,7 @@ The above query shows you the top 1000 deposits in the past 24 hours (`evt_block
[Getting Current NFT Holders](https://dune.com/queries/2858082){:target="_blank"}
-You can make use of the `erc721_ethereum.evt_trasnfer` table to get the holders of a NFT collection. The example below identifies the current holders of Bored Ape Yacht Club(BAYC) collection.
+You can make use of the `erc721_ethereum.evt_trasnfer` table to get the holders of a NFT collection. The example below identifies the current holders of Bored Ape Yacht Club(BAYC) collection. For ERC721 nft token, each of them have a unique token number (`tokenId`).
```
SELECT "to" as address,
@@ -226,16 +257,19 @@ WHERE rn = 1
GROUP BY 1
```
-For ERC721 nft token, each of them have a unique token number (`tokenId`).
+What this query does:
+
+- Get the recipients (`to`)
+
+- Get the token number (`tokenId`)
-From the query above, what it does is:
-- get the recipients (`to`)
-- get the token number (`tokenId`)
-- create a sequential numbering of rows to rank the deposits using `ROW_NUMBER()` windows function
-- to get the latest transfer of each token (`PARTITION BY tokenId ORDER BY evt_block_time DESC,evt_index DESC`)
+- Create a sequential numbering of rows to rank the deposits using `ROW_NUMBER()` windows function
+
+- To get the latest transfer of each token (`PARTITION BY tokenId ORDER BY evt_block_time DESC,evt_index DESC`)
We will just need to identify the latest recipient of each NFT token and we will just remove all other transactions (`WHERE rn = 1`).
-Aggregate by address will get you the current holder of BAYC collection!
+
+Aggregate by address will get you all current holders of BAYC collection!
From e4365caef56110a16464f1c620b6f2372faf82cf Mon Sep 17 00:00:00 2001
From: jh <0xroll.onchain@gmail.com>
Date: Sun, 10 Dec 2023 03:01:59 +0800
Subject: [PATCH 04/11] add eth query
---
docs/resources/sample-queries.md | 45 ++++++++++++++++++++++++++++++--
1 file changed, 43 insertions(+), 2 deletions(-)
diff --git a/docs/resources/sample-queries.md b/docs/resources/sample-queries.md
index f84cf624..9f11392b 100644
--- a/docs/resources/sample-queries.md
+++ b/docs/resources/sample-queries.md
@@ -5,8 +5,6 @@ description: Learn how to make use of popular tables and spells on Dune
# Sample Queries
-Dune is a platform that provides tools for querying, visualizing, and analyzing data from various chains. However, this can be difficult for new users that are not familiar with SQL/on chain data! Hence this guide will help you on your journey becoming a Dune wizard.
-
Refer to this [dashboard](https://dune.com/resident_wizards/sample-queries){:target="_blank"}, a collection of commonly requested queries over time, and this list will continue to grow! Don't find the query that you need? Check out the [Dune AI](https://dune.com/ai){:target="_blank"} or head down to our [Discord](https://discord.gg/dunecom).
@@ -271,6 +269,49 @@ We will just need to identify the latest recipient of each NFT token and we will
Aggregate by address will get you all current holders of BAYC collection!
+### Getting the current ETH balance
+
+```
+ -- outbound transfers
+ SELECT SUM(amount) as current_eth_balance FROM (
+ SELECT "from" AS address,
+ -CAST(tr.value AS DOUBLE)/POWER(10,18) AS amount,
+ tx_hash
+ FROM ethereum.traces tr
+ WHERE "from" = 0x29ffea86733d7feac7c353343f300e99b8910c77
+ AND success
+ AND (call_type NOT IN ('delegatecall', 'callcode', 'staticcall') OR call_type IS null)
+
+ UNION ALL
+
+ -- inbound transfers
+ SELECT to AS address, (CAST(value AS DOUBLE)/POWER(10,18)) AS amount,tx_hash
+ FROM ethereum.traces
+ WHERE to = 0x29ffea86733d7feac7c353343f300e99b8910c77
+ AND success
+ AND (call_type NOT IN ('delegatecall', 'callcode', 'staticcall') OR call_type IS null)
+
+ UNION ALL
+
+ -- gas costs
+ SELECT "from" AS address, -(CAST(gas_used AS DOUBLE)/POWER(10,18) * CAST(gas_price AS DOUBLE)),hash
+ FROM ethereum.transactions et
+ WHERE "from" = 0x29ffea86733d7feac7c353343f300e99b8910c77
+ ) x
+```
+
+What this query does:
+
+- Get all outbound and inbound transfers from `traces` table
+
+- Get all gas costs from the `transactions` table
+
+- Aggregate all transfers, summing up the inflows and subtracting outflows and gas fee
+
+For ETH on mainnet, you will have to use the `ethereum.traces`. They do not appear in erc20 transfer table as it is not an erc20 token.
+
+
+
From 63b424f87160ce61f131ef0a3d7cc6eddb5cc719 Mon Sep 17 00:00:00 2001
From: jh <0xroll.onchain@gmail.com>
Date: Sun, 10 Dec 2023 04:06:03 +0800
Subject: [PATCH 05/11] adding samples
---
.../images/etherscan-logs-event-sample.png | Bin 0 -> 22066 bytes
docs/resources/images/etherscan_logs.png | Bin 0 -> 23122 bytes
docs/resources/sample-queries.md | 118 +++++++++++++-----
3 files changed, 88 insertions(+), 30 deletions(-)
create mode 100644 docs/resources/images/etherscan-logs-event-sample.png
create mode 100644 docs/resources/images/etherscan_logs.png
diff --git a/docs/resources/images/etherscan-logs-event-sample.png b/docs/resources/images/etherscan-logs-event-sample.png
new file mode 100644
index 0000000000000000000000000000000000000000..3011a2f8dd2bb63195cf3938416063d7b4179c6e
GIT binary patch
literal 22066
zcmce;byQqWwxjRQjz=sC>tT(gI>Hg6O|VQ04k%AAC2Ik*NFB~T224}TGyYySABK`CIEnX
zpR~BBn!El{%Yz+`WaG)O-5t7uZ@53mypuIpN-{N;M@HW{iXuCG%)~XjSsKL0I}jBJ
zVP3AFwAmcUSYv<7#v|q*FJc%Z*d@Olhyp7uRWCq=5_-?wtALt1Ff9RBh17SW&XTwK<59lyt`)Gv9|Nll1^G_ddjiIv=RlWj<
z#D2jaMj3&Dg^FN-0sw@eben&&$Hj-jmR
ziO2B)0BnMgv0tCz-~lo4US+$-M^-0?wiYMEeh|;X>xF;-Vtjz1KMZulAzV;80I+H}
zisSPH8xSDoc5>e15MY@D?RJg!PI?X*kQ5>k@d@7RixDjVz>_eiD_WG$ZEkjhDuh5k
z%j*?qc͛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
literal 0
HcmV?d00001
diff --git a/docs/resources/images/etherscan_logs.png b/docs/resources/images/etherscan_logs.png
new file mode 100644
index 0000000000000000000000000000000000000000..2ed674d8f3b869ebcd8a31084cef8f350328efc7
GIT binary patch
literal 23122
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 0.1`)
- You can also add in a filter to get the top X holders (`LIMIT 100`) at the end of query
+### Getting Current ETH balance
+
+```
+ -- outbound transfers
+ SELECT SUM(amount) as current_eth_balance FROM (
+ SELECT "from" AS address,
+ -CAST(tr.value AS DOUBLE)/POWER(10,18) AS amount,
+ tx_hash
+ FROM ethereum.traces tr
+ WHERE "from" = 0x29ffea86733d7feac7c353343f300e99b8910c77
+ AND success
+ AND (call_type NOT IN ('delegatecall', 'callcode', 'staticcall') OR call_type IS null)
+
+ UNION ALL
+
+ -- inbound transfers
+ SELECT to AS address, (CAST(value AS DOUBLE)/POWER(10,18)) AS amount,tx_hash
+ FROM ethereum.traces
+ WHERE to = 0x29ffea86733d7feac7c353343f300e99b8910c77
+ AND success
+ AND (call_type NOT IN ('delegatecall', 'callcode', 'staticcall') OR call_type IS null)
+
+ UNION ALL
+
+ -- gas costs
+ SELECT "from" AS address, -(CAST(gas_used AS DOUBLE)/POWER(10,18) * CAST(gas_price AS DOUBLE)),hash
+ FROM ethereum.transactions et
+ WHERE "from" = 0x29ffea86733d7feac7c353343f300e99b8910c77
+ ) x
+```
+
+What this query does:
+
+- Get all outbound and inbound transfers from `traces` table
+
+- Get all gas costs from the `transactions` table
+
+- Aggregate all transfers, summing up the inflows and subtracting outflows and gas fee
+
+For ETH on mainnet, you will have to use the `ethereum.traces`. They do not appear in erc20 transfer table as it is not an erc20 token.
+
### Getting Number Of ERC20 Token Holders Over Time
[Getting Number Of ERC20 Token Holders Over Time](https://dune.com/queries/2749329){:target="_blank"}
@@ -269,46 +310,63 @@ We will just need to identify the latest recipient of each NFT token and we will
Aggregate by address will get you all current holders of BAYC collection!
-### Getting the current ETH balance
+### Using Logs Table For Specific Event
+
+[$ARKM Claimers From Logs Table](https://dune.com/queries/3269288){:target="_blank"}
```
- -- outbound transfers
- SELECT SUM(amount) as current_eth_balance FROM (
- SELECT "from" AS address,
- -CAST(tr.value AS DOUBLE)/POWER(10,18) AS amount,
- tx_hash
- FROM ethereum.traces tr
- WHERE "from" = 0x29ffea86733d7feac7c353343f300e99b8910c77
- AND success
- AND (call_type NOT IN ('delegatecall', 'callcode', 'staticcall') OR call_type IS null)
+SELECT block_time,
+ varbinary_ltrim(topic1) as address,
+ varbinary_to_uint256(topic2)/1e18 as amount_claimed
+FROM ethereum.logs
+where contract_address = 0x08c7676680f187a31241e83e6d44c03a98adab05
+and topic0 = 0xd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a
+order by 3 desc
+```
- UNION ALL
+What this query does:
- -- inbound transfers
- SELECT to AS address, (CAST(value AS DOUBLE)/POWER(10,18)) AS amount,tx_hash
- FROM ethereum.traces
- WHERE to = 0x29ffea86733d7feac7c353343f300e99b8910c77
- AND success
- AND (call_type NOT IN ('delegatecall', 'callcode', 'staticcall') OR call_type IS null)
+- Querying logs table by filtering the contract address (`contract_address`) and event signature(`topic0`)
- UNION ALL
-
- -- gas costs
- SELECT "from" AS address, -(CAST(gas_used AS DOUBLE)/POWER(10,18) * CAST(gas_price AS DOUBLE)),hash
- FROM ethereum.transactions et
- WHERE "from" = 0x29ffea86733d7feac7c353343f300e99b8910c77
- ) x
-```
+- Using varbinary functions to get the decoded data
-What this query does:
+The `ethereum.logs` table is one of the raw tables available that contains all events that are emitted. You will need to specify the contract address and topic0 to get the specific events you need. Each event has a unique signature (`topic0`), that you will be able to get this the logs page. [Here is a sample transaction hash of $ARKM claim](https://etherscan.io/tx/0xc127438f51ae6917d7b1b7709d50049162ae41bdac4201b5658cd9cc01c9c591){:target="_blank"}.
-- Get all outbound and inbound transfers from `traces` table
+
+
+
+
+ Click on the `Logs` tab.
+
+
+
+
+
+ In the `Claim` event, you will be able to identify:
+
+ - Address : `contract_address`
+
+ - Event signature : `topic0`
+
+ - Account : `topic1`
+
+ - Amount : `topic2`
+
+
+ ```
+ varbinary_ltrim(topic1) as address, -- removes the zeros
+ varbinary_to_uint256(topic2)/1e18 as amount_claimed -- converting varbinary to uint256
+ ```
+
+ In the `logs` table, they are raw data hence you will need to use [varbinary functions](https://dune.com/docs/query/DuneSQL-reference/Functions-and-operators/varbinary/?h=bytearray_to_uint#varbinary-functions){:target="_blank"} to decode them.
+
+ Since $ARKM token has 18 decimals, we use `/1e18` to get the actual amount that each address claimed.
+
+ It is advisable to get the contracts to be [decoded at Dune](https://dune.com/contracts/new){:target="_blank"} as querying from the raw tables can take a long time as they contain all the events emitted! To understand more about decoded tables, check out our [Decoding Docs](https://dune.com/docs/app/decoding-contracts/){:target="_blank"}
+
-- Get all gas costs from the `transactions` table
-- Aggregate all transfers, summing up the inflows and subtracting outflows and gas fee
-For ETH on mainnet, you will have to use the `ethereum.traces`. They do not appear in erc20 transfer table as it is not an erc20 token.
From 595a6d4b4653eac745beddf3fbb33b7b999a3606 Mon Sep 17 00:00:00 2001
From: jh <0xroll.onchain@gmail.com>
Date: Sun, 10 Dec 2023 04:50:37 +0800
Subject: [PATCH 06/11] add sample data
---
.../images/etherscan-logs-event-data.png | Bin 0 -> 27893 bytes
docs/resources/sample-queries.md | 70 ++++++++++++++++--
2 files changed, 65 insertions(+), 5 deletions(-)
create mode 100644 docs/resources/images/etherscan-logs-event-data.png
diff --git a/docs/resources/images/etherscan-logs-event-data.png b/docs/resources/images/etherscan-logs-event-data.png
new file mode 100644
index 0000000000000000000000000000000000000000..93f21bd2f8d19e43d3124c59549b0f559a4a4103
GIT binary patch
literal 27893
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
z