Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
在本机端口进行查询 由于是第一次运行该链 生成创世区块
( w9 S- s7 W2 H* b' T, \) O
! P  t+ s, n- c% E% n6 v通过http实现RPC命令的调用  实现添加块
. g7 R0 R# }$ o& v, q, o: ~# x3 J& J/ C: ^+ ^
查询当前所有块的信息! X$ X) ^/ ]& u8 ~4 a( z

2 ]5 z5 E% w( b. Q9 G% n- d这里只做了两个命令 分别是get和write
& T6 r7 N! u) Z0 k2 z6 V源代码如下
9 R+ n" e" k4 z2 v% `' i1 X; i基础功能的实现
# t$ K. W$ b6 k! J  s; a& T# I! L, o$ A
package core0 A% Y; {5 |& Y
import (
6 Z2 h; ~+ k# c        "crypto/sha256"
* n% F$ @( E$ _% T2 l        "encoding/hex"
: X, H& S8 n$ D; p" Y& p9 q7 E        "time") e: t, w' K" s: B( n! o
)& r' _1 e& {7 S) g4 ~. _# U9 N( L
//定义区块
  W1 A7 P8 T- n" p( stype Block struct {
& Q# ?' T0 }# e$ j" }        Index         int64  //区块编号. ?8 Q9 [8 b8 S  {9 C$ w
   
  1.     Timestamp     int64  //区块时间戳
    * @. m6 B: N: g4 v. r1 Y
  2.         PrevBlockHash string //上一个区块的hash值6 r, j9 B& Y( N% Y
  3.         Hash          string //当前区块哈希值7 h+ O" C' M, z4 o/ B3 v9 R9 R
  4.         Data string //区块数据
    8 Z  q, o, J% H7 m
  5. }" |& z/ j  a: L" f3 L. K# ~
  6. //计算Hash
    ; Z! I* ~" D% `9 Z* z
  7. func calculateHash(b *Block) string {
    8 S$ m0 H3 Z+ F" h' b4 P
  8.         blockData := string(b.Index) + string(b.Timestamp) + b.PrevBlockHash
    ) k/ i: E: B2 R/ U& C
  9.         hashInBytes := sha256.Sum256([]byte(blockData)), y/ T) P9 T; B: k0 f
  10.         return hex.EncodeToString(hashInBytes[:])
    6 K. c6 N/ o7 ^
  11. }
复制代码

6 Z+ F5 X: A1 v2 k, z ! |; T( R; |* s5 u6 |
//生成新的区块% ~! f0 x! y: \. ?/ G4 W
func GenerateNewBlock(preBlock *Block, data string) *Block {& u+ w  e8 Q) Z
        newBlock := &Block{}. x" |9 o1 Y+ n% c4 r: {) n" }3 K, v
        newBlock.Index = preBlock.Index + 1& a+ F' H. W( v$ t6 T9 Q
        newBlock.PrevBlockHash = preBlock.Hash
$ w, ?$ K1 X3 o  m  Z        newBlock.Timestamp = time.Now().Unix()  E+ Q+ J/ P6 o! P- l( f3 L
        newBlock.Hash = calculateHash(newBlock)
! B; Y9 j3 L. B8 A. V3 I        newBlock.Data = data
# w- g5 ?: s  I& w$ R' ^        return newBlock2 y9 F% R: A  C2 \
}
1 L. G0 ?8 w8 l 5 T' T& _8 P9 _$ D1 a6 g
//生成创始区块+ e, `; _) n7 e2 Q" p8 E
func GenerateGenesisBlock() *Block {7 N( u, j) k4 d, j$ T' v5 }
        preBlock := &Block{}; A- P0 b2 W: c0 b& C$ v  x; z
        preBlock.Index = -1
8 M. E( P, ]0 ]        preBlock.Hash = ""
* t7 D* c; U/ Q: I% R        return GenerateNewBlock(preBlock, "Genesis Block")
; E  t) ^5 q4 x0 @* r1 l$ |# W" k$ G}
: @- [: |1 e9 }  b$ E) w将基础功能实现的块进行链接 实现blockchain; V3 g5 W" S7 b1 F
package core9 E. p! ]" x. h1 I
  P/ \7 X. Y# J9 F% o, V
import (
' T& n/ H  V+ e' x" G. E        "fmt"# d! F6 d* b; r4 \4 [
        "log"
) p  G. R' q/ w0 H0 H8 o$ ^)- O$ k. o5 T* m7 G/ ]5 @

' b$ n; Y( x' h- k' X//定义区块链
. ]+ p( k, J. G8 c, ztype BlockChain struct {% T5 |% U, a; f/ V, ~
        Blocks []*Block
# }1 G) i  v$ k8 M) u" L}  G8 a+ \9 `" i( A0 ?; M: c* F
' x- r1 ]5 V6 @
//创建一个区块链% ~3 s# ?+ y) `/ A8 |
func NewBlockChain() *BlockChain {! |/ h; i$ `5 k
        genesisBlock := GenerateGenesisBlock(), l3 R/ N% [  N
        blockChain := &BlockChain{}
7 [4 Q2 ]- N& @+ v% T" ^( @        blockChain.AppendBlock(genesisBlock)
* g% V! e3 B4 A2 q+ G# m        return blockChain
& B# @( [  v% ]  t4 k" s}
  K2 x/ n1 j0 `9 F2 o/ Z6 [# E
) [4 A+ `" A' V4 H6 @6 x( [3 T2 q//记录区块数据* W) Z4 o) R1 F, m+ W6 K8 j
func (bc *BlockChain) SendData(data string) {# x9 F1 d! {0 w0 `
        preBlock := bc.Blocks[len(bc.Blocks)-1]
% B6 `5 O) O1 I* t& [( `" j        newBlock := GenerateNewBlock(preBlock, data)! X* p4 u3 J4 y. W
        bc.AppendBlock(newBlock)
+ Z; w7 g: ~( i) W; H}
  y5 K! a0 b: |/ ^8 i
$ T, a" `  a6 U0 s//往区块链添加区块1 i- f, _2 o% W1 ]8 Z5 Z7 N
func (bc *BlockChain) AppendBlock(newBlock *Block) {5 y" N; F$ o/ R! `4 g
        if len(bc.Blocks) == 0 {
$ m+ @2 v, j9 |5 a9 A& L                bc.Blocks = append(bc.Blocks, newBlock)! X$ k5 h7 V9 v/ U6 g& k
                return
5 ?7 b% D# B. s9 N        }  V) C5 I4 L! W4 L( t- e& F2 B
        if isValid(newBlock, bc.Blocks[len(bc.Blocks)-1]) {& ~" B; k5 Y$ }
                bc.Blocks = append(bc.Blocks, newBlock)
; d. G1 a3 ~: w6 D" z3 a        } else {
7 j4 @1 g4 C4 K& ]$ B  Z% w- z! {                log.Fatal("invalid block")1 f; S0 K: h) E  g) m
        }
1 G: W- z" t6 Q) t        return) R; H( l- C5 J3 s
}  ^3 C+ y7 L  ?. s; r- X: o# q
+ F# L1 ^& \9 M# D. ~% x, K
//输出区块链信息3 o* p, x2 ~+ F
func (bc *BlockChain) Print() {
% g% i$ F# z. q. D: j        for _, block := range bc.Blocks {/ s7 I1 ~4 F5 a3 t  V9 o9 [) p
                fmt.Printf("Index : %d\n", block.Index): _8 R% s: t0 P3 U
                fmt.Printf("Prev.Hash : %s\n", block.PrevBlockHash)  n* J) ?3 a6 k( L( j
                fmt.Printf("Curr.Hash : %s\n", block.Hash)
4 S" \- y/ X4 i7 |/ \6 f6 D5 c: F1 @                fmt.Printf("Curr.Data : %s\n", block.Data)
( j7 U+ q: {8 ^1 a                fmt.Printf("Curr.Timestamp : %d\n", block.Timestamp): O  K6 U/ @: }2 O
                fmt.Println("==========================================")
; z4 _7 k3 E; z5 j; [        }
: R' `9 I1 [, T$ V! R, @" M7 F}  Q3 {* `4 L1 [' o* B

  Q/ {5 w2 n2 y) L- T2 _+ M//验证区块
+ o. q4 v5 T+ W9 }# k+ Qfunc isValid(newBlock *Block, oldBlock *Block) bool {! c2 ]$ ^& ^- F
        if newBlock.Index-1 != oldBlock.Index {1 g9 Q% y- S9 }6 l" ?
                return false
& a# h7 X6 }1 `9 r; B, q; q& L        }
& D- @4 H8 H5 L, F2 T        if newBlock.PrevBlockHash != oldBlock.Hash {
1 C: M, P5 Z- B) f                return false5 P: [- C/ [0 I5 F, d' M
        }$ ?. d; f. `% T) n" K) }+ E
        if calculateHash(newBlock) != newBlock.Hash {- S9 X' n  Y; u. G- r9 T
                return false
' p+ V* ~1 z) R$ q% S        }+ h( u3 a# ?) N( N
        return true
- |0 \8 |' D7 v# R}4 A4 V% @  u" V$ i4 u7 ?
实现RPC接口的交互" n. B9 c& e: i! `, Z! O
  1. package main
    , h9 [' ~9 h  D, Z5 g

  2.   J/ ]' k: F0 y5 \6 i( q
  3. import (
    % A3 i+ W3 i$ z: P: R
  4.         "encoding/json", `* y! E& `9 P1 a1 a/ w, U
  5.         "BlockChain/core"
    8 a0 A% i1 g6 v! ^
  6.         "io"# w! P8 ^  `/ G! o  ~! ~' O9 r, r/ P% i
  7.         "net/http"
    ' X3 c- U" t, p2 H2 ?
  8. )3 B* D* ~3 {7 L# w

  9. 9 w. m/ |& G, X7 f: W1 ]+ R& S
  10. var blockChain *core.BlockChain
    5 B7 R0 F$ C  x  k) i( j, N
  11. . e: @2 j, k" S1 K9 S: H. k8 i7 R1 h
  12. func run() {
    3 x3 y+ `3 g" l0 u0 [$ l* o1 Q* S" H
  13.         http.HandleFunc("/block_chain/get", blockChainGetHandle)/ b0 l) c8 z! m+ U
  14.         http.HandleFunc("/block_chain/write", blockChainWriteHandle)/ P9 p/ V+ c( v1 a
  15.         http.ListenAndServe(":8332", nil)4 l: L) u7 q: B1 d( E9 @
  16. }0 G4 a: Q& J" }7 o
  17. ; E: n! l3 _7 Z; O0 N8 X% e1 ~: n, K% U
  18. func blockChainGetHandle(w http.ResponseWriter, r *http.Request) {$ w; U( s) s. P  l) i. F1 X; {9 s; `
  19.         bytes, err := json.Marshal(blockChain). I4 o$ N. o) a$ b+ X
  20.         if err != nil {
    6 t3 }. `$ N* H' U& d! H
  21.                 http.Error(w, err.Error(), http.StatusInternalServerError)/ Z6 [/ m' o. K8 ~, \7 E
  22.                 return5 J7 Q) I, n, D- r
  23.         }% D' E. M+ i$ D- M& }+ y( O
  24.         io.WriteString(w, string(bytes))
    1 D3 x( h" G, e& I- X* P
  25. }
    ( X3 u/ }# |  w' w
  26. % D$ ?# B9 n, b3 }
  27. func blockChainWriteHandle(w http.ResponseWriter, r *http.Request) {7 o# y* g. w# d1 B! g5 W+ J9 A
  28.         blockData := r.URL.Query().Get("data")' I" r, n1 n4 E
  29.         blockChain.SendData(blockData)
    . n. i0 `" b( l* n/ i
  30.         blockChainGetHandle(w, r)
    : b) l# v7 j' `0 x
  31. }
    ; f9 [8 a* W$ [) y/ E" d. x
  32. # w  s- A# K. f' Q; Z% \
  33. func main() {! r$ D. I4 ]7 E3 J; l
  34.         blockChain = core.NewBlockChain()# o' q  Q, d5 A  ?; \* q3 p
  35.         run()* N! J" s, L9 t) z
  36. }
复制代码

; B6 T9 A# f0 b" s' a% u8 f4 ~- Y通过两部分代码实现简易区块链的RPC调用
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

朋友一起走 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    16