阅读区块链入门指南笔记

阅读区块链入门指南笔记#

以下为阅读《区块链入门指南》 的笔记。

区块链基础知识与关键技术#

共识机制#

区块链网络是由多个网络节点组成的,其中每个节点都存有一份信息备份,那它们是如何对交易达成一致的呢?也就是说,它们作为独立的节点,需要有一种机制来保障互相信任,这就是共识机制。

常用的共识机制有PoW(Proof of Work)工作量证明,PoS(Proof of Stake)权益证明,DPoS(Delegated Proof of Stake委任权益证明,DBFT(Delegated Byzantine Fault Tolerance)等。

比特币/以太坊主要采用的是工作量证明机制,通过算力比拼来增加恶意节点的作恶成本。通过动态调整挖矿的难度来让一笔交易时间控制在 10 分钟左右(6 个确认),但随着比特币挖矿越来越火热,消耗资源越来越多,对环境造成破坏;有些矿池拥有大量资源,也会造成一些中心化的风险。

权益证明机制则是通过权益(一般是代币)持有者进行投票来达成共识。这种机制不需要像工作量证明一样进行大量的算力比拼,但是也有一些风险,称为Nothing at Stake问题,很多权益持有者会在所有区块都投注并从中获利。为了解决这个问题,系统设置了一些规则,如对同时在多个链创建区块的用户/在错误链上创建区块的用户设置一些惩罚机制。目前以太坊正在向这种共识机制转变。

EOS则采用了委任权益证明,选出一些代表性的节点来进行投票,这种方式目的是优化社区投票的效率和结果,但带来了一些中心化的风险。

DBFT共识机制则是通过对节点分配不同的角色来达成共识,这样可以很大程度降低开销和避免分叉,但是也有核心角色作恶的风险。

比特币核心技术解读#

节点分为全节点和轻节点两种,早期所有的节点都是全节点,但随着数据量越来越大,运行在手机或平板等设备上的比特币客户端不需要存储整个区块链的信息,称为Simplified Payment Verification(SPV)节点,也叫轻节点。

Merkle Tree(默克尔树)是区块链系统中非常核心的数据结构,主要用于数据完整性验证和提高效率。它在比特币、以太坊等主流区块链中都有使用。Merkle Tree 是一种哈希二叉树,每个叶子节点是一段数据(如交易记录)的哈希值,每个非叶子节点是其两个子节点哈希值的再哈希:

功能说明
数据完整性验证一笔交易变动会导致整棵树根变动
轻节点验证SPV 客户端只需 Merkle 证明即可验证交易
节省带宽不用全量同步交易数据

Merkle Tree 可以在不下载全部区块数据的情况下验证某笔交易是否包含在一个区块中。

这叫做 SPV(Simplified Payment Verification)轻节点机制,比特币钱包常用。

  • 只需下载:
    • 该交易的哈希值
    • 到 Merkle Root 的“路径节点”(叫 Merkle Proof)

有了钱包(和资产)后,就可以开始交易了。我们来通过一个典型的比特币交易来理解这一流程:

A 和 B 都拥有一个比特币钱包地址(可以用 Bitcoin Client 生成,原理如上),假设 A 要给 B 转账 5 个 BTC,A 需要得到 B 的钱包地址,然后用自己的私钥对A->B转账5个BTC这笔交易签名(因为 A 的私钥仅有自己知道,所以拥有私钥则是拥有钱包资产的归属权);然后发布这笔交易,在比特币系统中发起交易需要支付小额矿工费作为交易手续费;矿工会开始验证这笔交易的合法性,得到六个确认后交易就可以被比特币账本所接受,整个验证过程大约 10 分钟。

比特币系统中怎么避免双重花费呢?

比特币采用了一种叫UTXO(Unspent Transaction Outputs)的概念,当一个用户收到一笔 BTC 交易时,会计入UTXO中。

在这个示例中,A 想要给 B 转账 5 个 BTC,A 的这 5 个 BTC 可能来自于两个UTXO(2 BTC + 3 BTC),因此 A 在转账给 B 时,矿工需要检验的是这两笔UTXO在这笔交易之前有没有被花掉,如果检测已经被花费了,则交易不合法。

此外,UTXO有一个很重要的特性,不可分割,假如 A 有 20 个 BTC,他想转账 5 个 BTC 给 B,那交易会先将 20 个 BTC 作为输入,然后产生两个输出,一个向 B 转账 5 个 BTC,一个返还给 A 剩下的 15 个 BTC,因此,A 又拥有了一笔价值为 15 BTC 的 UTXO;如果单个UTXO不够支付,则可以组合多个形成输入,但总额一定要大于交易额。

矿工怎么验证交易发起者有足够的余额呢?

这个问题看起来很简单,第一反应是像支付宝这样查询一下余额是否足够就可以。但比特币是一种基于交易的账本模式,并没有帐户概念,因此并不能直接查询余额,要想知道一个帐户的剩余资产,则需要回顾以前所有的交易,并且找到所有UTXO并相加。

挖矿难度是如何调整的呢?

系统会在每产生 2016 个区块时(约两周)调整一次目标阈值,存在块头中,全网所有节点需要遵从新的难度进行挖矿,如果恶意节点不调整代码中的 target 的话,诚实的矿工则不会认可

Ethereum 核心技术解读#

比特币作为一种去中心化的数字货币,是极其成功的,但受限于比特币脚本(非图灵完备,只能处理一些简单的逻辑),并不能处理很复杂的业务。而Ethereum引入了智能合约,使去中心化的概念能够应用于更丰富的应用场景,因此也被称为区块链 2.0。

简单来说,Ethereum是一个开源的去中心化系统,使用区块链来存储系统状态变化,因此也被称为“世界计算机”;它支持开发者在区块链上部署运行不可变的程序,称为智能合约,因此可以支持广泛的应用场景;它使用数字货币Ether来衡量系统资源消耗,激励更多人参与Ethereum系统建设。

去中心化应用 DApp#

狭义来说,DApp 其实就是一个集成了用户界面、支持智能合约、运行于以太坊区块链上的应用。

ethereum_architecture

如上图所示,Ethereum应用实例部署在区块链网络上(智能合约运行于区块链虚拟机中),而 Web 程序只需要通过Web3.js对区块链网络进行RPC远程调用,这样用户就可以通过浏览器(DApp 浏览器或 MetaMask 等插件工具)访问去中心化服务应用了。

账户#

当我们需要登录一个网站或系统(比如邮箱)时,往往需要一个帐号和一个密码,密码通过加密算法以暗文的形式存储在中心化的数据库中。然而,以太坊是一个去中心化的系统,那是怎么生成账户的呢?

和比特币系统原理类似

  1. 首先生成一个仅有自己知道的私钥,假设为sk,采用ECDSA(Elliptic Curve Digital Signature Algorithm)椭圆曲线算法生成对应的公钥pk
  2. 采用keccak256算法对公钥pk求哈希值
  3. 截取后 160 位作为以太坊的地址

用户的私钥和地址一起组成了以太坊的账户,可以存储余额、发起交易等(比特币的余额是通过计算所有的UTXO得到的,而不是像以太坊一样存储在账户中)。

其实Ethereum账户分为两种类型,上述方式生成的叫Externally Owned Accounts(EOA),外部账户,也就是常规用户拥有的账户,主要是用来发送/接收Ether代币或者向智能合约发送交易(即调用智能合约)。

而另一种则是Contract Accounts,合约账户,不同于外部账户,这种账户是没有对应的私钥的,而是在部署合约的时候生成的,存储智能合约代码。值得注意的是,合约账户必须要被外部账户或者其他合约调用才能够发送或接收Ether,而不能自己主动执行交易。

钱包#

存储和管理Ethereum账户的软件/插件称为钱包,提供了诸如交易签名、余额管理等功能。钱包生成主要有两种方式,非确定性随机生成或根据随机种子生成。

智能合约#

上文提到,Ethereum区块链不仅仅存储交易信息,还会存储与执行智能合约代码。

智能合约控制应用和交易逻辑,Ethereum系统中的智能合约采用专属Solidity语言,语法类似于JavaScript,除此之外,还有Vyper、Bamboo等编程语言。智能合约代码会被编译为字节码并部署至区块链中,一旦上链则不可以再编辑。EVM作为一个智能合约执行环境,能够保障执行结果的确定性。

交易#

在Ethereum中,一个典型的交易是怎么样的呢?

  1. 开发者部署智能合约至区块链
  2. DApp 实例化合约、传入相应值以执行合约
  3. DApp 对交易进行数字签名
  4. 本地对交易进行验证
  5. 广播交易至网络中
  6. 矿工节点接收交易并进行验证
  7. 矿工节点确认可信区块后广播至网络中
  8. 本地节点与网络进行同步,接收新区块

架构#

ethereum_architecture_simple

Ethereum采用的是一种Order - Execute - Validate - Update State的系统架构。在这种架构下,当产生一笔新的交易,矿工会进行PoW工作量证明机制的运算;验证完成后,将区块通过gossip协议广播至网络中;网络中的其他节点接收到新区块后,也会对区块进行验证;最终,提交至区块链,更新状态。

Ethereum MPT(Merkle Patricia Tries)#

Ethereum 的 MPT(Merkle Patricia Trie)是以太坊中用于存储和验证数据结构的核心组成部分,它结合了 Merkle Tree 与 Patricia Trie 的优点,具备以下功能:

MPT(Merkle Patricia Trie)是一个确定性前缀树(deterministic prefix tree),带有加密哈希功能,主要用于:

  • 账户状态树(state trie):存储每个账户的 nonce、余额、存储根和代码哈希。
  • 存储树(storage trie):每个合约账户有自己的 trie,存储变量的 key-value。
  • 交易树(transaction trie):按顺序存储一个区块内所有交易。
  • 收据树(receipt trie):记录交易结果(gas 用量、日志等)。
特性描述
哈希结构所有节点都以 RLP 编码后,再进行 Keccak256 哈希计算
可验证性通过 Merkle Proof 机制,可验证某个 key 是否存在
前缀压缩Patricia Trie 会合并重复路径,提高查找效率
不可变性修改数据后整棵树哈希变化,因此可防篡改、可回滚

QA:

  • Pactricia Trie 是路径压缩的前缀树。 Trie 结构比较浪费存储空间,当键值对分布稀疏时效率较低,而以太坊的账户地址是 40 位十六进制数,地址约为 2^160 种,极其稀疏(防止哈希碰撞)。因此,需要对 Trie 结构进行路径压缩,也就是 Pactricia Trie,经过压缩后,树的高度明显减少,空间和效率都得到提升。