【大白話解析】 OpenZeppelin 的 MerkleProof 庫:Solidity 默克爾證明驗證工具全指南??(附源代碼)

?? 一、Merkle Tree 是什么?為什么要驗證它?

想象你有一個名單,比如:

["Alice", "Bob", "Charlie", "Dave"]

你想讓別人驗證:“我(比如 Alice)是不是在這個名單里?”,但不想把整個名單都放在區塊鏈上(太貴!)。

于是你用一種數據結構 —— ??Merkle Tree(默克爾樹)??,把所有名字(或它們的哈希)組織成一棵樹,最終得到一個唯一的“總照片”叫 ??Merkle Root(根哈希)??,你把這個根哈希存在區塊鏈上。

別人(比如 Alice)給你:

  • 她自己的名字的哈希(leaf)

  • 從她到根路徑上的一些“鄰居哈希”(proof)

  • 一組“怎么拼”的規則(proofFlags,或者按順序)

  • 你就能用這些信息,??在鏈上計算出根哈希,看是否和你存證的一樣??,如果一樣,說明她在名單里 ?


??? 二、這個庫(MerkleProof.sol)是干嘛的?

這是一個 ??工具庫(Library)??,提供了一系列函數,用來:

  • 驗證 ??單個數據?? 是否屬于某個 Merkle Tree

  • 驗證 ??多個數據(批量)?? 是否同屬于某個 Merkle Tree

  • 支持 ??不同存儲方式(memory / calldata)??

  • 支持 ??默認 Keccak256 哈希 或 自定義哈希函數??

它封裝了所有和 Merkle Proof(默克爾證明)驗證相關的核心邏輯,讓開發者可以很方便地集成到自己的 DApp / 合約中。


?? 三、文件結構 & 導入說明

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;import {Hashes} from "./Hashes.sol";
  • 使用 ??Solidity 0.8.20??

  • 引入了一個工具庫 Hashes.sol,它提供了一個關鍵函數:

    commutativeKeccak256(a, b)→ 這是一個 ??可交換順序的 Keccak256 哈希函數??,即 hash(a,b) == hash(b,a),這在構建 Merkle Tree 時非常有用,因為父子節點的左右順序有時不重要。


? 四、自定義錯誤

error MerkleProofInvalidMultiproof();
  • 當你傳入的 ??證明數據(proof)和葉子數據(leaves)不匹配??(數量不對,結構不合理)時,就會報這個錯,防止無效驗證。


? 五、核心功能分類

這個庫主要提供兩類驗證:

  1. ??單個數據驗證(verify / processProof)??

  2. ??多個數據同時驗證(multiProofVerify / processMultiProof)??

并且每種都支持:

  • ??普通版本(memory 存儲)??

  • ??高效版本(calldata 存儲,省 gas)??

  • ??默認 Keccak256 哈希??

  • ??自定義哈希函數??

我們逐一來看 ??


?? 1. 單個數據驗證(memory版)

?? 函數:verify(proof, root, leaf)

 /*** @dev 驗證單個葉子是否屬于默克爾樹* @param proof 證明路徑數組,包含從葉子到根的所有兄弟哈希* @param root 默克爾樹的根哈希* @param leaf 待驗證的葉子哈希* @return 如果驗證成功返回true,否則返回false* * 示例:* 假設默克爾樹有4個葉子:A、B、C、D* 驗證C是否在樹中:* bytes32[] memory proof = [D的哈希, (A+B)的哈希];* bool isValid = MerkleProof.verify(proof, rootHash, hash(C));*/function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {// 處理證明并與根哈希比較return processProof(proof, leaf) == root;}
  • ??作用??:驗證一個 leaf(比如你的地址哈希)是否屬于某個 Merkle Tree(通過 root 和 proof)

  • ??參數??:

    • proof: 從該葉子到根路徑上的 “兄弟節點哈希” 數組

    • root: Merkle Tree 的根哈希(存在鏈上的那個)

    • leaf: 你要驗證的葉子哈希(比如 keccak256(你的地址))

  • ??返回??:true/false,是否驗證通過

?? ??它是怎么做的???

  • 調用了 processProof(proof, leaf),這個函數會:

    • 從你的葉子開始

    • 依次和 proof 里的“兄弟哈希”做哈希組合(一層一層往上爬)

    • 最終得到一個哈希,就是這棵樹的根

  • 然后判斷這個計算出來的根,是否等于傳入的 root,一樣就 ?

?? 函數:processProof(proof, leaf)

/*** @dev 處理證明路徑,從葉子計算出根哈希* * 【實際區塊鏈場景】:* 比如你參與了一個 Token 空投,項目方用 Merkle Tree 管理所有空投用戶,* 你拿到:* - 你的葉子:你的錢包地址的哈希(比如 0x1111...)* - 一個證明路徑(proof):包含你從葉子到根過程中,每一層的“隔壁節點哈希”(兄弟節點)* - 你調用這個函數,傳入你的葉子 + 證明路徑,它就會幫你算出整棵樹的根哈希* - 然后你拿這個根去和項目方存在鏈上的根對比,如果一樣,你就能領空投啦!?* * @param proof 證明路徑數組*    這是一個數組,里面裝的是你在從葉子到根的過程中,每一層需要用到的“兄弟節點哈希”*    比如:[0x2222..., 0x3333..., 0x4444...],它們是你路徑上的“鄰居”* * @param leaf 待驗證的葉子哈希*    這是你自己的數據哈希,比如你的錢包地址經過 keccak256 后的值:0x1111...* * @return 計算得到的根哈希*    最終拼出來的 Merkle 樹的根,用來和鏈上存證的根做對比*/function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {// ?? 初始化:我們從葉子節點開始,這就是你自己的數據哈希bytes32 computedHash = leaf;// 比如:computedHash = 0x1111111111111111111111111111111111111111(你的地址哈希)// ?? 遍歷證明路徑中的每一個兄弟節點哈希,逐步向上計算父節點哈希for (uint256 i = 0; i < proof.length; i++) {// ?? 每次循環,你都會拿到一個“兄弟節點哈希”:proof[i]// 比如第1次循環:proof[0] = 0x2222...,第2次:proof[1] = 0x3333...,依此類推// ?? 使用一個“可交換的哈希函數”來合并:computedHash(你的節點)和 proof[i](兄弟節點)// 這里調用了 Hashes.commutativeKeccak256(...),它本質上就是 keccak256(abi.encodePacked(a, b))// 但“可交換”意味著你先傳 a 還是 b 都沒關系,結果是一樣的(keccak 本身是可交換的,只要順序一致)computedHash = Hashes.commutativeKeccak256(computedHash, proof[i]);// 【例子】:// 第1次循環:computedHash = keccak256(0x1111..., 0x2222...) → 假設結果是 0x1234...// 第2次循環:computedHash = keccak256(0x1234..., 0x3333...) → 假設結果是 0x5678...// 第3次循環:computedHash = keccak256(0x5678..., 0x4444...) → 假設最終根是 0xAAAA...}// ?? 最終返回:經過所有證明路徑節點合并后,得到的根哈希return computedHash;// 比如最終返回:0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA(Merkle 樹的根)}
  • 內部實現:就是不斷地把你的 leaf 和 proof 里的哈希兩兩組合(用commutativeKeccak256),最終返回根哈希


?? 2. 單個數據驗證(memory版,帶自定義哈希函數)

/*** @dev 帶自定義哈希函數的單個葉子驗證* @param proof 證明路徑數組* @param root 默克爾樹的根哈希* @param leaf 待驗證的葉子哈希* @param hasher 自定義哈希函數* @return 驗證結果* * 示例:* 使用SHA256作為哈希函數(需提前實現)* bool isValid = MerkleProof.verify(proof, rootHash, hash(C), sha256Hash);*/function verify(bytes32[] memory proof,bytes32 root,bytes32 leaf,function(bytes32, bytes32) view returns (bytes32) hasher) internal view returns (bool) {return processProof(proof, leaf, hasher) == root;}

這個功能是基于之前提到的:

??1. 單個數據驗證(memory版)??

的 ??升級版??,區別在于:

  • 之前用的哈希函數是 ?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/94285.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/94285.shtml
英文地址,請注明出處:http://en.pswp.cn/web/94285.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

機械學習綜合練習項目

數據集合完整項目文件已經上傳一、項目介紹案例介紹 案例是針對“紅酒.csv”數據集&#xff0c;在紅葡萄酒質量分析的場景 中&#xff0c;利用多元線性回歸來探索紅葡萄酒的不同化學成分如何共同 影響其質量評分。在建立線性回歸模型之后&#xff0c;當給出了紅葡萄酒 的新的一…

第3篇:配置管理的藝術 - 讓框架更靈活

前言 在前一章中&#xff0c;我們設計了強大的注解API。本章將深入探討配置管理系統的設計&#xff0c;學習如何將注解中的聲明式配置轉換為運行時可用的配置對象。 配置管理的核心挑戰 在我們的框架中&#xff0c;配置來源有三個層級&#xff1a;主要挑戰&#xff1a; &#x…

發版混亂怎么規范

你是否經歷過這種場景&#xff1a;臨到發版&#xff0c;一堆功能代碼擠在一起&#xff0c;測試分不清范圍&#xff0c;修復一個Bug可能引發三個新Bug&#xff1f;發布過程像一場豪賭&#xff1f;問題的核心往往在于分支策略和流程的混亂。今天&#xff0c;我們就來建立一套在絕…

【golang長途旅行第30站】channel管道------解決線程競爭的好手

channel 為什么需要channel 使用全局變量加鎖同步來解決goroutine的競爭&#xff0c;可以但不完美難以精確控制等待時間?&#xff08;主線程無法準確知道所有 goroutine 何時完成&#xff09;。全局變量容易引發競態條件?&#xff08;即使加鎖&#xff0c;代碼復雜度也會增加…

蘋果XR芯片介紹

蘋果的 XR 芯片技術主要體現在 A 系列、M 系列處理器以及專為空間計算設計的 R1 協處理器中。以下從技術架構、產品迭代和綜合對比三個維度展開分析&#xff1a;一、技術架構解析1. A 系列芯片&#xff08;以 A12 Bionic 為例&#xff09;制程工藝&#xff1a;7nm&#xff08;臺…

達夢數據庫巡檢常用SQL(三)

達夢數據庫巡檢常用SQL(三) 數據庫SQL運行檢查 數據庫SQL運行檢查 死鎖的事務情況: SELECT TO_CHAR(HAPPEN_TIME,YYYY-MM-DD HH24:MI:SS) HAPPEN_TIME,SQL_TEXT FROM V$DEADLOCK_HISTORY WHERE HAPPEN_TIME >DATEADD(DAY,-30,

基于SpringBoot的校園周邊美食探索及分享平臺

1. 項目簡介 項目名稱&#xff1a;校園周邊美食探索及分享平臺 項目背景&#xff1a;針對校園師生對周邊美食信息的需求&#xff0c;構建一個集美食推薦、鑒賞、評論互動及社交功能于一體的平臺&#xff0c;幫助用戶發現優質美食資源并進行分享交流。 主要目標&#xff1a; 提供…

Go數據結構與算法-常見的排序算法

雖然看過別人寫了很多遍&#xff0c;而且自己也寫過很多遍&#xff08;指的是筆記&#xff09;&#xff0c;但是還是要寫的就是排序算法。畢竟是初學Go語言&#xff0c;雖然之前寫過&#xff0c;但是還是打算再寫一遍。主要包括插入排序、選擇排序、冒泡排序、快速排序、堆排序…

第 6 篇:目標規則與負載均衡 - `DestinationRule` 詳解

系列文章:《Istio 服務網格詳解》 第 6 篇:目標規則與負載均衡 - DestinationRule 詳解 本篇焦點: 深入理解 DestinationRule 的核心作用:定義流量在到達目的地之后的行為。 詳細剖析其三大核心功能:服務子集 (Subsets), 流量策略 (Traffic Policy), TLS 設置。 動手實戰…

一個簡潔的 C++ 日志模塊實現

一個簡潔的 C 日志模塊實現 1. 引言 日志功能在軟件開發中扮演著至關重要的角色&#xff0c;它幫助開發者追蹤程序執行過程、診斷問題以及監控系統運行狀態。本文介紹一個使用 C 實現的輕量級日志模塊&#xff0c;該模塊支持多日志級別、線程安全&#xff0c;并提供了簡潔易用…

C語言---數據類型

文章目錄數據類型分類1. 基本類型 (Basic Types)a. 整數類型 (Integer Types)char (字符型)int (整型)short (短整型)long (長整型)long long (C99標準引入)圖片匯總b. 浮點類型 (Floating-Point Types)float (單精度浮點型)double (雙精度浮點型)long double (長雙精度浮點型)…

本搭建烏云漏洞庫

1.下載鏡像站文件&#xff0c;并拖入虛擬機 2.將bugs.rar解壓至網站根目錄下 /var/www/html 3.配置bugs/conn.php 4.在bugs下創建upload目錄&#xff0c;將10-14、15-a、15-b、16壓縮包文件解壓到該upload目錄 5.把wooyun.rar解壓到 /mysql/data/wooyun目錄下 6.配置hosts文件后…

Vmware虛擬機 處理器配置選項配置介紹

1. 處理器配置選項好&#x1f44c;&#xff0c;我來幫你逐一解讀 VMware 里 虛擬機處理器 這些選項的含義。 你截的圖里&#xff0c;主要有三塊內容&#xff1a; 處理器數量 每個處理器的內核數量 ©虛擬化引擎1?? 處理器數量 這是分配給虛擬機的 邏輯 CPU 插槽數。一般…

day40-tomcat

1.每日復盤與今日內容1.1復盤keepalived高可用配置搶占式與非搶占式腦裂keepalived處理Nginx掛掉1.2今日內容部署、安裝、配置tomcat(systemctl)Tomcat主配置文件部署靜態頁部署zrlog&#x1f35f;&#x1f35f;&#x1f35f;&#x1f35f;&#x1f35f;接入負載均衡掛載到NFS2…

【RA-Eco-RA4E2-64PIN-V1.0 開發板】步進電機的串口控制

【RA-Eco-RA4E2-64PIN-V1.0 開發板】步進電機的串口控制 本文介紹了 RA-Eco-RA4E2-64PIN-V1.0 開發板通過串口指令實現 28BYJ-48 步進電機旋轉角度和速度的精確控制的項目設計。 項目介紹 硬件連接&#xff1a;28BYJ-48 步進電機、ULN2003 驅動板、Jlink 調試器、供電電源等&am…

PiscCode基于 Mediapipe 的人體多模態關鍵點檢測與可視化系統 —— HumanMultiLandmarker 深度解析

一、引言 在計算機視覺領域&#xff0c;人體關鍵點檢測&#xff08;Human Pose Estimation&#xff0c;HPE&#xff09;一直是研究和應用的熱點方向之一。隨著深度學習與實時圖像處理技術的發展&#xff0c;人體姿勢估計已經從傳統的 2D 檢測走向了 3D 空間建模&#xff0c;并…

文獻閱讀筆記【物理信息機器學習】:Physics-informed machine learning

文獻閱讀筆記&#xff1a;Physics-informed machine learningSummaryResearch ObjectiveBackground / Problem Statement問題背景研究現狀需解決的問題問題出現的原因分析問題解決思路Method(s)問題建模作者解決問題的方法/算法1. 觀測偏差&#xff08;Observational Biases&am…

Linux服務環境搭建指南

實驗拓撲概述**實驗拓撲&#xff1a; APPSRV&#xff1a; 主機名&#xff1a;appsrv.example.com ip地址&#xff1a;192.168.100.10 網關&#xff1a;192.168.100.254 網卡為NAT模式 STORAGESRV&#xff1a; 主機名&#xff1a;storagesrv.example.com ip地址&#xff1a;192.…

[特殊字符] 數據庫知識點總結(SQL Server 方向)

一、數據庫基礎概念數據庫&#xff08;Database&#xff09;&#xff1a;存儲和管理數據的容器。數據表&#xff08;Table&#xff09;&#xff1a;以行和列形式組織數據。行&#xff08;Row&#xff09;&#xff1a;一條記錄。列&#xff08;Column&#xff09;&#xff1a;字…

【PSINS工具箱】MATLAB例程,二維平面上的組合導航,EKF融合速度、位置和IMU數據,4維觀測量

文章目錄關于工具箱程序簡介代碼概述核心功能與步驟運行結果MATLAB代碼關于工具箱 本文所述的代碼需要基于PSINS工具箱&#xff0c;工具箱的講解&#xff1a; PSINS初學指導&#xff1a;https://blog.csdn.net/callmeup/article/details/137087932 本文為二維平面上的定位&am…