Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
最火的热词相必就是区块链了,C++和GO是目前最适合区块链开发的两种语言,所以咱们学GO的肯定得学一点区块链的知识,但是区块链涉及太多密码学,金融学、p2p网络等知识了,从哪里切入呢,今天我们就从用go实现一条带有模拟挖矿系统的简单区块链。
2 E' w% b; O. C  h5 q; L1 P. e% H9 n代码分析
+ E# T, c6 S& u9 d$ b* T" }三大模块1 |+ o8 Y  x3 W  F# B& x
代码还是比较简单清晰的,主要有三个模块,Block模块、BlockChain模块、POW模块即挖矿模块。6 p! @& ]$ B+ d7 _2 a- o  l
运行流程
1 w6 w5 a. u. {! Q8 |, U6 i, f首先从定义一个区块开始,一个区块中包含的信息有区块信息,时间戳,前区块哈希值,现区块哈希值,经过挖矿后得到的哈希碰撞值等等。- ~. W( d: y8 u6 k% F: s4 o! H+ _
接着我们开启一个切片用来存放一个个区块,但是第一个区块是比较特殊的,我们称之为创世区块,在真实的比特币中,第一个区块是由创始人中本聪挖矿所得,没有前哈希值,所以这里我们直接将第一个创世区块创建添加到区块切片中。9 D; S& |$ f3 ?
然后给到一个添加区块的方法,用户添加区块信息后,经过POW挖矿系统才能成功添加到区块链上。  N% Q2 [& H( D4 @9 w4 k
有了大概的运行流程接下来再来看代码就会轻松很多了。
* C4 B# g6 b4 h3 E; m# Xpackage main
' d8 j/ I" T2 d6 k: Uimport (; r& w0 X  l4 k6 p
        "math/big"' |1 S5 d- P8 y: S
        "bytes"
) b! z5 c% g) i$ p4 Z+ h; F        "encoding/binary"
8 j2 ]4 B6 L0 z! _  x! F# M        "crypto/sha256"
1 A- N2 }0 Y" \% h5 y- q. Q! z        "fmt"
% n. n: I) V& y1 O9 S+ D4 D        "time"
4 T0 H) q3 B& r/ s% P)
( g7 u! q6 r0 t( v//Block模块
$ J) Z; P1 S+ r% `( Q" ~" N% ytype Block struct {
0 J; [% m  v* W) \! k; J4 x% C        Version uint64                //版本号
) i2 m' f5 {6 m' F8 D        MerkelRoot []byte        //这是一个默克尔数,这里先默认为空
8 M! f9 @# ^* J7 s, e+ L7 y7 z        TimeStamp string         //时间戳
7 ?3 R, Z3 j" e        Difficulty uint64        //难度值" h6 b. ^% R' m3 [
        Nonce uint64                //挖矿所找到的随机数  n- v" [* t" G
        PrevBlockHash []byte//前区块哈希值3 e, L* |. W, ?! a9 r
        Data []byte                        //插入的数据  X& g8 J& n0 P" S; o! H
        Hash []byte                        //当前区块哈希值
; a2 |0 N. U9 t4 \}
) _: h& ~$ B! m& w8 Q//给到一个创建新区块的方法
! s, l- u0 E2 Z* ^: V6 Ifunc newBlock(data,prehash []byte)*Block  {" y. R2 r5 W6 g8 U6 t6 @
        block:=Block{
  U7 P8 N3 p1 i% r5 `% e$ o                Version:00,4 s. }' J: B# ]# H2 p, D1 b/ [
                MerkelRoot:[]byte{},) ~$ D# M5 f( L: q1 h
                TimeStamp:time.Now().Format("2006-15:04:05"),
: M4 j2 V' ^2 k, r$ x# ^# p/ U5 e                Difficulty:difficulty,
- E3 ]* }5 x/ j4 G# K                Data:data,
7 a( E/ d# S' U/ m# q. ]                PrevBlockHash:prehash,
1 I! f% [( F% W% G9 ~" ~& Z: H        }3 {7 C. \/ t" E, n5 @8 @
        //需要被挖矿之后才能创建区块,所以调用挖矿函数% F( E: P) l/ O# b" Q0 v
        pow:=NewPOW(&block)
# L7 i& f5 u, T) G$ Z# Y; s: c        nonce,hash:=pow.Mine(), L% W* h8 G% |3 J
        //挖矿结束,得到哈希碰撞值0 p3 y0 ^) v$ a
        block.Nonce=nonce& J* Y6 @5 {) j3 s( U2 {
        block.Hash=hash, g' O, R; D1 l
        return &block' j( L* B% ?1 N$ ~8 {% u5 K
}
2 i% m5 C& a" D/ h+ b  f//Blockchain模块2 H5 ~1 R9 N  I7 h2 {7 W
const gnnesinfo="1996年9月2日,一代伟人诞生了"
7 g5 V* z: ~$ ]//给到一个区块链结构
) D( \8 S& _& P) O: R4 ?% K! |: Ktype Blockchain struct {( I7 u; D% S/ [$ N* V
        blocks []*Block4 u( F# j2 t, ?% f* A" h- U
}$ k0 R8 }* O( d! U  j
//将创世区块加入区块链,并返回一条可供操作的区块链1 B" I2 T5 @9 N: {" l
func NewblockChain()*Blockchain  {" g# |% Y, G5 {( U2 K
        var bc Blockchain
9 F* z" y; ]  H7 N8 w2 Q: m- z+ o        block:=newBlock([]byte(gnnesinfo),[]byte{})% Y4 V# _2 Z' j) n2 l/ d2 e. a" {% i
        bc.blocks=append(bc.blocks,block)* j. B" H3 _3 S. H9 S7 l5 y( N
        return &bc) L: ?. J4 Z# L( i, d. m
}- d  `8 A1 y; T( L
//给到一个增加区块的方法3 K0 C: m1 G0 V5 q! w. `" N
func (this *Blockchain)Addblock(data []byte)  {0 j! w0 o' M& O3 R" p6 d# G/ q
                lastblockhash:=this.blocks[len(this.blocks)-1].Hash" Z( q, _$ ?1 m$ e& @, E0 O
                block:=newBlock(data,lastblockhash)
5 J  J, X& [6 t                this.blocks=append(this.blocks,block)
& o6 F8 f' [/ R. c1 o}
% u* P1 \; n) u+ D# {//遍历,打印所有" |6 u& W+ C; A; L0 ~9 N1 d
func (this *Blockchain)PrintAll()  {
# x  _0 t2 ]; j5 ^6 w. D        for i,v:=range this.blocks {
& v: M1 }  L. K! Y                fmt.Printf("=========区块高度%d=========\n",i)' B, ^8 ~( q1 j! D. b  u
                fmt.Printf("Version : %d\n", v.Version)
3 a# V) ?0 e: ?+ @, p, Z, U                fmt.Printf("PrevBlockHash : %x\n", v.PrevBlockHash)9 R4 J- S( C& ~1 l( e1 n, \
                fmt.Printf("Hash : %x\n", v.Hash)$ w% E% U: s. n
                fmt.Printf("MerkleRoot : %x\n", v.MerkelRoot)
0 z- O5 N" m/ X! `( g4 t7 l3 d                fmt.Printf("TimeStamp : %s\n", v.TimeStamp)
; C- k- [. D/ u2 @! ?+ i2 @                fmt.Printf("Difficuty : %d\n", v.Difficulty)
. q) c5 d/ J* r$ ]                fmt.Printf("Nonce : %d\n", v.Nonce)1 V8 F0 Q, e/ V3 |
                fmt.Printf("Data : %s\n", v.Data)% y' Y" a/ p% q; e4 U, \
        }
% e; ?6 U/ {; y. J}
; g9 i3 a/ `" e: {7 u* Z3 `//pow挖矿模块* o+ b, f: z% o& M
const difficulty=24; n2 T0 `0 T  P# W( t+ x
//POW挖矿结构需要两个参数,一个是所需挖矿的区块,另一个是挖矿成功所需目标数字/ R" X# y$ @! o" a; r7 H
type ProofOfWork struct {
1 N) h& a+ |4 A% h  E        target *big.Int
& d$ t! E: H6 Y. O" y! m" q7 K        block *Block
  f4 _5 S  C% W' L' d* r# a7 Y. C}0 `6 e. _4 R' U1 r
//给到一个根据难度值得到哈希碰撞目标值的函数
7 ?* S- n8 O$ l6 u# M, t( Cfunc Gettargetint()*big.Int  {) u0 h6 j* P8 s8 c
        targetint:=big.NewInt(1)6 g: V7 Y2 ~5 v  [8 q; E
        targetint.Lsh(targetint,256-difficulty)
$ a6 G7 @# W8 A" I3 X5 H# @* V        return targetint& Y) w* g9 X' |
}
; t* }6 B5 Y2 z: z" Y5 Z//创建挖矿的方法- i" I9 z/ o% D# _, O( o( k
func NewPOW(block *Block)*ProofOfWork  {
5 I/ f+ W# L+ O- V5 Y        var this ProofOfWork
0 N4 b, V# P# c$ Y( O        this.block=block0 M1 x$ o( {: }- a+ p
        targetint:=Gettargetint()9 o! ~* Y4 |9 k7 s$ h; G) J- _
        this.target=targetint, P) E& Q/ ^) E6 f/ A: c
        return &this  q$ j- D) f, C+ V" |( }, O* \9 p
}
4 e% H; e6 [- i2 B//一个用来将uint64转化为字符切片的小函数,方便接下来的转化
1 }- r/ [& `0 a9 `% g* [+ s' |func uint2byte(num uint64)[]byte  {0 y! L' c" \+ x5 I! e) H/ G
        var buff bytes.Buffer4 _- C. g& m% {  c* I4 B% l
        binary.Write(&buff,binary.BigEndian,&num)
8 u9 h- t" k3 ]" N# X        return buff.Bytes()
- u' e$ e0 F# S8 `! l}) R, S8 n8 \8 b7 F7 ^! K
//挖矿的准备工作,将其他字符组合起来之后求其哈希值" e8 q) t9 ^8 `! ^7 B
func (pow *ProofOfWork)PreparetoMine(nonce uint64)[]byte {9 C. L9 |, O) l5 D( F( F2 o* h* B
        info:=[][]byte{
7 a* e* a& b" _9 ]                pow.block.PrevBlockHash,- L+ d+ x3 [% s/ K
                pow.block.Data,
" b( F, s2 X0 o8 K2 g6 a( }                uint2byte(nonce),
7 |4 G# x" D) d" R                uint2byte(pow.block.Version),
5 l! T* Z2 v' F7 [: D, p: V7 e                uint2byte(pow.block.Difficulty),3 I$ A5 V. L# Z
                []byte(pow.block.TimeStamp),2 j$ ]: H7 M0 \* o
                pow.block.MerkelRoot,
# |  G4 \7 A7 N. ?        }! i" X) _$ `7 e8 i" n2 E' r
        allinfo:=bytes.Join(info,[]byte{})% m( |; M4 M- p
        hash:=sha256.Sum256(allinfo)
5 T0 z% j7 V+ s7 v3 `/ E' c        return hash[:], ]0 W) X& h) J7 M
}: `8 b% E1 N* Y/ b/ D
//pow挖矿方法,返回两个参数,一个是碰撞成功的数字nonce,另一个是当前区块哈希值( _! \& F4 m, R$ q; r$ `5 z$ q
func (pow *ProofOfWork)Mine()(uint64,[]byte)  {8 L3 P0 a  f6 O- ?7 `- j- Y
        var nonce uint64
$ a4 V6 }: G- `, U        //nonce从0开始穷举,直到出现哈希值小于给到的目标值
+ G: b" `2 {' t% f; ^        var hash []byte$ |! s) H7 w0 d. ~! d0 T
        for  {
( P. r$ e% r, o  D4 A  z! n                hash=pow.PreparetoMine(nonce)1 F* M- `# N& Y0 ^( |
                var hashint big.Int/ b" X  t+ s6 J  [
                hashint.SetBytes(hash)
6 _" F. {% c! m# V1 Z7 o                //对比哈希值是否小于目标值,小于则成功退出
8 N5 _& N. \% [: G+ ?( Q: v  p                if hashint.Cmp(pow.target)==-1 {1 b& x' K7 I% Q& h* A0 H3 C
                        break
! R2 s. K+ Z" F% j                }  n; z+ p! B: c1 d4 A# T) {
                //不小于则继续穷举
. \  d5 R' q4 z- A4 _                nonce++
1 {+ S7 i; [  b# J        }6 Y/ R6 C; p/ S- I& o& W
        return nonce,hash
+ ?* q" X6 R& O: ^; t; X}
  y& P6 A  m2 Z- D* k  T//调用
- G" R+ {4 o! C' o7 k: x* P5 cfunc main()  {: t: X( d* s9 f6 ?, o. l5 F
bc:=NewblockChain()4 }4 W0 q) j9 h- j) Y
bc.Addblock([]byte("welcometo"))+ c& t9 V5 E3 }4 Q6 M- S
bc.Addblock([]byte("mycsdnblog"))
, D: M( g" d2 \6 sbc.PrintAll()7 \5 D0 D* F# h
}
! p/ ?- M1 g5 r: S以上就是一个微型的区块链了,虽然看起来很简单,但是对于理解比特币、区块链还是有不少帮助的。
标签: Pow
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

蓝天天使2017 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    10