Home 区块链数据解析(2):Address
Post
Cancel

区块链数据解析(2):Address

Data Concept

地址类型

  • 以太坊上的地址主要分为两种,一种是钱包地址,一种是合约地址

  • 相同之处
    • 数据内容一致,都是 40 个十六进制字符组成的字符串,同时都具备价值存储价值转移等功能
  • 不同之处
    • 交易只能由钱包地址发起
    • 合约地址被动执行
    • 合约是多种功能实现的桥梁,例如 dapp 的各种业务都是通过合约来实现
    • 合约是各种价值存储载体,例如 token,nft 等等

以太坊地址区别

通过了解两种地址的相同与不同,我们看看他们对应的结构是怎样的构成,同时了解通过一些分析场景来了解这些数据是如何应用的?我们先看看 wallet address 的情况,再来了解 contract address 以及它的各种实现的分析。

Contract 表现形式

  • 在区块链上,合约有多种具体表现形式,例如 erc20 token, nft 或者是一个协议 (protocol ) 的功能性合约

Wallet Address

Address 数据关系

分析纬度

wallet address 我们提供了以下的这些常用的分析:

Balance

  • 通过分析地址持有的热门 token ,知道当前钱包的总价值,可以用来追踪一些大鲸在链上的资金变动情况

Portfolio

  • 通过对 address 的组合,分析一个 portfolio 的资产情况,这个 portfolio 可以是个人的投资组合,也可以是实体公司的链上资产组合,例如 CEX , 通过 portfolio 的汇总,可以知道像币安这样的交易所资产的变化情况以及异动。

Tags

  • 标签是一种常用的分析场景,链上的地址只是一串数字,需要结合链下的数据对地址赋予意义更加有助于分析地址的情况。同时上面提到的大鲸,CEX 这些都是通过标签归纳得出的数据,从链上是无法直接获取这样的数据。

Balance 取数方法

balance 取数一般有两种方法:

  • 从链底层数据 token_transfers/traces 汇总计算
  • 通过归档节点从合约获取

这两种方法各有优劣,从链底层数据汇总计算可以方便计算历史每个时刻的持有,有助于分析历史的变化情况,但缺点是需要消耗比较大量的计算资源,同时余额如果是根据合约每日/实时进行 rebalance 的合约会计算不准,例如 SETH 等;从合约获取数据优点是数据准确,但如果要回溯历史上每天的情况成本相对较高,依赖归档节点性能以及合约调用量限制,因此一般用于取最新余额.

余额类型

以以太坊为例子,我们常用的余额类型分三种大类:

  • Gas token 余额,在以太坊即 ethers
  • ERC20 token 余额
  • NFT 余额,包括 ERC721 以及 ERC1155 类型

链底层数据取数

假设取钱包/合约地址为 0x81e4fb0c64bf49f89b57f6648562fc9a791b2e92 持有的 0x15d4c048f83bd7e37d49ea4c83a07267ec4203da token 最新的余额情况:

1
2
3
4
5
6
7
8
SELECT SUM(CASE
               WHEN from_address = '0x81e4fb0c64bf49f89b57f6648562fc9a791b2e92' THEN -amount_raw
               ELSE amount_raw
           END)/1e8
FROM ethereum_token_transfers
WHERE token_address = '0x15d4c048f83bd7e37d49ea4c83a07267ec4203da'
  AND (from_address = '0x81e4fb0c64bf49f89b57f6648562fc9a791b2e92'
       OR to_address = '0x81e4fb0c64bf49f89b57f6648562fc9a791b2e92')

合约取数

获取某个区块下用户持有的 ether 情况

使用 python 代码为例调用链上节点数据获取用户余额情况:

1
2
3
def query_eth_balance(wallet_address: str, block_number: int):
    balance = w3.eth.get_balance(w3.toChecksumAddress(wallet_address), block_identifier=block_number)
    return balance / (10 ** 18)

获取某个区块下用户持有的 ERC20 token 情况

使用 python 代码为例调用合约数据,获取用户 ERC20 某个时刻的持有情况,获取持有的 NFT 也可以通过同样的方法调用:

1
2
3
4
5
def query_erc20_balance(wallet_address: str, token_address: str, token_decimals: int, block_number: int):
    erc20_token = w3.eth.contract(address=token_address, abi=erc20_abi)
    token_balance_raw = erc20_token.functions.balanceOf(w3.toChecksumAddress(wallet_address)).call(
        block_identifier=block_number)
    return token_balance_raw / (10 ** token_decimals)

分析场景

查询某个地址当前持有 ERC20 最新余额

1
2
3
4
5
6
7
8
9
SELECT contract_address,
       amount AS balance,
       value
FROM address_latest_balance
WHERE CHAIN ='Ethereum'
  AND wallet_address= lower('0x81e4fb0c64bf49f89b57f6648562fc9a791b2e92')
  AND standard = 'ERC20'
ORDER BY 3 DESC
-- 这里使用 footprint 的 address_latest_balance 表进行查询,该表包含了所有地址最新的余额数据

资金流分析

32057e03-7e45-444d-b093-5030e1c40aa4

This post is licensed under CC BY 4.0 by the author.

区块链数据解析(1):Chain Data

区块链数据解析(4):DeFi

Comments powered by Disqus.