Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
最火的热词相必就是区块链了,C++和GO是目前最适合区块链开发的两种语言,所以咱们学GO的肯定得学一点区块链的知识,但是区块链涉及太多密码学,金融学、p2p网络等知识了,从哪里切入呢,今天我们就从用go实现一条带有模拟挖矿系统的简单区块链。( f8 ^4 Q' m8 e1 J+ h; d; P+ c
代码分析* c2 t' d3 D) `+ w3 j
三大模块
, g8 f4 j, Q. @2 ~代码还是比较简单清晰的,主要有三个模块,Block模块、BlockChain模块、POW模块即挖矿模块。
* N: L8 f! a: G7 V7 _/ V运行流程
/ B2 [  e' h' l7 p) t5 J首先从定义一个区块开始,一个区块中包含的信息有区块信息,时间戳,前区块哈希值,现区块哈希值,经过挖矿后得到的哈希碰撞值等等。
: ?2 q1 z. ], Y" G接着我们开启一个切片用来存放一个个区块,但是第一个区块是比较特殊的,我们称之为创世区块,在真实的比特币中,第一个区块是由创始人中本聪挖矿所得,没有前哈希值,所以这里我们直接将第一个创世区块创建添加到区块切片中。
4 v& ], h- |3 C8 |7 T4 F) d然后给到一个添加区块的方法,用户添加区块信息后,经过POW挖矿系统才能成功添加到区块链上。
& Y0 B. ~- X0 [0 v6 _2 D  ^3 i( \有了大概的运行流程接下来再来看代码就会轻松很多了。8 R0 l# n  h1 V, U2 K& a! {; ]+ G" x
package main
' _4 E) |* e7 k" cimport (
% }9 W( K5 E2 E! D: Z        "math/big"
/ k. G- }  k+ p! F) G* p& O        "bytes"
) h/ a+ J# E- ]( k6 n4 G; b, h3 X        "encoding/binary"
+ ^3 K7 g) {: ~4 j7 b6 ]/ q        "crypto/sha256"1 S  Z2 H5 ]/ j2 S
        "fmt"# ~  Q9 ~7 z3 D1 n& M1 P! r- g
        "time"
9 |) U  \/ j) u: f)
" F& [; L4 N  {# G( E//Block模块
6 z" m, j) }* g, O  Ptype Block struct {: v& T. [% [7 q2 n  D" P) t
        Version uint64                //版本号; P- N/ M4 k$ \& v9 @& x3 C
        MerkelRoot []byte        //这是一个默克尔数,这里先默认为空) l* h* z5 Q' q8 g& Y
        TimeStamp string         //时间戳, K4 h  ~6 v- i, T8 R! E
        Difficulty uint64        //难度值
8 b3 }0 {/ U: z! b1 I" z, Y: l        Nonce uint64                //挖矿所找到的随机数
3 x$ X0 o9 l$ J& |$ T/ t6 `( @5 _1 X        PrevBlockHash []byte//前区块哈希值' G- I; }# Y' ?4 `' o5 _8 {, E
        Data []byte                        //插入的数据9 `3 j, {* D- [6 h1 k# w' v% w
        Hash []byte                        //当前区块哈希值
: P3 M# D0 u: ?: G) B}$ \& E5 s& i& K% x/ U
//给到一个创建新区块的方法
# T+ M* M  ?- Y5 S1 Z  M8 M' G- C/ |func newBlock(data,prehash []byte)*Block  {7 z7 p8 j. H, v& h% J' ~) o
        block:=Block{
, m/ Q) L4 X4 w1 t/ r7 F                Version:00,8 \) K. y: N% H4 `% M
                MerkelRoot:[]byte{},# C2 L1 H# T& s" Z' D, D
                TimeStamp:time.Now().Format("2006-15:04:05"),4 W9 b0 W7 k" S7 V7 x
                Difficulty:difficulty,1 k  H$ g' @( G8 Z2 H: U9 b) z* y
                Data:data," \# o8 ?  X9 A5 ^3 Z2 H
                PrevBlockHash:prehash,
4 c2 t3 @' q+ p) e5 R' N        }, |4 }3 ]- a# W8 s0 j$ Q
        //需要被挖矿之后才能创建区块,所以调用挖矿函数! N8 j# I! ^6 G
        pow:=NewPOW(&block)
3 I# r- S2 k4 Q; D) f        nonce,hash:=pow.Mine()
" F7 P6 l, m9 S        //挖矿结束,得到哈希碰撞值
) U6 Y  E* F6 Z3 x7 _2 E- g        block.Nonce=nonce
( s, w7 b1 G$ o3 `% O3 i5 }, p        block.Hash=hash
6 {3 @, [$ C  X. q; {; P        return &block& L. a! B% A6 p+ N. O" v; A7 m& Y
}
  A: \3 ?# Z; q3 R. ?* U//Blockchain模块  `& ^' `% @6 G/ m8 v  K
const gnnesinfo="1996年9月2日,一代伟人诞生了"
  u7 k5 k; \/ M//给到一个区块链结构( m5 o: Y% S; _
type Blockchain struct {$ E% ?; p% u' \. e, C" K
        blocks []*Block
! p0 ]4 P! A- T/ a$ W( |}5 h# N) r% Q. L) U5 u1 r
//将创世区块加入区块链,并返回一条可供操作的区块链
- @4 I; L8 ]; a* p" Efunc NewblockChain()*Blockchain  {
; E( B  P0 ~$ e+ \! ~        var bc Blockchain  I' `/ W+ v7 X8 c
        block:=newBlock([]byte(gnnesinfo),[]byte{})
3 m& j- u, ]" E8 w; M% l/ l        bc.blocks=append(bc.blocks,block). L$ }3 L2 @4 r
        return &bc( R  @% \$ u; V; [! W+ Z
}
8 i; n) T8 G0 b* h2 v$ A. P% T//给到一个增加区块的方法
. |& u" S: T: h! L. Y7 U. _2 ^func (this *Blockchain)Addblock(data []byte)  {% h. ?: @+ {7 Q- M' ]# u' \
                lastblockhash:=this.blocks[len(this.blocks)-1].Hash
7 E8 q! [% g( o# y/ F$ I$ t                block:=newBlock(data,lastblockhash)( b1 z9 B/ t' c2 y3 U% r# i
                this.blocks=append(this.blocks,block)
) i' _* t1 ]6 q3 h, v7 c9 Z2 d}
: F$ W7 K* v& N//遍历,打印所有9 |: g* L* V' p& @1 ?6 p. v
func (this *Blockchain)PrintAll()  {
* G7 ]2 `1 W' P+ ^, f$ [+ Y        for i,v:=range this.blocks {  Z5 g& B/ l. Y7 }* r* s+ r
                fmt.Printf("=========区块高度%d=========\n",i)
0 T2 ]8 E+ x6 m& L9 c                fmt.Printf("Version : %d\n", v.Version)
' r0 ]! H9 k9 V9 V# |5 C$ \2 I+ y                fmt.Printf("PrevBlockHash : %x\n", v.PrevBlockHash)
; i6 [- a/ t! J+ v+ {                fmt.Printf("Hash : %x\n", v.Hash)
4 L5 E# L  Q& l3 S6 g" V# Y/ P                fmt.Printf("MerkleRoot : %x\n", v.MerkelRoot). ]: v: z  C6 z# A
                fmt.Printf("TimeStamp : %s\n", v.TimeStamp)& x$ f6 Q' N: n2 l7 S5 h0 g
                fmt.Printf("Difficuty : %d\n", v.Difficulty); D' t8 w- y3 f1 c/ @$ U
                fmt.Printf("Nonce : %d\n", v.Nonce)& U) B3 z+ g! G8 U
                fmt.Printf("Data : %s\n", v.Data)& E* W) N& C* k; N8 r& v3 n
        }
% O; g& N  ^7 v, E' M}/ {) t* W: a2 E2 c  e4 w  v2 }
//pow挖矿模块8 c9 i5 _8 }3 c2 S' |! D; z
const difficulty=24% o& N+ u; v5 o8 V! m
//POW挖矿结构需要两个参数,一个是所需挖矿的区块,另一个是挖矿成功所需目标数字
% {9 I( _6 T% f' q3 etype ProofOfWork struct {
( i! Y; w2 s, m+ P. D        target *big.Int
8 [% d2 ], F+ u. {        block *Block# g& _% x& A; E( y. Q
}8 S! t3 L* r* u, t
//给到一个根据难度值得到哈希碰撞目标值的函数( R- L2 \' c5 W; s3 T$ r  E: Z9 [
func Gettargetint()*big.Int  {5 T1 e& ^% s$ X
        targetint:=big.NewInt(1)
7 p7 @, J/ I1 G* L3 u3 W5 H4 v, d        targetint.Lsh(targetint,256-difficulty)
  V+ k( E$ w8 n( H  ~' L" G        return targetint
) G4 r1 d9 v9 m! F4 `1 t, _}2 w  N7 H, R, F1 ~$ Y+ n
//创建挖矿的方法8 v  P6 U9 W. A. z& d; Z/ ^7 y) v
func NewPOW(block *Block)*ProofOfWork  {( n) T, N  M  {/ H( f
        var this ProofOfWork
0 V: K$ |9 j& h  ]- ~1 d        this.block=block
; f+ f* ~5 G( _( Z0 W. W- d6 ~3 [        targetint:=Gettargetint()" S5 K& s) Y/ W5 w  ]
        this.target=targetint' g: f, e+ x& K6 m9 R+ Q
        return &this
9 q( _! l9 Q- W9 z: M' ]0 V}
) N: X8 r4 E% V' ?& K! `//一个用来将uint64转化为字符切片的小函数,方便接下来的转化
  u+ \6 j4 ]. ?" {: Z, {func uint2byte(num uint64)[]byte  {: p" @% i/ L# ~
        var buff bytes.Buffer+ Z+ d* }9 w1 d
        binary.Write(&buff,binary.BigEndian,&num)
' r8 N. F$ z$ r# _" U        return buff.Bytes()" ]% N# [6 L6 c. z7 q, b; J3 v. t7 n
}
  Z6 _4 k9 R+ a2 G//挖矿的准备工作,将其他字符组合起来之后求其哈希值7 a5 I2 s( i  p) g+ N
func (pow *ProofOfWork)PreparetoMine(nonce uint64)[]byte {- \9 k% z: T/ T+ c2 U& u3 s6 f& z
        info:=[][]byte{
; a0 c. t9 J; H                pow.block.PrevBlockHash,1 d9 w1 U6 x- N! \0 H9 N
                pow.block.Data,
* y" }) i, O; l2 c/ @                uint2byte(nonce),
1 W, S8 ^  @" }                uint2byte(pow.block.Version),+ Y, c& k/ j8 ^2 K( D0 e' X
                uint2byte(pow.block.Difficulty),, {( D3 V$ Q- w7 s9 r
                []byte(pow.block.TimeStamp),: l* d4 U( n# G% ?
                pow.block.MerkelRoot,
6 q' T# R7 C' T6 S, o( C  E7 \        }! O$ N  I6 r% s8 w7 }( \/ d: Y
        allinfo:=bytes.Join(info,[]byte{})  t& _" S+ Q7 |. z0 E1 Y" k2 `
        hash:=sha256.Sum256(allinfo)% @4 T' a. y4 U- n' J/ A
        return hash[:]
$ T! r& l6 Y) e2 x  u}9 e4 H, B, y, Z/ b
//pow挖矿方法,返回两个参数,一个是碰撞成功的数字nonce,另一个是当前区块哈希值
5 L, m3 Y+ t" q5 u" rfunc (pow *ProofOfWork)Mine()(uint64,[]byte)  {! o2 L- d1 o$ [' N- S
        var nonce uint64
5 u7 x3 V3 S+ H! X5 L        //nonce从0开始穷举,直到出现哈希值小于给到的目标值! X' r, }; m% J6 [$ M$ p! K
        var hash []byte
( L1 u" `, e+ ?; F        for  {
  n& Y0 u) e4 D+ q" r( l                hash=pow.PreparetoMine(nonce)
3 l" ?& ^4 O8 K                var hashint big.Int
0 l2 @* c2 Y) M2 G. R                hashint.SetBytes(hash)
9 U# k. ?1 X0 d9 s) \9 r$ F  V2 w, u                //对比哈希值是否小于目标值,小于则成功退出
4 h* X: c1 c- }9 g. F4 F/ t$ t, Z                if hashint.Cmp(pow.target)==-1 {9 s( j6 B' K& s) f) m
                        break
0 n% x4 \" ^/ a8 E! f% }' E& Q                }  l( W1 c6 a! \, O5 _
                //不小于则继续穷举
% a% p/ z) Q/ V' L                nonce++
1 |: S! r+ D4 [: }        }0 {+ _6 d- K: _* w% |7 E
        return nonce,hash+ o. J3 f- g1 X7 j7 F1 z$ [
}, Y2 N, W% D8 Q" `
//调用
7 Z. d7 L6 w7 K! \/ Ofunc main()  {4 u1 h) D/ c' ^2 X' a- Y, T3 P4 z
bc:=NewblockChain()
! n- E8 V0 M( `8 \2 W0 a6 ~bc.Addblock([]byte("welcometo")), m$ L$ _# Z2 c$ `% \% O9 W1 ]
bc.Addblock([]byte("mycsdnblog"))
8 F# R3 G2 H0 {: wbc.PrintAll()
0 Q- H2 {1 P9 D; U}
0 X  M7 W- B" g* E以上就是一个微型的区块链了,虽然看起来很简单,但是对于理解比特币、区块链还是有不少帮助的。
标签: Pow
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

蓝天天使2017 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    10