MerkleProof.sol 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. // SPDX-License-Identifier: MIT
  2. // OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/cryptography/MerkleProof.sol)
  3. pragma solidity ^0.8.0;
  4. /**
  5. * @dev These functions deal with verification of Merkle Trees proofs.
  6. *
  7. * The proofs can be generated using the JavaScript library
  8. * https://github.com/miguelmota/merkletreejs[merkletreejs].
  9. * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
  10. *
  11. * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
  12. */
  13. library MerkleProof {
  14. /**
  15. * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
  16. * defined by `root`. For this, a `proof` must be provided, containing
  17. * sibling hashes on the branch from the leaf to the root of the tree. Each
  18. * pair of leaves and each pair of pre-images are assumed to be sorted.
  19. */
  20. function verify(
  21. bytes32[] memory proof,
  22. bytes32 root,
  23. bytes32 leaf
  24. ) internal pure returns (bool) {
  25. return processProof(proof, leaf) == root;
  26. }
  27. /**
  28. * @dev Returns the rebuilt hash obtained by traversing a Merklee tree up
  29. * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
  30. * hash matches the root of the tree. When processing the proof, the pairs
  31. * of leafs & pre-images are assumed to be sorted.
  32. *
  33. * _Available since v4.4._
  34. */
  35. function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
  36. bytes32 computedHash = leaf;
  37. for (uint256 i = 0; i < proof.length; i++) {
  38. bytes32 proofElement = proof[i];
  39. if (computedHash <= proofElement) {
  40. // Hash(current computed hash + current element of the proof)
  41. computedHash = _efficientHash(computedHash, proofElement);
  42. } else {
  43. // Hash(current element of the proof + current computed hash)
  44. computedHash = _efficientHash(proofElement, computedHash);
  45. }
  46. }
  47. return computedHash;
  48. }
  49. function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
  50. assembly {
  51. mstore(0x00, a)
  52. mstore(0x20, b)
  53. value := keccak256(0x00, 0x40)
  54. }
  55. }
  56. }