グローバルナビゲーションへ

本文へ

フッターへ

お役立ち情報Blog



ブロックチェーンって何?Go言語で簡単なブロックチェーンを作成してみる

ビットコインやイーサリアムなど、仮想通貨についてのニュースを耳にすることが多くなりました。
今回は、これらの仮想通貨に主に使用されている「ブロックチェーン」技術について、Go言語で簡単なプロトタイプを作成してみます。

ちなみに、「仮想通貨」の他に「暗号資産」という言葉もよく使われています。 「仮想通貨」という呼称の方が多く使われているイメージですが、金融庁のHPによると「仮想通貨」から「暗号資産」への呼称変更が提案されています。

ただし今回の記事では、より一般的に使用されている「仮想通貨」という呼称で進めていきたいと思います。

7.「仮想通貨」から「暗号資産」への呼称変更 (中略) 最近では、国際的な議論の場において、“crypto-asset”(「暗号資 産」)との表現が用いられつつある。 また、現行の資金決済法において、仮想 通貨交換業者に対して、法定通貨との誤認防止のための顧客への説明義務を課しているが、なお「仮想通貨」の呼称は誤解を生みやすい、との指摘もある。 こうした国際的な動向等を踏まえれば、法令上、「仮想通貨」の呼称を「暗号資産」に変更することが考えられる。金融庁「仮想通貨交換業等に関する研究会」報告書

ブロックチェーンとは

ブロックチェーンとは、取引の記録(トランザクション)を「ブロック」と呼ばれる塊に格納し、暗号化したうえで直前のブロックと繋げる仕組みです。

直前のブロックを暗号化した「ハッシュ値」を次のブロックが保持する構造となっており、同じブロックの内容であればハッシュ値も同じになります。
もし過去に生成されたブロックを改ざんしようとした場合、ハッシュ値が次のブロックに入っている値と異なってしまうため、後続のブロックを全て変更しなくてはなりません。 そのため、改ざんが極めて難しいと言われています。

「ブロック」を作成する

完成したサンプルはこちらです

それでは、Goで実装を始めてみます。まずは、トランザクションを格納するブロックを作成します。

ブロックに格納する情報は複数ありますが、今回は以下の3つを入れて実装していきます。

type Block struct {
	previousHash [32]byte // 直前のブロックのハッシュ値
	transaction  []string
	timestamp    int64
}

続いて、ブロックを作成する関数を作成します。

func NewBlock(previousHash [32]byte, transaction []string) *Block {
	b := &Block{}

	b.previousHash = previousHash
	b.transaction = transaction
	b.timestamp = time.Now().UnixNano()

	return b
}

次に、ハッシュ関数を用いて、ブロックをハッシュ化するメソッドを作成します。
今回はハッシュ関数にsha256 を使用します。
また、JSONに変換する際はMarshalが必要になりますので、以下の記事を参考にしてください。

func (b *Block) Hash() [32]byte {
	m, err := json.Marshal(b)
	if err != nil {
		panic(err)
	}

	return sha256.Sum256(m)
}

func (b *Block) MarshalJSON() ([]byte, error) {
    	return json.Marshal(struct {
		Timestamp    int64    `json:"timestamp"`
		PreviousHash [32]byte `json:"previous_hash"`
		Transaction  []string `json:"transaction"`
	}{
		Timestamp:    b.timestamp,
		PreviousHash: b.previousHash,
		Transaction:  b.transaction,
	})
}

出力用のメソッドも作成しておきます。

func (b *Block) Print() {
	fmt.Printf("Timestamp       %d\n", b.timestamp)
	fmt.Printf("PreviousHash    %x\n", b.previousHash)
	fmt.Printf("Transaction     %s\n", b.transaction)
}

「ブロックチェーン」を作成する

ここまでで、複数のトランザクションを格納するブロックが作成できました。
次は、このブロックを繋げて、ブロックチェーンを作成します。 トランザクションは一時的にプールし、一定数溜まったらブロックに格納します。

type Blockchain struct {
	transactionPool []string // トランザクションを一時的にプールするフィールド
	block           []*Block
}

func NewBlockchain() *Blockchain {
	bc := &Blockchain{}
	bc.CreateBlock() // Genesis Blockの作成

	return bc
}

ブロックを作成し、ブロックチェーン構造体に追加するメソッドを作成します。
最初に作成されたブロック(Genesis Block)は直前のブロックのハッシュ値を取得できないので、ゼロ値を入れています。
トランザクションプールは一時的にトランザクションを格納しておく場所のため、ブロックが作成されたら空にします。

func (bc *Blockchain) CreateBlock() {
	if len(bc.block) == 0 {
		b := NewBlock([32]byte{}, nil)
		bc.block = append(bc.block, b)
	} else {
		ph := bc.block[len(bc.block)-1].Hash()

		b := NewBlock(ph, bc.transactionPool)
		bc.block = append(bc.block, b)
	}

	bc.transactionPool = nil
}

func (bc *Blockchain) AddTransaction(transaction string) {
	bc.transactionPool = append(bc.transactionPool, transaction)
}

ブロック同様、ブロックチェーンを出力するメソッドを作成します。

func (bc *Blockchain) Print() {
	for i, b := range bc.block {
		fmt.Printf("%s Block %d %s\n", strings.Repeat("=", 15), i, strings.Repeat("=", 15))
		b.Print()
	}
}

以上でブロックを作成し、ブロックチェーンに追加するメソッドができました。 それでは、main関数で出力してみます。
各ブロックにはトランザクションを2つずつ入れることにします。

func main() {
	bc := NewBlockchain()

	bc.AddTransaction("transaction1")
	bc.AddTransaction("transaction2")
	bc.CreateBlock()

	bc.AddTransaction("transaction3")
	bc.AddTransaction("transaction4")
	bc.CreateBlock()

	bc.Print()
}

出力結果

=============== Block 0 ===============
Timestamp       1618296335308193300
PreviousHash    0000000000000000000000000000000000000000000000000000000000000000
Transactions    []
=============== Block 1 ===============
Timestamp       1618296335308271000
PreviousHash    6408abd46e4b29fdf503f3543b808d85d92bd3563c8ea8ae58e1e155b360fb3e
Transactions    [transaction1 transaction2]
=============== Block 2 ===============
Timestamp       1618296335308277200
PreviousHash    3b2a4c4dcf816b37c208486b7a378eccbdec98a7bc01bb645938bdc235e4c001
Transactions    [transaction3 transaction4]

Block1から、直前のブロックのハッシュ値とトランザクションが入っていることが分かります。
これで簡単なブロックチェーンのプロトタイプが作成できました。

まとめ

今回は、簡単なブロックチェーンの実装をしてみました。
今回の記事では紹介できていませんが、分散台帳システムなど安全性に関する技術も多くありますので、今後紹介できればと思います。
また、ビットコイン払いなどで仮想通貨もより身近になっていくと思いますので、ブロックチェーンは今後も注目です。

この記事を書いた人

アーティス
アーティス
創造性を最大限に発揮するとともに、インターネットに代表されるITを活用し、みんなの生活が便利で、豊かで、楽しいものになるようなサービスやコンテンツを考え、創り出し提供しています。
この記事のカテゴリ

FOLLOW US

最新の情報をお届けします