Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
在本机端口进行查询 由于是第一次运行该链 生成创世区块
9 \( U( C5 b! ?9 |4 M- w: d) P: }5 L: ]
通过http实现RPC命令的调用  实现添加块
7 T9 ]; f! \! m' r7 b0 L4 K6 m$ x2 ~3 `
查询当前所有块的信息; q9 P- p" v0 J

' v- V" i4 O: s4 R& X1 B这里只做了两个命令 分别是get和write9 P$ d, O/ b% b/ x+ z8 s9 {
源代码如下
& ~- N; n9 H! O" B& V* h4 A基础功能的实现& P& ~0 Y! U; B- w; ~0 [) E

; {5 g& V5 Y% n# [7 p; z' r+ P  ?/ Q1 Zpackage core
: W4 a: f: n/ R" _0 Oimport (
, x; c4 L% X4 t        "crypto/sha256"
* X$ Z% O3 X2 a2 J# |        "encoding/hex"
: B1 m, Y' D1 z5 m8 R3 |        "time"
+ C7 i+ J0 [( ^- W8 {)6 R& r8 M" Y' p& N7 m9 P
//定义区块
6 p& h, l: N7 j7 |8 N. W" k9 ktype Block struct {
4 q) C7 ?# L3 P        Index         int64  //区块编号
2 y2 L) K; N* s6 L) u) n   
  1.     Timestamp     int64  //区块时间戳
    - f% h; V0 @0 S  s6 y; I6 f: T
  2.         PrevBlockHash string //上一个区块的hash值
    3 P2 a4 [& U$ W2 [6 I" U
  3.         Hash          string //当前区块哈希值
    5 Q0 M1 S' a4 ]6 S7 F2 _/ l  ?
  4.         Data string //区块数据! H! b0 D! Z0 a5 s
  5. }( h% q* b; w5 G# G. I
  6. //计算Hash
    . B$ y, i. y& d) w
  7. func calculateHash(b *Block) string {
    * S6 A) j+ O1 w4 j
  8.         blockData := string(b.Index) + string(b.Timestamp) + b.PrevBlockHash
    + e" x+ |8 l* F5 h3 K# W, f$ @
  9.         hashInBytes := sha256.Sum256([]byte(blockData))8 `2 J: O( p( S6 E
  10.         return hex.EncodeToString(hashInBytes[:])- z& A5 i: S% R% J" l# f
  11. }
复制代码
. Q' k! g2 m1 L* `& M( r

0 T* F$ l5 Y. |; T) U4 F0 E  g1 C//生成新的区块6 E2 U" }% Q* b' N- ?
func GenerateNewBlock(preBlock *Block, data string) *Block {
6 Y- ^( m7 w4 @7 u8 {( |        newBlock := &Block{}
7 H) d$ X, `3 E+ D6 {        newBlock.Index = preBlock.Index + 1- W3 ~/ G1 n$ r; L7 H
        newBlock.PrevBlockHash = preBlock.Hash# v9 X9 o5 u4 \* |+ R- ^4 V
        newBlock.Timestamp = time.Now().Unix()
' J7 l0 m: u5 x9 l! d        newBlock.Hash = calculateHash(newBlock)# m9 f9 v8 F0 G: [3 t. X9 A+ w
        newBlock.Data = data' B# q! A+ ]$ Z. t! @
        return newBlock
, J. v* n2 q  k}& }+ G- w: p4 r: g' V0 b

) C( s$ K- Q  b//生成创始区块
$ ~  h- _+ T% nfunc GenerateGenesisBlock() *Block {
/ @% _1 `+ \. k3 J6 g        preBlock := &Block{}
9 T& |) V9 F6 ~5 ?/ r        preBlock.Index = -1
) j) N" U, u$ _/ s$ P  ^: K        preBlock.Hash = ""
) d1 D8 x$ z+ B8 q; _; }  D8 e        return GenerateNewBlock(preBlock, "Genesis Block")
0 f$ i, I" {, t. n) ?}6 o: d% r" u% ]0 [- n
将基础功能实现的块进行链接 实现blockchain! P. Z6 }5 q! m# z( h
package core
) m0 y% g, R, j2 ~( g
* B# z3 c# h3 A3 j7 Z( m) zimport (7 r- R; v  e. j' I. O3 s) _
        "fmt"; B, R* s2 ]6 d' r& y+ w* X" u  [9 D; K
        "log"/ N7 D3 n* [# G' O  ?8 \* f# W
)2 h$ A6 w0 Z5 j6 c: |3 t( d' ~

' _7 v: z, E, ]6 O- N% b//定义区块链
% Z7 @9 k% s) j  W* U% ttype BlockChain struct {
1 {8 C! C: w/ X8 J        Blocks []*Block# X' X  T' q2 ^$ r
}
: Y8 v5 {, `, ^, F- h% w + _+ Z' z8 Z/ t  V, I
//创建一个区块链
8 [* @, S6 @- `: S, m( n3 l1 @func NewBlockChain() *BlockChain {$ a+ C/ D; p4 e4 {0 w
        genesisBlock := GenerateGenesisBlock()$ U1 H( ]& z! b8 [" v4 y8 h$ a
        blockChain := &BlockChain{}
3 e/ n. _- D0 u& B  j8 s        blockChain.AppendBlock(genesisBlock)
& @8 k, L4 q, Z3 ?4 K( @        return blockChain7 o, k" v" a& Y* b' a
}; O. W, y6 ^5 M: d( g- t
7 y; Z4 W3 m* L8 F# B. n, a+ O
//记录区块数据
4 a) X6 b9 B, Ffunc (bc *BlockChain) SendData(data string) {7 n" K: z. t5 i4 p4 Q; d  e
        preBlock := bc.Blocks[len(bc.Blocks)-1]  y: o# S+ b. q5 M* @
        newBlock := GenerateNewBlock(preBlock, data)3 C, _7 h4 _. p& i
        bc.AppendBlock(newBlock)
& O# r- Z2 F  b9 [( U}
/ c, X4 C. V8 @' \. t
; s" P5 N/ Y  E9 _//往区块链添加区块* Q) j) y8 O1 F- }
func (bc *BlockChain) AppendBlock(newBlock *Block) {1 ?5 ^) O/ |$ Q, w. X
        if len(bc.Blocks) == 0 {
" C: P9 a" a' I3 a. h9 q                bc.Blocks = append(bc.Blocks, newBlock), p+ T* Z, i/ R! K3 _2 L0 K) t4 x
                return
4 t; W8 {8 d+ J% k7 |! x7 j- l# U% L        }
! X8 z2 h+ Y: n9 H        if isValid(newBlock, bc.Blocks[len(bc.Blocks)-1]) {
: ]6 e6 x; j2 `% t$ i7 _! Y4 x                bc.Blocks = append(bc.Blocks, newBlock)
8 E2 G& z8 Y1 |, V3 {        } else {
4 m7 D) C0 Q- v9 I" R& W                log.Fatal("invalid block")
+ }) Q+ }, h1 y        }
2 D# |% q& n; @4 p, ~/ @        return9 k  f! P0 q8 Y; |' M
}- s3 r# z5 N7 ^5 [
) M! h/ }/ X0 j  p
//输出区块链信息
, q4 s1 @: z/ i/ o* s5 Gfunc (bc *BlockChain) Print() {% }( T6 t; t/ R: p. U
        for _, block := range bc.Blocks {
9 ^' M& B' [1 e, W. {. t$ g                fmt.Printf("Index : %d\n", block.Index)
. `0 w$ w  C) ~3 Q+ n                fmt.Printf("Prev.Hash : %s\n", block.PrevBlockHash)
% e! q7 I2 C( \5 |% B+ b' R                fmt.Printf("Curr.Hash : %s\n", block.Hash)3 V- A! C& d6 ]& h
                fmt.Printf("Curr.Data : %s\n", block.Data)
9 A) C) O: F% |) [* Z& m* i  E4 V                fmt.Printf("Curr.Timestamp : %d\n", block.Timestamp)" F! @0 a% R# g. K
                fmt.Println("==========================================")
& b4 g: A2 Q; y# Q# i        }
3 J0 w* {5 @6 T! {}
! Y  H3 @9 v$ b
) q  |* Z! t4 q* d//验证区块3 C: j) i4 L; j& G9 M
func isValid(newBlock *Block, oldBlock *Block) bool {. h* Q0 i& a9 |
        if newBlock.Index-1 != oldBlock.Index {
$ g* o+ J7 M# V/ L# o                return false
5 T' c; m4 e- }/ i        }$ g6 E% m! S4 |% t* G0 o
        if newBlock.PrevBlockHash != oldBlock.Hash {' w  M/ @+ t0 _! \' {( `
                return false
% q" y/ |1 s2 u* T9 G; U        }$ p* Z. t* C0 A: w6 U
        if calculateHash(newBlock) != newBlock.Hash {( D/ a+ c% f$ N+ a
                return false7 e, }0 N  Q6 Y% [6 U% g2 h& q
        }
. e! E* y& |; T        return true: T: ^8 Y9 _) j3 z( x( O
}9 }# ^) K0 O: t/ r) l
实现RPC接口的交互& }; s& _3 W. X' z
  1. package main  F3 i* Y& X2 s: [7 i% K
  2. & o" j4 n5 L& P+ h! _
  3. import (; s4 j( e" t" R, w0 e
  4.         "encoding/json"
    7 [7 F4 j1 e& A1 ]( {8 |( b5 ]
  5.         "BlockChain/core"# g' u9 s  l7 O. F' T) C5 t2 K
  6.         "io"9 B& ~  D4 [5 A2 x
  7.         "net/http", J: s, M' u) j4 j- d  S
  8. )
    2 E0 U: o+ v' C, C( R5 K

  9.   P( i# Q6 }7 \& j, b! j2 ^  e+ ~
  10. var blockChain *core.BlockChain! S  U: `6 S2 @  k3 y
  11. ' A3 S9 @: v! Z+ ]# Z
  12. func run() {8 f' u- c+ _! j3 Q
  13.         http.HandleFunc("/block_chain/get", blockChainGetHandle)
    ; `3 P, g8 R/ }2 ~# q& D
  14.         http.HandleFunc("/block_chain/write", blockChainWriteHandle)+ `, h" R  w6 ^5 H% ?1 _
  15.         http.ListenAndServe(":8332", nil): @1 d' ?' ?# Q5 W( B+ @5 F
  16. }
    5 R' ^7 L1 a  b9 W% `5 D. [
  17. 0 G# F2 r! v! X9 R5 s8 I" p/ B
  18. func blockChainGetHandle(w http.ResponseWriter, r *http.Request) {
    9 c4 G  c5 }7 V# i# |7 w
  19.         bytes, err := json.Marshal(blockChain)# u( U6 B& v1 C. M# ?0 b
  20.         if err != nil {2 V' H% \7 W/ I0 w: x  H- j. V
  21.                 http.Error(w, err.Error(), http.StatusInternalServerError)
    2 O$ {6 q, c; s$ Z" Q  V# ]
  22.                 return
    . c6 q) a+ U( i* v# ?5 O
  23.         }
    , w! m; {4 s* I8 C, z
  24.         io.WriteString(w, string(bytes))
      A; L/ U8 R" M
  25. }
    $ x# Q1 b& J; a$ e. P

  26. * p1 h7 [9 r% X* f; K/ _
  27. func blockChainWriteHandle(w http.ResponseWriter, r *http.Request) {/ V  p; B- l$ [: k" B
  28.         blockData := r.URL.Query().Get("data")2 Q+ |, ?. B0 k3 W
  29.         blockChain.SendData(blockData)
    , ~7 b% g6 l3 g, q2 S
  30.         blockChainGetHandle(w, r)
    . f' V7 y4 j. C' ?  M$ C$ W  m
  31. }
    4 Y3 j9 L  b% B8 h% h" n5 m
  32. 0 W, O  d* e7 v2 q
  33. func main() {! x$ c3 o/ R  `
  34.         blockChain = core.NewBlockChain()! S+ E9 _! I' E7 s  N
  35.         run()( s8 ?' v9 {7 u: A9 ^( s! E
  36. }
复制代码

: z3 E3 B( O; H+ n7 q2 D1 }1 C) Y通过两部分代码实现简易区块链的RPC调用
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

朋友一起走 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    16