Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
在本机端口进行查询 由于是第一次运行该链 生成创世区块. z0 v7 Z+ `3 C) a6 o
6 W# E" k( |8 l, F
通过http实现RPC命令的调用  实现添加块# [9 j' H1 K. K+ {
7 h1 v8 _! K3 P5 N0 f1 x
查询当前所有块的信息
  s4 B5 D9 X; m( E8 O+ t3 Z( s" T( r3 K7 ]
这里只做了两个命令 分别是get和write) ~! l. ?+ L  Q2 X( V6 X+ |: v
源代码如下1 T! s; B9 G; p4 c* z+ W
基础功能的实现
1 T4 X) V7 f5 o" N  v% S* t7 F' P) V& f8 a7 [
package core/ S9 H4 q1 U# {' C
import (
7 v4 \8 b# E! V        "crypto/sha256"* \* Q2 q. J" F5 p( a
        "encoding/hex": }  O2 x3 ]& _  t1 N
        "time"
$ m  |' i7 M3 a2 i# |* g' J$ J)
* Y+ P9 S( `, B  U* p3 Z* I& `/ K4 Z//定义区块
! R  \/ ~3 J- itype Block struct {% z) Y0 ~8 D0 M8 s
        Index         int64  //区块编号. A/ c  B- e+ m' B' }/ q
   
  1.     Timestamp     int64  //区块时间戳' L( G3 y6 u+ \# }2 l2 W' s/ j; I5 j( ?
  2.         PrevBlockHash string //上一个区块的hash值
      A" m: g3 u! v. N% j
  3.         Hash          string //当前区块哈希值
    ) J' P5 D- `  t% n, Y1 R3 Y
  4.         Data string //区块数据& v; c4 g0 Y, V1 I1 Q; |
  5. }
    9 u  N& x. ~7 N# `# S. ?/ m
  6. //计算Hash" `1 ?0 a7 P( L' J; J
  7. func calculateHash(b *Block) string {1 J9 n4 _0 s7 H* |  c' m8 v4 l7 G% t
  8.         blockData := string(b.Index) + string(b.Timestamp) + b.PrevBlockHash
    + X& f# r/ b8 W; _+ e7 B4 l9 F
  9.         hashInBytes := sha256.Sum256([]byte(blockData))
    # O( Q$ O5 e/ Z3 Z8 n
  10.         return hex.EncodeToString(hashInBytes[:])& \- W$ @) T( e
  11. }
复制代码
3 M) E& X2 _, b$ ^- E  [: A. B8 I

$ E% c- B% p0 x% ]' W//生成新的区块! ?; o4 T0 H# j
func GenerateNewBlock(preBlock *Block, data string) *Block {
) j* Y' M1 }% K; b, G  u+ i        newBlock := &Block{}- U$ q  M+ ?# k
        newBlock.Index = preBlock.Index + 17 j4 y. U. Z5 S4 d% _8 N# Q
        newBlock.PrevBlockHash = preBlock.Hash
& E/ n1 p2 r3 `4 a) j        newBlock.Timestamp = time.Now().Unix()0 s& f( l0 U5 d( w
        newBlock.Hash = calculateHash(newBlock)
- [3 C6 j9 ~9 Z, b        newBlock.Data = data5 C' L% u6 V5 L! |  X
        return newBlock) G: G& O) \2 ^8 d6 X
}
& E! j/ {+ L) k$ g5 j 9 @& j8 N( |! W- I3 U! a) I# N
//生成创始区块$ f5 G% Q0 H2 i7 `( m7 u
func GenerateGenesisBlock() *Block {
+ ^2 s8 P, D3 w2 G$ c' C. T        preBlock := &Block{}
- j8 ]2 L% i9 Q6 a; n$ J/ ^        preBlock.Index = -1
1 C( x+ R: U% t/ h+ k; C1 X: `        preBlock.Hash = ""9 a$ d) `' y" o6 ?5 k3 h
        return GenerateNewBlock(preBlock, "Genesis Block")
# F* R( B  P4 A' Z, }5 o7 w}; K/ Z8 M1 S/ W
将基础功能实现的块进行链接 实现blockchain0 ?3 X5 Z& L( n, B$ o2 o
package core+ W5 |+ E" e3 G+ d, m

. Q2 N( @" H; F1 H$ @- m9 Zimport (3 n$ w7 V+ M2 N- W
        "fmt"
3 w8 \6 X4 k0 N% H" h3 V' s        "log"
" x! u2 o2 r. Y( b3 F- l4 {)+ o: c( g$ I& {

/ m2 V/ ^3 H/ D! S//定义区块链
; C" V- I  e# O7 m& _type BlockChain struct {; `9 z9 s6 W0 t3 [- o
        Blocks []*Block
9 U! l3 Q7 y2 `5 D$ N9 s: |}& I6 P( N0 E4 F

+ Q* X- m- g9 W; O- m//创建一个区块链
+ |& @7 u# t8 a$ g7 t0 zfunc NewBlockChain() *BlockChain {
* ^0 ]; {+ }" z; |; k! ?        genesisBlock := GenerateGenesisBlock()
+ b3 G8 [& i" t1 w5 k        blockChain := &BlockChain{}6 `0 m* P+ ~6 C& S
        blockChain.AppendBlock(genesisBlock)
4 N- b  B/ Y: M% v7 n" Y        return blockChain. M' D4 {! a4 M9 W: w" b2 n/ e
}0 K7 z! B. x4 `' B( C# O

4 `1 y* z5 D$ |6 x) n7 [" o8 c//记录区块数据
5 k1 h, |+ Y& A! I. T3 Efunc (bc *BlockChain) SendData(data string) {5 V& _1 f1 w; v$ L% ?% a. J
        preBlock := bc.Blocks[len(bc.Blocks)-1]
$ s) U' r5 c# x0 h3 r: D/ k        newBlock := GenerateNewBlock(preBlock, data)
( {9 M% m8 X% u) p! m        bc.AppendBlock(newBlock)+ h% e6 o* I; L" u, t
}
! F3 u/ S3 y7 S+ h# I9 | / Q& r0 H" M+ i9 w! v
//往区块链添加区块* Z( ~3 d) W1 g- G
func (bc *BlockChain) AppendBlock(newBlock *Block) {% w0 K5 P" m- G
        if len(bc.Blocks) == 0 {
2 z. Y/ N( O7 `; I" o                bc.Blocks = append(bc.Blocks, newBlock)# n$ s! y, Y' V# Y
                return) w) q! F% D, K" |7 p8 w) o4 z, f
        }
; V; q( `% N0 b- A        if isValid(newBlock, bc.Blocks[len(bc.Blocks)-1]) {
  R7 F9 c# {7 K' L+ m  {                bc.Blocks = append(bc.Blocks, newBlock)( O2 P1 S1 q3 a. O0 R1 [2 U) o
        } else {
* f7 ]4 I) w) _+ K; j                log.Fatal("invalid block")
3 `& }8 }. Y5 C# d' F8 Y        }
' T" T) v& f$ E6 G. p        return2 Z8 c8 X6 d5 C0 i" Y0 ^$ ^& z
}
! X# o1 n' t( a+ r7 I8 ] , O! Z! K" j' x! ]) _
//输出区块链信息
) K$ [* h' F9 l. v# V% m1 vfunc (bc *BlockChain) Print() {
7 u! M4 N$ ^! J0 o        for _, block := range bc.Blocks {/ a+ b: p  w& c5 S5 K& y8 S; V, R9 S
                fmt.Printf("Index : %d\n", block.Index)
; V& G+ f8 K! G0 m! E( a                fmt.Printf("Prev.Hash : %s\n", block.PrevBlockHash)
3 a+ x3 q/ V% \) t                fmt.Printf("Curr.Hash : %s\n", block.Hash)
7 _9 C  w$ O8 v8 M/ G$ g8 ~                fmt.Printf("Curr.Data : %s\n", block.Data)1 _. U5 r% F; p. |- C8 w, f* S; u
                fmt.Printf("Curr.Timestamp : %d\n", block.Timestamp)
! _% @( u( {% @3 |! p$ y                fmt.Println("==========================================")
6 ]6 D; e2 n) I  g* o        }
8 S) y; K; @& A: R1 x2 q}7 a* s, r0 o2 O

, V. @$ R+ Q2 F# ~0 n2 T//验证区块) `# ~( @* B. N% ~" \* ?: @, ?& @
func isValid(newBlock *Block, oldBlock *Block) bool {
/ |4 K5 ~3 Z( _9 g        if newBlock.Index-1 != oldBlock.Index {
* T- K$ v6 H) U7 b- K6 I                return false
9 G$ }. P; k1 b" i/ J2 [        }
! ~: s/ g0 ~7 u8 ]1 \        if newBlock.PrevBlockHash != oldBlock.Hash {
. j- ^5 p" a# {5 X! v% D' d: @  C                return false
: _# d7 }9 R& O, b' i/ S7 `        }
5 X' B$ g! Z# r7 z2 \6 O        if calculateHash(newBlock) != newBlock.Hash {. y$ h& E/ S1 |
                return false5 J6 S0 p/ L' X3 j- u
        }3 J% X0 _/ b$ I, ]# H
        return true7 W6 i9 b7 @7 ~( M  l
}
0 Y" ?3 V9 D: \实现RPC接口的交互& K; Z  m. H" U9 g) O4 M
  1. package main6 c* H6 g+ ?- @  ]$ G

  2. 1 q7 T' Z; g$ h" T) U( n( e
  3. import (, v: \& x! r6 I/ X0 @
  4.         "encoding/json"
    ! Q8 ~! {6 Z. D# X+ m
  5.         "BlockChain/core"
    - `* \( |9 B7 g% G2 |- a
  6.         "io"7 M3 h! _$ H0 y$ [
  7.         "net/http"1 K* P% H$ q2 k- b% u% Z
  8. )  b9 K6 X# y; E2 h$ A4 j+ Q5 d+ d0 F
  9. 1 O' d# u/ v3 z( U
  10. var blockChain *core.BlockChain( ^" k, k, ?) Q7 g, _. s5 h) V
  11. 1 T/ n. q0 l  e5 Y2 l: J. g" D
  12. func run() {
      ]* \! ^& b- R- I( F8 w$ Z6 R( w
  13.         http.HandleFunc("/block_chain/get", blockChainGetHandle)7 a4 _6 [) s) A0 I0 X% ]7 x( Q) r+ C
  14.         http.HandleFunc("/block_chain/write", blockChainWriteHandle)" j0 o/ [% g3 b; j* E! p! w
  15.         http.ListenAndServe(":8332", nil)/ h& V; a. F7 W' \1 g9 c
  16. }! o3 e9 z5 P, G  N5 ~1 _
  17. 0 G4 i4 \& |) r! e* N- h& K
  18. func blockChainGetHandle(w http.ResponseWriter, r *http.Request) {: x/ ?1 V* j2 m) a! D7 @
  19.         bytes, err := json.Marshal(blockChain)2 t* d9 a% T  T( Z( B
  20.         if err != nil {" P( N6 b, Q6 o& k
  21.                 http.Error(w, err.Error(), http.StatusInternalServerError)4 U5 Y# r& B+ H; g( I
  22.                 return4 L" w) L* F2 ]( x8 ^+ a3 F9 r
  23.         }& @# \' ?0 f6 {# H$ h3 n
  24.         io.WriteString(w, string(bytes))
    * s/ G9 T/ o# q# S
  25. }
    ' L5 L/ ~) |8 p! _9 R1 S
  26. ; R1 Y4 _* ^8 w7 O* N% e5 a
  27. func blockChainWriteHandle(w http.ResponseWriter, r *http.Request) {
    , m3 w3 `- v: @4 @. T
  28.         blockData := r.URL.Query().Get("data")
    , t# S/ o! N$ z8 b% j( i
  29.         blockChain.SendData(blockData)) l6 B( G% A& a5 _) Q
  30.         blockChainGetHandle(w, r)" f4 D/ x8 q  X; X
  31. }
    1 P# O) ~+ q# O3 S
  32. 9 R! D9 c# V$ k# |7 Z& v
  33. func main() {
    0 w/ q1 ?8 x3 _9 `
  34.         blockChain = core.NewBlockChain()' x7 i+ V7 r5 e3 R+ h
  35.         run()( A+ t3 J, g% g: M* ~
  36. }
复制代码
9 d) S; c5 S$ [% l: v* Z7 u* w
通过两部分代码实现简易区块链的RPC调用
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

朋友一起走 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    16