区块链是如何工作的——用JavaScript演示
段琰baby
发表于 2022-11-20 23:53:01
125
0
0
这听起来很棒,那它是如何工作的呢?
为了说明区块链,我们将会使用一个名为BlockchainCLI的开源命令行工具。
% X9 m7 c/ `; Q6 r# S
我同时也建立了一个基于浏览器的版本3 P& V0 _* [4 }4 |0 @0 {
安装命令行工具
6 R/ G [) g# V% A/ G! Y
在此之前请先安装Node.js- d f; l. u4 j7 D
然后在你的命令行中运行以下指令:
npminstallblockchain-cli-g# p7 V) ?# s3 X" S; [
blockchain7 W1 F- b. h+ \' m. T
# @6 T8 A9 M( P i
你应该会看到?WelcometoBlockchainCLI!和一个blockchain→提示。这说明已经准备好了。% n4 c0 S! Y" G6 b3 r
; M! V9 n6 n- p
区块长什么样?
7 f0 z- m' { {8 q1 V
想要查看当前的区块链,你需要在命令提示行下输入blockchain或者bc。你应该会看到像下面的图片一样的一个区块。8 ~8 v/ Z5 G& j; s4 [
Index:是哪一个区块(创世块的索引是0)
Hash:块是否有效?; D0 U6 Y0 M( C* t% A1 f+ @: l5 Z; K
PreviousHash:前一个区块是否有效?
Timestamp:什么时候添加的区块?6 ^, x9 C; l: r: ^5 g
0 t7 O9 E3 p. w
Data:什么信息存储在区块上?
Nonce:在找到有效区块之前,我们进行了多少次迭代?
F; C+ Y5 Z R3 N& o8 \1 G m
创世块
每一个区块链都是从?GenesisBlock开始的。正如你们将要在后面看到的,区块链上的每一个区块都依赖于前一个区块。所以,需要创世块来挖出我们的第一个区块。 A) a" `( N, e/ Y: V, M x
当一个新的区块被开采时会发生什么?# y- }( k- Y; x
: g5 P; V9 ^ A% n' n2 @2 G2 G( p9 C
让我们挖出我们的第一个区块。在命令行中输入minefreeCodeCamp。
区块链查看链上最新的区块来获取index和previoushash。在这个案例下创世块是最新的区块。- R% g5 J/ J5 z0 ]
7 L y, }* R, k0 d0 j
Index:0+1=16 H( }6 N# a7 e! J( S
PreviousHash:0000018035a828da0…& V" W H5 I5 r9 Z( s7 L3 Y
1 _7 h5 X* G7 O* q7 T* H5 e! {' ~+ L: M
Timestamp:区块被添加的时间
Data:freeCodeCamp
- G- @& [: U% O/ p, C. S4 l; a
Hash:???0 }/ m- Y( ~! k! D3 b7 e, }
Nonce:???
! X6 h2 m7 K9 m+ X/ M/ {5 N( G
Hash是如何计算的?" O* R" p& D7 C( P8 m0 S
: q# \2 r* l' @. v
哈希值是唯一标识数据的固定长度的数值。2 r$ {5 G4 ?- {* g" a: ~
Hash是通过将Index、PreviousHash、Timestamp、Data和Nonce作为输入值来计算的。
/ v+ d6 k9 r) L. Y
CryptoJS.SHA256(index+previousHash+timestamp+data+nonce)
SHA256算法将会依据这些输入计算出一个唯一Hash值。同样的输入总是会返回同样的结果。
你是否注意到区块Hash中的四个前导0?2 p9 H5 g$ D& \- f4 t9 B
四个前导0是一个有效Hash的最低要求。所需前导0的数量被称之为难度
4 ^0 E4 |& `9 V
functionisValidHashDifficulty(hash,difficulty){% v5 _# r4 j- V( ?) [
( _: h" J' a, k
for(vari=0,b=hash.length;i=difficulty;
, v' J2 ?5 W2 N* g
}
这也被称为工作证明系统
Nonce是什么?2 K. P9 P2 T C4 y# m" K
Nonce是用来查找一个有效Hash的次数。
letnonce=0;1 x& [. Y0 ^9 K- ]' u* D
$ M' }* t% M: Q O
lethash;
0 e% ]$ K' {1 D. c/ E3 `8 B
letinput;
: Q2 ~, K5 F; w3 d2 _4 d
while(!isValidHashDifficulty(hash)){
6 [, W8 l- r8 ~7 p& ~- d7 s* q
nonce=nonce+1;5 Y+ S0 @. h4 t! a+ `, M- ^) u" Z
9 l, q! V* @* d, H4 ` I
input=index+previousHash+timestamp+data+nonce;& p. Y# \3 ~; f3 U4 u( c4 ?& @
hash=CryptoJS.SHA256(input)
}( B+ `! }: w1 B+ W3 f9 y
) r0 S5 q! o1 x4 q
Nonce迭代到直到Hash有效。在我们的案例中,一个有效的Hash至少要拥有4个前置0。查找与有效Hash对应的Nonce的过程就是挖矿。
随着难度的增加,可能的有效Hash数量就会减少。伴随着有效Hash的减少,我们需要更强的算力来查找有效Hash。
为什么这么重要?% s& ~+ V' p: U9 j1 g5 J+ \. o
5 N; y: \' U: g, A$ k$ b
这些机制非常重要,它们使区块链不可变。
( B$ L/ j. f4 Q, `* W: u4 J
如果我们有这么一个区块链“A->B->C”,而且有一个人想要改变区块A上的数据。那么会发生什么呢?( u4 [6 u% q* L# d: r
, K$ M M- S2 Y2 R$ T T
区块A上的数据改变了。- Q% c5 [' y( R2 F' `4 M
区块A的hash改变了,因为数据被用来计算hash。
区块A失效了,因为它的hash不再有4个前导0。- o/ h- O- \! B: V
% g V# Z5 C9 A# Z* t4 Q1 Q# h; R
区块B的hash改变了,因为区块A的hash被用来计算区块B的hash。
6 a% X3 F8 J2 z) _# S& L
区块B失效了,因为它的hash不再有4个前导0。 d' D6 S9 L5 H5 `0 c5 L- P
+ k& d r+ q8 @" {& R% H; ~
区块B的hash改变了,因为区块C的hash被用来计算区块B的hash。: o! C" G$ M. ?3 F0 W0 P' D
# e' J3 K3 u- }6 D' M& H! T
区块C失效了,因为它的hash不再有4个前导0。
+ G# f% Q( B( s
改变一个区块的唯一方法就是将这个区块重新挖一遍,接下来是所有的区块。由于总是有新的区块被添加,因此改变区块几乎是一件不可能的事。) k6 j+ p3 m: n2 F2 L: p/ R
/ d k) R. W+ [/ ?# s$ p" v
我希望这个教程能够对您有所帮助!+ i: |+ `0 L0 L, Q
安装命令行工具
! q6 f( P. c* e1 B6 V4 H1 N
在此之前请先安装Node.js9 V( U7 b/ P3 O$ b& x
4 {! A, X) }9 {% ^* b
然后在你的命令行中运行以下指令:
/ s- U) A7 r) `7 B# b8 o' H/ t
npminstallblockchain-cli-g5 i: @& m; A4 H% j( m, [, O% O
4 J$ I h' S: y) q$ u3 W3 e, f' Y
blockchain
- D% J( U3 [) m0 X7 \) F* `/ _
你应该会看到?WelcometoBlockchainCLI!和一个blockchain→提示。这说明已经准备好了。
区块长什么样?
想要查看当前的区块链,你需要在命令提示行下输入blockchain或者bc。你应该会看到像下面的图片一样的一个区块。0 l2 |- M8 W/ ~1 g4 z
Index:是哪一个区块(创世块的索引是0)?. @. B! d, \5 F5 W K
Hash:块是否有效?1 w' t& ^9 k8 O5 G3 @( I( E
0 A s1 ^# E5 ^/ p) j
PreviousHash:前一个区块是否有效?0 E! T* K/ `- h9 ~# k$ M9 M/ r3 c4 \
! K. Z' K2 m+ S. i+ c$ E
Timestamp:什么时候添加的区块?$ y' W" T$ z* c3 N2 @
: h& v3 G! r1 g* u
Data:什么信息存储在区块上?" Q& M; L3 a; [' y
Nonce:在找到有效区块之前,我们进行了多少次迭代?
创世块% b) y1 ?0 l) H3 f' w
( V' d3 f3 a. v( ^8 H! k* `
每一个区块链都是从?GenesisBlock开始的。正如你们将要在后面看到的,区块链上的每一个区块都依赖于前一个区块。所以,需要创世块来挖出我们的第一个区块。7 a; C4 ^4 V% z: x1 a3 T! e
. G1 h6 `3 q* ^4 r
当一个新的区块被开采时会发生什么?) T/ Q- }* P5 Q
让我们挖出我们的第一个区块。在命令行中输入minefreeCodeCamp。- Y& v! I: W$ C/ O
: d, [$ s G4 ]& ^' }
区块链查看链上最新的区块来获取index和previoushash。在这个案例下创世块是最新的区块。. |8 b! J, V8 |9 U
Index:0+1=1# ` t& K7 k; z. v, O0 U
) W m( j$ B8 @9 t+ y) P( L1 P1 V
PreviousHash:0000018035a828da0…
Timestamp:区块被添加的时间6 o0 Q {2 [; S4 Z6 `& Z- b# p
- U( p# p8 q$ w3 M' F/ Q
Data:freeCodeCamp
Hash:???
; Q& w3 M& y4 H( L; g4 B2 w# x
Nonce:???* I3 R+ o5 G7 r4 }! z# f& A
; Y9 \' `# I r d; C+ r1 g" a; i
Hash是如何计算的?
# `$ I! O4 S+ Z- [( M. K6 i" m
哈希值是唯一标识数据的固定长度的数值。+ g/ B; y3 Q7 e( c: o
Hash是通过将Index、PreviousHash、Timestamp、Data和Nonce作为输入值来计算的。! {+ z9 l; T- N
CryptoJS.SHA256(index+previousHash+timestamp+data+nonce)7 r" K: U2 v3 \" N6 C
5 A7 l2 i$ c }) l6 q* o
SHA256算法将会依据这些输入计算出一个唯一Hash值。同样的输入总是会返回同样的结果。
# t8 o- o7 a* N. L5 |2 w
你是否注意到区块Hash中的四个前导0?
四个前导0是一个有效Hash的最低要求。所需前导0的数量被称之为难度) J8 d$ J y. p5 u" M
functionisValidHashDifficulty(hash,difficulty){
- p& n" R0 _3 r0 n9 ~, N
for(vari=0,b=hash.length;i=difficulty;$ V: O, U* y5 l
}
这也被称为工作证明系统
& u! D2 ~: s2 q/ `& ?6 x! a
Nonce是什么?
) }$ R' I( m+ K9 T- r
Nonce是用来查找一个有效Hash的次数。 U5 U2 G7 M! Q# r9 b
letnonce=0;
lethash;/ |" S# c- G4 W' z. f7 w1 x' ^
: p" Y7 C2 q' o
letinput;
while(!isValidHashDifficulty(hash)){
+ i9 D2 e' A s$ r, m+ Z+ {1 o6 h. \
nonce=nonce+1;5 H* T. j' K; }( J: ^# Y, Y# a1 P
input=index+previousHash+timestamp+data+nonce;
hash=CryptoJS.SHA256(input)
7 L/ r% J/ U( t% o Z
}4 r# J) D: d# j6 @8 o
7 A" x+ g! ] V( e( L. E
Nonce迭代到直到Hash有效。在我们的案例中,一个有效的Hash至少要拥有4个前置0。查找与有效Hash对应的Nonce的过程就是挖矿。
随着难度的增加,可能的有效Hash数量就会减少。伴随着有效Hash的减少,我们需要更强的算力来查找有效Hash。+ T8 D5 B6 P3 n* |& m7 k1 w
) A! \4 W5 ` f5 {1 X
为什么这么重要?3 n+ n6 B9 c% I% R! e
* h4 r! F) }: _- r. u8 D$ m
这些机制非常重要,它们使区块链不可变。
! O; P7 R4 h# g3 q
如果我们有这么一个区块链“A->B->C”,而且有一个人想要改变区块A上的数据。那么会发生什么呢?8 y0 m" {1 S# i6 V/ k
区块A上的数据改变了。8 E( F( R, F3 j- z8 w
区块A的hash改变了,因为数据被用来计算hash。
区块A失效了,因为它的hash不再有4个前导0。- v0 _/ S! @: S3 g
, d% K* W" L7 u/ b1 j, |* j( }' h# w
区块B的hash改变了,因为区块A的hash被用来计算区块B的hash。
* v" x# t9 K4 z: Q: R8 e
区块B失效了,因为它的hash不再有4个前导0。6 U2 b9 l) U& [" X/ q- J, O
+ S$ @1 U( @( {4 j6 `
区块B的hash改变了,因为区块C的hash被用来计算区块B的hash。$ O" N9 S* `# v
1 ]; C: o* |; Z; d; n0 [5 P$ N
区块C失效了,因为它的hash不再有4个前导0。
+ @- X; S* a+ e% e( |
改变一个区块的唯一方法就是将这个区块重新挖一遍,接下来是所有的区块。由于总是有新的区块被添加,因此改变区块几乎是一件不可能的事。
成为第一个吐槽的人