---
# System prepended metadata

title: KrypoCamp 第二週課前學習MerkleTree

---

# KrypoCamp 第二週課前學習MerkleTree
### Merkle Tree概念
Merkle Tree是一種二元樹演算法。也就是Hash。
Hash基本上是一種不可逆的演算法。就是把一些可讀的或是相同的資料內容經過演算法變成不可讀或不會重覆的資料內容。
例如:
有一筆資料是MerkleTree，當MerkleTree經過Hash後變成QAZWSXEDC。如果當MerkleTree被改成merkltre時，經過Hash就會變成TGBYHNUJM，完全不一樣的資料內容。
只有是資料是MerkleTree經過Hash才會變成QAZWSXEDC。
而且獨立性，可防碰撞。
所以可以利用這方式來做為區塊鏈的資料驗証。

<p><a href="https://en.bitcoinwiki.org/wiki/File:Hash_Tree.svg#/media/File:Hash_Tree.svg"><img src="https://en.bitcoinwiki.org/upload/en/images/thumb/9/95/Hash_Tree.svg/1200px-Hash_Tree.svg.png" alt="Merkle tree - Hash tree"></a>

> 從葉節點向上計算出根節點
    
Top Hash 通常稱為root。
通常都會先把root產生出來，並記錄在合約上。
當有address要去mint時，可以用Merkle Tree來驗証是否為已知的address。如果是就能mint，不是就不能mint。
所以通常實作用於白名單。

### JavaScript 版本

- 安裝 merkletreejs 套件
- 安裝 ethers 套件

``` javascript=
const { MerkleTree } = require("merkletreejs");
const { ethers } = require("ethers");

const leaves = [
  { address: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" },
  { address: "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" },
  { address: "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC" },
].map((x) =>
  ethers.utils.keccak256(ethers.utils.solidityPack(["address"], [x.address]))
);
const tree = new MerkleTree(leaves, ethers.utils.keccak256, {
  sortPairs: true,
});

const root = tree.getHexRoot();
const leaf = ethers.utils.keccak256(
  ethers.utils.solidityPack(
    ["address"],
    ["0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC"]
  )
);
console.log(tree.getHexProof(leaf));
console.log(tree.verify(tree.getHexProof(leaf), leaf, root));
```
