ืื™ืš ืขื™ืฆื‘ืชื™ ื‘ืœื•ืงื™ื ื•ืขืกืงืื•ืช ื‘ื‘ืœื•ืงืฆ'ื™ื™ืŸ Go ืฉืœื™

ื›ื“ื™ ื‘ืกื•ืคื• ืฉืœ ื“ื‘ืจ ืœื”ื’ื™ืข ืœื‘ืœื•ืงืฆ'ื™ื™ืŸ ื•ืœื ืจืง ืœืžืกื“ ื ืชื•ื ื™ื, ืขืœื™ื ื• ืœื”ื•ืกื™ืฃ 3 ืืœืžื ื˜ื™ื ื—ืฉื•ื‘ื™ื ืœืคืจื•ื™ืงื˜ ืฉืœื ื•:

  • ืชื™ืื•ืจ ืžื‘ื ื” ื ืชื•ื ื™ ื”ื‘ืœื•ืง ื•ื”ืฉื™ื˜ื•ืช
  • ืชื™ืื•ืจ ืžื‘ื ื” ื”ื ืชื•ื ื™ื ื•ืฉื™ื˜ื•ืช ื”ืขืกืงืื•ืช
  • ืคื•ื ืงืฆื™ื•ืช ื‘ืœื•ืงืฆ'ื™ื™ืŸ ืฉืฉื•ืžืจื•ืช ื‘ืœื•ืงื™ื ื‘ืžืกื“ ื ืชื•ื ื™ื ื•ืžื•ืฆืื•ืช ืื•ืชื ืฉื ืœืคื™ ื”-hash ืื• ื”ื’ื•ื‘ื” ืฉืœื”ื (ืื• ืžืฉื”ื• ืื—ืจ).

ืื™ืš ืขื™ืฆื‘ืชื™ ื‘ืœื•ืงื™ื ื•ืขืกืงืื•ืช ื‘ื‘ืœื•ืงืฆ'ื™ื™ืŸ 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), ื”-hash ืฉืœ ืื•ืชื” ืขืกืงื”, ืกื•ื’ ื”ืขืกืงื” ืขืฆืžื”, ื—ื•ืชืžืช ื–ืžืŸ ื•ื›ื ื™ืกื•ืช ื•ืคืœื˜ื™ื. ื›ื ื™ืกื•ืช TxIn ืžืื—ืกื ื•ืช ืืช ื”-hash ืฉืœ ื”ืขืกืงื” ืฉื”ืคืœื˜ ืฉืœื” ืžื•ืคื ื”, ืืช ืžืกืคืจ ื”ืคืœื˜ ื•ื”-bytecode, ื•ื™ืฆื™ืื•ืช 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) ืžืฉืžืฉืช ื‘-Build() ื•ื‘-Check() ื›ื“ื™ ืœื”ืคื•ืš ืืช ื”-hash ืฉืœ ื”ืขืกืงื” ืฉื ื•ืฆืจ ืœืชื•ืื ืœ-hash ืฉืœ ื˜ืจื ื–ืงืฆื™ื•ืช ืฉื ื•ืฆืจื• ืžื™ื™ืฉื•ืžื™ JavaScript.

ื”ืฉื™ื˜ื” Build() ืžื’ื“ื™ืจื” ืืช ื”-hash ืฉืœ ื”ืขืกืงื” ื‘ืื•ืคืŸ ื”ื‘ื: tx.TxHash = preByteHash(tx.ToBytes()).

ืฉื™ื˜ืช ื”ืžื—ืจื•ื–ืช ToJSON() ืžืžื™ืจื” ืขืกืงื” ืœืžื—ืจื•ื–ืช JSON.

ืฉื™ื˜ืช ื”ืฉื’ื™ืื” FromJSON(data []byte) ื˜ื•ืขื ืช ืขืกืงื” ืžืคื•ืจืžื˜ JSON ื”ืžื•ืขื‘ืจ ื›ืคืจื•ืกืช ื‘ืชื™ื.

ืฉื™ื˜ืช Check() bool ืžืฉื•ื•ื” ืืช ื”-hash ื”ืžืชืงื‘ืœ ืžืฉื“ื” ื”-hash ืฉืœ ื”ื˜ืจื ื–ืงืฆื™ื” ืขื ื”-hash ื”ืžืชืงื‘ืœ ื›ืชื•ืฆืื” ืžื”-hash ืฉืœ ื”ื˜ืจื ื–ืงืฆื™ื” ื”ื–ื• (ื”ืชืขืœืžื•ืช ืžืฉื“ื” ื”-hash).

ืขืกืงืื•ืช ืžืชื•ื•ืกืคื•ืช ืœื‘ืœื•ืง: 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 ืžืื—ืกืŸ ืืช ื’ื•ื‘ื” ื”ื‘ืœื•ืง.
ื—ื•ืชืžืช ื–ืžืŸ.
HeaderSize ื”ื•ื ื’ื•ื“ืœ ื”ื‘ืœื•ืง ื‘ื‘ืชื™ื.
PrevBlockHash ื”ื•ื ื”-hash ืฉืœ ื”ื‘ืœื•ืง ื”ืงื•ื“ื, ื•-SelfBlockHash ื”ื•ื ื”-hash ืฉืœ ื”ื‘ืœื•ืง ื”ื ื•ื›ื—ื™.
TxsHash ื”ื•ื ื’ื™ื‘ื•ื‘ ื›ืœืœื™ ืฉืœ ืขืกืงืื•ืช.
MerkleRoot ื”ื•ื ื”ืฉื•ืจืฉ ืฉืœ ืขืฅ ืžืจืงืœ.

ื‘ื”ืžืฉืš ื”ืฉื“ื•ืช ื™ืฉ ืืช ื”ืžืคืชื— ื”ืฆื™ื‘ื•ืจื™ ืฉืœ ื™ื•ืฆืจ ื”ื‘ืœื•ืง, ื—ืชื™ืžืช ื”ื™ื•ืฆืจ, ื’ืจืกืช ื”ื‘ืœื•ืง, ืžืกืคืจ ื”ืขืกืงืื•ืช ื‘ื‘ืœื•ืง ื•ืขืกืงืื•ืช ืืœื• ืขืฆืžืŸ.

ื‘ื•ืื• ื ืกืชื›ืœ ืขืœ ื”ืฉื™ื˜ื•ืช ืฉืœื•:
ื›ื“ื™ ืœื™ืฆื•ืจ ื‘ืœื•ืง, ื”ืฉืชืžืฉ ื‘ืคื•ื ืงืฆื™ื” block.NewBlock(): NewBlock(prevBlockHash string, height int) *Block, ืฉืœื•ืงื— ืืช ื”-hash ืฉืœ ื”ื‘ืœื•ืง ื”ืงื•ื“ื ื•ืืช ื”ื’ื•ื‘ื” ืฉื ืงื‘ืข ืœื‘ืœื•ืง ืฉื ื•ืฆืจ ื‘ื‘ืœื•ืงืฆ'ื™ื™ืŸ. ืกื•ื’ ื”ื‘ืœื•ืง ื ืงื‘ืข ื’ื ืžืชื•ืš ืงื‘ื•ืข ื—ื‘ื™ืœืช ื”ืกื•ื’ื™ื:

b.DataType = types.BLOCK_TYPE.

ื”ืฉื™ื˜ื” AddTx(tx *transaction.TX) ืžื•ืกื™ืคื” ื˜ืจื ื–ืงืฆื™ื” ืœื‘ืœื•ืง.

ืฉื™ื˜ืช Build() ื˜ื•ืขื ืช ืขืจื›ื™ื ืœืฉื“ื•ืช ื”ื‘ืœื•ืง ื•ื™ื•ืฆืจืช ื•ืžื’ื“ื™ืจื” ืืช ื”-hash ื”ื ื•ื›ื—ื™ ืฉืœื•.

ื”ืฉื™ื˜ื” ToBytesHeader() []byte ืžืžื™ืจื” ืืช ื›ื•ืชืจืช ื”ื‘ืœื•ืง (ืœืœื ื˜ืจื ื–ืงืฆื™ื•ืช) ืœืคืจื•ืกืช ื‘ืชื™ื.

ืฉื™ื˜ืช ื”ืžื—ืจื•ื–ืช ToJSON() ืžืžื™ืจื” ืืช ื”ื‘ืœื•ืง ืœืคื•ืจืžื˜ JSON ื‘ื™ื™ืฆื•ื’ ืžื—ืจื•ื–ืช ืฉืœ ื”ื ืชื•ื ื™ื.

ืฉื™ื˜ืช ื”ืฉื’ื™ืื” FromJSON(data []byte) ื˜ื•ืขื ืช ื ืชื•ื ื™ื ืž-JSON ืœืžื‘ื ื” ื‘ืœื•ืง.

ื”ืฉื™ื˜ื” Check() bool ืžื™ื™ืฆืจืช ื’ื™ื‘ื•ื‘ ืฉืœ ื‘ืœื•ืง ื•ืžืฉื•ื•ื” ืื•ืชื• ืœื–ื” ืฉืฆื•ื™ืŸ ื‘ืฉื“ื” ื”ื’ื™ื‘ื•ื‘ ืฉืœ ื”ื‘ืœื•ืง.

ืฉื™ื˜ืช ื”ืžื—ืจื•ื–ืช GetTxsHash() ืžื—ื–ื™ืจื” ืืช ืกืš ื”-hash ืฉืœ ื›ืœ ื”ืขืกืงืื•ืช ื‘ื‘ืœื•ืง.

ื”ืฉื™ื˜ื” GetMerkleRoot() ืžืฆื™ื™ื ืช ืืช ื”ืฉื•ืจืฉ ืฉืœ ืขืฅ Merkle ืขื‘ื•ืจ ืขืกืงืื•ืช ื‘ื‘ืœื•ืง.

ืฉื™ื˜ืช Sign(privk string) ื—ื•ืชืžืช ื‘ืœื•ืง ืขื ื”ืžืคืชื— ื”ืคืจื˜ื™ ืฉืœ ื™ื•ืฆืจ ื”ื‘ืœื•ืง.

ืฉื™ื˜ืช SetHeight(height int) ื›ื•ืชื‘ืช ืืช ื’ื•ื‘ื” ื”ื‘ืœื•ืง ืœืฉื“ื” ืžื‘ื ื” ื”ื‘ืœื•ืง.

ื”ืฉื™ื˜ื” GetHeight() int ืžื—ื–ื™ืจื” ืืช ื’ื•ื‘ื” ื”ื‘ืœื•ืง ื›ืคื™ ืฉืฆื•ื™ืŸ ื‘ืฉื“ื” ื”ืžืชืื™ื ืฉืœ ืžื‘ื ื” ื”ื‘ืœื•ืง.

ืฉื™ื˜ืช ToGOBBytes() []byte ืžืงื•ื“ื“ืช ื‘ืœื•ืง ื‘ืคื•ืจืžื˜ GOB ื•ืžื—ื–ื™ืจื” ืื•ืชื• ื›ืคืจื•ืกืช ื‘ืชื™ื.

ืฉื™ื˜ืช ื”ืฉื’ื™ืื” FromGOBBytes(data []byte) ื›ื•ืชื‘ืช ื ืชื•ื ื™ ื‘ืœื•ืง ืœืžื‘ื ื” ื”ื‘ืœื•ืง ืžืคืจื•ืกืช ื”ื‘ืชื™ื ื”ืžื•ืขื‘ืจืช ื‘ืคื•ืจืžื˜ GOB.

ืฉื™ื˜ืช ื”ืžื—ืจื•ื–ืช GetHash() ืžื—ื–ื™ืจื” ืืช ื”-hash ืฉืœ ื”ื‘ืœื•ืง ื”ื ืชื•ืŸ.

ืฉื™ื˜ืช ื”ืžื—ืจื•ื–ืช GetPrevHash() ืžื—ื–ื™ืจื” ืืช ื”-hash ืฉืœ ื”ื‘ืœื•ืง ื”ืงื•ื“ื.

ืฉื™ื˜ืช SetPublicKey(pubk string) ื›ื•ืชื‘ืช ืืช ื”ืžืคืชื— ื”ืฆื™ื‘ื•ืจื™ ืฉืœ ื™ื•ืฆืจ ื”ื‘ืœื•ืง ืœื‘ืœื•ืง.

ื›ืš, ื‘ืืžืฆืขื•ืช ื”ืฉื™ื˜ื•ืช ืฉืœ ืื•ื‘ื™ื™ืงื˜ ื”-Block, ื ื•ื›ืœ ืœื”ืžื™ืจ ืื•ืชื• ื‘ืงืœื•ืช ืœืคื•ืจืžื˜ ืœืฉื™ื“ื•ืจ ื“ืจืš ื”ืจืฉืช ื•ืœืฉืžื™ืจื” ื‘ืžืกื“ ื”ื ืชื•ื ื™ื LevelDB.

ื”ืคื•ื ืงืฆื™ื•ืช ืฉืœ ื—ื‘ื™ืœืช ื”ื‘ืœื•ืงืฆ'ื™ื™ืŸ ืื—ืจืื™ื•ืช ืœืฉืžื™ืจื” ื‘ื‘ืœื•ืงืฆ'ื™ื™ืŸ: 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) ื›ื•ืชื‘ืช ืืช ื”-hash ืฉืœ ื”ื‘ืœื•ืง ื”ื ื•ื›ื—ื™ ืขื ื”ืžืคืชื— ืฉืฆื•ื™ืŸ ืขืœ ื™ื“ื™ ื”ืงื‘ื•ืข BLOCK_HASH ืœืžืกื“ ื”ื ืชื•ื ื™ื.

ื”ืคื•ื ืงืฆื™ื” GetTargetBlockHash() (ืžื—ืจื•ื–ืช, ืฉื’ื™ืื”) ืžื—ื–ื™ืจื” ืืช ื”-hash ืฉืœ ื”ื‘ืœื•ืง ื”ื ื•ื›ื—ื™ ื”ืžืื•ื—ืกืŸ ื‘ืžืกื“ ื”ื ืชื•ื ื™ื.

ืคื•ื ืงืฆื™ื™ืช ื”ืฉื’ื™ืื” SetTargetBlockHeight(height int) ื›ื•ืชื‘ืช ืœืžืกื“ ื”ื ืชื•ื ื™ื ืืช ื”ืขืจืš ืฉืœ ื’ื•ื‘ื” ื”ื‘ืœื•ืงืฆ'ื™ื™ืŸ ืขื‘ื•ืจ ื”ืฆื•ืžืช ืขื ื”ืžืคืชื— ืฉืฆื•ื™ืŸ ื‘ืงื‘ื•ืข BLOCK_HEIGHT.

ื”ืคื•ื ืงืฆื™ื” GetTargetBlockHeight() (int, error) ืžื—ื–ื™ืจื” ืืช ื’ื•ื‘ื” ื”ื‘ืœื•ืงืฆ'ื™ื™ืŸ ืขื‘ื•ืจ ืฆื•ืžืช ื ืชื•ืŸ, ื”ืžืื•ื—ืกืŸ ื‘ืžืกื“ ื”ื ืชื•ื ื™ื.

ื”ืคื•ื ืงืฆื™ื” CheckBlock(block IBlock) bool ื‘ื•ื“ืงืช ืชืงื™ื ื•ืช ืฉืœ ื‘ืœื•ืง ืœืคื ื™ ื”ื•ืกืคืช ื”ื‘ืœื•ืง ื”ื–ื” ืœื‘ืœื•ืงืฆ'ื™ื™ืŸ.

ืคื•ื ืงืฆื™ื™ืช ื”ืฉื’ื™ืื” AddBlock(ื‘ืœื•ืง IBlock) ืžื•ืกื™ืคื” ื‘ืœื•ืง ืœื‘ืœื•ืงืฆ'ื™ื™ืŸ.

ื”ืคื•ื ืงืฆื™ื•ืช ืœืื—ื–ื•ืจ ื•ื”ืฆื’ืช ื‘ืœื•ืงื™ื ื ืžืฆืื•ืช ื‘ืงื•ื‘ืฅ explore.go ืฉืœ ื—ื‘ื™ืœืช ื”ื‘ืœื•ืงืฆ'ื™ื™ืŸ:

ื”ืคื•ื ืงืฆื™ื” GetBlockByHash(ืžื—ืจื•ื–ืช hash) (*block.Block, error) ื™ื•ืฆืจืช ืื•ื‘ื™ื™ืงื˜ ื‘ืœื•ืง ืจื™ืง, ื˜ื•ืขื ืช ืœืชื•ื›ื• ื‘ืœื•ืง ืžืžืกื“ ื”ื ืชื•ื ื™ื, ืฉื”-hash ืฉืœื• ื”ื•ืขื‘ืจ ืืœื™ื•, ื•ืžื—ื–ื™ืจื” ืืœื™ื• ืžืฆื‘ื™ืข.

ื”ื™ืฆื™ืจื” ืฉืœ ื‘ืœื•ืง genesis ืžืชื‘ืฆืขืช ืขืœ ื™ื“ื™ ืคื•ื ืงืฆื™ื™ืช ื”ืฉื’ื™ืื” Genesis() ืžื”ืงื•ื‘ืฅ genesis.go ืฉืœ ื—ื‘ื™ืœืช ื”ื‘ืœื•ืงืฆ'ื™ื™ืŸ.

ื”ืžืืžืจ ื”ื‘ื ื™ื“ื‘ืจ ืขืœ ื—ื™ื‘ื•ืจ ืœืฆื•ืžืช ืœืงื•ื— ื‘ืืžืฆืขื•ืช ืžื ื’ื ื•ืŸ WebSocket.

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”