本文深入探讨了Aptos链上DeFi Swap交易的解析方法,详细分析了Liquidswap、Cellana和Panora等DEX的交易过程,对比了Coin和Fungible Asset(FA)在交易中的应用,并介绍了如何通过事件、资源变化以及GraphQL API来追踪和解析链上数据,文中还介绍了稳定币和预言机在Aptos上的应用,为读者提供了分析DeFi Swap交易的实用指南。
DeFi(去中心化金融)通过利用即时订单结算并为用户提供对其资产的直接控制,正在彻底改变金融。DeFi 应用的主要类别包括:
资产交易是最流行的应用之一,类似于传统金融中的股票购买或货币兑换。本文将详细探讨在 Aptos 上的 3 笔交换交易,其中资产使用 AMM 池 进行交换。如 数据概述(第 1 部分)中提到的,Aptos 上的资产在 传统币标准(币)和 可替代资产标准(FA)之间划分。这一区别在解释交易时将非常重要。
SQL 示例将使用 bigquery 数据集。
Defillama 列出了 Aptos 上的去中心化交易所(dexs),我们先从 liquidswap 中列出交易。
在他们的网站上点击交换会弹出带有交易模拟的 Petra 钱包。使用所示的“Function:” 字符串来过滤交易(也可以查看 来源 找出要使用哪个地址,关于 defillama liquidswap 页面 的更多信息)
SELECT *
FROM `bigquery-public-data.crypto_aptos_mainnet_us.transactions`
WHERE tx_type = 'user'
AND success
AND payload.entry_function_id_str = '0x9dd974aea0f927ead664b9e1c295e4215bd441a9fb4e53e5ea0bf22f356c8a2b::router::swap_exact_coin_for_coin_x1'
AND block_timestamp BETWEEN '2025–01–01' AND '2025–01–31'
LIMIT 100
在这个表中,请注意 payload.function
与 payload.entry_function_id
之间的差异是左侧的 0 填充。例如,另外一个 liquidswap 地址 0x163df34fccbf003ce219d3f1d9e70d140b60622cb9dd47599c25fb2f797ba6e
并没有使用 0 填充以符合 AIP-40。在 payload.function
字段中,它将正常显示为填充后的形式:0x0163df34fccbf003ce219d3f1d9e70d140b60622cb9dd47599c25fb2f797ba6e::scripts::swap
(例如 tx_version = 2294166635)。在这些情况下,以下逻辑将规范化地址长度:
IF(LENGTH(SPLIT(payload.entry_function_id_str, '::')[0]) != 64,
'0x' || LPAD(LTRIM(SPLIT(payload.entry_function_id_str, '::')[0],'0x'),64, '0') ||
SUBSTR(payload.entry_function_id_str, LENGTH(SPLIT(payload.entry_function_id_str, '::')[0])+1,
LENGTH(payload.entry_function_id_str)),
payload.entry_function_id_str) AS entry_function_id_str_normalized
在决定查看某个交易后,使用以下表格以获取更多上下文:
交易修改的资源在后一个表中,然而,这些变化通常难以解析,并且仅显示交易结束时的状态。事件对于展示中间步骤非常有用,通常用于驱动 dapp 前端的链下索引。
例如,尽管闪电贷(flash loan)将会在同一交易中借入并偿还,因此被借贷的池的余额将保持不变。通常,事件会被发出以标记交易中发生的闪电贷。
示例交易 2224014200
余额变化可以推断出发送者(odix)将 16.182 APT 兑换为 48k MOOMOO。余额变化可以通过查询我们的索引器 GraphQL 端点中的 fungible_asset_activities 来获取(示例)。
query get_balance {
fungible_asset_activities(
where: {transaction_version: {_eq: "2224014200"}}) {
event_index
storage_id
owner_address
asset_type
type
amount
}
}
Fungible asset activities 端点是从事件中解析而来的,包含 event_index
(标识符)和(事件)type
。由于此端点服务于币和可替代资产,storage_id
作为唯一标识符,用于获取任何给定所有者 + CoinStore/FungibleStore 的资产数量。
0. APT 从 odix 的 CoinStore 中流出
1. Liquidswap 池的费用会计(指示 0.1% 的费用)
2. Liquidswap 的 Oracle 定价更新
3. Liquidswap 流动性交换事件(包含费用)
4. MOOMOO 代币进入 odix 的 CoinStore
5. Gas费用声明(所有交易都有这个)
事件索引 3 值得特别关注,因为这是用来跟踪 liqudiswap 池活动的事件。可以从事件类型中解析出进出资产类型(按逗号分割 + SwapEvent 不加 <
)。
事件索引 0 和 4是从 CoinStore 取款/存款,附带数量但没有币种。使用 creation_num 并映射到 CoinStore 资源以获取币种类型。
查看原始 交易 时,取款/存款事件有一个 guid 结构,映射到 Coinstore(更改 0 和 1)结构以进行币种类型查找。
例如,更改 0 是 APT 的 CoinStore
{
"address": "0x22640edec47a907370ce5d2eaf10d60004177a874f8d998df9281e1c9093463e",
"state_key_hash": "0x220fdb58f7df47b3d28951e6c65356c5a97dc0a6cb594fa6e660b802c0e300f6",
"data": {
"type": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>",
"data": {
"coin": {
"value": "999500"
},
"deposit_events": {
"counter": "5817",
"guid": {
"id": {
"addr": "0x22640edec47a907370ce5d2eaf10d60004177a874f8d998df9281e1c9093463e",
"creation_num": "2"
}
}
},
"frozen": false,
"withdraw_events": {
"counter": "5727",
"guid": {
"id": {
"addr": "0x22640edec47a907370ce5d2eaf10d60004177a874f8d998df9281e1c9093463e",
"creation_num": "3"
}
}
}
}
},
"type": "write_resource"
}
事件 0 是从 CoinStore 取款(具有匹配的 creation_num 和地址,允许类型查找)
{
"guid": {
"creation_number": "3",
"account_address": "0x22640edec47a907370ce5d2eaf10d60004177a874f8d998df9281e1c9093463e"
},
"sequence_number": "5726",
"type": "0x1::coin::WithdrawEvent",
"data": {
"amount": "1618243104"
}
},
这里是一个 dune 查询,实现了这一查找逻辑。
0. Coinstore 持有 APT,属于 Odix
1. Coinstore 持有 MOOMOO,属于 Odix
2. Odix 的账户
3. Liquidswap 池的费用存储
4. Liquidswap 池的费用事件存储
5. Liquidswap 池的事件存储
6. Liquidswap 池信息
7. 表项变化(APT 供应跟踪) — 在几乎每笔交易中都有
使用 aptoscan explorer,可以方便地找到“主行动”,这是从事件中解析出来的(最近已添加到 labs explorer 由 0xbe1 的 Thalalabs 提供)以及在更改选项卡中的 diff 按钮。
池的前后币储备
可以通过查询 get_account_resources 并提供地址和版本,来检索到任意状态。
在这个例子中可能令人警觉的是,APT 从 odix 的 CoinStore 中流出并消失(WithdrawEvent 没有对应的 DepositEvent)。这是因为币不必存储在 CoinStore 中,可以放入资源(见上面的 coin_y_reserve.value
的增加)。
接下来,让我们看一下一个 cellana 交易,通过过滤它们的入口函数 0x4bf51972879e3b95c4781a5cdcb9e1ee24ef483e7d22f2d903626f126df62bd1::router::swap_route_entry_from_coin
。
交易 2293960645 中 13.387 APT 被交换为 100.12(本地)USDt。与 liquidswap 不同,Cellana 使用可替代资产(而非币)进行转换。
一个思路是,币可以存储在一个称为 CoinStore 的背包(地址)的口袋中,但也可以存储在不同的口袋中(如在上面的 liquidswap 示例中所示)。这些自定义口袋不保证有取款/存款事件。相比之下,只有一个 FA 可以存储在一个背包(地址)中,但现在需要为每个 FA 拥有一个背包(FungibleStore 没有类型参数)。
找到用户持有的所有币可以通过扫描用户地址的 0x1::coin::CoinStore<%
类型的资源实现。然而,如果币隐藏在其他口袋中,这可能并不全面。
找到用户拥有的所有 FA 则需要找到该用户拥有的所有 FungibleStore 对象,并且需要链下索引来进行高效查找(下面将详细说明)。
左侧为币(Coins),右侧为可替代资产(Fungible Assets),圆形代表资源,方形代表地址。
余额变化显示 APT 取款和 USDt 存款(顶端和底部)给发送者(0xc4bd),但中间还有许多交易。
APT 被存入 Cellana 的币库,随后合约铸造了一个 FA(资产 0xedc2704f2cef417a06d1756a04a16a9fa6faaed13af469be9cdfcac5a21a8e2e
)来代表这笔 APT,我将其称为 (Cellana FA) APT。最后,该资产通过池进行交换以换取 USDt,并存入发送者的 USDt FungibleStore。
检查 Cellana APT-USDt 池的 对象 0xe8797d7adaf48abd7becddc9c4494f1309d9a83a6ea0c4be708482cbc54e36af
显示了 (Cellana FA) APT 和 USDt。你需要在币页面上点击“所有”以显示 Cellana FA APT(默认情况下,带有特定符号的资产是隐藏的)在两个 FA 存储中(一个用于池,一个用于费用)。
(Cellana APT-USDt 池的所有币余额页面)
这些余额保存在 4 个 FungibleStore 对象中,属于该池。
排除了持有费用的 FungibleStore
这种表示使得跟踪 FA AMM 池非常简单。
0. 从 0xc4bd(发送者)取款 APT(币)
1. 存入 APT(币)到 Cellana 的币库 0x3b38
2. 存入(cellana FA)APT(扣除费用数)到池的存储 0x829f
3. 存入(cellana FA)APT(费用)到池的存储 0xeb36
4. 从池的存储取出 USDt(0x11f2)
5. Cellana 池交换事件
6. Cellana 汪池储备
7. 存入 USDt 到存储 0x3553(属于 0xc4bd)
CoinStore 和 FungibleStore 之间的相似之处:
FungibleStore 还增加了查找对象所有者的步骤,以了解谁获得了资产。
在内部,资源存储在以 state_key_hash
为键的插槽中( AIP-9)。可以在同一插槽中存储多种资源类型(resource_group_member)。对资源组内某个资源的任何更改都会导致所有资源被发出。这对于获取背景信息非常有用(例如,ObjectCore 的对象所有者资源在 FungibleStore 余额更改时会被发出)。
0. FungibleStore 持有的 USDt,属于被提取的池
1,2. 与 0 相同的 state_key_hash
,因此进行发出,尽管没有变化,可以在 ObjectCore(1)中找到 FA 的所有者
3. FungibleStore 属于发送者,取出的 USDt 存入其中
4,5. 与 3 相同的 state_key_hash
,因此也会被发出
6. CoinStore 持有 APT,属于 Cellana 钱包
7. FungibleStore 持有 (Cellana FA) APT,为池存入
8. 与 7 相同的 state_key_hash
,因此会被发出
9. CoinStore 持有的 APT,属于发送者
10. 发送者账户
11–17. Cellana 池(相同的 state_key_hash
)因费用会计的变化而被发出(16)
18. FungibleStore 持有的 (Cellana FA) APT 用于池费用
19. 与 18 相同的 state_key_hash
,因此也会被发出。
20–23. (Cellana FA) APT(相同的 state_key_hash
)因供应变化而发出(21)
24. APT 的供应作为表项。
与 CoinStore 不同,一个地址可以拥有多个 FungibleStore(如上所示的常规池和费用池)。这些将被表示为两个不同的对象,每个对象都有 FungibleStore,并且拥有相同的所有者和元数据(映射到相同的 FungibleAsset)。
对于大多数用例,每个用户只需要一个每种资产类型的 FungibleStore。我们将此特殊处理为“主可替代存储”,其地址是确定的,并使用 sha3_256(32-byte account address | 32-byte metadata object address | 0xFC)
导出( 参考)。
以下是验证此映射的 Python 代码:
import hashlib
def get_primary_fs_address(account_address, metadata_address):
"""
参数:
account_address: 一个 32 字节的十六进制字符串,表示账户地址。
metadata_address: 一个 32 字节的十六进制字符串,表示元数据地址。
返回:
一个 32 字节的十六进制字符串,表示主可替代存储地址。
"""
# 确保输入为 32 字节(64 个十六进制字符)
if len(account_address) != 66 or len(metadata_address) != 66 or not account_address.startswith("0x") or not metadata_address.startswith("0x"):
raise ValueError("账户地址和元数据地址必须是 32 字节十六进制字符串(包括 0x 前缀)。")
# 去掉 "0x" 前缀并转换为字节
account_bytes = bytes.fromhex(account_address[2:])
metadata_bytes = bytes.fromhex(metadata_address[2:])
fc_byte = bytes.fromhex("fc") # 0xFC 作为字节
# 拼接输入
input_bytes = account_bytes + metadata_bytes + fc_byte
# 计算 SHA3-256 哈希
sha3_hash = hashlib.sha3_256(input_bytes).digest()
# 将哈希转换为十六进制字符串
return "0x" + sha3_hash.hex()
## 示例用法:
account_address = "0xc4bd9cc8a2d85e9a9c89628dad734041477f86351eafc0b634114bc16d3451e8" # 发送者
metadata_address = "0x357b0b74bc833e95a115ad22604854d6b0fca151cecd94111770e5d6ffc9dc2b" # USDt
try:
hash_result = get_primary_fs_address(account_address, metadata_address)
print(f"主 FA 地址:{hash_result}") # 0x355303f5f1db46cc5917392cc8bf0b499c77846aedad54d7e2d7ada7328f477a
except ValueError as e:
print(f"错误:{e}")
在使用非主 fungible stores 的情况下(如上述池示例),我们可以使用 graphql 中的 current_fungible_asset_balances
(cfab)端点。
query cfab {
current_fungible_asset_balances(
where: {owner_address: {_eq: "0xe8797d7adaf48abd7becddc9c4494f1309d9a83a6ea0c4be708482cbc54e36af"}}
) {
storage_id
is_primary
asset_type
amount
last_transaction_version
}
}
storage_id
返回 FungibleStore 的地址,asset_type
返回可替代资产的地址。
请注意,对于本地迁移资产,还有单独的 _v1(币)和 _v2(FA)值,用于数量和资产类型(见下文)。amount
将包含币和 FA 的总和。
组合性是智能合约的一项强大特性,它大大增强了 DeFi 的灵活性和潜力。这允许合约之间无缝互动;例如,合约 A 可以调用合约 B,然后合约 B 可以调用合约 C,所有操作都在同一交易中执行。上述示例展示了通过一个池的 DeFi 交易,然而,使用一系列池的组合通常会提供更好的汇率。
Panora 是一个 DeFi 交换聚合器,它将寻找最佳路径(系列交换)并将其作为一笔交易提交。例如,以下 100 APT 的交易通过 Thetis 池和 ThalaSwap v2 池,最大化最终接收到的 lzUSDC 数量。
提交两个交易也可以完成同样的操作,然而,两个交易之间的链上状态可能已经改变,从而可能导致更差的汇率。聚合器构建的多次交换是原子性的,通过不断检索链上状态来寻找最佳路径。
顺便说一下,这就是过滤以获取合约地址的字段被称为 entry function 的原因。只有交易中调用的第一个函数才会被记录,事件可以用来推断在交易内调用的其他函数。此外,还可以不调用任何函数,提交一个运行脚本(二进制)的交易。
随着越来越多的合约被编写为 FA,将币锁定并铸造成特定 DeFi 平台的 FA(例如 Cellana FA APT)是相当繁琐的。为了解决此问题,我们引入了一种本地方式来迁移币 ⮂ FA( AIP-63)。
通过 2221267359 用户 0xa052 使用多个 Thala v1 和 Thala v2 池交换 3.79.. lzUSDC 以获取 0.004 APT。
在 octa(无小数)中,资产流动如下:
3_797_958 lzUSDC → 379_877_329 MOD(Thala v1 池)
379_877_329 MOD → 1_145_181_697 THL(Thala v1 池)
1_133_729_880 THL → 40_361_958 APT(Thala v1 池)
11_451_817 THL → 407_662 APT(Thala v2 池)
THL(币)的子集迁移到 FA 以通过 Thala v2 池进行交换,所得的 APT(FA)再次迁移回币。
FungibleStore 简称 FS
0. 从 0xa052 (发送者)取款 lzUSDC
1. Thala v1 池 lzUSDC — MOD 费用
2. Thala v1 池 lzUSDC — MOD 交换
3. Panora 交换
4. Thala v1 池 MOD — THL 费用
5. Thala v1 池 MOD — THL 交换
6. Panora 交换
7. Thala v1 池 THL — APT 费用
8. Thala v1 池 THL — APT 交换
9. Panora 交换
10, 11. THL(FA)在 FS 0x7bda 中的进出
12. Thala v2 池 THL — APT 费用 FS 存入 THL
13. Thala v2 池 THL — APT FS 存入 THL
14. Thala v2 池 THL — APT FS 取款 APT
15. Thala v2 池 THL — APT 交换
16, 17. APT(FA)在 FS 0x3ad 中的进出
18. Panora 交换
19. Panora 交换摘要
20. 存入 APT 给发送者
21. Gas费用声明
Panora 在每次交换后输出事件,并在最后给出总结。
Thala v1 池使用币,Thala v2 池使用 FA。在各种 Thala v1 池之间流动的币是没有事件的,因为不使用 CoinStore。一旦资产迁移到 FA,从 Thala v2 池进出则会有许多事件(10–17)。迁移是沉默的(没有事件),但可以通过 FA 的供应变化推断出来。
0xa 是原生 FA APT
0xb7cb 是 Panora
0,1,2,3,4,5. APT FA (0xa) 供应变化 -407_662(因迁移到币)
6. THL 币供应 -11_451_817(因迁移到 FA)
7. Panora 事件存储
8. Panora 事件存储
10,11,12,13,14. THL FA (0x377a) 供应变化 +11_451_817(迁移自币)
15,16. FungibleStore 的 APT (0x3ada) 余额为 0
17. Thalaswap v1 CoinStore 对 THL 的支持
18. Thalaswap v1 CoinStore 对 MOD 的支持
19. Thalaswap v1 CoinStore 对 lzUSDC 的支持
20. Thalaswap v1 池 lzUSDC — MOD
21. Thalaswap v1 池 lzUSDC — MOD 预言机
22. Thalaswap v1 池 THL — APT
23. Thalaswap v1 池 MOD — THL
24,25. FungibleStore 对 THL (0x7bda) 的余额为 0
26,27. FungibleStore 对 THL (0x84af) 的费用余额为 152_563_757
28. APT CoinStore 对 0xa052(发送者)供应变化 +40_697_120
29. lzUSDC CoinStore 对 0xa052(发送者)供应变化 -3_797_958
30. 0xa052(发送者)账户
31,32. FungibleStore 对 CELL (0xd060) 的余额为 0(不确定此处原因)
33,34. FungibleStore 对 THL (0xd970) 的余额为 THL-APT 池
35,36. FungibleStore 对 APT (0xf472) 的余额为 THL-APT 池
37. 表项跟踪 APT(币)供应
38. 表项记录 Thalaswap v1 池 MOD — THL
39. 表项记录 Thalaswap v1 池 THL — APT
40. 表项记录 Thalaswap v1 池 lzUSDC — MOD
变更 28 不完全相同于事件中的 APT,因为Gas支付的原因。
本地迁移在 coin_type 和 FA 地址之间存在确定性映射。
以下是验证 THL 映射的 Python 代码:
0x7fd500c11216f0fe3095d0c4b8aa4d64a4e2e04f83758462f2b127255643615::thl_coin::THL
0x377adc4848552eb2ea17259be928001923efe12271fef1667e2b784f04a7cf3a
import hashlib
def get_paired_fa(coin_type):
"""
https://github.com/aptos-labs/aptos-core/blob/677bfd1846bb6c064ea2dc9f7450790d3e305c23/sdk/src/types.rs#L151
参数:
coin_type: 表示币种类型的字符串。
返回:
一个 32 字节的十六进制字符串,表示可替代地址。
"""
# 确保输入为 32 字节(64 个十六进制字符)
if not coin_type.startswith("0x") or len(coin_type.split("::")) != 3:
raise ValueError("检查币种类型")
# 转换为字节
apt_metadata_bytes = bytes.fromhex("000000000000000000000000000000000000000000000000000000000000000a")
coin_type_bytes = coin_type.encode('utf-8')
object_suffix = bytes.fromhex("fe")
# 拼接输入
input_bytes = apt_metadata_bytes + coin_type_bytes + object_suffix
# 计算 SHA3-256 哈希
if coin_type == "0x1::aptos_coin::AptosCoin":
sha3_hash = apt_metadata_bytes
else:
sha3_hash = hashlib.sha3_256(input_bytes).digest()
# 将哈希转换为十六进制字符串
return "0x" + sha3_hash.hex()
## 示例用法:
coin = "0x7fd500c11216f0fe3095d0c4b8aa4d64a4e2e04f83758462f2b127255643615::thl_coin::THL" # THL
try:
hash_result = get_paired_fa(coin)
print(f"迁移的 FA 地址:{hash_result}") # 0x377adc4848552eb2ea17259be928001923efe12271fef1667e2b784f04a7cf3a
except ValueError as e:
print(f"错误:{e}")
在本地稳定币之前,Aptos 有来自 wormhole(桥接)和 layerzero(桥接)的桥接稳定币(USDC,USDT)。
Layerzero 桥接的资产变得更加流行,因为 wormhole 实现根据源链创建不同的资产,从而分割了流动性。
以下是一些桥接稳定币的 coin_type(FA 地址留给读者作为练习)
0xf22bede237a07e121b56d91a491eb7bcdfd1f5907926a9e58338f964a01b17fa::asset::USDC
layerzero 桥接的 USDC(lzUSDC)0xf22bede237a07e121b56d91a491eb7bcdfd1f5907926a9e58338f964a01b17fa::asset::USDT
layerzero 桥接的 USDT(lzUSDT)0x5e156f1207d0ebfa19a9eeff00d62a282278fb8719f4fab3a586a0a2c0fffbea::coin::T
wormhole 桥接的来自以太坊的 USDC(whUSDC)0xa2eda21a58856fda86451436513b867c97eecb4ba099da5775520e0f7492e852::coin::T
wormhole 桥接的来自以太坊的 USDT(whUSDT)0xc91d826e29a3183eb3b6f6aa3a722089fdffb8e9642b94c5fcd4c48d035c0080::coin::T
wormhole 桥接的来自Solana的 USDC(whUSDCso)0x79a6ed7a0607fdad2d18d67d1a0e552d4b09ebce5951f1e5c851732c02437595::coin::T
wormhole 桥接的来自 BSC 的 USDC(whUSDCbs)下面是本地稳定币的 FA 地址
0x357b0b74bc833e95a115ad22604854d6b0fca151cecd94111770e5d6ffc9dc2b
USDT0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b
USDC我们在 我们的探索者代码 中标记了一些地址,而社区维护一个 token 列表。稳定币和现实世界资产(RWAs,例如贷款)度量可以在 RWA.xyz 中找到。
我们有至少 3 个预言机向链上推送价格数据。我们有一些赞助的价格馈送,允许任何 dapp 访问最近的价格。由于数据在链上,因此可以通过以下方式访问:
SELECT
tx_version,
block_timestamp,
JSON_VALUE(key.name, '$.bytes') AS price_feed_id,
-- JSON_VALUE(value.content, "$.price_feed.price_identifier.bytes") AS price_feed_id,
TIMESTAMP_SECONDS(CAST(JSON_VALUE(value.content, "$.attestation_time") AS INT64)) as attestation_time,
TIMESTAMP_SECONDS(CAST(JSON_VALUE(value.content, "$.price_feed.price.timestamp") AS INT64)) as price_time,
TIMESTAMP_TRUNC(TIMESTAMP_ADD(TIMESTAMP_SECONDS(CAST(JSON_VALUE(value.content, "$.price_feed.price.timestamp") AS INT64)), INTERVAL 1 MINUTE), MINUTE) as ts_minute,
CAST(JSON_VALUE(value.content, "$.price_feed.price.price.magnitude") AS BIGNUMERIC) as price,
CAST(JSON_VALUE(value.content, "$.price_feed.price.expo.magnitude") AS BIGNUMERIC) as decimals,
CAST(JSON_VALUE(value.content, "$.price_feed.price.conf") AS BIGNUMERIC) as ci,
-- ema
CAST(JSON_VALUE(value.content, "$.price_feed.ema_price.price.magnitude") AS BIGNUMERIC) as price_ema,
CAST(JSON_VALUE(value.content, "$.price_feed.ema_price.conf") AS BIGNUMERIC) as ci_ema,
FROM `bigquery-public-data.crypto_aptos_mainnet_us.table_items`
WHERE 1=1
AND address = '0xd1321c17eebcaceee2d54d5f6ea0f78dae846689935ef53d1f0c3cff9e2d6c49' -- 这是表Handle
AND DATE(block_timestamp) = '2025-01-31'
LIMIT 100
Switchboard 向资源推送 价格 并可以通过以下方式检索:
-- https://app.switchboard.xyz/aptos/mainnet (加载可能需要一些时间)
SELECT
tx_version,
block_timestamp,
address AS oracle_address,
TIMESTAMP_SECONDS(CAST(JSON_VALUE(resource, "$.round_open_timestamp") AS INT64)) as round_open,
TIMESTAMP_SECONDS(CAST(JSON_VALUE(resource, "$.round_confirmed_timestamp") AS INT64)) as round_confirmed,
-- 跳过最大/最小/中位数解析
CAST(JSON_VALUE(resource, '$.result.value') AS BIGNUMERIC) AS price,
CAST(JSON_VALUE(resource, '$.result.dec') AS BIGNUMERIC) AS decimals,
FROM `bigquery-public-data.crypto_aptos_mainnet_us.resources`
WHERE 1=1
AND address IN (
'0xb8f20223af69dcbc33d29e8555e46d031915fc38cb1a4fff5d5167a1e08e8367', -- apt 预言机
'0x94a63284ace90c56f6326de5d62e867d915370a7d059bf974b39aefc699b8baa', -- usdt 预言机
'0xdc1045b4d9fd1f4221fc2f91b2090d88483ba9745f29cf2d96574611204659a5', -- usdc 预言机
'0xdc7f6fbc4efe2995e1e37b9f73d113085e4ee3597d47210a2933ad3bf5b78774', -- btc 预言机
'0x5af65afeeab555f8b742ce7fc2c539a5cb6a6fb2a6e6d96bc1b075fb28067808', -- sol 预言机
'0x7b5f536d201280a10d33d8c2202a1892b1dd8247aecfef7762ea8e7565eac7b6', -- eth 预言机
'0x4531f956f68ccf05ab29a1db5e73f7c828af5f42f2018b3a74bf934e81fef80f' -- cake 预言机
)
AND type_str = '0x7d7e436f0b2aafde60774efb26ccc432cf881b677aca7faaf2a01879bd19fb8::aggregator::AggregatorRound<0x7d7e436f0b2aafde60774efb26ccc432cf881b677aca7faaf2a01879bd19fb8::aggregator::CurrentRound>'
AND DATE(block_timestamp) = '2025-01-31'
LIMIT 100
Chainlink 将 价格 推送到 SmartTable (:c),最新价格可以通过视图函数检索:
curl --request POST \
--url https://fullnode.mainnet.aptoslabs.com/v1/view \
--header 'Accept: application/json, application/x-bcs' \
--header 'Content-Type: application/json' \
--data '{"function":"0x3f985798ce4975f430ef5c75776ff98a77b9f9d0fb38184d225adc9c1cc6b79b::registry::get_feeds","type_arguments":[],"arguments":[]}'
链上数据提供的透明性,加上解析和解释交易的能力,是 DeFi 的关键差异化因素。本文提供了对 Move 基础链上交换交易的实用指南,使有效分析 DeFi 交换成为可能。
从原始数据(事件、资源)起步可能具有挑战性,可以从由 fungible asset processor 创建的 parquet 文件中构建用于分析的派生表。
关于币与 FA 的更深入讨论可以在 最近的 Ottersec 博客 帖子中找到。
最后,作为给读者的练习,你能解析这些 DeFi 聚合交易发生了什么吗(2264429263、2134790741、2266956702、2142575114)?
- 原文链接: medium.com/aptoslabs/dat...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!