区块链是如何工作的——用JavaScript演示
段琰baby
发表于 2022-11-20 23:53:01
85
0
0
6 z% D+ l: w9 T" a. V
这听起来很棒,那它是如何工作的呢?
9 T. O! Z- k9 I% d, e
为了说明区块链,我们将会使用一个名为BlockchainCLI的开源命令行工具。) \( K* J- n3 w4 \/ Q, j& T
3 t! g; X& u, {. H
我同时也建立了一个基于浏览器的版本) p# s S, H# _6 l% l3 Y. Z
N9 b' k# _+ n+ v9 `
安装命令行工具
在此之前请先安装Node.js4 J" `3 ]: h$ G6 r' U5 l& ~
; Q' m5 n( C6 k% \& w1 E5 h6 ~% u
然后在你的命令行中运行以下指令:( p. O' s3 E" j5 F* g
npminstallblockchain-cli-g
6 a$ k; @' z# f9 k' U8 s0 ^! q
blockchain( a( y2 i! {2 o3 U; o
' I0 t. `5 [- U- g
你应该会看到?WelcometoBlockchainCLI!和一个blockchain→提示。这说明已经准备好了。6 U8 l% r5 d& @$ I/ p. E
区块长什么样?3 p2 d- P9 k& k% \- K
想要查看当前的区块链,你需要在命令提示行下输入blockchain或者bc。你应该会看到像下面的图片一样的一个区块。
Index:是哪一个区块(创世块的索引是0)7 ^8 J7 C5 ]. K' W% C# D
' M5 |" Q9 D6 s5 P( |
Hash:块是否有效? Z0 Q8 [+ R9 [$ D) G" Z
6 k* p$ G/ I C0 e3 A
PreviousHash:前一个区块是否有效?
4 c! k( T+ M/ s5 m0 u. A
Timestamp:什么时候添加的区块?" A7 |' r/ Z5 g( o( z
Data:什么信息存储在区块上?
; o4 f0 e4 h v' A
Nonce:在找到有效区块之前,我们进行了多少次迭代?# q1 l$ L. g6 w: c- W
创世块2 L6 F t, `+ W- G7 r
9 l. z+ F, D" Q- `- O) k
每一个区块链都是从?GenesisBlock开始的。正如你们将要在后面看到的,区块链上的每一个区块都依赖于前一个区块。所以,需要创世块来挖出我们的第一个区块。
$ ^1 N* ~. C2 L4 X6 C
当一个新的区块被开采时会发生什么?3 Q h/ H$ v. }; B$ z
让我们挖出我们的第一个区块。在命令行中输入minefreeCodeCamp。
区块链查看链上最新的区块来获取index和previoushash。在这个案例下创世块是最新的区块。. m$ J9 h( x0 Q1 s, x
! M f) L) t( q0 P
Index:0+1=1
PreviousHash:0000018035a828da0…
9 e! F0 J, S8 y0 w! R
Timestamp:区块被添加的时间2 I( M+ c, @) J9 q
Data:freeCodeCamp% C" e: k! W4 `
Hash:???# A$ [! X# V4 z! l4 ^
* i6 U) E" g' U
Nonce:???/ K% _9 x' Z- W
0 Q1 B! \2 Y8 B' M# K- ^- D
Hash是如何计算的?. o6 u! f( P* H! X- }. H
哈希值是唯一标识数据的固定长度的数值。
7 |' |; D9 g8 X/ H. F; W
Hash是通过将Index、PreviousHash、Timestamp、Data和Nonce作为输入值来计算的。) A" Y3 z3 n; R4 @% T
CryptoJS.SHA256(index+previousHash+timestamp+data+nonce)
, o5 j+ K |/ T) b; t
SHA256算法将会依据这些输入计算出一个唯一Hash值。同样的输入总是会返回同样的结果。 b7 j: `7 O" }' e! Z
G/ i3 ]1 A9 d \' z
你是否注意到区块Hash中的四个前导0?
四个前导0是一个有效Hash的最低要求。所需前导0的数量被称之为难度
3 q% {3 M8 c/ w3 I3 p- B) o. X: v
functionisValidHashDifficulty(hash,difficulty){
for(vari=0,b=hash.length;i=difficulty;
}9 f! q, }( _ N r! N: S( p5 ^* h
这也被称为工作证明系统
Nonce是什么?
Nonce是用来查找一个有效Hash的次数。 i X- a/ L6 A: j7 s
+ W/ I" ^/ w& g2 L9 Y
letnonce=0;
lethash;6 n8 Q4 H5 n/ ~+ x& ~
letinput; W: A6 E. v q9 ^( b
while(!isValidHashDifficulty(hash)){
# x' `1 e. s5 F0 K8 Z) ?& `' t' j
nonce=nonce+1;# ~9 P7 ?' B1 G. O4 v5 ?; ^, X' V- j
input=index+previousHash+timestamp+data+nonce;+ N2 W7 I p4 a- _2 P& V
hash=CryptoJS.SHA256(input)7 M5 N2 f# l% s+ U8 W
}
* ]& D4 R: k- K4 _) U- u0 n
Nonce迭代到直到Hash有效。在我们的案例中,一个有效的Hash至少要拥有4个前置0。查找与有效Hash对应的Nonce的过程就是挖矿。
随着难度的增加,可能的有效Hash数量就会减少。伴随着有效Hash的减少,我们需要更强的算力来查找有效Hash。
为什么这么重要?, c9 E7 y Z! ~7 N
这些机制非常重要,它们使区块链不可变。
如果我们有这么一个区块链“A->B->C”,而且有一个人想要改变区块A上的数据。那么会发生什么呢?
1 s8 r8 A3 n7 h5 q! b5 U7 b; ~
区块A上的数据改变了。" C* p, s5 e$ t. b) V; U( s
区块A的hash改变了,因为数据被用来计算hash。+ k, f0 G" F- P$ X4 o" K! ^$ L: s
区块A失效了,因为它的hash不再有4个前导0。 t8 b( W8 H8 z* B$ J1 J
3 g: d7 O# l1 }: c: t5 |
区块B的hash改变了,因为区块A的hash被用来计算区块B的hash。+ v- W; k) z* ]- `# A
区块B失效了,因为它的hash不再有4个前导0。2 `" V. u8 G0 h# v) u
. Z3 U! L |+ R6 i# S/ e
区块B的hash改变了,因为区块C的hash被用来计算区块B的hash。7 u4 ~$ N/ c3 J {% |: {
* n v0 A! N' C0 Y: Y/ P$ h; j( q
区块C失效了,因为它的hash不再有4个前导0。
改变一个区块的唯一方法就是将这个区块重新挖一遍,接下来是所有的区块。由于总是有新的区块被添加,因此改变区块几乎是一件不可能的事。# V+ c/ k( S& I. ^; x
我希望这个教程能够对您有所帮助!
# N3 U+ |1 y& ^; w# Z* d, b
安装命令行工具; L* a* I& o$ a( i" R; ]* V
. C. g! |( L: d' ]* @0 d! u/ o
在此之前请先安装Node.js
然后在你的命令行中运行以下指令:' n' X! f& d6 t+ P' Z; @" N) V
9 e% Z* N+ n) c! g3 R* I6 S8 V! ]3 t
npminstallblockchain-cli-g9 k9 g: n3 v% _6 j# r
$ L: ~' L# D2 A0 n# P3 U
blockchain
你应该会看到?WelcometoBlockchainCLI!和一个blockchain→提示。这说明已经准备好了。 T5 {1 [& l- ~6 L0 T5 W6 E
区块长什么样?, N0 N8 V: s5 N) O
想要查看当前的区块链,你需要在命令提示行下输入blockchain或者bc。你应该会看到像下面的图片一样的一个区块。9 a+ i V. j Z3 D
Index:是哪一个区块(创世块的索引是0)?
* p- w. e7 n) y" g4 T
Hash:块是否有效?
PreviousHash:前一个区块是否有效?
) X; M; V6 k2 C) }/ l1 Q8 \8 R
Timestamp:什么时候添加的区块?: {* j) f3 O7 q$ m* _
2 T* s+ U' S, G, b1 v* q
Data:什么信息存储在区块上?2 ~9 z. N/ [+ u: Y7 L4 I* S, g3 M
Nonce:在找到有效区块之前,我们进行了多少次迭代?4 D6 X* a2 `7 C5 b
! F2 q5 u+ u$ \+ M
创世块
" b% f$ R3 A. A% q2 f# ~
每一个区块链都是从?GenesisBlock开始的。正如你们将要在后面看到的,区块链上的每一个区块都依赖于前一个区块。所以,需要创世块来挖出我们的第一个区块。2 q. R2 _/ N! W8 b" o _
, { I$ \+ H2 u1 f. V [3 @6 m
当一个新的区块被开采时会发生什么?
6 G2 g! f8 p }7 }* G& Q
让我们挖出我们的第一个区块。在命令行中输入minefreeCodeCamp。
" T. X- I, T8 w/ Z5 V7 k! d
区块链查看链上最新的区块来获取index和previoushash。在这个案例下创世块是最新的区块。& \% `" f% G; T; T" [; H; T
Index:0+1=15 H5 m, R6 S* \# G6 o" r0 \
PreviousHash:0000018035a828da0…- ^8 W1 [! N# s$ z% n
( t( A) |, s. g
Timestamp:区块被添加的时间) c0 Y4 y3 B* K# d% t9 v
Data:freeCodeCamp/ z% S+ `# T- H1 Y4 p, B9 H: a
$ o# d# ?# }7 ]
Hash:???
9 D2 a1 O5 A5 T( \8 [* l
Nonce:???# `/ [! t5 J9 B5 U6 _" F: T# S4 Z. v
Hash是如何计算的?. f9 A. D0 Z X
! q' t6 S! n7 c0 ` G
哈希值是唯一标识数据的固定长度的数值。 \) @; r; U8 C8 x H
Hash是通过将Index、PreviousHash、Timestamp、Data和Nonce作为输入值来计算的。( r5 u5 ~* S3 a: l) `7 t
7 ^' o3 v H$ ?! X0 d6 w) x3 u6 v
CryptoJS.SHA256(index+previousHash+timestamp+data+nonce)9 U5 f; Q* J: ^$ L
2 h1 k. G, ]) I+ w
SHA256算法将会依据这些输入计算出一个唯一Hash值。同样的输入总是会返回同样的结果。" ~* ~$ B i( A: d" j
你是否注意到区块Hash中的四个前导0?
2 k! t5 s+ j- ]6 D8 b7 Y7 c
四个前导0是一个有效Hash的最低要求。所需前导0的数量被称之为难度# \4 M7 @0 _. p( W0 c
7 I b1 p( n8 v, U3 {8 u' _8 G# R# U
functionisValidHashDifficulty(hash,difficulty){0 C3 Q7 d* q- C" L) y |8 {. K) G9 n
* @5 ?+ p3 k H- Z$ J# _
for(vari=0,b=hash.length;i=difficulty;8 e# p" _2 W/ a' ?4 }
' o, {: G4 K6 g! v
}
: C5 T, G$ [6 _+ ^" i6 c# g1 q
这也被称为工作证明系统# b0 B" s$ J& ~* [
Nonce是什么?7 l! {7 `) V5 Y* `! D
: e J0 s/ E. b \- K9 l5 a
Nonce是用来查找一个有效Hash的次数。7 q: o' g2 r$ W2 i3 ~8 x) f
" `* G3 S8 m$ t8 i
letnonce=0;4 V' g, b I& `/ W) \# H' M3 \5 U
/ T J- M2 \6 K" H
lethash;4 u# J6 L9 G9 A' g( m% A
letinput;# P Q; Q3 T9 j. b' l, x
while(!isValidHashDifficulty(hash)){3 N, W% u. K3 @8 C0 C
( f# P% g) z5 F& i A
nonce=nonce+1;
input=index+previousHash+timestamp+data+nonce;9 K; j3 \3 t8 p) M' J
1 h+ Q5 y" ~" ^. p1 D
hash=CryptoJS.SHA256(input)
( [4 a2 t! M5 o( ^1 m
}9 }# b. b m) @7 b
Nonce迭代到直到Hash有效。在我们的案例中,一个有效的Hash至少要拥有4个前置0。查找与有效Hash对应的Nonce的过程就是挖矿。5 `9 i+ v2 G! w% {
随着难度的增加,可能的有效Hash数量就会减少。伴随着有效Hash的减少,我们需要更强的算力来查找有效Hash。; l; _, \& O, k
为什么这么重要?, u, D& E$ B( y+ e" _0 N! O
* {6 m+ k& m3 p& C g
这些机制非常重要,它们使区块链不可变。
0 F. F' M+ D: i- v$ T4 v
如果我们有这么一个区块链“A->B->C”,而且有一个人想要改变区块A上的数据。那么会发生什么呢?9 m9 U R. l5 ?# B2 i1 o& Y# p
区块A上的数据改变了。/ `& b8 a" @' @' [
0 T5 Z: H5 d6 q; d) m
区块A的hash改变了,因为数据被用来计算hash。
区块A失效了,因为它的hash不再有4个前导0。
区块B的hash改变了,因为区块A的hash被用来计算区块B的hash。% r b1 A8 a n: _
5 U" o: @4 I& y# w
区块B失效了,因为它的hash不再有4个前导0。4 j0 F7 Y9 U0 Q: `5 J
- Z% Y4 ~+ z" @- Q$ p7 B6 N
区块B的hash改变了,因为区块C的hash被用来计算区块B的hash。7 Q9 k* ]3 Z3 h1 ]6 T
' g4 b, n n7 g5 n7 g0 u
区块C失效了,因为它的hash不再有4个前导0。: `( b# C6 j4 Z7 W$ W0 O i& Y: p7 q
. o7 T3 q: Y# `: `: O- o( n
改变一个区块的唯一方法就是将这个区块重新挖一遍,接下来是所有的区块。由于总是有新的区块被添加,因此改变区块几乎是一件不可能的事。& ~( b! v. [) _/ m3 U+ p
成为第一个吐槽的人