NEAR 協議

如何運行的

NearProtocolLightClient 是 NEAR 輕客戶端 在 Solidity 中作為 Mapo 合約的實現。 輕客戶端的狀態定義為:

  1. 當前頭部的BlockHeaderInnerLiteView(包含height, epoch_id, next_epoch_id, prev_state_root, outcome_root, timestamp,為下一個epoch設置的區塊生產者的hash next_bp_hash , 以及所有區塊哈希的 merkle 根 block_merkle_root);

  2. 當前和下一個時期的區塊生產者集合。

epoch_id 指的是當前已知頭部的區塊所屬的紀元,而 next_epoch_id 是接下來的紀元。

輕客戶端通過此處 描述的特定 RPC 端點定期獲取 LightClientBlockView 的實例來運行。

輕客戶端不需要接收所有塊的 LightClientBlockView。 擁有塊“B”的“LightClientBlockView”足以驗證“B”祖先(包括“B”本身)中任何塊中關於狀態或結果的任何陳述。 特別是,擁有頭部的 LightClientBlockView 足以在本地驗證規範鏈上任何區塊中關於狀態或結果的任何陳述。

然而,為了驗證特定“LightClientBlockView”的有效性,輕客戶端必須在前一個紀元中驗證至少一個區塊的“LightClientBlockView”,因此要同步到頭部,輕客戶端必須獲取並驗證一個“ LightClientBlockView` 每個時代過去了。

如何驗證

更新塊頭

struct LightClientBlock {
        bytes32 prev_block_hash;
        bytes32 next_block_inner_hash;
        BlockHeaderInnerLite inner_lite;
        bytes32 inner_rest_hash;
        OptionalBlockProducers next_bps;
        OptionalSignature[] approvals_after_next;
        bytes32 hash;   
        bytes32 next_hash;
}

struct BlockHeaderInnerLite {
        uint64 height; // Height of this block since the genesis block (height 0).
        bytes32 epoch_id; // Epoch start hash of this block's epoch. Used for retrieving validator information
        bytes32 next_epoch_id;
        bytes32 prev_state_root; // Root hash of the state at the previous block.
        bytes32 outcome_root; // Root of the outcomes of transactions and receipts.
        uint64 timestamp; // Timestamp at which the block was built.
        bytes32 next_bp_hash; // Hash of the next epoch block producers set
        bytes32 block_merkle_root;
        bytes32 hash; // Additional computable element
}

struct PublicKey {
        bytes32 k;
}

struct Signature {
        bytes32 r;
        bytes32 s;
}

struct BlockProducer {
        PublicKey publicKey;
        uint128 stake;
        // Flag indicating if this validator proposed to be a chunk-only producer (i.e. cannot become a block producer).
        bool isChunkOnly;
}

struct OptionalBlockProducers {
        bool some;
        BlockProducer[] blockProducers;
        bytes32 hash; // Additional computable element
}

struct OptionalSignature {
        bool some;
        Signature signature;
}


prev_block_hashnext_block_inner_hashinner_rest_hash 字段用於重建當前和下一個塊的哈希值,以及將要簽署的批准,按照以下方式(其中 block_viewLightClientBlockView 的實例 ):

輕客戶端使用來自 LightClientBlockView 的信息更新它的頭部,當且僅當:

1.區塊高度高於當前區塊頭高度; 2. 區塊的epoch等於當前頭部已知的next_epoch_id; 3. 如果區塊的epoch等於頭部的next_epoch_id,則next_bps不為None; 4. approvals_after_next 包含來自相應時期的區塊生產者的 approval_message 上的有效簽名(見下一節); 5. approvals_after_next 中的簽名對應於總股份的 2/3 以上(見下一節)。 6.如果next_bps不為none,則sha256(borsh(next_bps))對應inner_lite中的next_bp_hash

為了簡化協議,我們要求下一個塊和下一個塊之後的塊都與 LightClientBlockView 對應的塊處於同一紀元。 保證每個紀元至少有一個最終區塊,在它之上構建的下兩個區塊在同一紀元中。

驗證證明數據

為了驗證交易或收據是否發生在鏈上,輕客戶端可以通過 rpc 提供 receipt_id 和輕客戶端頭部的塊哈希來請求證明。 rpc 將返回以下結構

其中包括輕客戶端證明給定交易或收據的執行結果所需的一切。

證明驗證可以分為兩步,執行結果根驗證和區塊默克爾根驗證。

執行結果根驗證

如果交易或收據的結果根包含在塊“H”中,則“outcome_proof”包含“H”的塊哈希,以及其給定分片中執行結果的默克爾證明。 H 中的結果根可以重建為

這個結果根必須匹配block_header_lite.inner_lite中的結果根。

區塊 Merkle 根驗證

回看區塊哈希可以通過以下方式從 LightClientBlockLiteView 計算出來

預期的區塊 merkle 根可以計算為

它必須與輕客戶端頭的輕客戶端塊中的塊默克爾根匹配。

證明

輕客戶端區塊 LightClientBlock

交易證明

Last updated

Was this helpful?