最終的に単なるデータベースではなくブロックチェーンを完成させるには、プロジェクトに 3 つの重要な要素を追加する必要があります。
- ブロックのデータ構造とメソッドの説明
- データ構造とトランザクションメソッドの説明
- データベースにブロックを保存し、ハッシュまたは高さ (またはその他) によってブロックを検索するブロックチェーン機能。
これは産業向けブロックチェーンに関する XNUMX 回目の記事です。
このシリーズの前回の記事に関して読者から寄せられた質問を思い出してください。この場合、ブロックチェーン データを保存するために LevelDB データベースが使用されていますが、他のデータベース、たとえば MySQL の使用を妨げるものはありません。 次に、このデータの構造を見てみましょう。
トランザクションから始めましょう:
そのデータ構造は次のとおりです。
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 は、生成されたトランザクション ハッシュを JavaScript アプリケーションから生成されたトランザクション ハッシュと互換性を持たせるために、Build() および Check() で使用されます。
Build() メソッドは、トランザクション ハッシュを次のように設定します: tx.TxHash = preByteHash(tx.ToBytes())。
ToJSON() 文字列メソッドは、トランザクションを JSON 文字列に変換します。
FromJSON(data []byte) エラー メソッドは、バイト スライスとして渡された JSON 形式からトランザクションを読み込みます。
Check() bool メソッドは、トランザクション ハッシュ フィールドから得られたハッシュと、このトランザクションのハッシュ (ハッシュ フィールドを無視した) の結果として取得されたハッシュを比較します。
トランザクションがブロックに追加されます。
ブロック データ構造はさらに大容量になります。
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 は前のブロックのハッシュであり、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() 文字列メソッドは、ブロックをデータの文字列表現の JSON 形式に変換します。
FromJSON(data []byte) エラー メソッドは、JSON からブロック構造にデータを読み込みます。
Check() bool メソッドはブロック ハッシュを生成し、それをブロック ハッシュ フィールドで指定されたものと比較します。
GetTxsHash() 文字列メソッドは、ブロック内のすべてのトランザクションの合計ハッシュを返します。
GetMerkleRoot() メソッドは、ブロック内のトランザクションのマークル ツリーのルートを指定します。
Sign(privk string) メソッドは、ブロック作成者の秘密キーを使用してブロックに署名します。
SetHeight(height int) メソッドは、ブロックの高さをブロック構造フィールドに書き込みます。
GetHeight() int メソッドは、ブロック構造の対応するフィールドで指定されたブロックの高さを返します。
ToGOBBytes() []byte メソッドは、ブロックを GOB 形式でエンコードし、バイト スライスとして返します。
FromGOBBytes(data []byte) エラー メソッドは、渡されたバイト スライスからブロック データを GOB 形式でブロック構造に書き込みます。
GetHash() 文字列メソッドは、指定されたブロックのハッシュを返します。
GetPrevHash() 文字列メソッドは、前のブロックのハッシュを返します。
SetPublicKey(pubk string) メソッドは、ブロック作成者の公開キーをブロックに書き込みます。
したがって、Block オブジェクトのメソッドを使用すると、ネットワーク経由で送信したり、LevelDB データベースに保存したりできる形式に簡単に変換できます。
ブロックチェーン パッケージの関数は、ブロックチェーンへの保存を担当します。
これを行うには、ブロックは 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(ハッシュ文字列) エラー関数は、BLOCK_HASH 定数で指定されたキーを持つ現在のブロックのハッシュをデータベースに書き込みます。
GetTargetBlockHash() (文字列、エラー) 関数は、データベースに保存されている現在のブロックのハッシュを返します。
SetTargetBlockHeight(height int) エラー関数は、BLOCK_HEIGHT 定数で指定されたキーを持つノードのブロックチェーンの高さの値をデータベースに書き込みます。
GetTargetBlockHeight() (int, error) 関数は、データベースに保存されている特定のノードのブロックチェーンの高さを返します。
CheckBlock(block IBlock) ブール関数は、ブロックをブロックチェーンに追加する前に、ブロックが正しいかどうかをチェックします。
AddBlock(block IBlock) エラー関数は、ブロックをブロックチェーンに追加します。
ブロックを取得および表示するための関数は、ブロックチェーン パッケージのexplore.go ファイルにあります。
GetBlockByHash(ハッシュ文字列) (*block.Block, error) 関数は、空のブロック オブジェクトを作成し、ハッシュが渡されたデータベースからブロックをロードし、そのブロックへのポインタを返します。
Genesis ブロックの作成は、ブロックチェーン パッケージの Genesis.go ファイルの Genesis() エラー関数によって実行されます。
次の記事では、WebSocket メカニズムを使用してクライアントをノードに接続する方法について説明します。
出所: habr.com