Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
在本机端口进行查询 由于是第一次运行该链 生成创世区块
! ^5 s; W) ?" i- L
8 k, z6 F6 |) W+ k# u通过http实现RPC命令的调用  实现添加块
. j% t$ z# H1 E! _) J3 V# m" W+ v- j" S2 G
查询当前所有块的信息3 \+ p# q+ G, U: ^+ X5 M3 ]( \
- k+ W; R) [6 o' L, n9 s4 U+ u7 ~
这里只做了两个命令 分别是get和write
% s- [: \% v$ Z源代码如下2 C. A6 e. d) x4 k% H# Y' \
基础功能的实现
* ]% l8 E$ p( [1 T
3 K; I* G* y: W/ q+ j% gpackage core* {. \% k. a4 K8 N* m4 [( d( ?1 W7 c
import (
: x+ S) a9 R1 Z4 s. {. @        "crypto/sha256"
; ~; |% e( e0 U( G. F% I' q        "encoding/hex"
! D% ~' H% p, h4 i) o( x& F$ g$ f        "time"
( S, F+ `% Q. h- ?- ~% O# I5 y)% a, h$ I5 f1 v$ T  F
//定义区块% |9 l2 _, B* G3 X/ t
type Block struct {
6 \& I7 M# X2 T4 T5 R        Index         int64  //区块编号' T( A2 l  c" q
   
  1.     Timestamp     int64  //区块时间戳# }+ G0 F4 f- N/ A
  2.         PrevBlockHash string //上一个区块的hash值
    $ D. {! a5 R8 ~0 ?, V3 @: q2 ]
  3.         Hash          string //当前区块哈希值9 E# I7 f+ Q3 w' y7 m
  4.         Data string //区块数据
    8 p8 H6 W6 E+ Z8 ]
  5. }5 I6 {" b  S' U9 R# ~9 W
  6. //计算Hash) m+ M' k6 Y' _4 C5 @  U6 O
  7. func calculateHash(b *Block) string {& g0 S, s8 a' g3 U0 m: B0 Y
  8.         blockData := string(b.Index) + string(b.Timestamp) + b.PrevBlockHash
    * b1 N  a, s- M
  9.         hashInBytes := sha256.Sum256([]byte(blockData))# p9 y, ], V' D* p4 ^
  10.         return hex.EncodeToString(hashInBytes[:])
    6 w7 p% S9 O$ |7 i
  11. }
复制代码
+ V: x- }6 G1 ~1 }0 ?' E' N

9 y5 J' ?+ H! k* F4 m. c: K//生成新的区块
% z9 P  P+ P! ^) }- |& j* i* a3 Ofunc GenerateNewBlock(preBlock *Block, data string) *Block {
5 U9 q2 T7 C9 D/ k4 V" B+ P6 Y: j& {/ Z9 ~        newBlock := &Block{}& b7 g, R1 x" {0 X4 e
        newBlock.Index = preBlock.Index + 1) e1 x4 H/ L. c0 f" ~% a, i* D
        newBlock.PrevBlockHash = preBlock.Hash
' l, Z! M0 n& T" e$ O/ M        newBlock.Timestamp = time.Now().Unix()0 A* i' r, s! H7 z7 K' N
        newBlock.Hash = calculateHash(newBlock)
8 f0 s$ A- m0 A" F, ^        newBlock.Data = data
: L1 Q6 @* D) P; k6 j        return newBlock
( V, A! }5 B! @$ |" e% v5 Z. E}
3 h# H4 J0 Z2 ~: j) R7 R # i) p, v" w3 X# \
//生成创始区块1 d; [- k- I  h0 t: H
func GenerateGenesisBlock() *Block {
3 Z% q; V+ s7 V% W3 X6 d        preBlock := &Block{}
1 \& t+ ~6 y9 }        preBlock.Index = -1) b2 {) ?5 }$ ]' ?
        preBlock.Hash = ""
' Z0 c% O2 L9 g. o6 D" k        return GenerateNewBlock(preBlock, "Genesis Block")0 E! f" K3 ?) x3 @. V8 j
}) Y0 [) F7 x7 ]6 j% x
将基础功能实现的块进行链接 实现blockchain
" x( V6 G+ E& [. npackage core9 v* E( t9 V2 u7 V3 N: k' [

- |: Z" a/ |2 m* i% z1 Gimport (
  Z2 y) L# K% }        "fmt"
3 Q* N+ f& \" D, A# M        "log"+ s. n3 N3 M( Y9 i! m
)
- G2 C1 g9 r1 v0 q
, H$ l9 ^- R1 F( d8 q6 Y//定义区块链8 K, J+ t8 b5 `) E; C, I
type BlockChain struct {3 ]5 ]  B3 b2 ]3 W; `, z
        Blocks []*Block
, U# I7 Y. K0 F* O5 t}
0 U3 p! v: h, i+ a' Q
/ `! S: ^0 H0 H. R" i8 M3 g' f//创建一个区块链
2 {- J; O0 \* e! S. g+ C) Cfunc NewBlockChain() *BlockChain {0 L, \0 {3 I% ~" @9 f0 c( g
        genesisBlock := GenerateGenesisBlock()
1 I% H+ O  q/ [% Q" n        blockChain := &BlockChain{}. i5 o' f6 u+ _% Z  S: |  A
        blockChain.AppendBlock(genesisBlock)
0 j9 y( u% _. i        return blockChain
# a+ B' p# v6 K+ G$ J' k}# q6 p, O* @# R+ g; h$ }: {- I

* D" M" B$ H3 z; b/ ]# ]+ W//记录区块数据
9 j. ~( ?1 K$ zfunc (bc *BlockChain) SendData(data string) {
. H. F" k8 |( ]6 U: |3 W8 H$ x        preBlock := bc.Blocks[len(bc.Blocks)-1]
# {5 f& e+ w8 O- z2 u0 k& q3 {        newBlock := GenerateNewBlock(preBlock, data)7 B; t' I+ I' _3 k+ Z; F" U7 a9 t
        bc.AppendBlock(newBlock)/ B4 F/ \# l( R4 ?0 f; N
}2 _: }1 L( E- p

$ Q6 ~; o* H- q6 k8 U# s* E7 G//往区块链添加区块
! _  T3 T5 d6 e( ^0 ~func (bc *BlockChain) AppendBlock(newBlock *Block) {
3 o% L7 k0 p* ^: c% |/ u2 U        if len(bc.Blocks) == 0 {
  O2 Z% G! s( c                bc.Blocks = append(bc.Blocks, newBlock)2 z0 s: g6 y% m5 `3 a
                return
  d8 j6 D  i0 }3 u  J- C8 A        }
" q" l% n8 i$ ?# }& e8 h; m4 |        if isValid(newBlock, bc.Blocks[len(bc.Blocks)-1]) {( P4 m3 s- B: m+ c
                bc.Blocks = append(bc.Blocks, newBlock)
. n' u% L: p" |. z2 w3 O7 f        } else {. V* J% j, ~5 t) n" k( }0 N
                log.Fatal("invalid block")
; r: V9 M6 x# ?7 b        }1 D, ]  Q( d- J. L
        return
- g9 t! z; ]6 F3 A! A5 {* p}
2 F# t$ `: @# d9 z0 C' V2 m 2 c' u6 q% M8 L- E
//输出区块链信息
/ g  c5 a( k1 \2 t+ Z2 Wfunc (bc *BlockChain) Print() {
& G; a  m. l1 n7 ~/ R9 l6 f" P        for _, block := range bc.Blocks {0 S) h( t, L: I4 a( @, k7 Q* O5 H
                fmt.Printf("Index : %d\n", block.Index)/ A* ~- e5 Q% u$ W* |
                fmt.Printf("Prev.Hash : %s\n", block.PrevBlockHash)/ _2 k" ?/ A: T  T
                fmt.Printf("Curr.Hash : %s\n", block.Hash)
; G5 }- X1 V' z+ q4 g5 Q                fmt.Printf("Curr.Data : %s\n", block.Data)  w: P2 q2 @2 _" v* r
                fmt.Printf("Curr.Timestamp : %d\n", block.Timestamp)  J4 @# n, Z+ _/ ^, ]' Q. E
                fmt.Println("==========================================")
! y$ e: q' e2 M5 Y/ J0 m5 y) x        }
; I4 L; P% f0 s& _4 K5 r}! B. V1 a8 }/ l( l4 o
0 _& N" f7 G4 ?! j3 R/ n; F4 V$ ]
//验证区块
( B3 M4 Q+ p' j- W7 ~, K3 }func isValid(newBlock *Block, oldBlock *Block) bool {
1 _8 O3 |) k2 A! ?6 w( Z        if newBlock.Index-1 != oldBlock.Index {
! R4 V( G+ }* s6 }                return false
9 h4 w2 p: E; z/ P9 ?0 J$ H/ S        }
/ y* r# l. J* J9 ]% z: q$ Y        if newBlock.PrevBlockHash != oldBlock.Hash {
0 O* M  B4 x  t, }                return false
1 n5 E% \2 u% |        }% B; S% y( G5 l  d
        if calculateHash(newBlock) != newBlock.Hash {5 d! M' Q" D# T; q8 {4 ]5 o
                return false" Z3 E  `; L4 i
        }
% q4 K$ \/ V. S5 E        return true
9 O8 V/ v$ y6 ~}
) E" ?* r& u# p  u- a3 t% U0 I# e$ ?实现RPC接口的交互; F0 v* m3 |7 d4 g) D
  1. package main% T8 H0 ^$ j2 ~+ l0 E- t1 M
  2. % K0 G- ^- O- F& ?7 S- M8 {
  3. import (
    : G1 U7 X) x2 Z0 G  @' i+ q
  4.         "encoding/json"
    " j% W. c5 h- m
  5.         "BlockChain/core"
      n6 X. ~! @7 d& w  [$ W
  6.         "io"* K. z$ g; ]6 \
  7.         "net/http"
    & X( r6 H$ ^0 N) a4 R
  8. )
    5 F' l4 z, ~8 ]$ o
  9. 6 I' N3 ]& k2 E7 {- T9 I: F% C
  10. var blockChain *core.BlockChain5 u" C2 S% f# b' [; Z

  11. 3 L5 w  N9 a1 b$ v: U6 [% \! ?" V
  12. func run() {0 l! g; t' @; D/ c- {- q' Z
  13.         http.HandleFunc("/block_chain/get", blockChainGetHandle)
    . n  u/ t, s2 A4 O3 q1 F6 _" `
  14.         http.HandleFunc("/block_chain/write", blockChainWriteHandle)
    + l# p/ m9 z5 W2 m# q! @
  15.         http.ListenAndServe(":8332", nil)
    6 g/ R) ]- O* X& ?8 c' A
  16. }
    ( e4 V+ h+ x* @( p) U2 G" ?3 B
  17. & a) T2 r. {3 y) b% {) N
  18. func blockChainGetHandle(w http.ResponseWriter, r *http.Request) {
    , X% g& G1 j$ k! }
  19.         bytes, err := json.Marshal(blockChain)
    ) i" E$ p. d  p! g! w: I
  20.         if err != nil {+ Q# v8 x" ~. x: n, [
  21.                 http.Error(w, err.Error(), http.StatusInternalServerError): p6 w+ O) N  T1 }& n  N: S2 C, M
  22.                 return! A4 Y) ]1 C4 s2 q
  23.         }) b* H2 d0 m' [- A' J4 m5 r2 S  U
  24.         io.WriteString(w, string(bytes))% F( s4 q$ V. q. L' \
  25. }% C) E, y& W0 y' q+ [7 ~

  26. ; R; O7 n. |% r# f* H; u: W. d2 p
  27. func blockChainWriteHandle(w http.ResponseWriter, r *http.Request) {  e9 {" s2 p& E
  28.         blockData := r.URL.Query().Get("data")* `$ l4 r7 l5 }; O2 @0 j
  29.         blockChain.SendData(blockData)
    - X1 |' K) d/ h/ j$ P& N' |% i* F
  30.         blockChainGetHandle(w, r)
    3 `2 F" ?, f+ [/ v. k! C- {
  31. }) Q' L* u" ]" i6 w
  32. + R4 L, T0 D. F4 ]" r% ^# R2 q9 V
  33. func main() {) d8 F3 |* J1 X! v& D4 I4 h
  34.         blockChain = core.NewBlockChain()) X2 X# }# u4 e' {
  35.         run()9 F5 q5 k6 Z8 c. u
  36. }
复制代码

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

本版积分规则

成为第一个吐槽的人

朋友一起走 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    16