mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2025-01-08 03:51:20 +00:00
34 lines
1.1 KiB
Solidity
34 lines
1.1 KiB
Solidity
|
// SPDX-License-Identifier: MIT
|
||
|
pragma solidity ^0.8.0;
|
||
|
|
||
|
library Merkle {
|
||
|
function checkMembership(
|
||
|
bytes32 leaf,
|
||
|
uint256 index,
|
||
|
bytes32 rootHash,
|
||
|
bytes memory proof
|
||
|
) internal pure returns (bool) {
|
||
|
require(proof.length % 32 == 0, "Invalid proof length");
|
||
|
uint256 proofHeight = proof.length / 32;
|
||
|
// Proof of size n means, height of the tree is n+1.
|
||
|
// In a tree of height n+1, max #leafs possible is 2 ^ n
|
||
|
require(index < 2 ** proofHeight, "Leaf index is too big");
|
||
|
|
||
|
bytes32 proofElement;
|
||
|
bytes32 computedHash = leaf;
|
||
|
for (uint256 i = 32; i <= proof.length; i += 32) {
|
||
|
assembly {
|
||
|
proofElement := mload(add(proof, i))
|
||
|
}
|
||
|
|
||
|
if (index % 2 == 0) {
|
||
|
computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
|
||
|
} else {
|
||
|
computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
|
||
|
}
|
||
|
|
||
|
index = index / 2;
|
||
|
}
|
||
|
return computedHash == rootHash;
|
||
|
}
|
||
|
}
|