# 【技术向】Sei Labs工程师发现IBC索引差异

By [Sei中文](https://paragraph.com/@sei) · 2023-11-27

---

[Subscribe](null)

Inter-Blockchain Communication (IBC) 协议是一个开创性的框架，旨在促进独立区块链之间的安全无缝通信，使它们能够相互传输代币和数据。IBC是一项复杂而具有挑战性的技术。

在过去的几个月里，Sei实验室工程团队观察到在几个第三方服务商上，Sei区块链上OSMO代币的总流入和流出存在差异。Sei实验室团队经过调查和分析确定了问题的可能原因：这些不匹配是由第三方服务商索引和解释数据的方式导致的。值得注意的是，这并不是由于任何链级问题。

本博文将详细介绍如何发现、调查此问题，并提出两种潜在解决方案。

注：在调查后，[Flipside Crypto](https://flipsidecrypto.xyz/?ref=blog.sei.io)团队被告知了此问题，并迅速修复，我们对他们的合作和支持表示感谢。

发现
--

问题最初是通过[Flipside报告](https://flipsidecrypto.xyz/hess/sei-bridge-flow-%F0%9F%9A%A2-sei-bridge-flow-RNy-4y?ref=blog.sei.io)暴露的，该报告似乎显示Sei区块链上OSMO的总流入自启动第二天以来似乎总比总流出要小。这是没有道理的 - 要进行交易流出，必须先放入代币，因此总流入必须等于或大于总流出。唯一可能发生这种情况的合理解释是Sei和Osmosis两侧IBC逻辑存在错误。

Sei实验室工程团队在Mintscan上查找了类似但不同的结果。差异如下：

*   [Mintscan](https://www.mintscan.io/sei/relayers?ref=blog.sei.io)：自主网启动以来OSMO多流出约4917796；
    
*   [Flipside](https://flipsidecrypto.xyz/hess/sei-bridge-flow-%F0%9F%9A%A2-sei-bridge-flow-RNy-4y?ref=blog.sei.io)：自主网启动以来OSMO多流出约3219878。
    

为了确定这些不一致性的起源，Sei实验室工程师重新索引了Sei主网启动后的前几天数据。他们的研究证实了流入和流出总量是一致的：

    (Net_Inflow_18520000_to_19300000 - Net_Outflow_18520000_to_19300000) + Bank Supply of IBC Uosmo on height 18520000 = total supply of uosmo at height 19300000.
    
    In this equation: Net_Inflow_18520000_to_19300000 = 289607886926903
    Net_Outflow_18520000_to_19300000 = 288034713858306 
    Bank Supply of IBC Uosmo on height 18520000 = 20685000 
    Bank supply of uosmo at height 19300000 = 1573193753597
    

调查
--

Sei实验室工程师现在已经发现了两个不同的第三方数据提供商看似不一致的流入和流出总量问题，并进行了根本原因分析。

在确认链上总量确实如预期般正确匹配后，关注点转向了第三方服务商如何对IBC数据进行索引。[Flipside](https://flipsidecrypto.xyz/?ref=blog.sei.io)在[GitHub](https://github.com/FlipsideCrypto/sei-models/tree/main?ref=blog.sei.io)上开源了他们的数据模型，因此这是一个好的起点。

Flipside的数据模型通过观察区块链上的 ['ibc\_transfer'](https://github.com/FlipsideCrypto/sei-models/blob/4402e94021d93f6fbbc5c480f9b1149ac193ddf1/models/silver/core/silver__transfers.sql?ref=blog.sei.io) 活动计算IBC流出，通过观察 ['write\_acknowledgement' 消息和 'packet\_data' 属性](https://github.com/FlipsideCrypto/sei-models/blob/main/models/silver/core/silver__transfers.sql?ref=blog.sei.io#L112-L138)计算IBC流入。

让我们看一下成功的IBC转账是如何进行的：

![来自链A到链B的原生代币（例如Sei上的Usei）的IBC转账](https://storage.googleapis.com/papyrus_images/e896ad64df18167f0a4b4be54c171ead08d2ea2720e7b206ce0805f7080c5816.png)

来自链A到链B的原生代币（例如Sei上的Usei）的IBC转账

1.  在链A上创建数据包（源链）：
    
    a. 链A上的用户启动向链B的代币转账。
    
    b. 这个操作导致在链A上创建一个表示代币转账的IBC数据包。链A上的代币被保存在**IBC托管**账户中，确保它们不会被双重花费。需要注意的是，这里的每个通道对应一个唯一的托管账户，例如osmo<>sei通道的[托管账户](https://www.seiscan.app/pacific-1/accounts/sei1a53udazy8ayufvy0s434pfwjcedzqv34mqnnd0/overview)与axelar<>sei通道的托管账户不同。
    
    c. **交易＃1：在链A上进行一次交易以启动转账。**
    
2.  将数据包中继到链B：
    
    a. 一个中继者注意到链A上的新数据包，并提交了一笔交易到链B作为中继数据包。
    
    b. 交易＃2：在链B上进行一次交易以接收数据包。
    
3.  在链B上处理数据包（目标链）：
    
    a. 链B处理数据包，为预期的接收方在链B上铸造相应的代币，然后生成确认。
    
4.  将确认中继到链A：
    
    a. 一个中继者注意到链B上的确认，并提交了一笔交易到链A来中继这个确认。
    
    b. 交易＃3：在链A上进行一次交易以处理确认。
    

因此，如果所有的**IBC转账**消息都被记录，而所有的交易都按照上述方式进行，总数就会匹配，对吧？理论上是的。

实际上，有一个问题：超时。一些IBC转账创建时带有超时参数，可以指定为块高度、时间戳，有时两者都有。在此时间或块高度之后，IBC数据包将被视为超时……那么接下来会发生什么？

![由于超时而未成功的来自链A到链B的IBC转账](https://storage.googleapis.com/papyrus_images/52e13432153215938c381f2abddaa1dff68e7609ef5e5c71f40319605a8f117e.png)

由于超时而未成功的来自链A到链B的IBC转账

如果一个中继者试图将一个已超时的IBC数据包中继到链B的IBC模块，该模块将返回一个超时错误。中继者通知链A上的发送模块数据包已超时（使用TimeoutPacket）。原本要转账的代币被发送回转账发起者，IBC转账失败。

现在您已经看到了IBC转账交易的生命周期，并了解了由于超时而导致这些交易有时会失败的原因，您就能理解在数据中观察到的IBC流入/流出差异的可能原因。Sei Labs工程团队回顾了Sei区块链启动后几天的交易数据。的确有许多流出IBC转账超时的情况。

第三方数据索引器将每个ibc\_transfer事件都计入IBC流出，即使该转账后来超时 - 即使转账交易在源链上最初成功，仍然有可能在中继期间超时。因此，这些数据提供商计算的总IBC流出既代表了成功的IBC转账，也代表了那些已经超时的转账。这就是为什么IBC流出大于流入的原因。

建议解决方案
------

与其处理IBC转账事件以获取流入/流出金额，Sei Labs工程团队建议统计从IBC模块账户中转出或转入的所有非本地代币的总量，因为这考虑了上述所有情况（即转入、转出以及超时后的退款）。

他们提供了以下代码片段，以实现这种方法来解析金额：

    // IBC Transactions: Check tx event for event type 'transfer' between ibc-transfer module account and sei account
    // Example: {"type":"transfer","attributes":
    // [{"key":"recipient","value":"sei1z3g0ccd0gpe6m4afjjmtxka269yyrymhwwvf3x"},
    //   {"key":"sender","value":"sei1yl6hdjhmkf37639730gffanpzndzdpmhrn8l3z"}, 
    // {"key":"amount","value":"7898600ibc/2CC0B1B7A981ACC748547..."}]}
    func ParseBridgeTx(txResponse *sdktypes.TxResponse, chainId string, msgTypes []string) ([]types.RawBridgeTx, error) {
    
        // txResponse here is the result the same as `seid q txs --events`
        for _, log := range txResponse.Logs {
            for _, event := range log.Events {
    ...
                if event.Type != transferEventType {
                    continue
                }
    ...
                amountCoins, err := sdktypes.ParseCoinsNormalized(amount)
                for _, amountCoin := range amountCoins {
    
                    // Case: IBC Transfer Bridge In or IBC Timeout Refund
                    if sender == IBCTransferModuleAccount {
                        bridgeUserAddress = recipient
                        bridgeAddress = sender
                        bridgeTxType = IBCTransferBridgeInType
                    }
    
                    // Case: IBC Transfer Bridge Out
                    if recipient == IBCTransferModuleAccount {
                        bridgeUserAddress = sender
                        bridgeAddress = recipient
                        bridgeTxType = IBCTransferBridgeOutType
                    }
    ...
                }
            }
        }      
    

在源链上对原生代币的流入和流出金额进行索引的方法与对非原生代币进行索引的方法相同。唯一的微妙区别是，与其从IBC模块账户中计算转账信息，你应该从**特定的IBC托管账户（用于你的通道）中计算**。

结论
--

在本报告中，我们阐述了Inter-Blockchain Communication（IBC）协议及其复杂的流入和流出索引过程的细微差异。

正如在Flipside仪表板中观察到的不一致性所证明的那样，索引中的异常可能导致社区内的误解。在使用IBC时，特别是在网络拥塞或遇到意外情况（如数据包超时）的情况下，所有利益相关方都必须意识到IBC的细微数据差异。

Sei Labs工程团队要对所有社区成员和利益相关方表达感谢，感谢他们的耐心和信任。团队已经充分配备并致力于确保我们链上所有IBC交易的透明度、准确性和效率。我们坚定不移地致力于建立信任，以维护IBC生态系统的完整性。

* * *

**Sei —— 专为交易设计的最快 L1**
-----------------------

不想错过 Sei 的最新动态？点击下方按钮免费订阅！

[“Sei中文”官方推特](https://twitter.com/Sei_ZH)、[Sei中文电报群](https://t.me/sei_chinese_group)、[Sei中文公告电报群](https://t.me/sei_chinese_announcement)已开通，现在Follow来第一时间了解Sei的最新进展：

[Subscribe](null)

---

*Originally published on [Sei中文](https://paragraph.com/@sei/sei-labs-ibc)*
