Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
最火的热词相必就是区块链了,C++和GO是目前最适合区块链开发的两种语言,所以咱们学GO的肯定得学一点区块链的知识,但是区块链涉及太多密码学,金融学、p2p网络等知识了,从哪里切入呢,今天我们就从用go实现一条带有模拟挖矿系统的简单区块链。
- s8 G: |- v8 i' A1 \  s/ P% q( u代码分析; v0 y$ t7 }+ t% V9 f" T/ ~2 p5 s0 ^
三大模块6 N: q0 F' D# d" q( X
代码还是比较简单清晰的,主要有三个模块,Block模块、BlockChain模块、POW模块即挖矿模块。, ?- e4 r3 O6 ]) M! Q- o
运行流程
1 e5 Q6 q. l. b  p- E1 g首先从定义一个区块开始,一个区块中包含的信息有区块信息,时间戳,前区块哈希值,现区块哈希值,经过挖矿后得到的哈希碰撞值等等。+ p6 n4 F/ n1 d3 ?8 S6 G
接着我们开启一个切片用来存放一个个区块,但是第一个区块是比较特殊的,我们称之为创世区块,在真实的比特币中,第一个区块是由创始人中本聪挖矿所得,没有前哈希值,所以这里我们直接将第一个创世区块创建添加到区块切片中。
, X( S& b: E2 L( s然后给到一个添加区块的方法,用户添加区块信息后,经过POW挖矿系统才能成功添加到区块链上。$ [8 [, s, O0 ~& b
有了大概的运行流程接下来再来看代码就会轻松很多了。
+ L7 E1 o2 u  R/ s. n5 _package main
3 H# V) ~& W0 P) V; k$ B6 jimport (
% k7 V: U: k7 p0 {4 C6 R        "math/big"
% {1 O! h9 N0 @1 t# w        "bytes"7 R& z: W9 Q- C% i' Z1 V
        "encoding/binary"" d( E' t8 P3 N& \9 [% v! Y) f% O
        "crypto/sha256"& P9 g0 I5 U) S8 ^+ J
        "fmt"" n2 d6 g! |5 i" N8 w) f
        "time"; Z" t/ U3 A) ~5 a& C0 Y, W
)
" @9 a* i+ v( H0 P) `3 ~//Block模块0 V( E% {$ g6 n: N
type Block struct {
$ M1 f: M3 \, d# x/ ~8 G        Version uint64                //版本号
& N" k6 g+ q0 [+ f) M# W        MerkelRoot []byte        //这是一个默克尔数,这里先默认为空2 v) d6 n- i) Z, L# ^7 ]; P
        TimeStamp string         //时间戳+ V. r2 H& z" o4 z$ }
        Difficulty uint64        //难度值% ^9 r, x) a! R8 j% z- Y7 Y# [
        Nonce uint64                //挖矿所找到的随机数* j. D: _# y4 v+ T
        PrevBlockHash []byte//前区块哈希值5 M! O7 N) u" ]% ]) I
        Data []byte                        //插入的数据
) z; A+ z3 A  t" ?' _* N: c: c8 h        Hash []byte                        //当前区块哈希值
% B# p- j0 N+ u7 b, x! }; p}
: \4 K# X* d' M  P//给到一个创建新区块的方法
; ^( r/ a5 t5 h4 Qfunc newBlock(data,prehash []byte)*Block  {5 n2 x( a3 V3 k! u) F
        block:=Block{5 H& H0 k. n, g% `5 {' [
                Version:00,1 E$ J2 a* o; i* A" X) K& e
                MerkelRoot:[]byte{},
5 c& l: l; p- u                TimeStamp:time.Now().Format("2006-15:04:05"),1 L3 g- u% e7 w
                Difficulty:difficulty,+ \# f0 z1 m' \8 s( p6 T3 r
                Data:data,
8 D7 L: m1 }4 J3 I6 T                PrevBlockHash:prehash,
8 M0 j* F6 x, l% I# X8 F& d& |9 T% w        }3 r5 B, g& q. J/ ]& a+ }4 C% r, V
        //需要被挖矿之后才能创建区块,所以调用挖矿函数) v- x3 U! D! ^( z! X
        pow:=NewPOW(&block)9 ]3 g  A, X$ F. w' B. f, ]; ]5 o
        nonce,hash:=pow.Mine()
8 ]5 x' H0 r; H; Y; R0 ?4 y  d" g1 A        //挖矿结束,得到哈希碰撞值
: N! C; c2 ~9 H" T0 q        block.Nonce=nonce: s% Y, I6 T7 J' Q6 n5 F9 A- B
        block.Hash=hash
. M+ \7 k# L* x  E( j8 G& U        return &block+ k& W6 C! V: A* R8 v. d+ ?3 Z
}
- f9 t+ k0 n( j. Y$ U//Blockchain模块- d0 G$ F" w! X! V0 r0 T4 M+ k: z% y$ F
const gnnesinfo="1996年9月2日,一代伟人诞生了"
2 @; n: ^& y: Y1 \% Q& [) {//给到一个区块链结构
4 j% V/ T2 X$ _+ G: `5 t- {type Blockchain struct {
7 I0 e! A' j, g, S2 b2 T        blocks []*Block
8 j9 ]+ z7 x; T! W' q0 ^}
6 m) Q; K! d. n, D//将创世区块加入区块链,并返回一条可供操作的区块链+ z: K& J  n! @% u6 g- v; ^
func NewblockChain()*Blockchain  {
. h* {$ [; S8 B+ ]        var bc Blockchain! D, |5 N* a* Y% o, ?: `
        block:=newBlock([]byte(gnnesinfo),[]byte{})) P$ l8 d. o3 O% v1 |9 F3 z" e& q
        bc.blocks=append(bc.blocks,block). F% z$ @. W% N# u0 R
        return &bc  m. o. S( o6 m/ E5 l/ T
}6 H1 h/ h6 e; R& T/ ^2 A
//给到一个增加区块的方法! Y4 V0 a/ l9 U# z( i
func (this *Blockchain)Addblock(data []byte)  {; k# H2 \0 o! p  b7 g
                lastblockhash:=this.blocks[len(this.blocks)-1].Hash( a8 l! C9 y: y4 K' [3 x
                block:=newBlock(data,lastblockhash)$ y* v, F6 |0 }- b2 [/ ]
                this.blocks=append(this.blocks,block)
7 A# H& H& u  D( |: K}
) k/ ^, ]& G6 H) l; O. N5 A//遍历,打印所有
1 F$ ^1 w- V: nfunc (this *Blockchain)PrintAll()  {# e5 J6 A5 l  q9 M1 W: U: B
        for i,v:=range this.blocks {/ m; p0 ?. p  ]. V9 `
                fmt.Printf("=========区块高度%d=========\n",i)
4 r3 z9 N- ^& f; L0 t  n                fmt.Printf("Version : %d\n", v.Version)5 D3 e; E9 g3 B$ b2 U0 i" z
                fmt.Printf("PrevBlockHash : %x\n", v.PrevBlockHash)4 E! u' ?7 o, l3 W# o9 `
                fmt.Printf("Hash : %x\n", v.Hash)
! d' \" ^+ |; d( Y; j                fmt.Printf("MerkleRoot : %x\n", v.MerkelRoot)
% H; c7 ^9 V1 T) ]8 A! t* X                fmt.Printf("TimeStamp : %s\n", v.TimeStamp)' J0 t- S, C# \0 [
                fmt.Printf("Difficuty : %d\n", v.Difficulty)
# P5 s/ E& D% H# ]( ]8 }$ i' W+ j                fmt.Printf("Nonce : %d\n", v.Nonce)
3 d8 W6 B/ o- C! Z9 L1 d( x8 E                fmt.Printf("Data : %s\n", v.Data)( n% O7 X2 [( j# j( I; {* D, W" T
        }
- ~9 B) c/ @% ~- M}* v- ~) t( C- Q4 ?
//pow挖矿模块# \1 s/ ^* V. m0 h- [
const difficulty=24
- p3 w5 d" @# X/ q//POW挖矿结构需要两个参数,一个是所需挖矿的区块,另一个是挖矿成功所需目标数字8 w8 w2 q- U/ ?# m
type ProofOfWork struct {
* l* m$ k$ {$ ?7 C6 W0 ^        target *big.Int
& T' R  ^" S* }, k% ~        block *Block+ O! K. w. B# v3 U2 g
}
/ T0 c. T$ e) W" V% P//给到一个根据难度值得到哈希碰撞目标值的函数
* [( n2 L  o, zfunc Gettargetint()*big.Int  {  R4 l) x  l2 \( b- |* n* p
        targetint:=big.NewInt(1)
! U2 t( \0 w" m7 W5 N4 Y        targetint.Lsh(targetint,256-difficulty)# n, a0 i9 b* Z( y: m/ S
        return targetint/ j: `5 W4 V. t. z" O
}9 ~9 K3 T, T0 A" R
//创建挖矿的方法; S0 U" r6 ~% j2 U; `1 x
func NewPOW(block *Block)*ProofOfWork  {! H# G) v3 Y) [9 T& j  P; v
        var this ProofOfWork5 a* k4 M' d$ T$ H& \1 |
        this.block=block
0 p+ z* R  z" ~+ O, Q# G% M1 s        targetint:=Gettargetint()- W8 |3 j. {$ Z1 a! O1 h
        this.target=targetint
) _2 W4 G# \7 y, X        return &this
$ N- B7 n4 Q9 K9 A3 M; T}7 _) S/ R+ W( G7 ]8 d: R
//一个用来将uint64转化为字符切片的小函数,方便接下来的转化
* M$ \* ]# q; E; Efunc uint2byte(num uint64)[]byte  {9 P/ G" A" O, ]% Y& i" T
        var buff bytes.Buffer% Z1 G) N+ P4 P
        binary.Write(&buff,binary.BigEndian,&num)
& ^8 Z+ b% F/ u! X        return buff.Bytes()' I1 g: n" o# `' e' C/ q
}0 _; D: e6 x1 U
//挖矿的准备工作,将其他字符组合起来之后求其哈希值
% d' l, g' M9 |4 kfunc (pow *ProofOfWork)PreparetoMine(nonce uint64)[]byte {
" B* e, l, d* B  D        info:=[][]byte{: L0 m' f. L6 E. S+ G, A$ O8 F7 S
                pow.block.PrevBlockHash,
9 k- T$ h$ s- l4 j4 f, Q                pow.block.Data,
# s1 S- U) O, ~0 w                uint2byte(nonce),
' Q+ |- o+ V! z% n1 p                uint2byte(pow.block.Version),
% h% X2 }$ `8 E3 |4 E8 R6 p                uint2byte(pow.block.Difficulty),' q! h) W' O- h2 Z( r8 U
                []byte(pow.block.TimeStamp),
. K  @* j# F% I2 k6 R$ G2 g1 |                pow.block.MerkelRoot,# q4 ~4 v3 j, M6 I$ e* e
        }
+ K" i4 b$ H  n. q        allinfo:=bytes.Join(info,[]byte{})
: w7 B9 m( a# \        hash:=sha256.Sum256(allinfo)9 a- ]8 m$ @* H$ r& p
        return hash[:]
: |/ c4 {' ]8 ~1 v; Q}
& F( J# [/ d: k$ j+ U4 n# @//pow挖矿方法,返回两个参数,一个是碰撞成功的数字nonce,另一个是当前区块哈希值3 G! [6 B0 F0 e: \! Z8 o6 ~, U& t. [
func (pow *ProofOfWork)Mine()(uint64,[]byte)  {
- n# T' C( `( Q- Y+ z        var nonce uint64, C$ H+ ]0 I) V. [5 E, i  B7 [  T
        //nonce从0开始穷举,直到出现哈希值小于给到的目标值$ }& I" h2 Y0 \6 E
        var hash []byte  y! s* }+ [5 r+ R
        for  {
( A7 X3 J/ ]2 t6 k! T$ c                hash=pow.PreparetoMine(nonce)
' @+ U- J$ j' g; q. B( O                var hashint big.Int& o0 K$ [3 e1 V5 |. T. c# Q
                hashint.SetBytes(hash)
$ x! `+ A& g& ~9 U                //对比哈希值是否小于目标值,小于则成功退出
6 U( ?0 }3 D: q, x6 E( P                if hashint.Cmp(pow.target)==-1 {
2 p6 J0 K' h4 s9 ~. U                        break; Z& N% s  o' t, H, Z, }; j( C2 L. T0 T
                }7 g" W: E0 a6 s+ ]% _$ r
                //不小于则继续穷举# B# d7 V+ U. A0 s! O% J( S
                nonce++
$ j' c/ }" C( x% M* c& F        }6 Y3 C) `, ]! ~5 h, `# y
        return nonce,hash9 y/ e& E! M' b& R
}
! \$ e+ w/ k) q. ~* x+ E- h9 I//调用
: ~. p( @1 f- K: k3 sfunc main()  {
2 S- z" R, L# p2 w- h6 F0 x* A/ Zbc:=NewblockChain()% ^5 b* a) u% P* h- r7 q
bc.Addblock([]byte("welcometo")), v0 S* P/ o( q) I5 H) I3 y
bc.Addblock([]byte("mycsdnblog"))
1 [9 E* J& w0 [, |- `% Fbc.PrintAll()% S" M0 \% ]$ p; g/ s6 y
}
0 G3 l7 a6 E/ Q* r3 m8 Z以上就是一个微型的区块链了,虽然看起来很简单,但是对于理解比特币、区块链还是有不少帮助的。
标签: Pow
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

蓝天天使2017 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    10