区块链是如何工作的——用JavaScript演示
段琰baby
发表于 2022-11-20 23:53:01
136
0
0
这听起来很棒,那它是如何工作的呢?
9 R( V% q( e4 o% [5 s+ L
为了说明区块链,我们将会使用一个名为BlockchainCLI的开源命令行工具。
我同时也建立了一个基于浏览器的版本; |. r& j% T# V! ~0 c+ {
' F# e& Q/ Q. |! ^0 K2 G, w3 g: G/ C
安装命令行工具* T5 q+ ^6 J- ~7 X
在此之前请先安装Node.js, k6 c; s. e2 K. z# u4 c7 q
然后在你的命令行中运行以下指令:
npminstallblockchain-cli-g
blockchain! t$ l8 f3 A1 o1 k/ P
1 k* g% d$ \ E7 `' H7 ^0 u
你应该会看到?WelcometoBlockchainCLI!和一个blockchain→提示。这说明已经准备好了。# N) j! _% V. Z
区块长什么样?' u, n, d- D& Y% K3 ~# G/ ]
想要查看当前的区块链,你需要在命令提示行下输入blockchain或者bc。你应该会看到像下面的图片一样的一个区块。% f& g% U( Z9 C
Index:是哪一个区块(创世块的索引是0)
Hash:块是否有效?
PreviousHash:前一个区块是否有效?0 d, E* E7 b; O* {# x" N
Timestamp:什么时候添加的区块?7 z. f1 h, u2 W% G/ m7 ~+ D$ J
9 A- U, h+ i0 b
Data:什么信息存储在区块上?0 v$ B% A$ q. g7 ^7 t* |: b
Nonce:在找到有效区块之前,我们进行了多少次迭代?$ f' o% S( a! |1 T: c/ h- E. i
' C" T' G3 E: d, r9 W* [& P
创世块5 a0 D, d3 j+ o
% ?4 J* p0 g E1 w
每一个区块链都是从?GenesisBlock开始的。正如你们将要在后面看到的,区块链上的每一个区块都依赖于前一个区块。所以,需要创世块来挖出我们的第一个区块。
h) Q6 x% r7 A7 x$ v1 Y
当一个新的区块被开采时会发生什么? b4 A8 O2 \4 u) h, y
c" Y& }' r3 K4 O* b! f
让我们挖出我们的第一个区块。在命令行中输入minefreeCodeCamp。7 P2 H* e7 L F4 x
区块链查看链上最新的区块来获取index和previoushash。在这个案例下创世块是最新的区块。
& v7 l: n3 P6 Z- T3 P2 x; f
Index:0+1=19 ]1 [9 l' u9 N6 z G
- n/ i2 p2 F' |. ]/ X4 B
PreviousHash:0000018035a828da0…
0 Q' C9 o6 r' b# {
Timestamp:区块被添加的时间
Data:freeCodeCamp8 b# N7 F1 H9 |& K
Hash:???
7 V, S# L- x- K4 {
Nonce:???
1 u$ e6 P- O: t p; r- u7 S# f5 X
Hash是如何计算的?
哈希值是唯一标识数据的固定长度的数值。
Hash是通过将Index、PreviousHash、Timestamp、Data和Nonce作为输入值来计算的。# {2 G1 ~9 x W4 A- Z0 ~
CryptoJS.SHA256(index+previousHash+timestamp+data+nonce)4 s c9 B3 _' g- h2 K' M
SHA256算法将会依据这些输入计算出一个唯一Hash值。同样的输入总是会返回同样的结果。
你是否注意到区块Hash中的四个前导0?# @. a# D5 k; S3 ?! {, u
3 N @. o$ _% M0 N
四个前导0是一个有效Hash的最低要求。所需前导0的数量被称之为难度) L5 E; C8 U" e/ a0 F N
functionisValidHashDifficulty(hash,difficulty){( t9 z2 a8 X" r5 C
! ~5 @! |- `$ V! |
for(vari=0,b=hash.length;i=difficulty;
}
这也被称为工作证明系统
3 a- P( O7 U& ~
Nonce是什么?
& P, S0 o% w$ n/ O E P7 g
Nonce是用来查找一个有效Hash的次数。3 m6 o4 I+ q9 B$ O6 U4 v" Y
! g- b) ?- `0 U# b6 P
letnonce=0;
: `: c# W# q" V g4 h$ i
lethash;/ e3 `5 L, i. {. Z1 a" E; {$ y# L) ]2 M
( r5 v, ]: ?4 c- W( g
letinput;
while(!isValidHashDifficulty(hash)){
nonce=nonce+1;
input=index+previousHash+timestamp+data+nonce;
' Y7 }. m, v# B( V
hash=CryptoJS.SHA256(input)
7 H2 ^/ S8 e( b! \' U
}
Nonce迭代到直到Hash有效。在我们的案例中,一个有效的Hash至少要拥有4个前置0。查找与有效Hash对应的Nonce的过程就是挖矿。; ^8 d. U/ X) f: Q4 ]/ k
随着难度的增加,可能的有效Hash数量就会减少。伴随着有效Hash的减少,我们需要更强的算力来查找有效Hash。) x8 |1 F/ q' g, d' m
! V6 X# ?+ U* Q: Y5 f+ d4 j
为什么这么重要?
这些机制非常重要,它们使区块链不可变。" M0 {( H, q2 ~' j
如果我们有这么一个区块链“A->B->C”,而且有一个人想要改变区块A上的数据。那么会发生什么呢?! _0 E3 F/ @! @" Z7 h. M; T
区块A上的数据改变了。( | s8 X! S6 A- L% l
; Z; ^3 S4 p( a7 D, g
区块A的hash改变了,因为数据被用来计算hash。
区块A失效了,因为它的hash不再有4个前导0。
3 U% N" k+ d1 B: r
区块B的hash改变了,因为区块A的hash被用来计算区块B的hash。 l' t9 H% U; X# U% F2 Z
2 z F, n6 i7 w2 W. ~
区块B失效了,因为它的hash不再有4个前导0。
区块B的hash改变了,因为区块C的hash被用来计算区块B的hash。! G: V( m; o5 H ?" d( W/ }
区块C失效了,因为它的hash不再有4个前导0。' I6 J5 n$ ^3 F; ~) G& [0 i
0 }. s" Z+ n8 a% u$ e* U3 |, c
改变一个区块的唯一方法就是将这个区块重新挖一遍,接下来是所有的区块。由于总是有新的区块被添加,因此改变区块几乎是一件不可能的事。% `0 x- ?% M% e/ w
我希望这个教程能够对您有所帮助!; J2 f2 L: I6 t4 n% c. } }
9 G8 t! a* U; |/ p6 G
安装命令行工具
/ c) d! Y) J. p
在此之前请先安装Node.js ]+ P# }) ~4 L
; X4 b4 h* J- d, c1 i' ^+ D7 q, Q
然后在你的命令行中运行以下指令:
npminstallblockchain-cli-g
blockchain
你应该会看到?WelcometoBlockchainCLI!和一个blockchain→提示。这说明已经准备好了。8 W# a# A; X2 y
% `/ K# \1 k) k' J4 H
区块长什么样?3 L3 i Z Z( f
想要查看当前的区块链,你需要在命令提示行下输入blockchain或者bc。你应该会看到像下面的图片一样的一个区块。6 {8 j( e6 W* F$ n
Index:是哪一个区块(创世块的索引是0)?
6 J. d2 b5 V1 P* N4 V. Y# ]& h& L
Hash:块是否有效?3 |! _5 G9 x8 i W8 ?/ N' M
PreviousHash:前一个区块是否有效?5 R# N6 `# A! s9 ~$ I. H
Timestamp:什么时候添加的区块?& k0 Z- H" A! h1 S; s/ |
. U! y6 C/ E$ ^4 |
Data:什么信息存储在区块上?" U- L2 f7 n/ Q* c
Nonce:在找到有效区块之前,我们进行了多少次迭代?
_6 R. t7 T* X; k4 W+ n
创世块! G1 y! H8 |- o4 r5 j) H
* J' v Z6 r: `( p7 N# \! r% V+ s
每一个区块链都是从?GenesisBlock开始的。正如你们将要在后面看到的,区块链上的每一个区块都依赖于前一个区块。所以,需要创世块来挖出我们的第一个区块。
5 Z/ a- `# c1 Z+ L6 g3 [
当一个新的区块被开采时会发生什么?+ H' O# Q) ~4 p6 q$ g5 b& c
让我们挖出我们的第一个区块。在命令行中输入minefreeCodeCamp。
区块链查看链上最新的区块来获取index和previoushash。在这个案例下创世块是最新的区块。
( s0 d) W6 M: ], X/ K% t
Index:0+1=1
1 G+ D! {0 L, m; @6 n* I n% }1 ]" P
PreviousHash:0000018035a828da0…, N# g3 F0 j* b
6 V, c& n6 o4 n2 u. o
Timestamp:区块被添加的时间( L- W, Q, X/ c& V; H: Q1 p: u
Data:freeCodeCamp! H" _: _+ l; U. ^/ @2 J
3 |5 j' Q, b$ Q6 w# B3 M; x5 U
Hash:??? S L2 e C2 y3 W
Nonce:???, a$ Z; t2 W% r* @% _9 O% x
Hash是如何计算的?* D8 n: O5 m& t4 q1 m& w) U- I
) y9 {# ]. J( Q( w$ b
哈希值是唯一标识数据的固定长度的数值。
7 z( Q: Z% A+ l9 \
Hash是通过将Index、PreviousHash、Timestamp、Data和Nonce作为输入值来计算的。 G( ~5 Z7 ^$ X, ~6 ]
+ ~" l' c- m; p& v6 O* f8 W. p
CryptoJS.SHA256(index+previousHash+timestamp+data+nonce)" L1 ]9 h3 p2 G& ~
SHA256算法将会依据这些输入计算出一个唯一Hash值。同样的输入总是会返回同样的结果。
. O/ k. q* a" E, Y# `. e
你是否注意到区块Hash中的四个前导0?" s+ c @$ l" Q5 C; }: {" J9 Q o* \
* O& G2 s3 F# y: d- P
四个前导0是一个有效Hash的最低要求。所需前导0的数量被称之为难度3 U2 j( H8 F7 ]; Q# ~
functionisValidHashDifficulty(hash,difficulty){
; L' q) L4 h6 [3 ]& X1 [, P' {
for(vari=0,b=hash.length;i=difficulty;
}
这也被称为工作证明系统
Nonce是什么?: n1 z* t; |. [" M3 y
Nonce是用来查找一个有效Hash的次数。( ?; c: y' R/ J
letnonce=0;2 x, C" S; I* E8 F: N: O
+ n/ j; m- h, h# g; w
lethash;, A) ]% ^6 d9 ?' o9 O# h% m
3 z7 ]) X4 ~0 u9 `* ?. o# a" D
letinput;
( [! ]0 |- ~3 F
while(!isValidHashDifficulty(hash)){& F; U# G: x! }* I- H# N, K3 J1 p1 {. w
nonce=nonce+1;
/ S J% ^' q0 _* B7 z
input=index+previousHash+timestamp+data+nonce;5 g* ~0 L7 R n/ \; B1 l# i
hash=CryptoJS.SHA256(input)9 o% Q0 f% b+ L
8 r2 u- |5 z2 h2 n
}
Nonce迭代到直到Hash有效。在我们的案例中,一个有效的Hash至少要拥有4个前置0。查找与有效Hash对应的Nonce的过程就是挖矿。
3 X- \0 s7 z8 p8 j' t6 F# K+ V& d
随着难度的增加,可能的有效Hash数量就会减少。伴随着有效Hash的减少,我们需要更强的算力来查找有效Hash。! Y$ E' \, h. I5 u6 ]
为什么这么重要?
( m. ~% l# E' Z! ?1 b$ i$ j
这些机制非常重要,它们使区块链不可变。
如果我们有这么一个区块链“A->B->C”,而且有一个人想要改变区块A上的数据。那么会发生什么呢? `* t- L( o2 A& x4 e# A
区块A上的数据改变了。5 g' I5 b' K0 ^& Z9 m) E0 b
区块A的hash改变了,因为数据被用来计算hash。
区块A失效了,因为它的hash不再有4个前导0。8 @* W6 C5 n1 O4 f9 I
区块B的hash改变了,因为区块A的hash被用来计算区块B的hash。. q9 _8 \) m( q3 c$ ~
3 o4 O) ~' A; ~2 ?) {1 m& o' L
区块B失效了,因为它的hash不再有4个前导0。4 g' l" a' `: k" m3 ^, N5 @/ x6 e, c
区块B的hash改变了,因为区块C的hash被用来计算区块B的hash。
区块C失效了,因为它的hash不再有4个前导0。
改变一个区块的唯一方法就是将这个区块重新挖一遍,接下来是所有的区块。由于总是有新的区块被添加,因此改变区块几乎是一件不可能的事。
成为第一个吐槽的人