区块链是如何工作的——用JavaScript演示
段琰baby
发表于 2022-11-20 23:53:01
98
0
0
这听起来很棒,那它是如何工作的呢?
为了说明区块链,我们将会使用一个名为BlockchainCLI的开源命令行工具。$ V \+ e+ W; A0 d3 w1 K4 D$ O6 S. Y
+ I3 r, F# d A# B/ x ?# E
我同时也建立了一个基于浏览器的版本7 U5 Q7 }6 J4 p4 o
8 j/ H8 \5 u% ~- ?& u. B. @ @$ o, g
安装命令行工具/ w9 m* p3 W, a/ x' x; Y2 j: X7 X! ?
在此之前请先安装Node.js, @4 C( C" C" d- ~) J
% t+ z* {$ V: {) F# x
然后在你的命令行中运行以下指令:
8 J3 c% ~) B$ ^8 Q( @
npminstallblockchain-cli-g v6 A8 q. W/ I/ r/ D
blockchain0 c! u2 u2 k# L3 h( ^
2 y5 V) F3 A; B, w: N# l6 L2 |0 H6 X
你应该会看到?WelcometoBlockchainCLI!和一个blockchain→提示。这说明已经准备好了。% E7 l! v8 a# b( ^
S2 \7 S+ ?) k/ o4 l
区块长什么样?
7 @ x" T: q/ s5 } H
想要查看当前的区块链,你需要在命令提示行下输入blockchain或者bc。你应该会看到像下面的图片一样的一个区块。
# @: n0 a- F; z; D9 _# @
Index:是哪一个区块(创世块的索引是0)( R7 i0 `$ x% T
Hash:块是否有效?
4 \6 u& ^7 T- o0 q8 S( `6 x
PreviousHash:前一个区块是否有效?% O! m7 o& M# B' v
Timestamp:什么时候添加的区块?) A; s6 c4 H+ h. I5 ?) b
% X. c5 h; |4 T3 p# q& ~0 D& |
Data:什么信息存储在区块上?# Y/ m {+ }& r: ?/ G
4 Z8 `8 c; P- R- J
Nonce:在找到有效区块之前,我们进行了多少次迭代?5 j/ f1 R# O8 n6 `7 ^8 q: R
2 F. r5 [6 h8 F# U' O
创世块/ A4 d" S( z2 \- |# l4 X& U" ~$ n
每一个区块链都是从?GenesisBlock开始的。正如你们将要在后面看到的,区块链上的每一个区块都依赖于前一个区块。所以,需要创世块来挖出我们的第一个区块。6 _! d7 Z5 |" d1 t1 k. e9 \
/ \5 _& C6 Z( g# G1 o: |- B! h* v
当一个新的区块被开采时会发生什么?
& J# {' [ n( g# M6 r
让我们挖出我们的第一个区块。在命令行中输入minefreeCodeCamp。
9 h) ]9 [' G3 t4 F( d6 I/ v
区块链查看链上最新的区块来获取index和previoushash。在这个案例下创世块是最新的区块。
1 E% A! }$ b6 e5 `8 [* \( a5 |# s
Index:0+1=12 N. E( R0 f% Z& ]0 E$ L. C5 Q
PreviousHash:0000018035a828da0…
Timestamp:区块被添加的时间
) z4 I! `; ?9 L+ J& A |0 G
Data:freeCodeCamp- \3 E3 w5 Q U z( H+ V
Hash:???
" {4 ?: H" S! ~4 u
Nonce:???
* G4 G( g* {: T- t4 U# Y
Hash是如何计算的?; v) b$ Z8 K2 t# N& L
# b: o- H6 @4 }1 R. L# x4 M
哈希值是唯一标识数据的固定长度的数值。
Hash是通过将Index、PreviousHash、Timestamp、Data和Nonce作为输入值来计算的。
+ D( a, J) R) A% T9 K
CryptoJS.SHA256(index+previousHash+timestamp+data+nonce)
SHA256算法将会依据这些输入计算出一个唯一Hash值。同样的输入总是会返回同样的结果。
' h9 n2 M- j% }. ?
你是否注意到区块Hash中的四个前导0?
2 b' @$ b3 E2 S# M$ G
四个前导0是一个有效Hash的最低要求。所需前导0的数量被称之为难度
functionisValidHashDifficulty(hash,difficulty){
for(vari=0,b=hash.length;i=difficulty; ]1 \; l' D. T! V, U. L/ Z5 g7 @
}
/ R3 a/ [5 U8 J# L, \9 U* b7 p
这也被称为工作证明系统+ C' u2 A. m4 q' E' f5 c
+ ~5 T' _+ c5 l5 C! v( w
Nonce是什么?$ X/ F0 B% m4 |0 C
Nonce是用来查找一个有效Hash的次数。
7 C3 o$ H) B0 ^
letnonce=0;
lethash;* o. {. n, K& Z$ @6 y- J
% l0 }7 I+ i( A* T
letinput;8 x, B( i$ c# h# [2 w, D; P( h
while(!isValidHashDifficulty(hash)){
, w3 H* n% y7 ?; A, C. b6 K
nonce=nonce+1;8 o9 E7 n# ]1 g) Q9 i! G: |
; [: E% m( S* K% @
input=index+previousHash+timestamp+data+nonce;7 \: m, J. g6 K: H: h
1 m+ h9 d0 s& V5 H
hash=CryptoJS.SHA256(input)1 o) ~' R+ I8 ?% q" {8 C' f
; Z) I7 M6 I+ C3 R3 {- `: k( O: H
}
Nonce迭代到直到Hash有效。在我们的案例中,一个有效的Hash至少要拥有4个前置0。查找与有效Hash对应的Nonce的过程就是挖矿。! J! r5 Y2 ~0 b' Z, P( j; ]
随着难度的增加,可能的有效Hash数量就会减少。伴随着有效Hash的减少,我们需要更强的算力来查找有效Hash。
为什么这么重要?. O$ K; \! X/ I) _9 z+ s
这些机制非常重要,它们使区块链不可变。9 G0 @$ X, p# {& _4 W
如果我们有这么一个区块链“A->B->C”,而且有一个人想要改变区块A上的数据。那么会发生什么呢?5 J1 c t, O7 p* {4 V! b5 x
区块A上的数据改变了。
) V+ b) `8 n& [% W0 ^+ j0 ?
区块A的hash改变了,因为数据被用来计算hash。7 ]$ s2 I, e0 G7 w' ?
区块A失效了,因为它的hash不再有4个前导0。0 C( d! w- D6 |7 O$ I3 f8 G6 e
* ^4 C- x" |' _7 L
区块B的hash改变了,因为区块A的hash被用来计算区块B的hash。, R5 g, G; v9 ~" s
区块B失效了,因为它的hash不再有4个前导0。
区块B的hash改变了,因为区块C的hash被用来计算区块B的hash。
; K$ q1 t7 E( S
区块C失效了,因为它的hash不再有4个前导0。
改变一个区块的唯一方法就是将这个区块重新挖一遍,接下来是所有的区块。由于总是有新的区块被添加,因此改变区块几乎是一件不可能的事。
我希望这个教程能够对您有所帮助!: y( @5 B* O2 U8 o
, G1 x; k( X* _* E$ S
安装命令行工具' v& D* m; F0 b' n
在此之前请先安装Node.js
然后在你的命令行中运行以下指令:
( d9 t( ^# t2 U [" |% {
npminstallblockchain-cli-g4 [. s2 v# C, ?1 X/ m
blockchain
0 |" {* K o' D/ O+ T; l0 @
你应该会看到?WelcometoBlockchainCLI!和一个blockchain→提示。这说明已经准备好了。
区块长什么样?
/ V7 G8 F9 U3 V* H {
想要查看当前的区块链,你需要在命令提示行下输入blockchain或者bc。你应该会看到像下面的图片一样的一个区块。! D! r0 }; b- u
Index:是哪一个区块(创世块的索引是0)?8 r5 R) s+ M7 m, V/ u
Hash:块是否有效?
3 F/ L1 ]$ |: ?( y" {) p
PreviousHash:前一个区块是否有效?
1 v6 p R& H3 Z9 h6 D) w$ D
Timestamp:什么时候添加的区块?7 e/ J! I/ v' j9 a
, ]" C& ^0 A1 v5 v3 V! ]6 Q0 Z
Data:什么信息存储在区块上? b$ y3 v0 ~5 v0 \/ u" F
Nonce:在找到有效区块之前,我们进行了多少次迭代?
' [; c% z/ I4 v5 Z( }' E
创世块
" T8 a C/ q6 }# R0 l Y; y7 W
每一个区块链都是从?GenesisBlock开始的。正如你们将要在后面看到的,区块链上的每一个区块都依赖于前一个区块。所以,需要创世块来挖出我们的第一个区块。( @$ Q- x' f$ @. |: s4 k) g
. ^( O8 a }: v6 {5 X
当一个新的区块被开采时会发生什么?
让我们挖出我们的第一个区块。在命令行中输入minefreeCodeCamp。) R' V: s6 x% G( ]7 \3 I4 C
' u4 @: C5 h1 m. m
区块链查看链上最新的区块来获取index和previoushash。在这个案例下创世块是最新的区块。: o, \8 o; k; I4 S. c+ P
4 _. G1 [" ^; J* g6 V4 [7 U$ V1 u
Index:0+1=1( Y y1 {* b( Z) I; a3 i" Q
PreviousHash:0000018035a828da0…( `7 y( T+ _$ }4 T& T7 o
+ p2 c- m( Y8 M. N) K
Timestamp:区块被添加的时间* v1 q. {+ f5 w, U* q( {1 R& L! e
Data:freeCodeCamp5 ]0 A% x, R0 x) ]% z
! Y7 n8 S8 P: U7 V
Hash:???
% ~+ i9 \; g! Z- L9 k4 V
Nonce:???
Hash是如何计算的?7 @& _2 _3 P1 y4 F8 F7 `5 ?
5 A# b5 s% C4 b1 {2 u4 o
哈希值是唯一标识数据的固定长度的数值。
7 L1 g- ], J% x: t$ G- @# y9 n, B' D1 h
Hash是通过将Index、PreviousHash、Timestamp、Data和Nonce作为输入值来计算的。
1 ?$ J% G! G3 z, m* [7 R# s1 l
CryptoJS.SHA256(index+previousHash+timestamp+data+nonce)
4 J7 E; i( A. u5 ]+ e8 R4 p8 A
SHA256算法将会依据这些输入计算出一个唯一Hash值。同样的输入总是会返回同样的结果。
你是否注意到区块Hash中的四个前导0?
1 c, G, F- l# I/ x7 _. T( M
四个前导0是一个有效Hash的最低要求。所需前导0的数量被称之为难度) x+ n- w9 v, C4 C' _
functionisValidHashDifficulty(hash,difficulty){1 }% {3 Q* `; |% \. e
U& g- u& q }, C$ K: @ @. W
for(vari=0,b=hash.length;i=difficulty;/ b$ e* Y8 K: n& Q8 s) T
2 x" D% |2 C+ T
}7 {2 i1 T" Y% \& c7 q7 R6 W' Y: _
$ y* i. |9 a) s7 ^9 e( m# m
这也被称为工作证明系统, _1 k9 H0 X9 _, o* L
Nonce是什么?( o$ h: ~2 d9 d
Nonce是用来查找一个有效Hash的次数。1 ?0 s4 J8 l, C# [9 M
letnonce=0;
! g) v0 B& ?$ f8 d0 O
lethash;, s1 a' O4 ^) n; m9 P1 Y% x
: s% c* x; X. e9 U7 q- L/ A, Z" k
letinput;
* y2 t6 `4 f" Y; p( a& v4 b2 o% _2 Y
while(!isValidHashDifficulty(hash)){
: j- s1 H( b' T
nonce=nonce+1;. t- O! F. _# w6 w5 P9 o% H
input=index+previousHash+timestamp+data+nonce;+ k9 v7 ~% k( W) Z+ Z+ S4 A9 L
2 I7 j1 ^+ v3 z+ p
hash=CryptoJS.SHA256(input)- S3 W1 O$ }* W% N# g8 P2 {
* R7 j! h3 Z" M. J
}
* z% g6 V* f/ }4 g) }: `5 |
Nonce迭代到直到Hash有效。在我们的案例中,一个有效的Hash至少要拥有4个前置0。查找与有效Hash对应的Nonce的过程就是挖矿。
随着难度的增加,可能的有效Hash数量就会减少。伴随着有效Hash的减少,我们需要更强的算力来查找有效Hash。
为什么这么重要?
这些机制非常重要,它们使区块链不可变。
0 f/ G& R2 p; r/ P
如果我们有这么一个区块链“A->B->C”,而且有一个人想要改变区块A上的数据。那么会发生什么呢?: i3 j% \7 C$ L6 D
区块A上的数据改变了。5 F) `+ k! { s9 [; V7 W
区块A的hash改变了,因为数据被用来计算hash。
; x4 x6 [0 P' F- ^- W
区块A失效了,因为它的hash不再有4个前导0。* R# g* L4 m4 q7 l7 ]$ [
7 B9 p1 P6 i) Y" v
区块B的hash改变了,因为区块A的hash被用来计算区块B的hash。6 A: P/ q4 X" h, B/ M- X7 \
区块B失效了,因为它的hash不再有4个前导0。% ?8 e+ v4 o0 X3 R% L
/ `. a0 F+ R, `, `: d. X
区块B的hash改变了,因为区块C的hash被用来计算区块B的hash。
区块C失效了,因为它的hash不再有4个前导0。4 c9 s, x5 ]3 C3 l* `' R9 i' ^: V
* T& P2 O5 ?2 R1 k- L, x9 t
改变一个区块的唯一方法就是将这个区块重新挖一遍,接下来是所有的区块。由于总是有新的区块被添加,因此改变区块几乎是一件不可能的事。
成为第一个吐槽的人