Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
最火的热词相必就是区块链了,C++和GO是目前最适合区块链开发的两种语言,所以咱们学GO的肯定得学一点区块链的知识,但是区块链涉及太多密码学,金融学、p2p网络等知识了,从哪里切入呢,今天我们就从用go实现一条带有模拟挖矿系统的简单区块链。
* @9 Y; p" p+ }, Z, q5 c代码分析) F3 h" E7 A' g0 i3 M6 t) A2 ?
三大模块+ a% O( K9 G0 h3 U) q, E
代码还是比较简单清晰的,主要有三个模块,Block模块、BlockChain模块、POW模块即挖矿模块。6 r, [! x# p) M7 I4 z7 i
运行流程, z2 I: L3 z. O8 C
首先从定义一个区块开始,一个区块中包含的信息有区块信息,时间戳,前区块哈希值,现区块哈希值,经过挖矿后得到的哈希碰撞值等等。
' R7 c% Q! V- ]3 e3 b1 ]" P4 m# @接着我们开启一个切片用来存放一个个区块,但是第一个区块是比较特殊的,我们称之为创世区块,在真实的比特币中,第一个区块是由创始人中本聪挖矿所得,没有前哈希值,所以这里我们直接将第一个创世区块创建添加到区块切片中。
- b3 ^& e4 r! o* {" `9 ^6 F然后给到一个添加区块的方法,用户添加区块信息后,经过POW挖矿系统才能成功添加到区块链上。" z1 T: b) @5 p! Y1 ~( ^  c# H
有了大概的运行流程接下来再来看代码就会轻松很多了。
, z" y- V; g4 ~8 I) qpackage main! ?! b. P" |# K% `+ Y1 D$ N& N0 R
import (0 X  b% E' W0 A6 G
        "math/big"
/ ^' g2 v5 j1 ]. b  o! I        "bytes"
( S* S' v. d; L        "encoding/binary"
4 u# W- m6 U$ g& s. z        "crypto/sha256"1 X. ?2 |$ O4 f1 ?- |: [
        "fmt"
7 y4 s) {+ S, a! q        "time"  b- \' Y* D0 u  L
)4 d: S4 O* Y( K) t+ T
//Block模块/ E. ~( x  d) b7 x5 E1 z' }
type Block struct {. [2 F: I$ }' D2 E% L. u
        Version uint64                //版本号
  j1 J" e+ o! j/ [3 x3 G* {+ @% A        MerkelRoot []byte        //这是一个默克尔数,这里先默认为空
  x' V3 h! A# z/ C        TimeStamp string         //时间戳
9 g0 W5 y/ K/ f8 X' C: k        Difficulty uint64        //难度值9 G' Z( g0 b9 }% ~6 d- K
        Nonce uint64                //挖矿所找到的随机数
' W8 H/ @% \4 G$ r+ W        PrevBlockHash []byte//前区块哈希值, i  g" X9 X- [% J# O* z0 U, k4 Q8 w
        Data []byte                        //插入的数据
' d+ `5 `2 o9 D; r* d4 X        Hash []byte                        //当前区块哈希值. M7 |6 F4 T2 L% {6 _, u
}
8 p3 P% C, N; h1 w//给到一个创建新区块的方法
2 ^, }+ p* V  \8 Pfunc newBlock(data,prehash []byte)*Block  {; k" g$ `* ~$ C0 p4 b" A
        block:=Block{- c8 z% P8 I3 e- _% w( c' ^
                Version:00,0 N5 z& Y# X4 r5 c+ q+ Z8 T
                MerkelRoot:[]byte{},4 a, i6 k6 A; |
                TimeStamp:time.Now().Format("2006-15:04:05"),, H" y2 ?4 s/ I
                Difficulty:difficulty,
) r- ?# q0 d! A8 Q2 l# h- D                Data:data,
& p8 _* V; t8 v                PrevBlockHash:prehash,2 M# ^! H4 i, ~7 x! |% s
        }8 p8 [& S8 c" y/ J0 X
        //需要被挖矿之后才能创建区块,所以调用挖矿函数
, O8 a, m4 q7 R* }& _        pow:=NewPOW(&block)% A9 c# ~4 F( P8 _
        nonce,hash:=pow.Mine()+ J7 M1 Y1 [9 |1 u" C1 X; X0 Q2 S
        //挖矿结束,得到哈希碰撞值
  h2 r7 M2 N0 h2 o1 b1 n, A: n        block.Nonce=nonce) b2 d) x" D. E0 F
        block.Hash=hash: U$ h5 M+ P# m- z
        return &block: B3 _/ e9 w8 _2 o4 k& _
}+ p4 w6 e- {$ N% N5 _
//Blockchain模块% W0 n, z3 K- G7 m. H' D( \& X
const gnnesinfo="1996年9月2日,一代伟人诞生了"
( U7 K1 h. v( M/ J' E0 e" [//给到一个区块链结构3 b! i; }% B+ r' J# ^" P6 f
type Blockchain struct {; c' g( |" }9 y* @: r$ E
        blocks []*Block
6 E% d& x- q- j" W" y}& X, K# z5 D" J- [: z& w
//将创世区块加入区块链,并返回一条可供操作的区块链4 g2 U) t1 i- H' x& e
func NewblockChain()*Blockchain  {) V4 S7 I9 k& d
        var bc Blockchain
7 l+ A( Z1 x1 ?# U) c6 Q& f7 q        block:=newBlock([]byte(gnnesinfo),[]byte{})
& Y- D+ z4 d* D        bc.blocks=append(bc.blocks,block)
- [5 n; ~; A  l+ ^' }        return &bc6 q/ K7 K6 C5 q$ ~; M: k8 g  @( q
}
0 P4 P' C$ j$ N: B- f6 X6 f  R//给到一个增加区块的方法
8 c- x. I# Q1 J9 a6 v5 Y8 L% G' lfunc (this *Blockchain)Addblock(data []byte)  {
& o1 C5 `: T. F# P* r& T                lastblockhash:=this.blocks[len(this.blocks)-1].Hash" l% w5 k) h3 S0 H" U
                block:=newBlock(data,lastblockhash)
4 F# ?0 ~% Y$ _* w, Q) W                this.blocks=append(this.blocks,block)$ X: V. m4 H/ b! E( Y/ i; g
}
5 o/ @+ L! l( f+ l, z//遍历,打印所有1 h; c0 m+ f" S% h7 \) b
func (this *Blockchain)PrintAll()  {* q$ e! e/ u! n  F
        for i,v:=range this.blocks {
; B* h3 @% k' u5 x                fmt.Printf("=========区块高度%d=========\n",i)
. d& k# G+ _1 N/ ]1 k. A4 C2 U6 F' p                fmt.Printf("Version : %d\n", v.Version)- G6 U0 Q& W9 ?, T8 ~% |
                fmt.Printf("PrevBlockHash : %x\n", v.PrevBlockHash)
4 g7 ]- Q4 [, A& Z: ~: B8 V                fmt.Printf("Hash : %x\n", v.Hash)
4 y3 d! n- X% ]/ l* m8 r2 _                fmt.Printf("MerkleRoot : %x\n", v.MerkelRoot)0 W: i; b4 H) k1 q. K
                fmt.Printf("TimeStamp : %s\n", v.TimeStamp)
9 |- v5 A9 {9 F; s* @& h                fmt.Printf("Difficuty : %d\n", v.Difficulty)$ o. v: J- G* d- M
                fmt.Printf("Nonce : %d\n", v.Nonce)6 J* M) L; m6 d
                fmt.Printf("Data : %s\n", v.Data)0 p0 n* s5 k4 H' C
        }$ M0 p: n# Z5 n. d5 p( `
}/ i% r. d$ U% s7 [1 Q
//pow挖矿模块
9 m; U% H$ a. K  G3 nconst difficulty=24! g7 {) p# h9 I7 l% H. h6 X1 V- t
//POW挖矿结构需要两个参数,一个是所需挖矿的区块,另一个是挖矿成功所需目标数字
0 |" _8 P- f' q' Y6 J  ntype ProofOfWork struct {
, ^! Z, V) @( X* K2 J+ l3 j' }        target *big.Int
: u0 t0 D0 C# `! @- R        block *Block( t% n6 x( w1 _0 `1 F% q% a
}
( Z. Z/ D/ s% Z2 z( N! z5 F//给到一个根据难度值得到哈希碰撞目标值的函数$ ~' B. j6 ?5 N8 s: r4 x, b
func Gettargetint()*big.Int  {2 Z  `3 p3 A# g6 M3 k
        targetint:=big.NewInt(1)
( {. l/ H# ^: ]; d3 O3 o/ h        targetint.Lsh(targetint,256-difficulty)* \6 g$ d$ j& `- N8 L2 ^0 h
        return targetint
7 L9 F4 F$ |5 z+ M  ]& k8 j* O( g}( f5 ?- e' I5 e) j- {$ F- O
//创建挖矿的方法2 }9 i2 c8 t4 m# s" B8 [
func NewPOW(block *Block)*ProofOfWork  {
1 k! |/ C! v* N" n        var this ProofOfWork, q; j, G) V1 s$ r, g9 D
        this.block=block
$ x6 Q( N8 ~8 e' d        targetint:=Gettargetint()
" V/ N" |) N# Y5 s4 X: p2 d& y. [( R        this.target=targetint3 S) r- J0 s+ z0 N- N, n
        return &this
" j# w# l" L# O9 o3 D- Q}
1 V% G( [" y2 N9 F) X9 \' s//一个用来将uint64转化为字符切片的小函数,方便接下来的转化
3 O- E- d) e/ I  h7 e- U0 b" @; Sfunc uint2byte(num uint64)[]byte  {3 Q" \( O2 H4 x7 z4 q
        var buff bytes.Buffer
4 a/ J+ C; J& |" F% O        binary.Write(&buff,binary.BigEndian,&num). U! m1 ]' `1 \0 }! [# X3 s# m
        return buff.Bytes()
. ]& h. }' H$ F( |0 @- \& G) x* W7 w}
. R6 X' _4 t! ^( d//挖矿的准备工作,将其他字符组合起来之后求其哈希值
9 \  R- l' ]: ^2 M0 m0 l& U& U5 ~func (pow *ProofOfWork)PreparetoMine(nonce uint64)[]byte {
, U- F' T" t+ |% I0 V9 S2 ^/ S        info:=[][]byte{
, D9 g+ N5 t! c5 F- e                pow.block.PrevBlockHash,9 Y, i  R' L- j* V6 [5 ^
                pow.block.Data,- T" v/ N9 }* F: {4 A+ N( J
                uint2byte(nonce),4 R9 Q) `# k" I9 z' U
                uint2byte(pow.block.Version),& p- y5 v' d4 }0 E# n+ C8 }
                uint2byte(pow.block.Difficulty),; W9 b, [) a2 |+ l0 w
                []byte(pow.block.TimeStamp),# R9 W/ T9 g5 ]7 }# l
                pow.block.MerkelRoot,
6 E0 }* r" P9 }) z# X        }
( n0 ^! O2 R2 W  j* f- X        allinfo:=bytes.Join(info,[]byte{})
/ L3 l: B6 H( \% H        hash:=sha256.Sum256(allinfo)
: v9 G3 b1 `- T& k% d        return hash[:]
6 t  G; W0 l, G4 b3 l3 T}: \5 Z2 ?9 y4 a" I
//pow挖矿方法,返回两个参数,一个是碰撞成功的数字nonce,另一个是当前区块哈希值
0 d; G3 o) @( F! @1 tfunc (pow *ProofOfWork)Mine()(uint64,[]byte)  {7 a7 a" ^( Q. B3 C* x
        var nonce uint648 c& {3 i0 _) W& P6 A! w) q1 F" v
        //nonce从0开始穷举,直到出现哈希值小于给到的目标值# E! Y! x( D, q
        var hash []byte/ Q0 e! l* f7 O3 B( W5 G
        for  {
& d& A  j3 e3 \/ R& U& t& e                hash=pow.PreparetoMine(nonce)
- W0 F1 M6 }" W) E                var hashint big.Int
2 @5 H/ N* z) V# X                hashint.SetBytes(hash)
4 B6 C/ @) F/ J( G$ z2 i                //对比哈希值是否小于目标值,小于则成功退出
2 Y& q* P. j* @  v1 J                if hashint.Cmp(pow.target)==-1 {
4 _! L+ B% a8 _; F1 w! O% F) f                        break* \) u7 W% X+ s9 N
                }7 ?$ e' y$ Y" t
                //不小于则继续穷举6 l; {0 ]& v: U, m/ o
                nonce++
& D. o  s# g7 o. c$ G2 X0 `        }* j$ }. o% L; l' G
        return nonce,hash
- T( u+ ]# P5 ?# E6 |3 V}: \7 i9 u/ k( ^6 Y7 O5 ~0 N
//调用* y; X+ j' J' `
func main()  {- ]5 A% W+ Q" b# p* Y0 ^8 E$ p
bc:=NewblockChain()
6 v1 l, O5 Y- E( _bc.Addblock([]byte("welcometo"))
9 A: F0 L2 U' b3 l% z0 z# ^! y6 Xbc.Addblock([]byte("mycsdnblog"))6 s( W" I! u7 L* l; t2 ~) Q
bc.PrintAll()
& i8 o1 x0 |; `# Q( B}6 o. ]( s9 i% b. ~) H* w$ d
以上就是一个微型的区块链了,虽然看起来很简单,但是对于理解比特币、区块链还是有不少帮助的。
标签: Pow
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

蓝天天使2017 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    10