Untuk akhirnya menciptakan blockchain dan bukan hanya sekedar database, kita perlu menambahkan 3 elemen penting ke proyek kita:
- Deskripsi struktur data dan metode blok
- Deskripsi struktur data dan metode transaksi
- Fungsi Blockchain yang menyimpan blok dalam basis data dan menemukannya di sana berdasarkan hash atau tingginya (atau cara lain).

Ini adalah artikel kedua tentang blockchain untuk industri, yang pertama .
Mengingat pertanyaan pembaca tentang artikel sebelumnya dalam seri ini, perlu dicatat: LevelDB digunakan untuk menyimpan data blockchain dalam kasus ini, tetapi tidak ada yang menghalangi Anda untuk menggunakan basis data lain, seperti MySQL. Sekarang mari kita lihat struktur data ini.
Mari kita mulai dengan transaksi:
Berikut adalah struktur datanya:
type TX struct {
DataType byte
TxHash string
TxType byte
Timestamp int64
INs []TxIn
OUTs []TxOut
}
type TxIn struct {
ThatTxHash string
TxOutN int
ByteCode string
}
type TxOut struct {
Value int
ByteCode string
}TX menyimpan tipe data (untuk transaksi 2), hash transaksi, tipe transaksi itu sendiri, stempel waktu, serta input dan output. Input TxIn menyimpan hash dari output transaksi yang direferensikan, nomor output, dan bytecode, sementara output TxOut menyimpan nilai dan juga bytecode.
Sekarang mari kita lihat tindakan apa yang dapat dilakukan transaksi pada datanya, yaitu, mari kita menganalisis metodenya.
Untuk membuat transaksi, gunakan fungsi transaction.NewTransaction(txtype byte) *TX.
Metode AddTxIn(thattxhash[]byte, txoutn int, code[]byte)(*TxIn, error) menambahkan input ke transaksi.
Metode AddTxOut(value int, data []byte) (*TxOut, error) menambahkan output ke transaksi.
Metode ToBytes()[]byte mengubah transaksi menjadi potongan byte.
Fungsi internal preByteHash(bytes []byte) string digunakan dalam Build() dan Check() untuk membuat hash transaksi yang dihasilkan kompatibel dengan hash transaksi yang dihasilkan dari aplikasi JavaScript.
Metode Build() menetapkan hash transaksi sebagai berikut: tx.TxHash = preByteHash(tx.ToBytes()).
Metode string ToJSON() mengubah transaksi menjadi string JSON.
Metode kesalahan FromJSON(data []byte) memuat transaksi dari format JSON yang dilewatkan sebagai irisan byte.
Metode bool Check() membandingkan hash yang dihasilkan dari bidang hash transaksi dengan hash yang diperoleh dengan melakukan hash pada transaksi ini (tidak termasuk bidang hash).
Transaksi ditambahkan ke blok:
Struktur data blok lebih banyak jumlahnya:
type Block struct {
DataType byte
BlockHeight int
Timestamp int64
HeaderSize int
PrevBlockHash string
SelfBlockHash string
TxsHash string
MerkleRoot string
CreatorPublicKey string
CreatorSig string
Version int
TxsN int
Txs []transaction.TX
}Tipe Data menyimpan tipe data yang digunakan node untuk membedakan blok dari transaksi atau data lainnya. Untuk sebuah blok, nilainya adalah 1.
BlockHeight menyimpan tinggi suatu blok.
Stempel waktu stempel waktu.
HeaderSize adalah ukuran blok dalam byte.
PrevBlockHash adalah hash dari blok sebelumnya, dan SelfBlockHash adalah hash dari blok saat ini.
TxsHash adalah hash transaksi bersama.
MerkleRoot adalah akar pohon Merkle.
Kolom berikut berisi kunci publik pembuat blok, tanda tangan pembuat, versi blok, jumlah transaksi dalam blok, dan transaksi itu sendiri.
Mari kita lihat metodenya:
Untuk membuat blok, gunakan fungsi block.NewBlock(): NewBlock(prevBlockHash string, height int) *Block, yang menerima hash dari blok sebelumnya dan tinggi yang ditetapkan untuk blok yang dibuat di blockchain. Jenis blok juga ditentukan dari konstanta paket types:
b.DataType = types.BLOCK_TYPE.Metode AddTx(tx *transaction.TX) menambahkan transaksi ke suatu blok.
Metode Build() memuat nilai ke dalam bidang blok dan menghasilkan serta menetapkan hash saat ini.
Metode ToBytesHeader()[]byte menerjemahkan header blok (tanpa transaksi) menjadi irisan byte.
Metode string ToJSON() mengubah blok menjadi format JSON dalam representasi string data.
Metode kesalahan FromJSON(data []byte) memuat data dari JSON ke dalam struktur blok.
Metode bool Check() menghasilkan hash blok dan membandingkannya dengan yang ditentukan dalam bidang hash blok.
Metode string GetTxsHash() mengembalikan total hash dari semua transaksi dalam blok.
Metode GetMerkleRoot() menetapkan akar pohon Merkle untuk transaksi dalam suatu blok.
Metode Sign(privk string) menandatangani blok dengan kunci pribadi pembuat blok.
Metode SetHeight(height int) menuliskan tinggi blok ke bidang struktur blok.
Metode GetHeight() int mengembalikan tinggi blok seperti yang ditentukan dalam bidang terkait dari struktur blok.
Metode ToGOBBytes() []byte mengodekan blok dalam format GOB dan mengembalikannya sebagai irisan byte.
Metode kesalahan FromGOBBytes(data []byte) menulis data blok ke struktur blok dari potongan byte berformat GOB yang diteruskan.
Metode string GetHash() mengembalikan hash dari blok yang diberikan.
Metode string GetPrevHash() mengembalikan hash dari blok sebelumnya.
Metode SetPublicKey(pubk string) menuliskan kunci publik pembuat blok ke blok.
Jadi, dengan menggunakan metode objek Block, kita dapat dengan mudah mengubahnya ke dalam format untuk transmisi melalui jaringan dan menyimpannya ke basis data LevelDB.
Fungsi paket blockchain berikut bertanggung jawab untuk menyimpan ke blockchain:
Untuk melakukan ini, blok harus mengimplementasikan antarmuka IBlock:
type IGOBBytes interface {
ToGOBBytes() []byte
FromGOBBytes(data []byte) error
}
type IBlock interface {
IGOBBytes
GetHash() string
GetPrevHash() string
GetHeight() int
Check() bool
}Koneksi basis data dibuat sekali saat paket diinisialisasi dalam fungsi init():
db, err = leveldb.OpenFile(BLOCKCHAIN_DB_DEBUG, nil).CloseDB() adalah pembungkus untuk db.Cloce() - dipanggil setelah bekerja dengan fungsi paket untuk menutup koneksi ke basis data.
Fungsi kesalahan SetTargetBlockHash(hash string) menulis hash blok saat ini ke database dengan kunci yang ditentukan oleh konstanta BLOCK_HASH.
Fungsi GetTargetBlockHash() (string, error) mengembalikan hash blok saat ini yang disimpan dalam database.
Fungsi kesalahan SetTargetBlockHeight(height int) menuliskan nilai tinggi blockchain ke database untuk node dengan kunci yang ditentukan oleh konstanta BLOCK_HEIGHT.
Fungsi GetTargetBlockHeight() (int, error) mengembalikan tinggi blockchain untuk node tertentu, yang disimpan dalam database.
Fungsi bool CheckBlock(block IBlock) memeriksa kebenaran suatu blok sebelum menambahkan blok tersebut ke blockchain.
Fungsi kesalahan AddBlock(block IBlock) menambahkan blok ke blockchain.
Fungsi untuk mengambil dan melihat blok terletak di file explore.go dari paket blockchain:
Fungsi GetBlockByHash(hash string) (*block.Block, error) membuat objek blok kosong, memuat blok dari database yang hashnya diteruskan ke sana, dan mengembalikan penunjuk ke sana.
Pembuatan blok genesis dilakukan oleh fungsi kesalahan Genesis() dari file genesis.go paket blockchain.
Artikel berikutnya akan membahas menghubungkan klien ke node menggunakan mekanisme WebSocket.
Sumber: www.habr.com
