MerkleProof.sol 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. // SPDX-License-Identifier: MIT
  2. // OpenZeppelin Contracts (last updated v4.6.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. * WARNING: You should avoid using leaf values that are 64 bytes long prior to
  14. * hashing, or use a hash function other than keccak256 for hashing leaves.
  15. * This is because the concatenation of a sorted pair of internal nodes in
  16. * the merkle tree could be reinterpreted as a leaf value.
  17. */
  18. library MerkleProof {
  19. /**
  20. * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
  21. * defined by `root`. For this, a `proof` must be provided, containing
  22. * sibling hashes on the branch from the leaf to the root of the tree. Each
  23. * pair of leaves and each pair of pre-images are assumed to be sorted.
  24. */
  25. function verify(
  26. bytes32[] memory proof,
  27. bytes32 root,
  28. bytes32 leaf
  29. ) internal pure returns (bool) {
  30. return processProof(proof, leaf) == root;
  31. }
  32. /**
  33. * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
  34. * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
  35. * hash matches the root of the tree. When processing the proof, the pairs
  36. * of leafs & pre-images are assumed to be sorted.
  37. *
  38. * _Available since v4.4._
  39. */
  40. function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
  41. bytes32 computedHash = leaf;
  42. for (uint256 i = 0; i < proof.length; i++) {
  43. bytes32 proofElement = proof[i];
  44. if (computedHash <= proofElement) {
  45. // Hash(current computed hash + current element of the proof)
  46. computedHash = _efficientHash(computedHash, proofElement);
  47. } else {
  48. // Hash(current element of the proof + current computed hash)
  49. computedHash = _efficientHash(proofElement, computedHash);
  50. }
  51. }
  52. return computedHash;
  53. }
  54. function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
  55. assembly {
  56. mstore(0x00, a)
  57. mstore(0x20, b)
  58. value := keccak256(0x00, 0x40)
  59. }
  60. }
  61. }