# 密码学与区块链

By [R0chGh0st](https://paragraph.com/@r0ckgh0st) · 2022-09-12

---

1\. 密码学背景知识
===========

这一章节的作用就是介绍区块链是密码学的一项重要应用，通过介绍其中使用的密码学技术向大家强调私钥的重要性，如果确实不愿意理解这部分内容的请直接跳过，**只要记住私钥对于保护数字资产安全非常重要就可以了**。

### 1.1 杂凑函数与Merkle树

在以太坊中，杂凑函数（又称哈希函数）无处不在。哈希函数本身具有单向性性质，使得其在所有的加密货币中都有着广泛的应用。哈希函数能够将任意长度的输入映射为固定长度的输出，该输出也被称为散列值。在 ETH 中使用的杂凑函数为keccak256，能产生256bits长的摘要数据。

关于杂凑函数部分的内容，可以关注我在 Web3 Study 中编写的介绍，将详细介绍杂凑函数的参数特性，并代码角度介绍了杂凑使用方法及应用：利用钱包公钥配合keccak256生成钱包地址的方法。

[https://web3study.club/crypto/hash](https://web3study.club/crypto/hash)

Merkle树符合数据结构中所提到的树形结构，主要的作用是使用哈希树保存信息。Merkle树中，交易信息（数据或其哈希值）被记录于树的叶子节点上。以比特币中使用的二叉Merkle树为例，每个叶子都代表着一条交易对应的哈希值，按照从下至上的顺序，可以将两个相邻的叶子的哈希值组合，通过运算形成一个全新的哈希值，且该哈希值成为树节点后，可以继续与其相邻的节点组合。重复一定的次数之后，Merkle树的唯一根节点形成，将根节点保存在区块头中，对交易的验证仅仅需要对支付进行简单验证即可，同时支持验证支付协议SPV。下述代码给出了利用Merkle树构造 NFT 白名单的验证代码，并给出了leafNodes\[0\]对应地址在证明身份时需要提供的Hash证明序列信息。

    let hre = require("hardhat");
    let { MerkleTree } = require("merkletreejs");
    let { keccak256 } = require("keccak256");
    
    let whitelistAddress =
      ["0xcd404712d55d839902a9f4b5935f514829378728",
        "0xCCC26c4d84e997904Dc204d83ea912278C8b60a2",
        "0x72dA088a22D1ebcD790765977b09741bE0AB2819",
        "0xc02055721cD6a553Ac58487ABD1E085CFeF24521",
        "0x9f63389D0eb66FCc9D9631Cc5D0FcFe594DCb749",
        "0xb75f07A2749a312496788a7b73fDD386EA529F2B"];
    
    let leafNodes = whitelistAddress.map(addr => hre.ethers.utils.keccak256(addr))
    
    
    console.log(leafNodes);
    
    let Merkle_Tree = new MerkleTree(leafNodes, hre.ethers.utils.keccak256)//, { SortPairs: true });
    
    console.log(Merkle_Tree.toString());
    
    let hashing_proof = leafNodes[0];
    console.log(Merkle_Tree.getHexProof(hashing_proof));
    

![Hexproof在Merkle树中的对应信息](https://storage.googleapis.com/papyrus_images/ce8620f5d58c327586cc6e5c76a2bffc3dcaf5137aba4af3c3e18fdf9e04c10c.png)

Hexproof在Merkle树中的对应信息

Merkle树具备两项重要特征：快速定位修改和零知识证明。当交易数据被篡改时，只有根节点和与之相关的子节点路径会受到影响。由于根节点的哈希值会发生变化，沿着根节点进行追溯，即可以快速定位到实际发生改变的交易。在证明某个区块中包含某个交易的时候，仅仅需要构造merkle树，并公布对应的交易链条即可，验证者也仅需要验证生成的root是否与公布的一致，即可证明交易是否被包含在区块之中，且该过程不涉及到其他交易的真实内容。体现了零知识证明的特性：向验证者证明我有某个屋子的钥匙，但不直接把钥匙给验证者。

### 1.2 公钥密码学

公钥密码学是现代计算机和信息安全的重要技术之一。以太坊并没有像Web2.0的系统一样为用户提供中心化的用户管理服务，相反，其应用公钥密码学技术，通过在创建区块链钱包时生成公私钥对的方式为用户赋予身份，公钥是身份的唯一标识，而公钥和私钥组合在一起可以成功标识一个以太坊账户。公钥可帮助链上用户锁定目标，而私钥用于控制账户内持有的资产，**在交易中，私钥用来生成数字签名**，任何人（不管是黑客还是正常用户）掌握了私钥即掌握了私钥控制账户内持有的数字资产，因为他可以通过私钥签名一笔转移交易将账户内资产转移至其控制的区块链账户。

---

*Originally published on [R0chGh0st](https://paragraph.com/@r0ckgh0st/didPyvfOsBih71t9DPTl)*
