MerkleTreeWithHistory.sol 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // https://tornado.cash
  2. /*
  3. * d888888P dP a88888b. dP
  4. * 88 88 d8' `88 88
  5. * 88 .d8888b. 88d888b. 88d888b. .d8888b. .d888b88 .d8888b. 88 .d8888b. .d8888b. 88d888b.
  6. * 88 88' `88 88' `88 88' `88 88' `88 88' `88 88' `88 88 88' `88 Y8ooooo. 88' `88
  7. * 88 88. .88 88 88 88 88. .88 88. .88 88. .88 dP Y8. .88 88. .88 88 88 88
  8. * dP `88888P' dP dP dP `88888P8 `88888P8 `88888P' 88 Y88888P' `88888P8 `88888P' dP dP
  9. * ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
  10. */
  11. pragma solidity ^0.5.8;
  12. library Hasher {
  13. function poseidon(uint256[] memory input) public pure returns (uint256);
  14. }
  15. contract MerkleTreeWithHistory {
  16. uint256 public levels;
  17. uint8 constant ROOT_HISTORY_SIZE = 100;
  18. uint256[] private _roots;
  19. uint256 public current_root = 0;
  20. uint256[] private _filled_subtrees;
  21. uint256[] private _zeros;
  22. uint32 public next_index = 0;
  23. constructor(uint256 tree_levels, uint256 zero_value) public {
  24. levels = tree_levels;
  25. _zeros.push(zero_value);
  26. _filled_subtrees.push(_zeros[0]);
  27. for (uint8 i = 1; i < levels; i++) {
  28. _zeros.push(hashLeftRight(_zeros[i-1], _zeros[i-1]));
  29. _filled_subtrees.push(_zeros[i]);
  30. }
  31. _roots = new uint256[](ROOT_HISTORY_SIZE);
  32. _roots[0] = hashLeftRight(_zeros[levels - 1], _zeros[levels - 1]);
  33. }
  34. function hashLeftRight(uint256 left, uint256 right) public pure returns (uint256 hash) {
  35. uint256[] memory data = new uint256[](2);
  36. data[0] = left;
  37. data[1] = right;
  38. hash = Hasher.poseidon(data);
  39. }
  40. function _insert(uint256 leaf) internal {
  41. uint32 current_index = next_index;
  42. require(current_index != 2**levels, "Merkle tree is full. No more leafs can be added");
  43. next_index += 1;
  44. uint256 current_level_hash = leaf;
  45. uint256 left;
  46. uint256 right;
  47. for (uint256 i = 0; i < levels; i++) {
  48. if (current_index % 2 == 0) {
  49. left = current_level_hash;
  50. right = _zeros[i];
  51. _filled_subtrees[i] = current_level_hash;
  52. } else {
  53. left = _filled_subtrees[i];
  54. right = current_level_hash;
  55. }
  56. current_level_hash = hashLeftRight(left, right);
  57. current_index /= 2;
  58. }
  59. current_root = (current_root + 1) % ROOT_HISTORY_SIZE;
  60. _roots[current_root] = current_level_hash;
  61. }
  62. function isKnownRoot(uint256 root) public view returns(bool) {
  63. if (root == 0) {
  64. return false;
  65. }
  66. // search most recent first
  67. uint256 i;
  68. for(i = current_root; i < 2**256 - 1; i--) {
  69. if (root == _roots[i]) {
  70. return true;
  71. }
  72. }
  73. // process the rest of roots
  74. for(i = ROOT_HISTORY_SIZE - 1; i > current_root; i--) {
  75. if (root == _roots[i]) {
  76. return true;
  77. }
  78. }
  79. return false;
  80. // or we can do that in other way
  81. // uint256 i = _current_root;
  82. // do {
  83. // if (root == _roots[i]) {
  84. // return true;
  85. // }
  86. // if (i == 0) {
  87. // i = ROOT_HISTORY_SIZE;
  88. // }
  89. // i--;
  90. // } while (i != _current_root);
  91. }
  92. function getLastRoot() public view returns(uint256) {
  93. return _roots[current_root];
  94. }
  95. function roots() public view returns(uint256[] memory) {
  96. return _roots;
  97. }
  98. function filled_subtrees() public view returns(uint256[] memory) {
  99. return _filled_subtrees;
  100. }
  101. function zeros() public view returns(uint256[] memory) {
  102. return _zeros;
  103. }
  104. }