1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 |
- // SPDX-License-Identifier: MIT
- // OpenZeppelin Contracts (last updated v4.6.0) (utils/cryptography/MerkleProof.sol)
- pragma solidity ^0.8.0;
- /**
- * @dev These functions deal with verification of Merkle Trees proofs.
- *
- * The proofs can be generated using the JavaScript library
- * https://github.com/miguelmota/merkletreejs[merkletreejs].
- * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
- *
- * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
- *
- * WARNING: You should avoid using leaf values that are 64 bytes long prior to
- * hashing, or use a hash function other than keccak256 for hashing leaves.
- * This is because the concatenation of a sorted pair of internal nodes in
- * the merkle tree could be reinterpreted as a leaf value.
- */
- library MerkleProof {
- /**
- * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
- * defined by `root`. For this, a `proof` must be provided, containing
- * sibling hashes on the branch from the leaf to the root of the tree. Each
- * pair of leaves and each pair of pre-images are assumed to be sorted.
- */
- function verify(
- bytes32[] memory proof,
- bytes32 root,
- bytes32 leaf
- ) internal pure returns (bool) {
- return processProof(proof, leaf) == root;
- }
- /**
- * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
- * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
- * hash matches the root of the tree. When processing the proof, the pairs
- * of leafs & pre-images are assumed to be sorted.
- *
- * _Available since v4.4._
- */
- function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
- bytes32 computedHash = leaf;
- for (uint256 i = 0; i < proof.length; i++) {
- bytes32 proofElement = proof[i];
- if (computedHash <= proofElement) {
- // Hash(current computed hash + current element of the proof)
- computedHash = _efficientHash(computedHash, proofElement);
- } else {
- // Hash(current element of the proof + current computed hash)
- computedHash = _efficientHash(proofElement, computedHash);
- }
- }
- return computedHash;
- }
- function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
- assembly {
- mstore(0x00, a)
- mstore(0x20, b)
- value := keccak256(0x00, 0x40)
- }
- }
- }
|