区块链是如何工作的——用JavaScript演示
段琰baby
发表于 2022-11-20 23:53:01
140
0
0
这听起来很棒,那它是如何工作的呢?
为了说明区块链,我们将会使用一个名为BlockchainCLI的开源命令行工具。7 u; H- Y r; A# B& {0 ]* G/ ]
! J& E5 g9 k3 M" l
我同时也建立了一个基于浏览器的版本+ P0 u: m5 {* J7 Q
6 x* x' F& y5 v4 x! s, G
安装命令行工具
/ s: y6 b/ x: F( }4 M v8 O
在此之前请先安装Node.js
" e& @( O& E4 o, f
然后在你的命令行中运行以下指令:
npminstallblockchain-cli-g
blockchain
你应该会看到?WelcometoBlockchainCLI!和一个blockchain→提示。这说明已经准备好了。
区块长什么样?
4 f9 u' b8 j: y. c$ t9 @
想要查看当前的区块链,你需要在命令提示行下输入blockchain或者bc。你应该会看到像下面的图片一样的一个区块。
Index:是哪一个区块(创世块的索引是0)$ _- w$ M% N R4 K T
0 s6 y4 ], k/ C0 L$ w7 r2 W2 Q
Hash:块是否有效?# j* [. {6 n b7 s4 Y) k& |
PreviousHash:前一个区块是否有效?
Timestamp:什么时候添加的区块?6 b0 f* `8 \) d7 Z3 L+ B! }2 H
5 I; }9 c6 ?& i, ?
Data:什么信息存储在区块上?
Nonce:在找到有效区块之前,我们进行了多少次迭代?
: p1 h* z4 Q e7 G5 _6 X. ?% n
创世块
0 t* w) V# E* F0 J# \3 s2 j" X" H3 b
每一个区块链都是从?GenesisBlock开始的。正如你们将要在后面看到的,区块链上的每一个区块都依赖于前一个区块。所以,需要创世块来挖出我们的第一个区块。
4 K% d, |. r; t8 H
当一个新的区块被开采时会发生什么?
5 Q* r$ B5 I7 R( P- y1 A7 H' @% \
让我们挖出我们的第一个区块。在命令行中输入minefreeCodeCamp。
3 K1 ~# j d. V& l' D( a: U
区块链查看链上最新的区块来获取index和previoushash。在这个案例下创世块是最新的区块。% q+ W, t; I; g
! t1 g/ h' b/ ? w
Index:0+1=1) Y4 G& ]) E A: w' i0 C; U. z
) X; n( c0 S u0 |6 x
PreviousHash:0000018035a828da0…7 j4 a% _! h- U7 z
. k v7 D* _3 r% s8 R' g& E+ S; [( u
Timestamp:区块被添加的时间; u% ^4 O5 U5 R3 J: r) t' ?4 u3 t, P
5 p7 z7 t% w7 q. G
Data:freeCodeCamp
Hash:???
Nonce:???8 j) J7 G+ ~) V2 U2 f) J6 e
Hash是如何计算的?4 K6 Y0 Q3 f h& G ]
哈希值是唯一标识数据的固定长度的数值。5 l7 d& h$ G6 {! R5 o g
Hash是通过将Index、PreviousHash、Timestamp、Data和Nonce作为输入值来计算的。, z- O& R+ e2 [2 R7 q0 \
CryptoJS.SHA256(index+previousHash+timestamp+data+nonce); H7 x& `$ _+ V$ k" N+ L7 B T& J4 O
- C2 C% B' U) g# F! T
SHA256算法将会依据这些输入计算出一个唯一Hash值。同样的输入总是会返回同样的结果。) W9 `$ Z6 L: w& ~# \6 j1 ^+ _
3 E' ~( D& r3 f8 M+ Y& f
你是否注意到区块Hash中的四个前导0?
四个前导0是一个有效Hash的最低要求。所需前导0的数量被称之为难度
functionisValidHashDifficulty(hash,difficulty){
3 y6 H3 o( n1 F! B5 I4 h9 }
for(vari=0,b=hash.length;i=difficulty;" e5 R# g4 Y6 ^8 v0 g4 b: w, q+ C
}
) K# S/ l' l) O
这也被称为工作证明系统1 o2 |* a, x3 B4 Y
2 Z0 G8 p' t2 L2 S7 a5 t/ F
Nonce是什么?0 b7 n; o: ?4 g* l! v
: u0 Z/ P$ O+ U G' J$ J
Nonce是用来查找一个有效Hash的次数。
letnonce=0;" ~0 H0 \( q, `+ k7 I4 |! w
+ Y5 _& r0 d- N5 ^# P
lethash;4 r5 \5 Z$ b% }/ q
letinput;
while(!isValidHashDifficulty(hash)){
nonce=nonce+1;- g) K0 v3 m D) m
input=index+previousHash+timestamp+data+nonce;- N i' B4 Y/ [2 ^9 E4 W
- P W5 ^' Y' O, e. Q- M
hash=CryptoJS.SHA256(input)* w* m6 r) _" S7 A+ C/ f9 E$ H
?8 A8 O h9 K
}
. Z" y7 a3 g+ C, u7 o* l
Nonce迭代到直到Hash有效。在我们的案例中,一个有效的Hash至少要拥有4个前置0。查找与有效Hash对应的Nonce的过程就是挖矿。0 B' Z' A( `5 A% G7 r7 e
" K: z0 w3 _8 \0 N o4 g( z Z
随着难度的增加,可能的有效Hash数量就会减少。伴随着有效Hash的减少,我们需要更强的算力来查找有效Hash。# T. H- I' o' T1 ^: o! U
+ Q; K @' J% O, J |( P
为什么这么重要?
这些机制非常重要,它们使区块链不可变。
$ ~& P" x' B( V1 f
如果我们有这么一个区块链“A->B->C”,而且有一个人想要改变区块A上的数据。那么会发生什么呢?- }" A3 H4 G6 `2 O' a6 B3 X& l! H
区块A上的数据改变了。- o" ]9 i( g$ N. U9 x( ~' M- E3 M
3 s% | M' a0 h+ g2 f
区块A的hash改变了,因为数据被用来计算hash。
* R, V& Y y: U8 @
区块A失效了,因为它的hash不再有4个前导0。9 ~8 d& c- N4 t+ J* Y
9 W& y7 x e) ^
区块B的hash改变了,因为区块A的hash被用来计算区块B的hash。& k: N8 Z8 [" o
1 y' t$ {% U2 j1 `
区块B失效了,因为它的hash不再有4个前导0。' ]7 ?3 {0 u5 b L0 G( r
区块B的hash改变了,因为区块C的hash被用来计算区块B的hash。& _) o9 o7 P8 A
区块C失效了,因为它的hash不再有4个前导0。8 R9 J/ Y) Q6 b" E7 Z, k
改变一个区块的唯一方法就是将这个区块重新挖一遍,接下来是所有的区块。由于总是有新的区块被添加,因此改变区块几乎是一件不可能的事。- ?0 g0 D$ ]! w' d/ d
我希望这个教程能够对您有所帮助!& T l# }0 x; K
安装命令行工具; E. R& A3 K! Q! a8 g
- b4 q! w: ]! e4 I7 O' A. r
在此之前请先安装Node.js
3 |7 z2 X, b# B c5 G7 r6 s3 a" n
然后在你的命令行中运行以下指令:2 U+ T3 ^( j! ~* Y# l- A
npminstallblockchain-cli-g! q. k# L+ }9 Y' |
blockchain
- }" k- H% a. ?+ d
你应该会看到?WelcometoBlockchainCLI!和一个blockchain→提示。这说明已经准备好了。
+ N% O) [5 t! Z1 L: v
区块长什么样?. N8 V0 h9 o4 k; E. I' n& J
想要查看当前的区块链,你需要在命令提示行下输入blockchain或者bc。你应该会看到像下面的图片一样的一个区块。
Index:是哪一个区块(创世块的索引是0)?
Hash:块是否有效?' q/ m5 T2 w/ X
PreviousHash:前一个区块是否有效?, O0 I, H0 Y# i) j
Timestamp:什么时候添加的区块?
Data:什么信息存储在区块上?
Nonce:在找到有效区块之前,我们进行了多少次迭代?0 h" y& p: l: C) N5 ~2 a: }( |% F* Y
5 K2 k3 g8 o3 j3 d- y* U; I
创世块
每一个区块链都是从?GenesisBlock开始的。正如你们将要在后面看到的,区块链上的每一个区块都依赖于前一个区块。所以,需要创世块来挖出我们的第一个区块。
当一个新的区块被开采时会发生什么?# G y+ t0 E, |
让我们挖出我们的第一个区块。在命令行中输入minefreeCodeCamp。) p$ u( {) x$ Y/ S) w0 v7 V O
区块链查看链上最新的区块来获取index和previoushash。在这个案例下创世块是最新的区块。
" \ S( {# ~* Q- Z% K
Index:0+1=16 h( K1 ~( M# d9 I0 J& \- G
5 Z+ n) h( k6 g3 q( u5 r# E: G1 j
PreviousHash:0000018035a828da0…
+ w5 @7 v6 I0 `% @# F O8 k
Timestamp:区块被添加的时间
Data:freeCodeCamp7 K' l, n: g# i
Hash:???" u O. c- z! s. R+ I
8 Y! j2 l" ]8 H2 O( `- m) g
Nonce:???
Hash是如何计算的?
: O* s+ t' {0 A- v( e& X
哈希值是唯一标识数据的固定长度的数值。8 N) m: O; W5 |* H
Hash是通过将Index、PreviousHash、Timestamp、Data和Nonce作为输入值来计算的。. I( g$ P) j$ L! O% m* b
CryptoJS.SHA256(index+previousHash+timestamp+data+nonce)
SHA256算法将会依据这些输入计算出一个唯一Hash值。同样的输入总是会返回同样的结果。, P: @- u" t4 R
) f$ ^7 c/ f! h9 _: Y5 O! @- Z/ q
你是否注意到区块Hash中的四个前导0?
g/ x) {0 C3 T @& F" a$ m( y
四个前导0是一个有效Hash的最低要求。所需前导0的数量被称之为难度/ l4 b3 l6 F/ u. X; G5 D- Y
functionisValidHashDifficulty(hash,difficulty){9 I2 r& q1 [8 m
& I0 h0 B" e& h& G7 N1 D2 _. M
for(vari=0,b=hash.length;i=difficulty;
+ F6 P9 J6 [7 C ]* W; z1 b/ O3 ]# ?
}
这也被称为工作证明系统/ p9 m7 u+ ?" _! |" `" }1 M
Nonce是什么?# b% n8 P1 a- m3 [7 m' E
9 Z) `% ?2 J8 P* w2 Q) J
Nonce是用来查找一个有效Hash的次数。9 o6 _2 }& o) p- O
letnonce=0;
. _! ?4 n$ g/ R$ O7 L) @+ f
lethash;2 ^8 T" S+ Z' d3 u8 d
letinput;9 Y1 r" c ]7 m- c5 B
while(!isValidHashDifficulty(hash)){, G% t# \" p- o" [0 p+ c2 [
nonce=nonce+1;8 \: a4 m/ a- N s' j& q
input=index+previousHash+timestamp+data+nonce;' i+ E( m* V$ Q' ~
w/ Z0 b5 X) X% d* U4 y0 b( q+ n
hash=CryptoJS.SHA256(input)
}0 c: V/ G; U) I! U) C, d
Nonce迭代到直到Hash有效。在我们的案例中,一个有效的Hash至少要拥有4个前置0。查找与有效Hash对应的Nonce的过程就是挖矿。5 d0 q; B. [2 a$ Z8 [% s9 V: I
8 l3 @5 I: {) A
随着难度的增加,可能的有效Hash数量就会减少。伴随着有效Hash的减少,我们需要更强的算力来查找有效Hash。
; K( K; Q* v, t
为什么这么重要?
$ k: U; `0 U) W
这些机制非常重要,它们使区块链不可变。
如果我们有这么一个区块链“A->B->C”,而且有一个人想要改变区块A上的数据。那么会发生什么呢?) g% D9 ~9 Y, m
: H8 S' F/ x/ \# R3 N9 k
区块A上的数据改变了。
区块A的hash改变了,因为数据被用来计算hash。8 v# T4 o( h2 k4 e( ?. q
区块A失效了,因为它的hash不再有4个前导0。8 [6 f" j) t$ o! M3 F4 y
! v2 k* F, i0 B# u% Z
区块B的hash改变了,因为区块A的hash被用来计算区块B的hash。
C' C( u( e1 c* K0 D
区块B失效了,因为它的hash不再有4个前导0。1 {8 W7 Y e8 H$ O# N" h& @& o
区块B的hash改变了,因为区块C的hash被用来计算区块B的hash。" o* a: E9 `1 D2 O/ }
3 T" m) s3 E/ @4 C' F3 `
区块C失效了,因为它的hash不再有4个前导0。
- N! T: A5 b4 {. u x/ n
改变一个区块的唯一方法就是将这个区块重新挖一遍,接下来是所有的区块。由于总是有新的区块被添加,因此改变区块几乎是一件不可能的事。2 K+ \/ z# s. `) C/ P' M! g
成为第一个吐槽的人