Bagaimana saya merancang blok dan transaksi di blockchain Go saya

Untuk akhirnya menghasilkan blockchain, dan bukan hanya database, kita perlu menambahkan 3 elemen penting ke proyek kami:

  • Deskripsi struktur data dan metode blok
  • Deskripsi struktur data dan metode transaksi
  • Fungsi Blockchain yang menyimpan blok dalam database dan menemukannya di sana dengan hash atau tinggi (atau sesuatu yang lain).

gambar

Ini adalah artikel kedua tentang blockchain untuk industri, yang pertama di sini .

Mengingat pertanyaan-pertanyaan yang diajukan pembaca kepada saya di artikel sebelumnya dari seri ini, harus dicatat: dalam kasus ini, basis data LevelDB digunakan untuk menyimpan data blockchain, tetapi tidak mengganggu penggunaan yang lain, ucapkan MySQL yang sama. Dan sekarang kita akan memahami struktur data ini.

Mari kita mulai dengan transaksi: github.com/Rusldv/bcstartup/blob/master/transaction/builder.go

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 ini, tipe transaksi itu sendiri, stempel waktu, dan juga input dan output. Input TxIn menyimpan hash transaksi yang menjadi rujukan output, jumlah output ini dan bytecode, dan output TxOut menyimpan beberapa nilai dan juga bytecode.

Sekarang mari kita lihat tindakan apa yang dapat dilakukan transaksi pada datanya, mis. mari kita menganalisis metodenya.

Untuk membuat transaksi, gunakan fungsi transaction.NewTransaction (txtype byte) * TX.

Metode AddTxIn (thattxhash [] byte, txoutn int, kode [] byte) (* TxIn, error) menambahkan input ke transaksi.

Metode AddTxOut (nilai int, data [] byte) (* TxOut, kesalahan) menambahkan output ke transaksi.

Metode ToBytes () [] byte mengubah transaksi menjadi irisan byte.

Fungsi internal string preByteHash (byte [] byte) digunakan dalam Build () dan Periksa () untuk kompatibilitas hash transaksi yang dibuat dengan hash transaksi yang dihasilkan dari aplikasi JavaScript.

Metode Build () menetapkan hash transaksi sebagai berikut: tx.TxHash = preByteHash (tx.ToBytes ()).

Metode ToJSON () string mengubah transaksi menjadi string JSON.

Metode kesalahan FromJSON (data [] byte) memuat transaksi dari format JSON yang dikirim sebagai irisan byte.

Metode Periksa () bool membandingkan hash yang diterima dari bidang hash transaksi dengan hash yang diperoleh sebagai hasil hashing transaksi ini (tidak termasuk bidang hash).

Transaksi ditambahkan ke blok: github.com/Rusldv/bcstartup/blob/master/block/builder.go

Struktur data blok ini lebih produktif:

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, simpul di atasnya, dan melepaskan blok dari transaksi atau data lainnya. Untuk blok, nilai ini adalah 1.

BlockHeight menyimpan ketinggian blok.
Stempel waktu stempel waktu.
Ukuran blok HeaderSize dalam byte.
PrevBlockHash hash dari blok sebelumnya, dan SelfBlockHash - saat ini.
TxsHash adalah hash transaksi yang umum.
MerkleRoot - Akar pohon Merkle.

Berikutnya dalam bidang adalah kunci publik pencipta blok, tanda tangan pencipta, versi blok, jumlah transaksi dalam blok dan transaksi ini sendiri.

Pertimbangkan metodenya:
Fungsi block.NewBlock () digunakan untuk membuat blok: NewBlock (prevBlockHash string, height int) * Block, yang mengambil hash dari blok sebelumnya dan ketinggian yang ditetapkan untuk blok yang dibuat di blockchain. Tipe blok dari konstanta paket tipe juga disetel:
b.DataType = types.BLOCK_TYPE.


Metode AddTx (tx * transaction.TX) menambahkan transaksi ke blok.

Metode Build () memuat nilai ke bidang blok dan menghasilkan dan menetapkan hash saat ini.

Metode byte ToBytesHeader () [] menerjemahkan header blok (tanpa transaksi) menjadi irisan byte.

Metode ToJSON () dari string menerjemahkan blok ke dalam format JSON dalam representasi string dari data.

Metode kesalahan FromJSON (data [] byte) memuat data dari JSON ke dalam struktur blok.

Metode Periksa () bool menghasilkan hash blok dan membandingkannya dengan yang ditentukan dalam bidang hash blok.

Metode string GetTxsHash () mengembalikan hash umum dari semua transaksi di blok.

Metode GetMerkleRoot () menetapkan akar pohon Merkle untuk transaksi di blok.

Metode Tanda (string privk) menandatangani blok dengan kunci pribadi pembuat blok.

Metode SetHeight (tinggi int) menulis ketinggian blok ke bidang struktur blok.

Metode int GetHeight () mengembalikan ketinggian blok seperti yang ditunjukkan dalam bidang yang sesuai dari struktur blok.

Metode byte ToGOBBytes () [] mengkodekan blok dalam format GOB dan mengembalikannya sebagai irisan byte.

Metode kesalahan FromGOBBytes (data [] byte) menulis data blok ke struktur blok dari slice byte yang ditransmisikan dalam format GOB.

String metode GetHash () mengembalikan hash dari blok ini.

String metode GetPrevHash () mengembalikan hash dari blok sebelumnya.

Metode SetPublicKey (string pubk) menulis kunci publik pencipta blok ke blok.

Jadi, dengan menggunakan metode objek Block, kita dapat dengan mudah mengonversinya menjadi format untuk transmisi melalui jaringan dan menyimpannya ke basis data LevelDB.

Fungsi paket blockchain bertanggung jawab untuk menyimpan ke blockchain: github.com/Rusldv/bcstartup/tree/master/blockchain.

Untuk 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 sekali selama inisialisasi paket 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 database.

Fungsi kesalahan SetTargetBlockHash (hash string) menulis hash dari blok saat ini dengan kunci yang ditentukan oleh konstanta BLOCK_HASH dalam database.

Fungsi GetTargetBlockHash () (string, error) mengembalikan hash dari blok saat ini yang disimpan dalam database.

Fungsi kesalahan SetTargetBlockHeight (height int) menulis ke database nilai ketinggian 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 (blok IBlock) memeriksa kebenaran blok sebelum menambahkan blok ini ke blockchain.

Fungsi kesalahan AddBlock (blok IBlock) menambahkan blok ke blockchain.

Fungsi untuk menerima dan melihat blok terletak di file explore.go dari paket blockchain:

Fungsi GetBlockByHash (hash string) (* block.Block, error) menciptakan objek blok kosong, memuat blok dari database yang hash dilewatkan ke sana dan mengembalikan pointer ke sana.

Blok genesis dibuat oleh fungsi kesalahan Genesis () dari file genesis.go dari paket blockchain.

Pada artikel selanjutnya, kita akan berbicara tentang menghubungkan ke node klien menggunakan mekanisme WebSocket.

All Articles