https://github.com/anders94/blockchain-demo
这是原代码github的地址,此工程主要对哈希运算,区块链,分布式区块链,代币,币基概念进行了可视化展示。
一、运行环境配置
笔者使用的是windows环境,因此需要配置安装Node.js环境(Node.js 是一个基于 Chrome V8 JavaScript 引擎构建的 JavaScript 运行时环境。简单来说,Node.js 让 JavaScript 可以在服务器端运行,而不仅仅局限于浏览器中),可以参考下面的教程安装配置。
https://blog.youkuaiyun.com/Natsuago/article/details/145567734
然后管理员模式打开cmd,首先git clone https://github.com/anders94/blockchain-demo.git
然后cd到项目路径,npm install
之后就是npm start,在浏览器输入http://localhost:3000
二、项目复现
1、哈希(Hash)
对于sha256算法可以参考下面的blog,有很详细的解释
SHA-256算法流程分析与详解——Github工程结合示例和动画演示-优快云博客
2、区块(Block)
在一个区块内,初始无数据,有一个初始的额随机数使得无数据时区块的哈希值满足开头四个0,但是当输入数据时,哈希值就会发生变化,可见原来的随机数不满足区块的哈希值为开头四个0
这个时候我们点击挖矿,也就是让随机数从0开始递增,每递增一个数和当前有数据的区块计算一次哈希值,直到满足所得的哈希值开头为四个0为止,这个过程就是挖矿(mining)
此时随机数进行了更新,同时更新的随机数和数据一起计算的区块的哈希值满足了开头4个0的条件,至此挖矿过程结束。
在上述描述中我们把希望的开头四个0的哈希值称为难度等级,可以在对应的文件中进行修改。
但是由于十六进制值中有 16 种可能的字符,每次将难度增加 1,谜题就会变得 16 倍困难
3、区块链(Blockchain)
这里涉及到在区块链数据结构中存储交易记录,如下图所示,区块1中包括区块头和根为R12的默克尔树(包含了被标记为交易1和交易2的两笔交易以及分别指向它们的哈希引用R1和R2),区块2除了包括区块头2和根为R34的默克尔树之外,还包含一个对区块头1的哈希引用B1,同理区块3也包含一个对区块头2的哈希引用B2,而对于区块1而言,它是整个区块链的开头,因此不存在前一个区块,也不包含对前一个区块头的任何引用。
同时,对于区块链结构,如果仅改变最后一个区块的数据并进行挖矿则与第二部分介绍的过程相同
本区块挖矿后仅更新本区块的随机数,不会影响前面的区块
但是,如果改变前面区块的输入,则会影响后面的区块,例如改变区块4的输入,区块5的哈希值也会收到影响。
这个时候只能区块4重新挖矿,区块5重新挖矿,才能得到正确的链。
区块链的数据结构主要包括区块头和包含交易数据的默克尔树,这样的链状结构使得区块链对于数据修改变得非常敏感,例如下图中,如果交易2被修改,则指向交易2的哈希引用R2变了,对应的默克尔树的根R12也发生变化,从而指向区块头1的哈希引用B1无效,进而连锁反应B2也会无效。
因此,要想修改某笔交易记录就要引发修改的点开始依次重写区块数据,一直到整条链的末端,成本巨大;除此之外,哈希难题对于每一个区块头都是唯一的,这取决于其独特的内容,这两点保证了历史交易记录的不可变性。区块头的每一次重写都需要解决哈希难题,这就使区块链数据结构成为一个仅可添加新数据的结构。
每个区块头必须满足以下规则:
(1)它必须包含对前一个区块头的有效哈希引用
(2)必须包括有效交易数据的默克尔树的根
(3)必须包含正确的哈希难度等级
(4)其时间戳需在之前区块头标记的时间戳之后
(5)必须包含一个随机数
(6)上述5个数据组合在一起计算出的哈希值满足难度等级
验证规则确保只有付出计算成本解决哈希难题之后,才能将新区块添加到区块链数据结构中(通过解决哈希难题,向区块链数据结构中添加新区块的活动,也被称为挖矿)
4、分布式的区块链(Distributed Blockchain)
分布式账本(Distributed Ledger)是一种在多个节点之间共享、复制和同步的账本。它不依赖于任何中心化的机构来维护和管理,而是通过网络中的所有节点共同参与,确保数据的一致性和准确性。
对于分布式的区块链而言,如果区块未被修改,则每个节点下的各条区块链数据均相同,节点(peer)A、B、C均相同。
但是如果某个节点下的某各区块发生修改,例如我们修改节点B下区块4的数据,
我们将节点B的区块4和区块5都重新挖矿(remined)后发现节点A和节点C的最后一个区块的hash开头均为0000e4b,而发生修改的节点B下的最后一个区块的hash变为了0000621,一对比就可以发现是节点B下的数据被更改了。
这也体现了分布式账本的特点
- 去中心化:账本分布在多个节点上,没有单一的控制中心。这意味着即使某个节点出现问题,整个系统仍然可以正常运行。
- 透明性:所有参与者都可以查看账本上的交易记录。这种透明性有助于建立信任,减少欺诈行为。
- 不可篡改性:一旦交易被记录在账本上,就很难被修改或删除。这是因为每个节点都保存了账本的完整副本,任何篡改行为都会被其他节点发现。
- 高可用性与容错性:由于账本数据在多个节点中分布和备份,即便部分节点发生故障,系统依然能够正常运作,保持数据的一致性和可访问性。
5、代币(Tokens)
代币(Token) 是区块链上的 数字资产,具有一定的价值、功能或权益。它与 区块链原生币(如 ETH、BTC) 不同,通常是在现有区块链(如以太坊、BSC、Solana)上发行的。
和之前的区块链数据不同,这里我们更加细化模拟了交易的内容,详细记录了交易的转移
同理如果我们如果改变某笔交易,会使后面的区块全部失效,需要remined
需要注意的是这里我们交易记录只包含了金额的流向,而不包含账户的余额。
6、币基交易(coinbase transaction)
比特币区块链上的每个区块之中都会包含一个或者多个交易( transaction ),其中第一个交易就叫做 Coinbase 交易。Coinbase 交易是矿工创建的,主要是为了奖励矿工为了进行 POW 挖矿而付出的努力。
奖励分为两部分。一部分是出块奖励,这部分是相对固定的,当前每个区块的出块奖励是12.5BTC,每四年减半一次。另外一部分是手续费,当前区块的每个交易中都会包含一定的对矿工的奖励,也就是交易手续费。创建 Coinbase 交易的时候,矿工会把所有交易中的手续费累加到一起,然后把这笔钱转账给自己。
简单来说 coinbase 就是系统生成的币。“Coinbase 交易”也叫做 “Generation 交易”,也就是“生成交易”,这是因为其他的普通交易中,都是去转账已有的比特币,而这个交易是专门从无到有的去生成新的比特币的。精确一点说,coinbase 就是“生成交易”中的 input 。
在这个demo中我们在最初的区块中增加了币基交易,即生成了100的代币支付给了anders