Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
在本机端口进行查询 由于是第一次运行该链 生成创世区块3 u( m& R$ R3 h4 [' v: O

- l9 @$ L( t. Q& F3 |; ]通过http实现RPC命令的调用  实现添加块2 k" G! _" B6 p" k6 U. n

& Z9 H) e  a+ g' k9 k, A查询当前所有块的信息1 |8 p' K( c* x9 f

- e$ E7 }0 k5 k5 T. u这里只做了两个命令 分别是get和write7 i3 _' {  g" e7 ]; {
源代码如下( j, k& \  T) v) X0 q
基础功能的实现
% ^: c1 w# d4 N% Y! }& \
. }; t* b$ t  ?3 E! ]8 H# B4 k8 Fpackage core
1 j/ r3 T; ^; d4 iimport (
% M1 r" m# o" x# l, d        "crypto/sha256"( W* {! G2 o' z* A* a0 j
        "encoding/hex"
% {  Q. O# Z+ _& v& j  S. Q* m        "time"
, W  g( k* h7 t9 W. J$ m)8 m+ v% h, X' `# m* R& R
//定义区块
$ n& e' V, j, T! x5 Mtype Block struct {8 m5 O- `: u0 i" \1 k$ A" {' }
        Index         int64  //区块编号9 }: \& n4 M3 y+ h4 J$ ]% H
   
  1.     Timestamp     int64  //区块时间戳
    5 L" Y* |, P* c  G# N
  2.         PrevBlockHash string //上一个区块的hash值
    # R+ ^7 V) g1 T
  3.         Hash          string //当前区块哈希值* g! F, f* k3 L' T3 S* F# i' X
  4.         Data string //区块数据- O3 B! _- @% w! J, C5 J
  5. }
    * g2 E0 _6 [7 u$ o2 l' b3 b
  6. //计算Hash
    ' `. R& s$ }: D2 o
  7. func calculateHash(b *Block) string {
    ' k# z/ c1 E. e+ T7 D
  8.         blockData := string(b.Index) + string(b.Timestamp) + b.PrevBlockHash
      Q' W, G8 p) r% {& E+ l( |! w
  9.         hashInBytes := sha256.Sum256([]byte(blockData))5 M* ~% J1 T8 s+ Z& w( W7 n% w
  10.         return hex.EncodeToString(hashInBytes[:])
    2 D, _7 i  W* e8 X
  11. }
复制代码

# w) g% `/ a+ a! H" E3 t# z 5 U( |( k. p, Y8 {* J
//生成新的区块
3 s8 n! p& g4 @2 z8 cfunc GenerateNewBlock(preBlock *Block, data string) *Block {
3 Z% ^, W5 J( C9 Q6 ]        newBlock := &Block{}
+ n" U  J/ d  t! U        newBlock.Index = preBlock.Index + 1* I; r! i' z9 Q" w3 s6 \' G
        newBlock.PrevBlockHash = preBlock.Hash) u5 q$ ]1 h) f: h# Y0 F; M, m
        newBlock.Timestamp = time.Now().Unix()/ Q& G7 \$ ^2 M1 j8 F; z4 P
        newBlock.Hash = calculateHash(newBlock)6 _! B2 C8 @% Q) \7 H4 k4 R
        newBlock.Data = data1 v9 ]3 [7 z0 }
        return newBlock
9 l. M5 \+ p/ L8 u( n}
4 [) A, @7 K# {  l/ f. E
9 g" m& K& D" U6 `2 f# q//生成创始区块
2 a- s* \2 G2 E. N4 Q( n; n$ bfunc GenerateGenesisBlock() *Block {" ]. }3 c$ p  C* q! o/ @
        preBlock := &Block{}
& H: K( @4 B- d0 j6 J" g0 y        preBlock.Index = -1
* F0 \$ t5 K5 C. q        preBlock.Hash = ""
6 o! K+ I3 w7 p6 w        return GenerateNewBlock(preBlock, "Genesis Block")
: i0 c  }+ _& W0 q$ z7 c+ ^}
0 D' L: G+ v2 t1 r- u将基础功能实现的块进行链接 实现blockchain
- ?0 \9 J- l) f; q3 d, A( jpackage core
: n% X% P8 r% I& K
. G" M7 s& F* r# s( I: timport (
, R* X+ \" H* g: i* [( ]        "fmt"
, x4 S( A; o9 R. k9 c  k        "log"
5 V$ D4 ]5 x7 p/ R9 ]& `# f; A)& z) q: |6 ]$ d  E% P4 T7 f

  G6 g3 G0 l( u" x: }! m% i//定义区块链
* F4 h, b" @4 s2 N& M! E3 Qtype BlockChain struct {
; x( a5 E+ V4 ~. P& d  U        Blocks []*Block1 t' W0 T' {* Q# k3 }0 @
}6 f- l0 w8 b; S5 N8 y7 m2 c9 c) ?

. M. y3 I$ x' N$ B  C/ g//创建一个区块链, q- K$ D6 }, t- ^7 `
func NewBlockChain() *BlockChain {# f6 h! i: |2 \
        genesisBlock := GenerateGenesisBlock()* _0 K$ l& ]8 H) i
        blockChain := &BlockChain{}
4 k) |, A1 o: n7 x2 l        blockChain.AppendBlock(genesisBlock)
% _  \" r. Z% P6 T; u* n        return blockChain3 `3 G% W  Y  n" u$ Q
}1 M8 k) O$ X+ m. ~; D2 q: M. Z; A
8 ^" N- B4 \7 o: z  j0 C1 v
//记录区块数据* l: n0 h& y% d3 i
func (bc *BlockChain) SendData(data string) {
2 L7 Q" ~. D" a! U' u# a        preBlock := bc.Blocks[len(bc.Blocks)-1], d: |) h* l8 l) H0 r  E7 ?
        newBlock := GenerateNewBlock(preBlock, data)
4 b7 _0 c& c- I8 N        bc.AppendBlock(newBlock)
  J$ s8 u0 q) N8 a' l0 e6 w}/ O2 w1 ~5 M2 q2 b6 c: V

# p  b1 A% ^* M7 e0 P//往区块链添加区块
7 @5 Z" j9 t  _0 r% _( g% \func (bc *BlockChain) AppendBlock(newBlock *Block) {( {9 M6 U# _4 B# g! O! q7 X0 S3 @
        if len(bc.Blocks) == 0 {
6 y: F/ j7 F4 {9 X  G" @                bc.Blocks = append(bc.Blocks, newBlock)
8 j# q1 s0 q: L3 f# h' e5 U                return
- j, F- L* r6 w+ S        }6 g# l, k- T+ o: I6 n/ m: n8 Y
        if isValid(newBlock, bc.Blocks[len(bc.Blocks)-1]) {6 Z7 f9 B1 n. F1 p, {9 \$ b3 S
                bc.Blocks = append(bc.Blocks, newBlock)
# N8 S- }" I9 c9 ?        } else {
) P/ ]/ m, e) m4 V                log.Fatal("invalid block")
7 k  U* Y1 a" i! C        }
& S% z+ B# `  J8 O% y' B        return
7 G* Y: q  o$ Y2 ?}6 y) `0 F( p( J0 m( K4 B% Q) G2 K

1 W' V& ?; [5 `% h2 ^//输出区块链信息
8 N! g: L/ R$ p% ifunc (bc *BlockChain) Print() {
. v; ?% a8 N. U3 `+ U1 F        for _, block := range bc.Blocks {
7 N. N6 j" w& }6 q% P/ B                fmt.Printf("Index : %d\n", block.Index). [0 w4 q9 ?, t1 a7 m
                fmt.Printf("Prev.Hash : %s\n", block.PrevBlockHash)5 [2 R+ s  V/ F6 V1 B
                fmt.Printf("Curr.Hash : %s\n", block.Hash)
) Q. V9 h6 R0 D- {- P) d                fmt.Printf("Curr.Data : %s\n", block.Data)7 I0 l6 d4 v5 b
                fmt.Printf("Curr.Timestamp : %d\n", block.Timestamp)
/ ^/ |# n; o4 Z, i  S1 C                fmt.Println("==========================================")- M2 Z9 o: x  D# }; W0 u
        }& ]& _: Z$ l1 m. r5 V
}6 _& L; Q' ]2 F" K0 m

3 ~6 B  [& H$ ]& y! P6 m3 J3 B//验证区块) J6 U7 ]9 P! ~: {/ M1 G7 r
func isValid(newBlock *Block, oldBlock *Block) bool {
2 M; y) b6 U1 \/ x1 i        if newBlock.Index-1 != oldBlock.Index {( O; a9 V1 {2 V
                return false6 G" z3 ?, k' ]" W- @* Q1 [" ~
        }
" p* _8 m5 U4 _3 ]/ I9 o4 e4 t        if newBlock.PrevBlockHash != oldBlock.Hash {
$ G$ X- p/ I: G1 S; u                return false
0 A6 Z, ~9 C$ @8 a* k/ q        }. H  Q  O0 f2 H5 e
        if calculateHash(newBlock) != newBlock.Hash {5 i; Z' G8 k$ n  A1 f* b; k
                return false
8 J& L- r, @( o% a" C3 ^        }
2 l* j% ]( x. n+ X        return true; o# t/ v+ @$ k" n% o* {
}6 i, r$ q0 E6 P$ A' b% P' E
实现RPC接口的交互
" q+ x/ E- f' W3 i5 h) B* r
  1. package main2 a7 q# o2 l/ ]* ~% r4 @& T

  2. " Z8 ^  i0 v9 m( s0 k1 D9 g3 W% ?
  3. import (5 S5 J- ]7 W# z; p' B2 b
  4.         "encoding/json"
    : x- W) `2 L' f
  5.         "BlockChain/core"& o) C7 j. q6 R
  6.         "io", `9 u& Y  r2 |. N; n
  7.         "net/http"
    ( z; C) v# q0 i' P
  8. )+ q5 y- t( R$ m& f% {8 _1 J
  9. % E2 P( `/ A: [$ @: Y+ S
  10. var blockChain *core.BlockChain' B! o) O% W# Z
  11. ! M& o) X! s* I! Y
  12. func run() {  e* t7 ^& S: C/ M
  13.         http.HandleFunc("/block_chain/get", blockChainGetHandle)
    4 F0 z% F2 ~5 O; I  d; U' F
  14.         http.HandleFunc("/block_chain/write", blockChainWriteHandle)1 `1 ?2 X8 v$ |/ Y- k
  15.         http.ListenAndServe(":8332", nil)
    $ s% J6 P* C; J- c9 W
  16. }8 G) e3 V! A" m
  17. 1 t% @# |6 p% M8 _8 l! ]2 \6 _
  18. func blockChainGetHandle(w http.ResponseWriter, r *http.Request) {
    + K! b6 s+ v: q/ o3 X! `
  19.         bytes, err := json.Marshal(blockChain)
    4 m" S. J5 l! _8 _- Y
  20.         if err != nil {
    / L; ?2 G1 X8 W
  21.                 http.Error(w, err.Error(), http.StatusInternalServerError)
    3 O+ \" i% u8 o5 s7 p  p' \7 A
  22.                 return
    / o# Q- @. i/ R4 I' |- |! X" E
  23.         }9 K9 ^, {  n% _) D# ~
  24.         io.WriteString(w, string(bytes)); H) n/ Z3 z) a9 ~3 R4 C: b4 M+ J
  25. }3 n+ l( |% B% s! s3 B
  26. - y  K$ W8 J3 N" d
  27. func blockChainWriteHandle(w http.ResponseWriter, r *http.Request) {
    # v7 `3 ?5 i2 k+ o3 W
  28.         blockData := r.URL.Query().Get("data")
    8 r: O( Q" [: ^
  29.         blockChain.SendData(blockData)- e3 q8 }4 {: S- q
  30.         blockChainGetHandle(w, r): z7 G4 i/ \/ D) @9 L) d# b
  31. }
    % i/ V* e: t# v% j

  32. ! V5 K) Z" W) {- }6 Z- s. r
  33. func main() {
    2 a& A1 o2 i+ [9 E' E- k# H
  34.         blockChain = core.NewBlockChain()0 f% ]& I- n( v
  35.         run()0 e+ b/ i# D7 o/ ^
  36. }
复制代码
. L* U. N" j6 G" m
通过两部分代码实现简易区块链的RPC调用
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

朋友一起走 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    16