Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
在本机端口进行查询 由于是第一次运行该链 生成创世区块9 g- ]$ s9 L  V; z9 T( N
; k) g1 |0 g9 e. V) r( L3 j" s
通过http实现RPC命令的调用  实现添加块
0 C- X: Q3 g# p+ U- ?
5 |. ~; f$ e% ?# K/ N" X" {查询当前所有块的信息
6 X: f1 H! e) D  r$ Z2 E4 ^0 r* \
0 b# u  O- v$ l7 {# x这里只做了两个命令 分别是get和write4 x: ?& @, D1 N- O/ s1 o( f
源代码如下6 j2 o7 ]) V% F0 z; f! \: O7 e
基础功能的实现
& l- V5 C0 g3 E4 h3 b4 l3 ^- u6 b. g% W9 s: E+ n8 t
package core3 }  w7 d3 ^$ B; Z. S/ D( m
import (' l; Q3 J$ K- j& H/ ^
        "crypto/sha256"0 n" `6 g  a+ ?$ x8 v) K2 c
        "encoding/hex"4 E; \$ [. Q, g" H5 J1 O9 i
        "time"5 |; S1 \7 `  i( e
)
! Z/ M1 Y( j* T: G1 a: O8 i//定义区块5 R/ E- @) ^% r) o& I
type Block struct {
) d, t* _/ n. q( p: F+ k& W% o        Index         int64  //区块编号  T4 J. b; Y& q7 d. z
   
  1.     Timestamp     int64  //区块时间戳
    + W+ ^0 i0 P  X6 T0 o
  2.         PrevBlockHash string //上一个区块的hash值
    ( L0 c# N! c, c2 U* f. p! _: J0 m
  3.         Hash          string //当前区块哈希值
    0 {8 C6 Y$ \; D2 z& r' x8 f* u
  4.         Data string //区块数据
    3 ^: b- I/ n4 `. k$ b
  5. }8 r& N: m9 c  y3 N
  6. //计算Hash; ?" ?6 Q' X5 I+ Z6 U8 P/ d0 M
  7. func calculateHash(b *Block) string {
    % U8 N6 o9 h8 e
  8.         blockData := string(b.Index) + string(b.Timestamp) + b.PrevBlockHash
    4 g% b4 M; ^3 P" U! D
  9.         hashInBytes := sha256.Sum256([]byte(blockData))) y' i; ^0 e0 S1 F) M
  10.         return hex.EncodeToString(hashInBytes[:])$ a# s! v% v7 Q' C4 B4 W/ C
  11. }
复制代码
+ g! _0 B* B  \

' C  `( l' Q" ~  {* H  g! r9 h//生成新的区块; h% ^4 E+ g7 b- R3 }- O0 m
func GenerateNewBlock(preBlock *Block, data string) *Block {. a8 Z" o" j  P& E2 w  h
        newBlock := &Block{}8 m  o5 p9 z6 ?# A8 I% |1 e
        newBlock.Index = preBlock.Index + 1
+ [+ n- O4 ?1 h3 y: _* p        newBlock.PrevBlockHash = preBlock.Hash8 K) {) E& ?( P$ B/ w$ m* T
        newBlock.Timestamp = time.Now().Unix()
% Q& E. F# s6 o        newBlock.Hash = calculateHash(newBlock)
: L1 A# h! \8 q% u2 f        newBlock.Data = data
( j, }7 b8 l8 a+ `0 Y8 g        return newBlock
; T+ q" s( Z* J}
1 G* {$ q5 p8 p# f
7 |& K: u2 ^# q/ p2 v  N  p0 }//生成创始区块
# a, u7 i6 h: v7 ^0 Bfunc GenerateGenesisBlock() *Block {
; R, u" g/ q  D/ L        preBlock := &Block{}1 x; S6 v# z+ a% T2 b
        preBlock.Index = -12 M( x1 Y+ H+ E8 t0 i" D" d$ v
        preBlock.Hash = ""
; L& W6 S1 y6 R5 G8 z5 ?        return GenerateNewBlock(preBlock, "Genesis Block")  ]/ M: q4 d2 ?! K. L" Y4 \; M
}0 R. N/ b. G/ R( V/ B& a
将基础功能实现的块进行链接 实现blockchain6 |" R( b4 [4 q  J0 |" C2 q
package core
- W7 z( V% G/ P% w
7 u4 U; @9 |1 v9 ]" W9 Vimport () \5 y$ ^2 o5 G' b) @8 v" X; ~
        "fmt"
1 a6 |* @: D; _% F% w8 ~! u        "log"
1 f- T* u9 |* ?# t$ X)+ L$ Z, ?* e- Q0 Q' t0 j

$ J2 d0 Z. ~* J//定义区块链
7 c- Z2 Z% m. ftype BlockChain struct {3 o9 o5 E8 }9 A" L
        Blocks []*Block0 P/ x- B1 m1 m- r5 w
}; E' k: y! f/ _3 G4 Y: V* j

; P! H& B: U  k  Z2 i& I  e1 d//创建一个区块链1 p: M7 ^' Z% o- |5 g/ J
func NewBlockChain() *BlockChain {
# c8 C0 p6 g+ M3 t1 d! u1 f        genesisBlock := GenerateGenesisBlock()
" R% J+ d, B- c7 E        blockChain := &BlockChain{}: e8 q( d, ^3 j! `' }' l4 {
        blockChain.AppendBlock(genesisBlock)
2 S+ H' M" V/ H+ w        return blockChain
/ v8 g& N. j& {1 g. W9 S7 K}
# G! m; g; W. O5 D5 M5 W
6 G# @) e. X5 I" |  H  @$ ?//记录区块数据, J7 E% n' f5 s4 M# b
func (bc *BlockChain) SendData(data string) {# x6 j; m; K) z" {) j( i9 O+ ?
        preBlock := bc.Blocks[len(bc.Blocks)-1]- `3 L% s6 P- n7 S
        newBlock := GenerateNewBlock(preBlock, data)
3 \1 t' _$ Q) d3 E' ?, K1 t0 I7 ?        bc.AppendBlock(newBlock)2 S2 D* A2 v$ {1 D4 B4 y) D
}) ]5 h7 y/ l" X! w, [' W$ O. z
, G6 Y5 O- m, D* P( W* o
//往区块链添加区块! t9 l" ~0 l  Z) @% Z1 q+ V8 t2 C/ t; J4 c
func (bc *BlockChain) AppendBlock(newBlock *Block) {% p1 O+ `6 J8 k7 _$ V% c- Y  M* F7 {
        if len(bc.Blocks) == 0 {
$ d1 c% N4 r6 D                bc.Blocks = append(bc.Blocks, newBlock)3 l% A& g) ?  K
                return
" x+ W( H4 @% d6 M        }
3 W) l# i5 L' d" ]  `3 M4 |# X        if isValid(newBlock, bc.Blocks[len(bc.Blocks)-1]) {; ~7 c; w4 z/ V8 ^
                bc.Blocks = append(bc.Blocks, newBlock)
) i( j4 B. `" {, f        } else {
2 Q) V" h: p( t                log.Fatal("invalid block")( x* S; C3 M& F+ y& x: k& v
        }
0 a* M& Y5 f5 p, J# C6 k: m7 V5 H        return; [6 B) |+ x% a1 j; F
}
; B/ e  q' _# e* ?
* f, z9 v2 q2 L. o1 v) H2 N//输出区块链信息
+ v: q1 ~/ N  b1 Z8 ~func (bc *BlockChain) Print() {
# F0 I3 `9 a) g        for _, block := range bc.Blocks {
) R+ A9 ?; ~. Z0 ?" q+ ]                fmt.Printf("Index : %d\n", block.Index)$ k/ h, S9 f, m4 \) b- p" P
                fmt.Printf("Prev.Hash : %s\n", block.PrevBlockHash)
, i5 j7 z3 D, [+ m1 D8 M* c                fmt.Printf("Curr.Hash : %s\n", block.Hash)
, [4 B; `0 p6 I5 m5 I1 C/ R                fmt.Printf("Curr.Data : %s\n", block.Data)* A5 Q6 C" t! _; x" E
                fmt.Printf("Curr.Timestamp : %d\n", block.Timestamp)
, Q( @$ c- V' t' [! I( L                fmt.Println("==========================================")
8 H  ]3 m8 j5 e& v5 H5 Z        }8 a9 A, [: E" h
}2 B7 k9 z' P  Q; R& a+ z7 L3 j. N

* Z! q9 t! b2 m/ f//验证区块
2 x# K6 `0 D) |+ e4 R6 gfunc isValid(newBlock *Block, oldBlock *Block) bool {
0 I' P5 K- Y% J+ b0 q        if newBlock.Index-1 != oldBlock.Index {: T6 h. H$ p; L( I! P' v1 M3 a9 }% f
                return false
  F$ \/ C. L5 t8 A) P7 w        }+ y) i0 f5 e7 k
        if newBlock.PrevBlockHash != oldBlock.Hash {
8 F. a' V) U" v6 F6 ]                return false
5 F. x6 W& i) m& k9 [% |1 x        }2 n, E: V/ C1 j
        if calculateHash(newBlock) != newBlock.Hash {
6 V5 y! |- b* L7 V                return false% {( h7 e  x- p5 a& N
        }
5 T9 H- V5 Q( C        return true# \( v$ E4 j# i# q$ W
}
/ b- l& t- N: @7 F实现RPC接口的交互% m: @" Q% w$ L6 e' P' e3 W
  1. package main
    / M3 S/ @) |6 t" Q

  2. 3 ~" s6 o% M7 h5 S: _) F
  3. import (
    ! l5 Q- b1 `/ R& y- f/ q, H2 h
  4.         "encoding/json"
    7 i. Z! n: Z& D, M5 |; h
  5.         "BlockChain/core"  w! \) c- ]% K4 K0 g& a2 V
  6.         "io"
    0 W$ w7 H; h* H9 k- n
  7.         "net/http"
    2 r9 g0 B$ k- L  ]/ W8 r
  8. )
    9 C& X; T. ?* J7 H
  9. ! O2 V4 M# a" \3 Z
  10. var blockChain *core.BlockChain. p( }' ?2 }; _& e/ E
  11. " U! \+ p+ Y2 M% E  a8 \
  12. func run() {
    " z* g3 Q: [$ ^
  13.         http.HandleFunc("/block_chain/get", blockChainGetHandle)4 [4 m  |# s" V$ j
  14.         http.HandleFunc("/block_chain/write", blockChainWriteHandle)
    % L0 H, Z% ]+ N! ?7 I8 f
  15.         http.ListenAndServe(":8332", nil), T8 j8 v. z- `, _
  16. }" o( c3 V* T+ J* v8 Q( U9 L
  17. 2 d  @# L5 u, d: X; d
  18. func blockChainGetHandle(w http.ResponseWriter, r *http.Request) {1 N& x* o# d7 n" P% z( f# @7 [
  19.         bytes, err := json.Marshal(blockChain)
    , p2 \( m0 `, e
  20.         if err != nil {  O& y0 J1 A. W+ U
  21.                 http.Error(w, err.Error(), http.StatusInternalServerError)/ m2 N$ Q2 Q0 m( y
  22.                 return
    # x' p) |2 |0 G) s1 |0 e& U8 J
  23.         }3 Y/ `+ H, M" L( A4 P
  24.         io.WriteString(w, string(bytes))/ _0 P1 P$ w- n5 P" T. a# P
  25. }
    / \* ^% n+ ?4 u4 h+ J" A. }- H

  26. 3 F" C1 e, R! y/ A, ]
  27. func blockChainWriteHandle(w http.ResponseWriter, r *http.Request) {" W8 x3 I( J; Q9 n- ~, ?) P! p
  28.         blockData := r.URL.Query().Get("data")# L1 u1 Z# H: i, M2 x8 O
  29.         blockChain.SendData(blockData)
    2 z0 n$ n5 _) d) |  e$ @( T
  30.         blockChainGetHandle(w, r)" @# W0 I3 {: l  w6 k$ g6 S- P
  31. }4 C$ G. p) Z2 ^. I

  32. : T" c' U& Q6 N' D$ i& R
  33. func main() {; n/ a5 E7 r) A1 f/ k
  34.         blockChain = core.NewBlockChain()
    - Q* W) |, |( I, a0 ?- P1 w8 P
  35.         run()
    1 H4 |8 Z2 O8 o/ K& q7 N9 N
  36. }
复制代码

* R& Y' V( Q5 Y& o; ?- G通过两部分代码实现简易区块链的RPC调用
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

朋友一起走 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    16