AppHash)。
对于 ibc-go 而言,有两类重要的证明:存在性证明和不存在性证明,这两个术语也常与成员证明和非成员证明交替使用。在本指南中,我们统一使用“存在性”和“不存在性”。
存在性证明
存在性证明用于那些需要验证对手方状态、且交易执行后会写入可证明状态的 IBC 交易。例如,这包括对握手和数据包相关的 IBC store 状态进行验证。 简单来说,存在性证明用于证明树中确实存在某个特定的键和值。在底层,一个 IBC 存在性证明由两个证明组成:其一是证明该键存在于 IBC store/IBC 根哈希中的 IAVL 证明,其二是证明 IBC 根哈希存在于 multistore 根哈希中的证明。不存在性证明
不存在性证明用于验证对手方状态中某项数据的缺失,即证明某个键在状态中不存在。如上所述,这类证明可用于让数据包超时:通过证明对手方尚未将数据包回执写入 store,从而说明一次代币转账并未成功发生。 某些树(例如 SMT)可能会为不存在的键设置一个哨兵空子节点。在这种情况下,ICS-23 证明规范应包含这个EmptyChild,以便 ICS-23 能正确处理不存在性证明。
在某些情况下,如果对手方没有能力证明某项数据不存在,就有必要对不存在性证明进行“模拟”。由于验证方法的设计将完整控制权交给客户端实现,因此客户端可以通过验证一个非空哨兵值 ABSENCE 的存在,来支持那些不提供缺失证明的链。在这些特殊情况下,所提供的证明将是一个 ICS-23 Existence 证明,而客户端将验证在给定高度下,给定路径上是否存储了 ABSENCE 值。
状态验证方法:VerifyMembership 和 VerifyNonMembership
所有 IBC 数据类型的状态验证函数现已整合为两个通用方法:VerifyMembership 和 VerifyNonMembership。
根据 LightClientModule 接口定义,可以看到:
exported.Path,其定义见 ICS-24 host requirements。成员验证要求调用方提供以 []byte 编组后的值。对于非数据包处理的验证,延迟周期值应设为零。core IBC 现在允许证明高度为零,并且可以将其传入 VerifyMembership 和 VerifyNonMembership。如果零证明高度属于无效行为,则轻客户端负责返回错误。
具体示例请参见 ICS-23 implementation。
IBC uses merkle proofs in order to verify the state of a remote counterparty state machine given a trusted root, and ICS-23 is a general approach for verifying merkle trees which is used in ibc-go. Currently, all Cosmos SDK modules contain their own stores, which maintain the state of the application module in an IAVL (immutable AVL) binary merkle tree format. Specifically with regard to IBC, core IBC maintains its own IAVL store, and IBC apps (e.g. transfer) maintain their own dedicated stores. The Cosmos SDK multistore therefore creates a simple merkle tree of all of these IAVL trees, and from each of these individual IAVL tree root hashes it derives a root hash for the application state tree as a whole (the
AppHash).
For the purposes of ibc-go, there are two types of proofs which are important: existence and non-existence proofs, terms which have been used interchangeably with membership and non-membership proofs. For the purposes of this guide, we will stick with “existence” and “non-existence”.
Existence proofs
Existence proofs are used in IBC transactions which involve verification of counterparty state for transactions which will result in the writing of provable state. For example, this includes verification of IBC store state for handshakes and packets. Put simply, existence proofs prove that a particular key and value exists in the tree. Under the hood, an IBC existence proof is comprised of two proofs: an IAVL proof that the key exists in IBC store/IBC root hash, and a proof that the IBC root hash exists in the multistore root hash.Non-existence proofs
Non-existence proofs verify the absence of data stored within counterparty state and are used to prove that a key does NOT exist in state. As stated above, these types of proofs can be used to timeout packets by proving that the counterparty has not written a packet receipt into the store, meaning that a token transfer has NOT successfully occurred. Some trees (e.g. SMT) may have a sentinel empty child for non-existent keys. In this case, the ICS-23 proof spec should include thisEmptyChild so that ICS-23 handles the non-existence proof correctly.
In some cases, there is a necessity to “mock” non-existence proofs if the counterparty does not have ability to prove absence. Since the verification method is designed to give complete control to client implementations, clients can support chains that do not provide absence proofs by verifying the existence of a non-empty sentinel ABSENCE value. In these special cases, the proof provided will be an ICS-23 Existence proof, and the client will verify that the ABSENCE value is stored under the given path for the given height.
State verification methods: VerifyMembership and VerifyNonMembership
The state verification functions for all IBC data types have been consolidated into two generic methods, VerifyMembership and VerifyNonMembership.
From the LightClientModule interface definition, we find:
exported.Path, as defined in ICS-24 host requirements. Membership verification requires callers to provide the value marshalled as []byte. Delay period values should be zero for non-packet processing verification. A zero proof height is now allowed by core IBC and may be passed into VerifyMembership and VerifyNonMembership. Light clients are responsible for returning an error if a zero proof height is invalid behaviour.
Please refer to the ICS-23 implementation for a concrete example.