Xây dựng blockchain đơn giản với golang. P1 - Cấu trúc cơ bản
Blockchain
23
White

Trần Mỹ viết ngày 14/03/2018

XIn chào mọi người.

Thời gian gần đây mình có tìm hiểu về blockchain và golang. Mình viết bài viết này với mục đích chia sẻ và tổng hợp những kiến thức đã thu nạp được.

Mình dự định sẽ viết khoảng 5 phần. Ở mỗi phần mình dự định sẽ trình bày những tính chất của blockchain gắn với implement tương ứng. Đây là bài viết đầu tiên trong số đó.

Mình cũng là nhập môn với golang và blockchain, rất vui nếu nhận được góp ý từ mọi người. :smiley:

Lời nói đầu

Mình nghĩ điều này có thể hữu ích với những ai nhập môn với blockchain, nên trước khi vào bài viết mình xin chia sẻ 1 lưu ý nhỏ như sau :
Hiện nay khi ta nói là muốn xây dựng 1 ứng dụng blockchain, theo mình thì sẽ có 2 hướng đó là :

  1. Xây dựng từ đầu đến cuối
    Khi theo hướng này, ta sẽ cần viết code từ đầu đến cuối, từ hello world cho đến viết cấu hình để nó chạy ổn định trên 1 server nào đó. Theo hướng này ta sẽ khá tốn công sức. (Hoặc nếu làm về tiền ảo thì ta có thể fork từ 1 repo có sẵn trên github rồi tùy biến nó - sẽ tốn ít công sức hơn).

  2. Xây dựng dựa trên các nền tảng về blockchain
    Khi theo hướng này, ta sẽ xây dựng ứng dụng blockchain dựa trên hoặc dùng 1 nền tảng blockchain sẵn có. Với ethereum thì mình nghĩ có thể hình tượng bằng việc ta xây dựng ứng dụng với blockchain thuê từ họ. Các bạn có thể tham khảo các nền tảng sau : EthereumHyperledger, Eos

Vì mục đích tìm hiểu nên bài viết của mình sẽ đi theo hướng thứ nhất . Trong thực tế có thể bạn sẽ muốn đi theo hướng thứ 2, có thể sẽ giảm chi phí và phù hợp hơn.

Kết thúc chuỗi bài viết này, mình hi vọng thể hiện được các đặc điểm sau của blockchain :

  • Cấu trúc block
  • Network
  • Proof of work
  • Address
  • Transaction
  • Persistent

Dữ liệu mà blockchain của mình lưu sẽ mang chủ đề về tiền ảo - dữ liệu được lưu là các transactions.

Giới thiệu

Có lẽ blockchain đã là khái niệm quen thuộc với mọi người. Các bạn có thể tham khảo định nghĩa theo wikipedia

Trong bài viết này mình sẽ tập trung vào phần implement lên các tính chất của blockchain, về mặt lý thuyết mình sẽ đề cập qua khi đề cập đến các phần tương ứng.

Xây dựng

1. Cấu trúc Blockchain

Blockchain là cấu trúc chuỗi các block. Trong cấu trúc dữ liệu giải thuật có thể bạn đã làm quen với singly linked list hoặc stack. 2 cấu trúc này có thể nói là tập hợp các phần tử, mà mỗi phần tử chứa liên kết đến phần tử tiếp theo nó. Blockchain có thể nói là 1 singly linked list mà mỗi block là một phần tử.

Vậy mình sẽ implement blockchain với 1 struct tương ứng, và là ... array.

type Blockchain struct {
    blocks []*Block
}

Ở bài viết này với mục đích trình bày thật đơn giản 1 blockchain thì mình nghĩ array là phù hợp. Trong thực tế, blockchain có thể được lưu trong database hoặc file (và mỗi block tương ứng với 1 file, 1.dat, 2.dat chẳng hạn), nên cấu trúc sẽ cần điều chỉnh để phù hợp với cấu trúc lưu trữ.

Ở bài đầu tiên này mình định sẽ định nghĩa thật đơn giản cỡ hello world, và sẽ định nghĩa đầy đủ hơn ở các bài viết sau.

Bạn có thể sẽ muốn tham khảo cấu trúc blockchain của ethereum ở đây

2. Cấu trúc Block

Block là phần tử cơ bản của 1 blockchain. Mình mô hình hóa bằng cấu trúc sau :

type Block struct {
    Hash          []byte
    PrevBlockHash []byte
    Data          []byte
    Timestamp     int64
}

Các trường dữ liệu lưu trong 1 block :

  • Hash : Giá trị dùng để "chứng nhận" 1 block. 1 giá trị hash sẽ tương ứng với 1 bộ dữ liệu của block. Khi 1 bit trong block thay đổi thì giá trị hash tính ra được sẽ thay đổi theo.
  • PrevBlockHash : Giá trị hash của block trước nó. (Block đầu tiên sẽ có giá trị bằng 0)
  • Data : Dữ liệu lưu trong block. (Thực tế thường là transaction đối với tiền ảo)
  • Timestamp : Thời gian block được sinh ra.

Block đầu tiên thường được gọi là Genesis block.

3. Hàm

Mình sẽ trình bày từ hàm main() như sau :

main.go

func main() {
    bc := InitBlockchain() // Khởi tạo blockchain

    bc.AddBlock("Doraemon send 1 btc to batman")  // Thêm block
    bc.AddBlock("Batman send 2 btc to superman")  // Thêm block
    bc.AddBlock("Batman send 1 btc to girls")  // Thêm block

    fmt.Println()

    // Duyệt và in thông tin các blocks
    for _, block := range bc.blocks {
        fmt.Printf("Hash : %x\n", block.Hash)
        fmt.Printf("Data : %s\n", block.Data)
        fmt.Printf("Timestamp : %x\n", block.Timestamp)
        fmt.Printf("Previous Hash : %x\n", block.PrevBlockHash)
        fmt.Println()
    }
}

Ý đồ của mình rất đơn giản : khởi tạo 1 blockchain, thêm các block, và in ra chúng. Ý nghĩa các hàm như sau ;

blockchain.go

func InitBlockchain() *Blockchain {
    once.Do(func() {
        instantiated = &Blockchain{[]*Block{NewGenesisBlock("Genesis block")}}
    })
    return instantiated
}

InitBlockchain() khởi tạo 1 blockchain. Với block ban đầu được khởi tạo bằng NewGenesisBlock()

block.go

func NewGenesisBlock(starting string) *Block {
    return NewBlock(starting, []byte{})
}

....

func NewBlock(data string, prevBlockHash []byte) *Block {
    block := &Block{[]byte{}, prevBlockHash, []byte(data), time.Now().Unix()}
    block.SetHash()
    return block
}

NewGenesisBlock() tham chiếu đến hàm khởi tạo 1 block là NewBlock(). NewBlock() khởi tạo 1 block mới. (Ta có thể bỏ qua không dùng NewGenesisBlock() ở đây, nhưng ở các bài viết sau genesisblock có thể sẽ đặc biệt hơn block thường nên ta sẽ để 1 hàm riêng)

block.go

func (b *Block) SetHash() {
    bTimeStamp := []byte(strconv.FormatInt(b.Timestamp, 10))
    blockAsBytes := bytes.Join([][]byte{b.PrevBlockHash, b.Data, bTimeStamp}, []byte{})
    hash := sha256.Sum256(blockAsBytes)
    b.Hash = hash[:]
}

SetHash() đặt giá trị hash cho block. Ta sẽ cần các giá trị khác được khai báo trước khi SetHash() được gọi.
Thuật toán sha256 mình dùng là thuật toán mã hóa dùng nhiều trong bitcoin, nhưng ta cũng có thể dùng thuật toán khác.

Cụ thể hơn các bạn có thể tham khảo tại source code mình đã chuẩn bị ở đây

Chạy

$ ./make # hoặc go build .
$ ./simplebc # (tên file thực thi)

Hash : e853230d005fc53266564f214ab070be12cef7e69e7379d8df825e796d8fabe3
Data : Genesis block
Timestamp : 5a538edf
Previous Hash :

Hash : 0fd24c200dda690cde7c684e9132bf8282f5ddcde81592322a3817c127edeead
Data : Doraemon send 1 btc to batman
Timestamp : 5a538edf
Previous Hash : e853230d005fc53266564f214ab070be12cef7e69e7379d8df825e796d8fabe3

Hash : 8f3edc23d5f78a57b6e6ff8484e82f56b7a7509f543df7be3cca2d57587b5349
Data : Batman send 2 btc to superman
Timestamp : 5a538edf
Previous Hash : 0fd24c200dda690cde7c684e9132bf8282f5ddcde81592322a3817c127edeead

Hash : 45d12c451a618a825c123bbfc8cc9b8a31f605579063ad0d02be2b03c7957315
Data : Batman send 1 btc to girls
Timestamp : 5a538edf
Previous Hash : 8f3edc23d5f78a57b6e6ff8484e82f56b7a7509f543df7be3cca2d57587b5349

Khi chạy terminal sẽ in ra các blocks đi kèm với các thông tin của chúng.

Nội dung phần 1 của mình kết thúc tại đây :smiley:

Chi tiết cách build và cấu trúc files các bạn có thể tham khảo source code ở đây

Tổng kết

Ở phần này mình đã xây dựng 1 cấu trúc đơn giản về BlockchainBlock. Ở bài viết tiếp theo mình dự định sẽ xây dựng 1 mạng lưới mà trong đó các node có khả năng chia sẻ (1 cách rất đơn giản) blockchain của nhau.

Tham khảo

https://jeiwan.cc/posts/building-blockchain-in-go-part-1/

TranMy 30-11-2017

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Trần Mỹ

9 bài viết.
86 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
28 5
Xin chào mọi người. Thời gian ngắn gần đây mình có tìm hiểu 1 chút về Bitcoin và Blockchain, và để củng cố kiến thức thu nạp được mình quyết định ...
Trần Mỹ viết 9 tháng trước
28 5
White
15 1
Xin chào mọi người. Đây là phần 2 trong bài viết về xây dựng blockchain đơn giản với golang của mình. Ở (Link) mình đã trình bày về việc xây dựng...
Trần Mỹ viết 6 tháng trước
15 1
White
14 2
Xin chào mọi người. Đây là phần 3 trong bài viết của mình về xây dựng blockchain với ngôn ngữ Go. Các bạn có thể có thể tham khảo 2 phần trước củ...
Trần Mỹ viết 6 tháng trước
14 2
Bài viết liên quan
White
11 5
Tạm xóa
Giaosucan viết 5 tháng trước
11 5
White
10 2
Xin chào mọi người. Đây là phần 4 trong bài viết của mình về xây dựng 1 blockchain đơn giản với ngôn ngữ Go. Các bạn có thể có thể tham khảo 3 ph...
Trần Mỹ viết 5 tháng trước
10 2
White
10 4
Lời nói đầu Trong thời gian qua, với cơn sốt về giá trị của các đồng tiền ảo mà nổi bật là Bitcoin, chắc chẳn mọi người cũng dần quen thuộc với thu...
Lưu Xuân Trọng viết 3 tháng trước
10 4
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
9 bài viết.
86 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!