Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
最火的热词相必就是区块链了,C++和GO是目前最适合区块链开发的两种语言,所以咱们学GO的肯定得学一点区块链的知识,但是区块链涉及太多密码学,金融学、p2p网络等知识了,从哪里切入呢,今天我们就从用go实现一条带有模拟挖矿系统的简单区块链。) O3 E& \) L  L! `: s
代码分析
( q1 D- g/ T. j0 v三大模块
& ^/ ~& C; i$ l/ N8 Q% O% e1 U9 q2 G代码还是比较简单清晰的,主要有三个模块,Block模块、BlockChain模块、POW模块即挖矿模块。0 _& w2 `$ A+ K2 \
运行流程
: I& m# N7 ]& M4 A/ ]: _$ b, y3 ]6 F5 M首先从定义一个区块开始,一个区块中包含的信息有区块信息,时间戳,前区块哈希值,现区块哈希值,经过挖矿后得到的哈希碰撞值等等。& r/ X( U$ S8 M  {' Y
接着我们开启一个切片用来存放一个个区块,但是第一个区块是比较特殊的,我们称之为创世区块,在真实的比特币中,第一个区块是由创始人中本聪挖矿所得,没有前哈希值,所以这里我们直接将第一个创世区块创建添加到区块切片中。. p$ s3 M, y( b
然后给到一个添加区块的方法,用户添加区块信息后,经过POW挖矿系统才能成功添加到区块链上。9 A# x! i8 h3 B, ^: k5 E3 o
有了大概的运行流程接下来再来看代码就会轻松很多了。
0 D. [2 U( Y; u+ Y! c5 \( Rpackage main
4 x9 l. B8 e6 a+ j/ ]  u) himport (( K2 E  b7 r& e* t9 I- H
        "math/big"" O' D  F' h! k2 Z- }0 R
        "bytes", e( T$ F; }  l: T, e- j3 L$ ?/ f
        "encoding/binary"
% R. S8 ?( \( j3 \8 M% ~" W        "crypto/sha256"9 l% E" b0 m2 D$ ^2 |# K; r
        "fmt"
. I' t) Q5 |0 H        "time"
  S! `* X! h# i/ {& d9 Z)2 B+ R' I+ F; I
//Block模块
, W2 S# l) \/ Q% E  a. Jtype Block struct {
4 c1 F3 L( p3 T6 ?4 y        Version uint64                //版本号
, M. a+ }- S, K        MerkelRoot []byte        //这是一个默克尔数,这里先默认为空( [+ [8 {4 M# d* K! A3 {
        TimeStamp string         //时间戳
4 P2 v% P7 y! p$ t! C        Difficulty uint64        //难度值
+ `, ^2 r) x  @" P- J        Nonce uint64                //挖矿所找到的随机数
3 n* N& d0 }- r" x        PrevBlockHash []byte//前区块哈希值, y. u! C+ g2 p* o
        Data []byte                        //插入的数据
- t9 O+ V) u/ [( h& D8 ]. m        Hash []byte                        //当前区块哈希值
1 T4 C, M' j% ^$ H) @}
. j- v+ G& P) i* l9 z: L( C7 _//给到一个创建新区块的方法( x! [/ ~4 n- T/ a% r4 j
func newBlock(data,prehash []byte)*Block  {0 b9 U, X2 ~9 ]7 T" C+ V- C
        block:=Block{
! H* C8 _+ u" Q+ Y1 M                Version:00,$ L4 r# V6 N4 d! x# Z- f
                MerkelRoot:[]byte{},- y" Y  z0 B6 |) b/ ?" j, Y! b. }/ ?, M
                TimeStamp:time.Now().Format("2006-15:04:05"),4 X: Y& D5 K+ ?" L: F) q
                Difficulty:difficulty,
8 k) O4 Z8 V% \. {7 [; p3 F                Data:data,
* H: h: l3 t. s+ d, u, S7 B                PrevBlockHash:prehash,
2 v% `4 L8 i. v7 _3 C        }
% r1 M' E& y% y: x6 t/ N  t        //需要被挖矿之后才能创建区块,所以调用挖矿函数
+ v" ^4 Z3 n) t0 U3 B5 H' t        pow:=NewPOW(&block)* c  v5 n2 I: c/ s
        nonce,hash:=pow.Mine()
5 u* d3 H: F6 [        //挖矿结束,得到哈希碰撞值  X& a0 Q9 g, J1 E* z/ s
        block.Nonce=nonce0 @5 N* h) `4 D3 i# ~7 G
        block.Hash=hash9 H( Z4 L( l& ^' _* r4 l
        return &block" C% C" d' d% W7 g
}
$ a/ C" @* Z5 Y9 q/ `2 q4 E//Blockchain模块' y  j) k, P1 m( g3 R/ ^9 ]
const gnnesinfo="1996年9月2日,一代伟人诞生了" 7 _( P- X: t, u7 F6 `
//给到一个区块链结构' P! K4 p9 D7 j  B1 L. s
type Blockchain struct {
6 |1 u; V: v  x- e- t/ R' Q! b6 Z        blocks []*Block
- C- e$ m1 K* T( {( Z" _0 g6 P6 H/ V  d}
7 W1 n/ u' s$ c5 \) P3 ~* I//将创世区块加入区块链,并返回一条可供操作的区块链
3 c7 F& W5 X' A. Zfunc NewblockChain()*Blockchain  {
& g) d1 c) |) e! L  x$ j        var bc Blockchain) q% T2 N( k6 j4 T9 G
        block:=newBlock([]byte(gnnesinfo),[]byte{})% {' {9 Z' j6 O, I, ^  n
        bc.blocks=append(bc.blocks,block)8 e4 V# ~) f" e3 e( S4 R# j
        return &bc* L+ u1 |! w$ w* {3 q  s4 o, D4 H
}; w! v4 t/ g2 n7 E" X7 B2 m' |
//给到一个增加区块的方法
2 _' E$ M2 j; `0 ~" t  zfunc (this *Blockchain)Addblock(data []byte)  {
7 Z! q% d2 r; k! L# @/ R1 b                lastblockhash:=this.blocks[len(this.blocks)-1].Hash
  G3 A3 H3 `/ V% O$ Y& s                block:=newBlock(data,lastblockhash)
/ ]& M3 t: Q+ |' r                this.blocks=append(this.blocks,block)
- K4 b$ `. ]: i4 e, m8 _}
3 w8 G, `8 T7 \6 c. q2 ?5 z//遍历,打印所有
8 g, R2 L6 @$ {( W& ^, zfunc (this *Blockchain)PrintAll()  {
( F& k$ r: S4 a( j' C2 R- U        for i,v:=range this.blocks {. d3 H7 O6 R7 G4 I/ H
                fmt.Printf("=========区块高度%d=========\n",i): j/ y4 x& [& T! N
                fmt.Printf("Version : %d\n", v.Version)( K9 e8 U* i: _1 m3 M
                fmt.Printf("PrevBlockHash : %x\n", v.PrevBlockHash)& E2 s! [% w9 O  T/ w1 i, M& K
                fmt.Printf("Hash : %x\n", v.Hash)
- S- l% i2 m% _                fmt.Printf("MerkleRoot : %x\n", v.MerkelRoot)
$ H& b: p2 O9 [; C& d* a                fmt.Printf("TimeStamp : %s\n", v.TimeStamp)
9 q% a9 h+ R0 s( s4 t/ t                fmt.Printf("Difficuty : %d\n", v.Difficulty)
( f3 h% G) x; g                fmt.Printf("Nonce : %d\n", v.Nonce)
# s. M$ X% V+ u: V2 R' C                fmt.Printf("Data : %s\n", v.Data)2 q1 }' q2 I9 Z5 _. ^. ]
        }
% L  I# r: F, }9 @}" E; E, k, b9 R: i5 J1 U
//pow挖矿模块; K) I. v1 n$ ]' i! B
const difficulty=24
7 ~9 F' L' N3 G2 W/ P//POW挖矿结构需要两个参数,一个是所需挖矿的区块,另一个是挖矿成功所需目标数字
  K, T$ O* Q' A8 ]/ ]" ktype ProofOfWork struct {: i; t2 A2 ?" ^) q
        target *big.Int+ \' n' o0 j4 X) y0 @7 w) b3 P
        block *Block9 |" ~2 Y* _, h9 v/ p9 r
}! g: W* G3 J% W9 O; {) f  M9 u
//给到一个根据难度值得到哈希碰撞目标值的函数
" E. D4 |9 X0 x  _func Gettargetint()*big.Int  {
6 D$ B! b) n: I& P        targetint:=big.NewInt(1)4 T0 b9 w  i% L0 e0 f% h7 N
        targetint.Lsh(targetint,256-difficulty)
6 f: C+ w; j6 ]4 M        return targetint/ X% Z1 `( k- k1 I$ |! o" Z
}& p* P6 l9 O: z4 y! n
//创建挖矿的方法
3 ]0 ?) r* X# Y* dfunc NewPOW(block *Block)*ProofOfWork  {4 q$ ~+ t" E  C. V" c/ t- K/ e
        var this ProofOfWork2 W' E* H/ R" D' s/ T
        this.block=block
- O8 J2 x; A' k* P6 |  j; [        targetint:=Gettargetint()
9 G( i4 R+ K/ s        this.target=targetint* z  ~  s7 B; C0 z
        return &this0 Q- s& e( J1 G! a; G" }
}3 ~6 r; v5 o& Z5 z; ^$ |
//一个用来将uint64转化为字符切片的小函数,方便接下来的转化
& o7 ]# h+ Z( S& e6 Ffunc uint2byte(num uint64)[]byte  {# @) c/ }+ {7 a. I* b8 G: h
        var buff bytes.Buffer5 }* w' N% D, Y6 v! s" o
        binary.Write(&buff,binary.BigEndian,&num)
" F8 c5 w$ w( s/ u. h3 b# f% ]        return buff.Bytes()
& G9 K* @5 o" R3 F}9 A. R, z& l: x2 g: F. W: E4 x
//挖矿的准备工作,将其他字符组合起来之后求其哈希值
: j. S/ ~1 j7 D3 afunc (pow *ProofOfWork)PreparetoMine(nonce uint64)[]byte {/ k5 P! I4 w, l7 I
        info:=[][]byte{
- ]% j2 L) u" z2 ]* W                pow.block.PrevBlockHash,
' v+ D* F( I& E* J                pow.block.Data,
( U! e( a. O2 e0 x, N                uint2byte(nonce),, {( j5 e" \- ]! Y0 ~! F
                uint2byte(pow.block.Version),. R4 K, ]0 s  X3 C6 \% r/ W
                uint2byte(pow.block.Difficulty),
& E, {. f+ l/ O, U                []byte(pow.block.TimeStamp),
! s$ T3 w1 P% t* V/ e                pow.block.MerkelRoot,
+ Q# O+ s3 `2 q, y# Q1 ]- A        }
5 ^! m: ]* `( c  W        allinfo:=bytes.Join(info,[]byte{})& V2 G9 W0 H% L
        hash:=sha256.Sum256(allinfo)
2 g0 @8 M/ l- ~+ V" R" `        return hash[:]1 L" w' }; T$ U, T( a/ c
}, w5 F7 X' e( v& Y2 \
//pow挖矿方法,返回两个参数,一个是碰撞成功的数字nonce,另一个是当前区块哈希值
! ]5 B  _& Z: I" |' R7 F. g4 Sfunc (pow *ProofOfWork)Mine()(uint64,[]byte)  {
% b/ r5 R2 d! t: U        var nonce uint64$ U' ]/ N" D) M% D. n+ ?0 v$ ]7 A$ d
        //nonce从0开始穷举,直到出现哈希值小于给到的目标值
+ x; [" j  D7 Q0 B2 w        var hash []byte' U5 f3 C; y# T7 l  d, h$ d- A  K
        for  {4 |* l* m* |8 e) h
                hash=pow.PreparetoMine(nonce)
7 f7 T/ L1 `( T) |  `# R/ V" d5 T                var hashint big.Int3 q% t0 w, X( z) @
                hashint.SetBytes(hash)
  G/ n" \6 I9 X" D/ D% u3 Y                //对比哈希值是否小于目标值,小于则成功退出* f& @/ y  `# I: _: N
                if hashint.Cmp(pow.target)==-1 {
/ A1 ^. A# @0 R! @: y, s                        break
  V1 |" j7 `0 L* R4 b" K                }
6 T( h/ p: }) a, B" X1 S7 Z0 [" `9 n9 e                //不小于则继续穷举) z# J* Q! u( W) ], G! [
                nonce++
9 C6 Q5 s  h: z) b        }
, I" |- Y/ N& X. ?1 S! |3 J9 e4 X        return nonce,hash7 r) H+ D  U# e: A
}& w( A+ M* W9 ^
//调用, M3 p) z, F% P$ z* O
func main()  {0 h4 U- {- _+ q3 e
bc:=NewblockChain()! ^: V7 X# o& m. ^* F* x
bc.Addblock([]byte("welcometo"))& U; d5 k4 j0 h3 ?
bc.Addblock([]byte("mycsdnblog"))( ~2 ^6 U: U8 a! H
bc.PrintAll()
0 g9 y' \) k* E}( P' k- |) ]7 ^
以上就是一个微型的区块链了,虽然看起来很简单,但是对于理解比特币、区块链还是有不少帮助的。
标签: Pow
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

蓝天天使2017 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    10