Как я ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π» Π±Π»ΠΎΠΊΠΈ ΠΈ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ Π² своСм Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π΅ Π½Π° Go

Для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π² ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎΠΌ счСтС получиляся Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½, Π° Π½Π΅ просто Π±Π°Π·Π° Π΄Π°Π½Π½Ρ‹Ρ…, Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π² свой ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ 3 Π²Π°ΠΆΠ½Ρ‹Ρ… элСмСнта:

  • ОписаниС структуры Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² Π±Π»ΠΎΠΊΠ°
  • ОписаниС структуры Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ
  • Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡΠΎΡ…Ρ€Π°Π½ΡΡŽΡ‚ Π±Π»ΠΎΠΊΠΈ Π² Π‘Π” ΠΈ находят ΠΈΡ… Ρ‚Π°ΠΌ ΠΏΠΎ ΠΈΡ… Ρ…Π΅ΡˆΡƒ ΠΈΠ»ΠΈ высотС (ΠΈΠ»ΠΈ Π΅Ρ‰Π΅ ΠΊΠ°ΠΊ Π½ΠΈΠ±ΡƒΠ΄ΡŒ).

Как я ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π» Π±Π»ΠΎΠΊΠΈ ΠΈ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ Π² своСм Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π΅ Π½Π° Go

Π­Ρ‚ΠΎ вторая ΡΡ‚Π°Ρ‚ΡŒΡ ΠΏΡ€ΠΎ Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½ для ΠΏΡ€ΠΎΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΎΡΡ‚ΠΈ, пСрвая Ρ‚ΡƒΡ‚.

Вспоминая вопросы, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠ½Π΅ Π·Π°Π΄Π°Π²Π°Π»ΠΈ Ρ‡ΠΈΡ‚Π°Ρ‚Π΅Π»ΠΈ ΠΊ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅ этого Ρ†ΠΈΠΊΠ»Π°, слСдуСт ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ: для хранСния Π΄Π°Π½Π½Ρ‹Ρ… Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π° Π² Π΄Π°Π½Π½ΠΎΠΌ случаС ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π±Π°Π·Π° Π΄Π°Π½Π½Ρ‹Ρ… LevelDB, Π½ΠΎ Π½ΠΈ Ρ‡Π΅Π³ΠΎ Π½Π΅ ΠΌΠ΅ΡˆΠ°Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π»ΡŽΠ±ΡƒΡŽ Π΄Ρ€ΡƒΠ³ΡƒΡŽ, скаТСм Ρ‚Ρƒ ΠΆΠ΅ MySQL. А Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ разбСрСмся со структурой этих Π΄Π°Π½Π½Ρ‹Ρ….

НачнСм с Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ: github.com/Rusldv/bcstartup/blob/master/transaction/builder.go

Π’ΠΎΡ‚ Π΅Π΅ структура Π΄Π°Π½Π½Ρ‹Ρ…:

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 хранятся Ρ‚ΠΈΠΏ Π΄Π°Π½Π½Ρ‹Ρ… (для Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ 2), Ρ…Π΅Ρˆ этой Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ, Ρ‚ΠΈΠΏ самой Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ, врСмСнная ΠΌΠ΅Ρ‚ΠΊΠ°, Π° Ρ‚Π°ΠΊΠΆΠ΅ Π²Ρ…ΠΎΠ΄Ρ‹ ΠΈ Π²Ρ‹Ρ…ΠΎΠ΄Ρ‹. Π’Ρ…ΠΎΠ΄Ρ‹ TxIn хранят Ρ…Π΅Ρˆ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ, Π½Π° Π²Ρ‹Ρ…ΠΎΠ΄ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΡΡΡ‹Π»Π°ΡŽΡ‚ΡΡ, Π½ΠΎΠΌΠ΅Ρ€ этого Π²Ρ‹Ρ…ΠΎΠ΄Π° ΠΈ Π±Π°ΠΉΡ‚ΠΊΠΎΠ΄, Π° Π²Ρ‹Ρ…ΠΎΠ΄Ρ‹ TxOut хранят, ΠΊΠ°ΠΊΠΎΠ΅-Π½ΠΈΠ±ΡƒΠ΄ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈ Ρ‚ΠΎΠΆΠ΅ Π±Π°ΠΉΡ‚ΠΊΠΎΠ΄.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ посмотрим ΠΊΠ°ΠΊΠΈΠ΅ дСйствия Π½Π°Π΄ своими Π΄Π°Π½Π½Ρ‹ΠΌΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ транзакция, Ρ‚.Π΅. Ρ€Π°Π·Π±Π΅Ρ€Π΅ΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹.

Для создания Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ слуТит функция transaction.NewTransaction(txtype byte) *TX.

ΠœΠ΅Ρ‚ΠΎΠ΄ AddTxIn(thattxhash []byte, txoutn int, code []byte) (*TxIn, error) добавляСт Π²Ρ…ΠΎΠ΄ ΠΊ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ.

ΠœΠ΅Ρ‚ΠΎΠ΄ AddTxOut(value int, data []byte) (*TxOut, error) добавляСт Π²Ρ‹Ρ…ΠΎΠ΄ ΠΊ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ.

ΠœΠ΅Ρ‚ΠΎΠ΄ ToBytes() []byte ΠΏΡ€Π΅Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ Π² Π±Π°ΠΉΡ‚ΠΎΠ²Ρ‹ΠΉ срСз.

ВнутрСнняя функция preByteHash(bytes []byte) string примСняСтся Π² Build() ΠΈ Check() для совмСстимости создаваСмого Ρ…Π΅ΡˆΠ° Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ с Ρ…Π΅ΡˆΠ°ΠΌΠΈ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΌΠΈ ΠΈΠ· ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π½Π° JavaScript.

ΠœΠ΅Ρ‚ΠΎΠ΄ Build() Π·Π°Π΄Π°Π΅Ρ‚ Ρ…Π΅Ρˆ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ: tx.TxHash = preByteHash(tx.ToBytes()).

ΠœΠ΅Ρ‚ΠΎΠ΄ ToJSON() string ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ Π² JSON строку.

ΠœΠ΅Ρ‚ΠΎΠ΄ FromJSON(data []byte) error Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ ΠΈΠ· Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° JSON, ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΠΎΠ³ΠΎ Π² Π²ΠΈΠ΄Π΅ Π±Π°ΠΉΡ‚ΠΎΠ²ΠΎΠ³ΠΎ слайса.

ΠœΠ΅Ρ‚ΠΎΠ΄ Check() bool сравниваСт ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Ρ… Ρ…Π΅Ρˆ ΠΈΠ· поля Ρ…Π΅ΡˆΠ° Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ с Ρ…Π΅ΡˆΠ΅ΠΌ, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹ΠΌ Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ Ρ…Π΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ этой Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ (Π±Π΅Π· ΡƒΡ‡Π΅Ρ‚Π° поля Ρ…Π΅ΡˆΠ°).

Π’Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ Π΄ΠΎΠ±Π°Π²Π»ΡΡŽΡ‚ΡΡ Π² Π±Π»ΠΎΠΊ: github.com/Rusldv/bcstartup/blob/master/block/builder.go

Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° Π΄Π°Π½Π½Ρ‹Ρ… Π±Π»ΠΎΠΊΠ° Π±ΠΎΠ»Π΅Π΅ объСмная:

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 Ρ…Ρ€Π°Π½ΠΈΡ‚ Ρ‚ΠΈΠΏ Π΄Π°Π½Π½Ρ‹Ρ…, ΠΏΠΎ Π½Π΅ΠΌΡƒ Π½ΠΎΠ΄Π° ΠΈ ΠΎΡ‚Π»Π΅Ρ‡Π°Π΅Ρ‚ Π±Π»ΠΎΠΊ ΠΎΡ‚ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ ΠΈΠ»ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΡ… Π΄Π°Π½Π½Ρ‹Ρ…. Для Π±Π»ΠΎΠΊΠ° это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ€Π°Π²Π½ΠΎ 1.

BlockHeight Ρ…Ρ€Π°Π½ΠΈΡ‚ высоту Π±Π»ΠΎΠΊΠ°.
Timestamp Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ ΠΌΠ΅Ρ‚ΠΊΡƒ.
HeaderSize Ρ€Π°Π·ΠΌΠ΅Ρ€ Π±Π»ΠΎΠΊΠ° Π² Π±Π°ΠΉΡ‚Π°Ρ….
PrevBlockHash Ρ…Π΅Ρˆ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π³ΠΎ Π±Π»ΠΎΠΊΠ°, Π° SelfBlockHash β€” Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ.
TxsHash β€” это ΠΎΠ±Ρ‰ΠΈΠΉ Ρ…Π΅Ρˆ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ.
MerkleRoot β€” ΠΊΠΎΡ€Π΅Π½ΡŒ Π΄Π΅Ρ€Π΅Π²Π° ΠœΠ΅Ρ€ΠΊΠ»Π°.

Π”Π°Π»Π΅Π΅ Π² полях находится ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ ΠΊΠ»ΡŽΡ‡ создатСля Π±Π»ΠΎΠΊΠ°, подпись создатСля, вСрсия Π±Π»ΠΎΠΊΠ°, количСство Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ Π² Π±Π»ΠΎΠΊΠ΅ ΠΈ собствСнно сами эти Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ.

Рассмотрим Π΅Π³ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹:
Для создания Π±Π»ΠΎΠΊΠ° примСняСтся функция block.NewBlock(): NewBlock(prevBlockHash string, height int) *Block, которая ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Ρ…Π΅Ρˆ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π³ΠΎ Π±Π»ΠΎΠΊΠ° ΠΈ высоту ΡƒΡΡ‚Π°Π½ΠΎΠ²Π»Π΅Π½Π½ΡƒΡŽ для созданного Π±Π»ΠΎΠΊΠ° Π² Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π΅. Π’Π°ΠΊΠΆΠ΅ задаСтся Ρ‚ΠΈΠΏ Π±Π»ΠΎΠΊΠ° ΠΈΠ· константы ΠΏΠ°ΠΊΠ΅Ρ‚Π° types:

b.DataType = types.BLOCK_TYPE.

ΠœΠ΅Ρ‚ΠΎΠ΄ AddTx(tx *transaction.TX) добавляСт Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ Π² Π±Π»ΠΎΠΊ.

ΠœΠ΅Ρ‚ΠΎΠ΄ Build() Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ значСния Π² поля Π±Π»ΠΎΠΊΠ° ΠΈ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΈ устанавливаСт Π΅Π³ΠΎ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ Ρ…Π΅Ρˆ.

ΠœΠ΅Ρ‚ΠΎΠ΄ ToBytesHeader() []byte ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΈΡ‚ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Π±Π»ΠΎΠΊΠ° (Π±Π΅Π· Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ) Π² Π±Π°ΠΉΡ‚ΠΎΠ²Ρ‹ΠΉ слайс.

ΠœΠ΅Ρ‚ΠΎΠ΄ ToJSON() string ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΈΡ‚ Π±Π»ΠΎΠΊ Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ JSON Π² строковом прСдставлСнии Π΄Π°Π½Π½Ρ‹Ρ….

ΠœΠ΅Ρ‚ΠΎΠ΄ FromJSON(data []byte) error Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ· JSON Π² структуру Π±Π»ΠΎΠΊΠ°.

ΠœΠ΅Ρ‚ΠΎΠ΄ Check() bool Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ…Π΅Ρˆ Π±Π»ΠΎΠΊΠ° ΠΈ сравниваСт с Π·Π°Π΄Π°Π½Π½Ρ‹ΠΌ Π² ΠΏΠΎΠ»Π΅ Ρ…Π΅ΡˆΠ° Π±Π»ΠΎΠΊΠ°.

ΠœΠ΅Ρ‚ΠΎΠ΄ GetTxsHash() string Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΎΠ±Ρ‰ΠΈΠΉ Ρ…Π΅Ρˆ всСх Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ Π² Π±Π»ΠΎΠΊΠ΅.

ΠœΠ΅Ρ‚ΠΎΠ΄ GetMerkleRoot() Π·Π°Π΄Π°Π΅Ρ‚ ΠΊΠΎΡ€Π΅Π½ΡŒ Π΄Π΅Ρ€Π΅Π²Π° ΠœΠ΅Ρ€ΠΊΠ»Π° для Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ Π² Π±Π»ΠΎΠΊΠ΅.

ΠœΠ΅Ρ‚ΠΎΠ΄ Sign(privk string) подписываСт Π±Π»ΠΎΠΊ ΠΏΡ€ΠΈΠ²Π°Ρ‚Π½Ρ‹ΠΌ клюСм создатСля Π±Π»ΠΎΠΊΠ°.

ΠœΠ΅Ρ‚ΠΎΠ΄ SetHeight(height int) записываСт высоту Π±Π»ΠΎΠΊΠ° Π² ΠΏΠΎΠ»Π΅ структуры Π±Π»ΠΎΠΊΠ°.

ΠœΠ΅Ρ‚ΠΎΠ΄ GetHeight() int Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ высоту Π±Π»ΠΎΠΊΠ° Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΡƒΠΊΠ°Π·Π°Π½ΠΎ Π² ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΠΎΠ»Π΅ структуры Π±Π»ΠΎΠΊΠ°.

ΠœΠ΅Ρ‚ΠΎΠ΄ ToGOBBytes() []byte ΠΊΠΎΠ΄ΠΈΡ€ΡƒΠ΅Ρ‚ Π±Π»ΠΎΠΊ Π² GOB Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π΅Π³ΠΎ Π² Π²ΠΈΠ΄Π΅ Π±Π°ΠΉΡ‚ΠΎΠ²ΠΎΠ³ΠΎ слайса.

ΠœΠ΅Ρ‚ΠΎΠ΄ FromGOBBytes(data []byte) error записываСт Π΄Π°Π½Π½Ρ‹Π΅ Π±Π»ΠΎΠΊΠ° Π² структуру Π±Π»ΠΎΠΊΠ° ΠΈΠ· ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΠΎΠ³ΠΎ Π±Π°ΠΉΡ‚ΠΎΠ²ΠΎΠ³ΠΎ слайса Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ GOB.

ΠœΠ΅Ρ‚ΠΎΠ΄ GetHash() string Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ…Π΅Ρˆ Π΄Π°Π½Π½ΠΎΠ³ΠΎ Π±Π»ΠΎΠΊΠ°.

ΠœΠ΅Ρ‚ΠΎΠ΄ GetPrevHash() string Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ…Π΅Ρˆ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π³ΠΎ Π±Π»ΠΎΠΊΠ°.

ΠœΠ΅Ρ‚ΠΎΠ΄ SetPublicKey(pubk string) записываСт Π² Π±Π»ΠΎΠΊ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ ΠΊΠ»ΡŽΡ‡ создатСля Π±Π»ΠΎΠΊΠ°.

Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Block ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π»Π΅Π³ΠΊΠΎ ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ для ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ ΠΏΠΎ сСти ΠΈ сохранСния Π² Π±Π°Π·Ρƒ Π΄Π°Π½Π½Ρ‹Ρ… LevelDB.

Π—Π° сохранСния Π² Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½ ΠΎΡ‚Π²Π΅Ρ‡Π°ΡŽΡ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΠ°ΠΊΠ΅Ρ‚Π° blockchain: github.com/Rusldv/bcstartup/tree/master/blockchain

Для этого Π±Π»ΠΎΠΊ Π΄ΠΎΠ»ΠΆΠ΅Π½ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Ρ‹Π²Π°Ρ‚ΡŒ интСрфСйс IBlock:

type IGOBBytes interface {
	ToGOBBytes() []byte
	FromGOBBytes(data []byte) error
}

type IBlock interface {
	IGOBBytes
	GetHash() string
	GetPrevHash() string
	GetHeight() int
	Check() bool

}

ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊ Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ… создаСтся ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π· ΠΏΡ€ΠΈ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΠ°ΠΊΠ΅Ρ‚Π° Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ init():

db, err = leveldb.OpenFile(BLOCKCHAIN_DB_DEBUG, nil).

CloseDB() это ΠΎΠ±Π΅Ρ€Ρ‚ΠΊΠ° для db.Cloce() β€” вызываСтся послС Ρ€Π°Π±ΠΎΡ‚Ρ‹ с функциями ΠΏΠ°ΠΊΠ΅Ρ‚Π°, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΡŒ соСдинСниС с Π‘Π”.

Ѐункция SetTargetBlockHash(hash string) error записываСт Π² Π‘Π” Ρ…Π΅Ρˆ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ Π±Π»ΠΎΠΊΠ° с ΠΊΠ»ΡŽΡ‡Π΅ΠΌ Π·Π°Π΄Π°Π½Π½Ρ‹ΠΌ константой BLOCK_HASH.

Ѐункция GetTargetBlockHash() (string, error) Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ…Π΅Ρˆ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ Π±Π»ΠΎΠΊΠ°, хранящийся Π² Π‘Π”.

Ѐункция SetTargetBlockHeight(height int) error записываСт Π² Π‘Π” Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ высоты Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π° для Π½ΠΎΠ΄Ρ‹ с ΠΊΠ»ΡŽΡ‡Π΅ΠΌ Π·Π°Π΄Π°Π½Π½Ρ‹ΠΌ константой BLOCK_HEIGHT.

Ѐункция GetTargetBlockHeight() (int, error) Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ высоту Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π° для Π΄Π°Π½Π½ΠΎΠΉ Π½ΠΎΠ΄Ρ‹, Ρ…Ρ€Π°Π½ΠΈΠΌΡƒΡŽ Π² Π‘Π”.

Ѐункция CheckBlock(block IBlock) bool выполняСт ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ Π±Π»ΠΎΠΊΠ° Π½Π° ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΡΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π΄ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ΠΌ этого Π±Π»ΠΎΠΊΠ° Π² Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½.

Ѐункция AddBlock(block IBlock) error добавляСт Π±Π»ΠΎΠΊ Π² Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½.

Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ для получСния ΠΈ просмотра Π±Π»ΠΎΠΊΠΎΠ² находятся Π² Ρ„Π°ΠΉΠ»Π΅ explore.go ΠΏΠ°ΠΊΠ΅Ρ‚Π° blockchain:

Ѐункция GetBlockByHash(hash string) (*block.Block, error) создаСт пустой ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π±Π»ΠΎΠΊΠ°, Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ Ρ‚ΡƒΠ΄Π° Π±Π»ΠΎΠΊ ΠΈΠ· Π‘Π” Ρ…Π΅Ρˆ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π΅ΠΉ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½ ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π½Π° Π½Π΅Π³ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ.

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π±Π»ΠΎΠΊΠ° гСнСзиса осущСствляСтся Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ Genesis() error ΠΈΠ· Ρ„Π°ΠΉΠ»Π° genesis.go ΠΏΠ°ΠΊΠ΅Ρ‚Π° blockchain.

Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅ Ρ€Π΅Ρ‡ΡŒ ΠΏΠΎΠΉΠ΄Π΅Ρ‚ ΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡŽ ΠΊ Π½ΠΎΠ΄Π΅ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° WebSocket.

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com