Untuk menghasilkan blockchain dan bukan hanya database, kita perlu menambahkan 3 elemen penting ke proyek kita:
- Deskripsi struktur dan metode data blok
- Deskripsi struktur data dan metode transaksi
- Fungsi Blockchain yang menyimpan blok dalam database dan menemukannya di sana berdasarkan hash atau tingginya (atau yang lainnya).
Ini adalah artikel kedua tentang blockchain untuk industri, yang pertama
Mengingat pertanyaan yang diajukan pembaca kepada saya tentang artikel sebelumnya dalam seri ini, perlu diperhatikan: dalam hal ini, database LevelDB digunakan untuk menyimpan data blockchain, tetapi tidak ada yang menghalangi Anda untuk menggunakan yang lain, katakanlah, MySQL. Sekarang mari kita lihat struktur data ini.
Mari kita mulai dengan transaksi:
Berikut 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 dari transaksi tersebut, tipe transaksi itu sendiri, stempel waktu, serta input dan output. Input TxIn menyimpan hash dari transaksi yang outputnya direferensikan, jumlah output dan bytecode ini, dan output TxOut menyimpan beberapa nilai dan juga bytecode.
Sekarang mari kita lihat tindakan apa yang dapat dilakukan suatu transaksi pada datanya, mis. Mari kita lihat metodenya.
Untuk membuat transaksi, gunakan fungsi transaksi.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.
String fungsi internal preByteHash(bytes []byte) digunakan di Build() dan Check() untuk membuat hash transaksi yang dihasilkan kompatibel dengan hash transaksi yang dihasilkan dari aplikasi JavaScript.
Metode Build() menyetel 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 diteruskan sebagai potongan byte.
Metode Check() bool membandingkan hash yang dihasilkan dari bidang hash transaksi dengan hash yang diperoleh dari hashing transaksi ini (mengabaikan bidang hash).
Transaksi ditambahkan ke blok:
Struktur data blok lebih banyak:
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
}
DataType menyimpan tipe data, node menggunakannya dan membedakan blok dari transaksi atau data lainnya. Untuk satu blok nilainya adalah 1.
BlockHeight menyimpan ketinggian 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 umum transaksi.
MerkleRoot adalah akar dari pohon Merkle.
Selanjutnya pada kolom tersebut terdapat 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 mengambil hash dari blok sebelumnya dan ketinggian yang ditetapkan untuk blok yang dibuat di blockchain. Tipe blok juga diatur dari konstanta paket tipe:
b.DataType = types.BLOCK_TYPE.
Metode AddTx(tx *transaction.TX) menambahkan transaksi ke blok.
Metode Build() memuat nilai ke dalam bidang blok dan menghasilkan serta menyetel hashnya saat ini.
Metode ToBytesHeader() []byte mengubah header blok (tanpa transaksi) menjadi potongan byte.
Metode string ToJSON() mengonversi blok ke format JSON dalam representasi string data.
Metode kesalahan FromJSON(data []byte) memuat data dari JSON ke dalam struktur blok.
Metode Check() bool menghasilkan hash blok dan membandingkannya dengan yang ditentukan dalam bidang hash blok.
Metode string GetTxsHash() mengembalikan total hash dari semua transaksi di blok.
Metode GetMerkleRoot() menentukan akar pohon Merkle untuk transaksi dalam sebuah blok.
Metode Sign(privk string) menandatangani blok dengan kunci pribadi pembuat blok.
Metode SetHeight(height int) menulis tinggi blok ke bidang struktur blok.
Metode int GetHeight() mengembalikan ketinggian blok seperti yang ditentukan dalam bidang struktur blok yang sesuai.
Metode ToGOBBytes() []byte mengkodekan blok dalam format GOB dan mengembalikannya sebagai potongan byte.
Metode kesalahan FromGOBBytes(data []byte) menulis data blok ke struktur blok dari potongan byte yang diteruskan dalam format GOB.
Metode string GetHash() mengembalikan hash dari blok yang diberikan.
Metode string GetPrevHash() mengembalikan hash dari blok sebelumnya.
Metode SetPublicKey(pubk string) menulis kunci publik pembuat blok ke blok.
Jadi, dengan menggunakan metode objek Block, kita dapat dengan mudah mengubahnya menjadi format untuk transmisi melalui jaringan dan disimpan ke database LevelDB.
Fungsi paket blockchain 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 database dibuat satu kali ketika 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 database.
Fungsi kesalahan SetTargetBlockHash(hash string) menulis hash dari blok saat ini dengan kunci yang ditentukan oleh konstanta BLOCK_HASH ke database.
Fungsi GetTargetBlockHash() (string, error) mengembalikan hash dari blok saat ini yang disimpan dalam database.
Fungsi kesalahan SetTargetBlockHeight(height int) menulis ke database nilai tinggi blockchain untuk node dengan kunci yang ditentukan oleh konstanta BLOCK_HEIGHT.
Fungsi GetTargetBlockHeight() (int, error) mengembalikan ketinggian blockchain untuk node tertentu, yang disimpan dalam database.
Fungsi bool CheckBlock(block IBlock) memeriksa kebenaran blok sebelum menambahkan blok ini ke blockchain.
Fungsi kesalahan AddBlock(block IBlock) menambahkan blok ke blockchain.
Fungsi untuk mengambil dan melihat blok ada di file explore.go dari paket blockchain:
Fungsi GetBlockByHash(hash string) (*block.Block, error) membuat objek blok kosong, memuat blok ke dalamnya dari database, hash yang diteruskan ke sana, dan mengembalikan pointer ke sana.
Pembuatan blok genesis dilakukan oleh fungsi kesalahan Genesis() dari file genesis.go paket blockchain.
Artikel selanjutnya akan membahas tentang menghubungkan klien ke sebuah node menggunakan mekanisme WebSocket.
Sumber: www.habr.com