Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
最火的热词相必就是区块链了,C++和GO是目前最适合区块链开发的两种语言,所以咱们学GO的肯定得学一点区块链的知识,但是区块链涉及太多密码学,金融学、p2p网络等知识了,从哪里切入呢,今天我们就从用go实现一条带有模拟挖矿系统的简单区块链。  @/ u$ M9 h  G! q7 I
代码分析
+ D; W. z4 M( M' ~) z三大模块
3 X: }. _/ \$ }: f0 o/ h( u& j代码还是比较简单清晰的,主要有三个模块,Block模块、BlockChain模块、POW模块即挖矿模块。
6 Z4 X9 H0 W8 u+ u& u运行流程
0 B' Q. u2 w' k$ E首先从定义一个区块开始,一个区块中包含的信息有区块信息,时间戳,前区块哈希值,现区块哈希值,经过挖矿后得到的哈希碰撞值等等。, J0 x( I3 h6 [7 h& |# u) R3 E7 x
接着我们开启一个切片用来存放一个个区块,但是第一个区块是比较特殊的,我们称之为创世区块,在真实的比特币中,第一个区块是由创始人中本聪挖矿所得,没有前哈希值,所以这里我们直接将第一个创世区块创建添加到区块切片中。& B& c! g  c1 Q1 i; Q$ Q! T
然后给到一个添加区块的方法,用户添加区块信息后,经过POW挖矿系统才能成功添加到区块链上。
8 d9 g: B) E0 V, \1 b- Z有了大概的运行流程接下来再来看代码就会轻松很多了。; r* ]  d3 D1 E; m' T1 m7 A
package main8 Z+ j( g7 i/ A/ L0 S" Z' {/ ^
import (/ x2 J5 T2 ^* j
        "math/big"7 t6 J' E. S. q! T
        "bytes"
  E' y6 \. [6 K0 d( Z& o8 s4 g        "encoding/binary": U  `' G! F+ d% S4 L  P( S
        "crypto/sha256"
2 L" R* G4 c/ z& I. j6 k: d2 D        "fmt"
+ t/ `8 R# Z0 I5 e+ A5 L/ _        "time"5 N3 M: a' S" l* o4 D
)* r, C, y% N, h$ d  h
//Block模块" H2 @& M6 y/ }6 M! N
type Block struct {6 r* N0 @9 M" t  e: @& [
        Version uint64                //版本号
9 W2 [2 [  K1 s0 h. D$ i2 v        MerkelRoot []byte        //这是一个默克尔数,这里先默认为空
3 X- q  W( h$ W6 L8 P; r) W        TimeStamp string         //时间戳
. Y# q$ {1 }6 I6 B1 G; |; c4 E        Difficulty uint64        //难度值5 W  D( j' X* ~
        Nonce uint64                //挖矿所找到的随机数5 ~# l! p8 V7 p% u
        PrevBlockHash []byte//前区块哈希值& ~% `& v, K' [( n& M
        Data []byte                        //插入的数据. j2 j: {2 L8 d7 Q) l
        Hash []byte                        //当前区块哈希值
2 I# `# W, a9 Q2 H  u% D}3 {' L; e& y2 i( m: l3 z. @4 N
//给到一个创建新区块的方法, J) l* z- Y, D7 L
func newBlock(data,prehash []byte)*Block  {
4 W% H3 m) q( P, V        block:=Block{8 e* ]+ w( ?% a3 p" ^
                Version:00,- ?! z# V' ~" `
                MerkelRoot:[]byte{},
9 [. p. k: H) i5 q1 a; ^                TimeStamp:time.Now().Format("2006-15:04:05"),! \. X% ~0 l9 t8 y- ]
                Difficulty:difficulty,$ @' b) ~/ J1 H* P$ Y5 G7 H6 K
                Data:data,
  F8 J5 c2 p, t9 T. ~1 \                PrevBlockHash:prehash,
1 k) b" Q6 G$ ]$ c" P) P( z  D        }
& i+ z  D& P$ o, L3 e* I. O        //需要被挖矿之后才能创建区块,所以调用挖矿函数) J+ b1 e7 y9 M( s! c, {& q
        pow:=NewPOW(&block)9 J' z2 t# f! b- K! ~& J7 Y
        nonce,hash:=pow.Mine()
$ t. a) b0 P6 U, w! q# F        //挖矿结束,得到哈希碰撞值
/ w, r1 |: Y* k; N; d# s  Q6 t8 r        block.Nonce=nonce
" h5 \  f; Q6 A! C        block.Hash=hash4 m% q; n' ?* N( m& h
        return &block
8 Y: ^( v; _  t0 R0 v7 I5 v}  _  e: s) [& P4 A
//Blockchain模块
& Z% T. C7 q) gconst gnnesinfo="1996年9月2日,一代伟人诞生了"
4 O8 O) k# q2 G/ \  d//给到一个区块链结构
5 k7 @1 W1 p1 Z, Htype Blockchain struct {1 Z0 w* l: T0 d0 v' \' ]
        blocks []*Block, {8 U3 n, n- \0 h
}
) X9 ~+ h  Y6 o//将创世区块加入区块链,并返回一条可供操作的区块链
; G; K2 r' o5 @+ c$ zfunc NewblockChain()*Blockchain  {
. n0 E0 p8 y% G4 X, z. ^        var bc Blockchain
. C7 \1 L6 D& p% a  N        block:=newBlock([]byte(gnnesinfo),[]byte{})
  R  d: S+ m8 p2 a2 C/ I& a        bc.blocks=append(bc.blocks,block)# K: b) E3 S1 _% A
        return &bc
! h; z' G, U2 w0 C* S# e! x6 C}
0 v" q3 @% F2 U% q//给到一个增加区块的方法8 b3 }( D. g. w
func (this *Blockchain)Addblock(data []byte)  {
( `8 N! a3 r/ Y: e# C# K                lastblockhash:=this.blocks[len(this.blocks)-1].Hash
- Q* _' L3 A4 u' J8 i8 T; y) A                block:=newBlock(data,lastblockhash)
' H9 N) R- X2 ]4 {- M5 b4 r                this.blocks=append(this.blocks,block)
1 Z% d) n" R- H6 Y0 a, J}8 ?3 T, J7 J. L4 H( m; u3 {* j
//遍历,打印所有% c0 o9 d' w9 g. I4 c4 P8 Q
func (this *Blockchain)PrintAll()  {/ S+ {+ s) W" f, |
        for i,v:=range this.blocks {
2 J! j" s, |% s                fmt.Printf("=========区块高度%d=========\n",i)
- L3 P% w' x2 R. |9 |3 S                fmt.Printf("Version : %d\n", v.Version)
& b6 ~! ^4 v$ z& P* n/ a& s                fmt.Printf("PrevBlockHash : %x\n", v.PrevBlockHash)( f5 _3 o$ b# k0 Y% z  o
                fmt.Printf("Hash : %x\n", v.Hash)
5 w9 k$ z+ p- x$ w' ~7 a                fmt.Printf("MerkleRoot : %x\n", v.MerkelRoot)
0 J9 V. [0 e9 n6 H+ }$ V                fmt.Printf("TimeStamp : %s\n", v.TimeStamp)1 E, k7 B$ q' `0 C
                fmt.Printf("Difficuty : %d\n", v.Difficulty)& |7 N" I8 @; N- g. z
                fmt.Printf("Nonce : %d\n", v.Nonce)
3 X- K! m( g/ R' ^! D                fmt.Printf("Data : %s\n", v.Data)% A( ]0 C. [) m1 C1 y
        }
2 X& Z) _7 q4 S}% |9 P" v; V2 B/ Z
//pow挖矿模块
5 j/ y2 |$ U4 w0 L* Kconst difficulty=24
1 @3 H) l: u/ o% P//POW挖矿结构需要两个参数,一个是所需挖矿的区块,另一个是挖矿成功所需目标数字
- x( k! c; G4 ~9 U, a9 z0 Otype ProofOfWork struct {+ ]7 W, H% L* c1 _( C
        target *big.Int
- t6 {: u, o& a. F$ [; x5 m        block *Block
7 _$ p8 i+ E7 G! P7 w; f3 J}
$ A9 ~, q5 b" @//给到一个根据难度值得到哈希碰撞目标值的函数
1 Z9 C' a% w' k3 X4 M' a) Ofunc Gettargetint()*big.Int  {
1 u, k, i) ?7 k  s; s$ h        targetint:=big.NewInt(1)
0 B4 e2 w! B* x: h- l        targetint.Lsh(targetint,256-difficulty)7 M4 ^8 o2 P) m
        return targetint5 U. Y+ y" U3 W+ F* J# `# K6 _2 C6 Z
}
! b9 m# W  ~4 |8 L4 V  M  h//创建挖矿的方法
" E1 u; y" D9 Y6 H! K0 Zfunc NewPOW(block *Block)*ProofOfWork  {( @7 I1 l( v( L; _$ A
        var this ProofOfWork
% {3 I. v; A5 P: g0 `5 o0 \        this.block=block% C; E, h" Z1 {4 P' q' a
        targetint:=Gettargetint()
2 _2 O' r" `5 ~1 B+ K        this.target=targetint; P1 Q3 F0 t& {' m/ d( M
        return &this/ ^$ o1 _% Q* x* S6 z
}# `3 V+ k" e2 J& x( e' a* `
//一个用来将uint64转化为字符切片的小函数,方便接下来的转化# U1 W) O& ~% O/ g( D4 m$ o
func uint2byte(num uint64)[]byte  {
1 M1 P3 J- w3 i/ C, h        var buff bytes.Buffer( F, C/ K( _/ N  O% p1 S1 N
        binary.Write(&buff,binary.BigEndian,&num)
( E% K5 l9 f, D. _  E" t        return buff.Bytes()+ @/ Z" D& d6 i# P7 p
}
5 w! a: K6 I( L( C* K# a//挖矿的准备工作,将其他字符组合起来之后求其哈希值
0 Q1 k9 A2 ~$ hfunc (pow *ProofOfWork)PreparetoMine(nonce uint64)[]byte {
8 B  g* h2 `9 a4 c        info:=[][]byte{
, K& E+ R1 m4 z2 n3 I                pow.block.PrevBlockHash,( ^3 Q1 z, J3 ~, }
                pow.block.Data,' T  k* E& H9 y4 n) s* f2 L
                uint2byte(nonce),& _1 o9 b$ O0 [0 A3 G; f- ?) l
                uint2byte(pow.block.Version),) v9 f% y: X3 b& D
                uint2byte(pow.block.Difficulty),, E" ~/ p9 b  t% F! j' |2 @1 n/ \
                []byte(pow.block.TimeStamp),. r  d; w. l( o; X: ?
                pow.block.MerkelRoot," J2 N6 J+ ?( K* W: Y  B
        }! J9 M  k8 ]7 s! k/ X+ X( e
        allinfo:=bytes.Join(info,[]byte{})# Q! s5 s9 s* i4 [+ f' M4 r( W
        hash:=sha256.Sum256(allinfo)
2 {( t+ F! k8 [9 j6 A; }" p        return hash[:]& |/ M8 a( o2 J3 {$ D# u
}
/ c5 e$ N, d  @" U1 i% H; _( |//pow挖矿方法,返回两个参数,一个是碰撞成功的数字nonce,另一个是当前区块哈希值+ `0 r) S  z) {: }! N$ j/ \0 w
func (pow *ProofOfWork)Mine()(uint64,[]byte)  {
1 Q. _1 M7 b+ b4 [, N8 e" Z        var nonce uint64- S) L$ l* k) z$ b$ G9 J
        //nonce从0开始穷举,直到出现哈希值小于给到的目标值9 m2 A- H: H$ A! E- Q1 q/ D) @
        var hash []byte' q6 w  z* O/ X% E$ _3 D* `" i4 p* B6 @1 a
        for  {" X- @7 O8 Y# k6 t
                hash=pow.PreparetoMine(nonce)- o* i" }' S. C: E$ U
                var hashint big.Int
6 G, N3 H3 `. p$ [                hashint.SetBytes(hash)
. _5 M5 ~7 S7 W5 M, J& x                //对比哈希值是否小于目标值,小于则成功退出* r2 q% U7 C9 Q" [* x" ]
                if hashint.Cmp(pow.target)==-1 {2 Q! S9 l+ X: |% k2 e: h' Z
                        break6 E- D; D; T4 c- L# Q; [  t0 O
                }4 |% S8 B  a6 p: k0 D5 y: J2 a
                //不小于则继续穷举+ h, k6 U7 P2 b* m9 R( m
                nonce++
6 s$ i+ i# O# q0 ]& j, O' Z# m; E        }
" z1 x& t3 y6 r7 Q: M0 P4 Q        return nonce,hash8 E% u- {( [0 w- ~' U: I3 I
}
  Z2 G8 o( h3 X" Q" R//调用
" J* j' j8 V5 V% Yfunc main()  {- n9 d7 {3 E# e; ?9 M9 T
bc:=NewblockChain()
8 j+ i. S! F' C6 g& P+ ~bc.Addblock([]byte("welcometo")); ^' B7 U# g8 O0 ]6 E  W- g0 X1 n
bc.Addblock([]byte("mycsdnblog"))% S7 k6 z8 o& e8 a6 v* f
bc.PrintAll()
* S$ L* g; e& h3 J% w. @$ c$ v}
5 P% O% i$ K( z以上就是一个微型的区块链了,虽然看起来很简单,但是对于理解比特币、区块链还是有不少帮助的。
标签: Pow
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

蓝天天使2017 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    10