Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
在本机端口进行查询 由于是第一次运行该链 生成创世区块
$ a# H. A( M+ G/ S9 I& m& F5 }( P: v8 e% ^, ^; Z
通过http实现RPC命令的调用  实现添加块
$ v* M* D. f" e
$ [2 p2 n  D" `+ b9 n% t' @查询当前所有块的信息
) }; Z- \3 _1 F- q- K8 @
& Y' s  \# z& ~* t这里只做了两个命令 分别是get和write
5 [* |+ O- L  G+ D" k& R; x9 A源代码如下3 W& t6 P! |5 x8 T
基础功能的实现
( Y4 ?0 C: P- M2 ~" q. _
+ x2 ^8 P# ~2 e0 A; l* j7 kpackage core# j8 q. H7 g1 {( `0 S
import (
4 t, x  s: v% p: |- a- o: @, o        "crypto/sha256". N8 g: e9 y1 [3 w+ T- H6 Z% G
        "encoding/hex"
$ x9 P3 d2 a2 h' C: P8 Z        "time"
. Z/ u" t. r4 D9 k0 @1 L)
* t' M9 [% _& L7 l& W; }//定义区块  @+ u! ?; u0 J0 X. Q& x6 a, F5 i
type Block struct {
1 J" e" E% [4 {" N        Index         int64  //区块编号+ m( Y/ V: N! R* ]/ P, S7 D1 ^
   
  1.     Timestamp     int64  //区块时间戳2 b1 J% z# r$ t7 l. R' e+ h* Y" r
  2.         PrevBlockHash string //上一个区块的hash值$ R) J& |: m4 t5 ?
  3.         Hash          string //当前区块哈希值3 Y8 d( p3 t) S: C6 [; K! \
  4.         Data string //区块数据
    ; y# y7 [8 J3 f7 `$ E
  5. }  A$ b, |$ `6 T# c
  6. //计算Hash( T" x# h+ t& t5 D" m5 o: L
  7. func calculateHash(b *Block) string {/ k' S  b1 X% h- L) N
  8.         blockData := string(b.Index) + string(b.Timestamp) + b.PrevBlockHash
    # Z2 c! q0 |( {$ z* V& ~9 Z
  9.         hashInBytes := sha256.Sum256([]byte(blockData)). \8 z, V8 f0 B: [- ~6 w& G0 u3 h  U+ G
  10.         return hex.EncodeToString(hashInBytes[:])
    # f+ }+ |3 v3 \- \. {
  11. }
复制代码
" B1 _: C2 q+ ]

5 S) u; y2 k; v7 s1 ~; y! l//生成新的区块( j# C) ]) K4 [
func GenerateNewBlock(preBlock *Block, data string) *Block {* P/ x# a1 D2 k: Q- l+ Q, v4 N, z
        newBlock := &Block{}/ ~  e; ~& O) T* t' R, a
        newBlock.Index = preBlock.Index + 1
! N+ r' M7 z) s( q& C/ O        newBlock.PrevBlockHash = preBlock.Hash# P! q2 ^1 a2 E! J
        newBlock.Timestamp = time.Now().Unix()
2 S8 ~' y2 i. H        newBlock.Hash = calculateHash(newBlock)
1 t0 R, l7 l! l* }1 ?$ f        newBlock.Data = data
1 V9 b  B! \: E( X+ M0 Q. j        return newBlock, J' F- Z0 g* M( V' e: ]* u& {
}
4 H8 o3 L9 w1 ~. N
5 m7 P! g8 e; `+ m$ }2 T! v//生成创始区块
! e1 ?; F$ S' ]8 ]& S- {func GenerateGenesisBlock() *Block {
1 v" h1 Q; i2 d0 Y        preBlock := &Block{}
) L4 M5 J  w. d$ [) H# _6 r4 F        preBlock.Index = -1. L$ _5 ^  M2 b' m
        preBlock.Hash = ""
9 @2 L9 Q& K" K1 L. W( ?        return GenerateNewBlock(preBlock, "Genesis Block")( v5 W& H! H- b9 S
}" T$ z6 Y& x) c* R( X8 K& f
将基础功能实现的块进行链接 实现blockchain  N, b" y# D1 d6 ~6 u: S; w
package core! x! b4 p" N; c  k# o

& V& f% \- V/ G7 ~5 simport (& D7 ?6 l6 ]+ G7 }, L% B% }' h
        "fmt"( ^5 @1 B  O' X- f% s
        "log"/ ?) b% a7 J8 t, @/ L  b* y
)
% q  }6 L) f  y . o5 @! p+ p; H
//定义区块链
5 ^' `! {7 n5 p" A, ?) gtype BlockChain struct {, A- B5 j9 A* A# \
        Blocks []*Block
& d" a1 h7 z  c1 v) U}! L9 b3 T2 X8 t3 R

8 ~7 h; O# ^0 V5 Y6 @, s//创建一个区块链
6 [; c: \3 g6 X$ G  d) Afunc NewBlockChain() *BlockChain {
. n6 a5 [* ]: P( X  N* f6 B) ]        genesisBlock := GenerateGenesisBlock()
$ ~  `8 T4 E7 e% n  e" r+ o" b7 ^        blockChain := &BlockChain{}
* z4 X: |" |$ a. r        blockChain.AppendBlock(genesisBlock)
6 e6 j0 `% i! \& k$ f$ O7 Q        return blockChain9 a* k9 r8 G$ H' G! F
}: f$ s5 L( z& F8 T! n
9 q) h3 [( ?( f9 G9 D
//记录区块数据
4 L' T/ }% x' g$ U4 H# \func (bc *BlockChain) SendData(data string) {
: w7 `4 j4 ^, l, `        preBlock := bc.Blocks[len(bc.Blocks)-1]. f$ ]. @7 }% c# n' x* M
        newBlock := GenerateNewBlock(preBlock, data)
& X+ L) {6 D% d5 U+ G3 r+ W        bc.AppendBlock(newBlock)8 Y4 N2 b2 U, Z8 L
}
% S+ h% t" |% [( z1 x& ~ ' M$ k" M1 n0 j- Q5 o3 m. ]! P
//往区块链添加区块
7 A) [- u7 ]- F4 m0 n; n7 dfunc (bc *BlockChain) AppendBlock(newBlock *Block) {0 q1 L; g; ^; s1 i3 \$ a* [! c
        if len(bc.Blocks) == 0 {# l% G, j6 `& Z8 B- u& E! I
                bc.Blocks = append(bc.Blocks, newBlock)) S- {9 c0 ~7 c9 X5 h; U+ k+ F
                return9 v8 H5 q, j4 F
        }
1 H+ X; H) U* m% Y        if isValid(newBlock, bc.Blocks[len(bc.Blocks)-1]) {
) Z& b' B- }8 ]+ p. s. C  @$ `                bc.Blocks = append(bc.Blocks, newBlock)" M1 `( \$ O( a: `/ ]* a
        } else {
0 G7 D4 y8 @0 n1 d5 _& C                log.Fatal("invalid block")
( j# [" @5 s2 U4 t        }
1 \5 ?: g+ U9 E5 ^5 J        return7 l4 X4 w" L% N7 C
}# {  ]) `8 |  }$ t" n
8 I+ D6 n3 i6 {% p4 V$ `6 d; U2 \0 t
//输出区块链信息
/ }7 I; Y2 H& }% Yfunc (bc *BlockChain) Print() {& o2 j- a+ t* {
        for _, block := range bc.Blocks {
! M: {9 C: }1 A1 T                fmt.Printf("Index : %d\n", block.Index)% G) H3 }+ _/ \
                fmt.Printf("Prev.Hash : %s\n", block.PrevBlockHash): r7 r+ }: D0 v) p! N* K0 D4 H
                fmt.Printf("Curr.Hash : %s\n", block.Hash)
% d& M2 y3 Q8 `1 i4 B2 M                fmt.Printf("Curr.Data : %s\n", block.Data)
) h& Y9 T0 l: C0 Y1 @2 Q' Z, ?9 _% }                fmt.Printf("Curr.Timestamp : %d\n", block.Timestamp)9 u0 L( q# q: Y- F' ^& g) k
                fmt.Println("==========================================")& J" q' R- k% a0 a
        }
# y7 i: p0 z5 k) z: v6 u}
# |0 N( g$ _6 R$ a
' i" C. y7 c4 h: U4 X//验证区块3 o% A1 C0 O% F+ F' q$ o) \
func isValid(newBlock *Block, oldBlock *Block) bool {
+ [% g, B7 a5 H        if newBlock.Index-1 != oldBlock.Index {& b4 O% d* Z# ~- Q
                return false" V# u1 _2 Q2 n: ?' s) Z) ~
        }: z3 \# k- k5 S) R5 S
        if newBlock.PrevBlockHash != oldBlock.Hash {/ c* `+ M8 Y; ^' ^
                return false( A7 ]6 |8 I9 ~' P
        }* W% L% L* q& b7 \8 X3 |. Z: \
        if calculateHash(newBlock) != newBlock.Hash {, f4 a# b/ ~! {: r; B3 p! ~7 _
                return false0 Z1 |& M  e; b+ C
        }
; i+ @4 N7 W$ |9 R2 N        return true" C: r# g9 \9 ]& o% y& D, v
}. B+ T4 H% W: X8 l3 H8 F
实现RPC接口的交互! g# O* A: i) r4 p
  1. package main
    1 ^- h% U4 t8 C6 i
  2. & Y6 p6 W6 f5 M/ J! {& ~6 v# T
  3. import (  j: i: [3 u5 u) ?+ O! d/ F: T
  4.         "encoding/json"
    1 y6 r1 F! v, Q' ~/ X! S0 T8 A& }8 G8 ~
  5.         "BlockChain/core"
    - q) c; b9 m2 c2 c0 \& @
  6.         "io"
    1 [" w: S( Y( k4 t
  7.         "net/http"8 @0 ?0 B4 X! ~  n9 d
  8. )! ]! g5 J1 `+ b2 `/ M

  9. 6 j1 B, o- ^7 ?) g7 c, g
  10. var blockChain *core.BlockChain3 D2 E/ R) s6 h, P! W

  11.   g. z+ }4 p7 D
  12. func run() {/ q! [- r& D9 _5 x
  13.         http.HandleFunc("/block_chain/get", blockChainGetHandle)8 o/ a! p, V( v! w) h
  14.         http.HandleFunc("/block_chain/write", blockChainWriteHandle)
    , u9 u4 a  B" m0 r4 A: J) w; d4 w
  15.         http.ListenAndServe(":8332", nil)
    ) d9 h' [4 k) ]8 L8 k* r. t
  16. }
    - P7 b" ^" W+ q& m
  17. 6 p6 ?4 a2 T4 V+ m) c. E! `9 J
  18. func blockChainGetHandle(w http.ResponseWriter, r *http.Request) {
    ' ^. x: S# ~; x: O+ K6 M
  19.         bytes, err := json.Marshal(blockChain)
    - u# [% n9 r9 A* A9 }
  20.         if err != nil {/ u4 t  F5 h% O. D* C/ M  v. p$ m0 r
  21.                 http.Error(w, err.Error(), http.StatusInternalServerError)8 P! W$ \. z! ^4 r# @$ q" X
  22.                 return
      U; u' F8 D9 @  k- ~" n1 h3 s: x
  23.         }
    $ P# h4 Y/ e# z
  24.         io.WriteString(w, string(bytes))% |% t9 Y  f9 {! e5 l7 Z8 }8 O3 @; @
  25. }
    & T8 k" S3 j. y/ p

  26. / u8 e5 i- X7 v9 B" ]: \
  27. func blockChainWriteHandle(w http.ResponseWriter, r *http.Request) {! F8 o# d9 v" W) t' h
  28.         blockData := r.URL.Query().Get("data")
    5 F  y9 B9 G) j- v1 g/ t) N) h) r1 Q& w
  29.         blockChain.SendData(blockData). L/ E! e  e4 w3 N, `$ J- ~
  30.         blockChainGetHandle(w, r)
    : t5 z6 w4 j3 i- a4 D) _
  31. }
    ' i/ O/ A3 ^3 O% \. N6 W6 u6 l7 d2 s: K

  32. 2 ]9 l4 b2 J; p/ d6 @4 o% o, A
  33. func main() {
    2 [! y5 E3 j# w
  34.         blockChain = core.NewBlockChain()
    " L, s+ i4 Q6 e1 ?( V
  35.         run()
    ; y+ o4 L6 z# y4 m! M6 a
  36. }
复制代码
0 ~+ L$ V+ R: y( S7 n
通过两部分代码实现简易区块链的RPC调用
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

朋友一起走 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    16