type
status
date
slug
summary
tags
category
icon
password
这段时间对区块链的技术原理产生兴趣,找了北大肖臻老师的《区块链技术与应用》来看,学完了 BTC 数据结构部分,趁着周末时间用 Java 实现了一个简易的比特币区块链数据结构,模拟了链上交易、挖矿等基本功能,写篇文章来记录一下。

比特币区块链特性

比特币区块链的设计和实现的核心是通过一种高度安全、去中心化的公共账本来记录所有比特币交易,这个账本是通过一个持续增长的区块链实现的,每个区块中包含多个交易。
区块链系统满足了下面几个关键特性:
  1. 安全性和不可篡改性 区块链中每个区块的哈希值都是通过 SHA-256 加密哈希函数基于其内容计算的出,而下一个区块中又包含着上一个区块的哈希值,因此对区块数据的任何微小修改都会引起这个区块和后续区块哈希值的巨大变化,从而被其他网络节点检测到。 每个区块使用Merkle树来组织和验证交易数据的完整性。Merkle根是所有交易哈希的总和,存储在区块头部,为所有包含的交易提供了一种验证机制。 工作量证明(Proof of Work)要求矿工解决复杂的计算问题以添加新区块,增加了对任何尝试篡改区块的昂贵计算成本,保证了安全性。
  1. 分布式和去中心化 比特币使用点对点网络(P2P),每个节点都持有区块链的完整副本,或至少是其关键部分的副本。通过向矿工提供区块奖励,激励矿工参与交易验证和区块创建过程,来维持整个区块链网络的运行。
  1. 透明性和匿名性 每笔交易都被记录在公开可查询的区块链上,任何人都可以查看交易的历史纪录和区块详细信息,但同时你的个人信息不会暴露出来,区块链上唯一的身份标识就是你的公链地址。

技术实现

下面区块链的简易实现,完整代码可以通过
Bitcoin
wanghao-SunSkyUpdated Jun 24, 2024
这个链接查看。
首先区块链是为了满足比特币交易,而一个基本的交易包含:交易 ID、交易发起人、交易接收人、交易金额、时间戳
其中交易 ID 由其它信息计算 Hash 得出。

区块用来存放多个交易,区块由矿工打包而成,除了包含一系列链上交易信息之外,还要包含一些额外信息来保证区块链的安全性。
  • previousHash:上一个区块的 Hash 值,作为连接上一个区块的指针。
  • merkleRoot:由区块内的交易通过一个 merkle 树,每笔交易作为一个叶子节点,两两 Hash 得到的最终的一个根哈希值。任何一笔交易信息的变动,都会导致最终根哈希值的不同。
  • Nonce 和 Target:比特币区块链产生新区块的过程被称为挖矿,而挖矿就是找到一个值(Nonce),使其和区块头中其他信息共同得到的 Hash 值小于某个 Target。Target 会随着时间以及当前链上算力的变化而调整,以保证能让矿工每隔大概 10min 挖出一个新区块。
初此之外区块头里还有些其他信息,比如 version(区块链版本),以及 timeStamp(时间戳)等,下面是一个区块结构的 Java 实现
一个区块由区块头(Block Header)和区块体(Block Body)组成。区块体中包含每笔交易,区块头中包含所需要的一些信息。计算区块的 Hash 值时只计算区块头中的信息,因为区块头中已经包含了每笔交易两两 hash 而成的 Merkle 根。
每笔交易在添加进入区块时,都要验证其是否合法,比如要验证交易发起者的签名是否能和其公钥对应上,验证交易发起者的余额是否能让其完成本次支付等。
挖矿的过程就是穷举nonce 值,使区块头的整体 Hash 值小于给定的 target 值。

有了区块就要有区块链,区块链中维护着还未被打包到区块中的交易,以及上面提到的难度目标和挖矿奖励(矿工每挖掘出一个区块获得的比特币奖励,用来激励矿工参与交易和打包的过程,每四年会进行减半)等。
矿工打包时会从当前未打包的交易中优选选择对自己更有利的交易,比如交易费用更高的交易,这样能为矿工带来更高的矿工费收益。

最后实现一个简易的挖矿过程:
 
区块链在实际实现上更加复杂,下面是一个比特币区块的实际案例:
notion image

写在最后

本文只是我学习区块链一周后对其结构的一个粗浅理解和总结,有很多不足和没有考虑到的地方,请谅解。

📎 参考文章

 
 
我的博客搭建之旅初探 Cloudflare Workers