人生は勉強ブログ

https://github.com/dooooooooinggggg

ブロックチェーンの概要

参考にした本

ビットコインとブロックチェーン:暗号通貨を支える技術

ビットコインとブロックチェーン:暗号通貨を支える技術

ビットコインとは

ビットコインという単語には色々な側面がある。

この本質をついている文章が、本にあった。

ビットコインは、プロトコル名でもあり、ネットワーク名でもあり、さらには分散コンピューティングのイノベーションの名称でもあります。 通貨としてのビットコインは、このイノベーションの最初の応用にすぎません。

この技術の本質は、通貨のようなシビアな領域にも応用することができる、基盤技術であると考えている。

歴史

ビットコインは、2008年に、サトシナカモト名義で、Bitcoin: A Peer-to-Peer Electronic Cash System というタイトルでネット上に公開された。この論文は、たった9ページである。

この技術では、既存の技術を組み合わせることで、中央政府を持たない、完全に分散化されたシステムを実現した。

既存の通貨では、ある中央政府が価値を保証することによって、信用を達成していた。 しかし、ビットコインでは、分散化された信用を基礎にしている。

流れとしては、

トランザクションが、ビットコインの分散合意形成の仕組みにおいて信用され受け入れられ、最後にブロックチェーンに正しい取引として記帳される。 この、全取引履歴は、http://blockchain.infoで見ることができる。

用語として、各ユーザーのことを、ノードと呼ぶことにする。

トランザクション

トランザクションとは

トランザクションとは、ビットコインの所有者が、他の人にビットコインを送ったことを、ビットコインネットワークに示すことである。

トランザクションは、簿記でいう、個々の取引行のようなもので、

それぞれのトランザクションには、一個以上のインプットと一個以上のアウトプットがそれぞれある。

一つのトランザクションのインプットとアウトプットの額は、インプットの方がわずかに大きい。この差額は、トランザクション手数料となる。

また、トランザクションには、電子署名が含まれる。

簡単に書くと、 インプットには、送金主と、送金額。 アウトプットには、送金先と、送金額と、手数料が含まれている。

トランザクションが承認されるには

あるトランザクションは、だいたい、258バイトである。

このトランザクションは、資金の所有者を確認し、新しい所有者を割り当てるために必要な情報の全てが含まれている。 このトランザクションが、ビットコインネットワークに送られて初めて、分散元帳(もとちょう)であるブロックチェーンの一部になる。

まず、このトランザクションは、peer to peerネットワークによって、数秒以内に大半のノードに伝わる。

これで、まだブロックに含まれてはいない(多少のリスクはある)が、承認されたとみなすこともできる。

マイニング

トランザクションは、マイニングによって承認されるまで、全ネットワークに共有されている元帳の一部となることはできない。

ビットコインにおいて、信用の仕組みは、計算によって成り立っている。ブロックの中に取り込まれるためには、膨大な計算を必要とするが、これを検証する際には、わずかな計算で住むようになっている。

この仕組みによって、各ノードでの検証が可能となっている。

マイニングには、主に二つの目的がある。

  1. それぞれのブロックの中に、新しいビットコインを作り出す。詳しくは後述。
  2. 信用を作り出す。膨大な計算リソースをつぎ込むことを保証しているので、それが信用になるからである。

鍵、アドレス、ウォレット

ビットコインの所有権は、デジタル鍵(公開鍵暗号)、ビットコインアドレス、デジタル署名に基礎をおいている。

デジタル鍵は、ビットコインネットワークの中に保持されているのではなく、個々のユーザーによって保持され、ウォレットに保存されている。(つまりプライベート)

この機構は、ビットコインプロトコルとは完全に独立で、オフラインであっても、デジタル鍵の生成と、管理を行うことができる。

ある秘密鍵があり、この秘密鍵は、公開鍵を生成することができる。そして、公開鍵から、ビットコインアドレスを生成することができる。

しかし、その逆は不可能で、ビットコインアドレスから、公開鍵を生成することはできないし、公開鍵から秘密鍵を生成することはできない。

この、公開鍵と、秘密鍵による電子署名を、ユーザーはトランザクションに記載する。

この公開鍵と、電子署名によって、各ノードはトランザクションを検証し、そのトランザクションが有効なものかどうかを検証することができる。

ビットコインアドレス

ビットコインアドレスは、秘密鍵から生成された、公開鍵によって生成される。

具体的に、かくと、公開鍵をハッシュ化したものがビットコインアドレスとなる。

公開鍵を、SHA256でハッシュ化したのち、RIPEMD160でハッシュ化して、160bitの数字を作り出す。

A = RIPEMD160( SHA256(K) )

こうして生成された文字列は、通常、base58と呼ばれる形にエンコードされた状態で、ビットコインアドレスとして生成される。

この、58という数字は、最も広く使われているbase64と呼ばれるエンコード方式から、見間違いを起こしやすい、

0,O,l,I,記号+,記号/の六個を除いたものだ。

さらに間違いを防ぐために、base58Check形式になる。

これは、チェックサムを利用したもので、ここでは説明を割愛する。

base58Checkエンコードされた文字列に対して、version prefixを追加することによって、エンコードしたデータの先頭に固有の文字があわられるため、

データが見やすい形式になる。

ビットコインアドレスは、1 Pay to Script Hash アドレスは、3 bitcoin testnet アドレスは、m or n

ウォレット

ウォレットはつまり、秘密鍵を管理したり、生成したりするためのもの。

そこにビットコインの実体はない。

ビットコインを持つ、ということは、トランザクションに対応する秘密鍵を所有することと等しい

ここで、秘密鍵を管理するときの、やり方の違いを説明する。

非決定性ウォレット

これは、ランダムな秘密鍵を大量に保有するもの。

基本的に、秘密鍵は、一度しか使われないので、トランザクションのたびに、必要に応じて、新しい鍵が生成されることになる。

これは、管理が面倒。

決定性ウォレット

決定性ウォレットとは、あるシードから、一方向ハッシュ関数を用いて、大量の秘密鍵を生成していく方式である。

このウォレットは、シードさえあれば、全ての鍵を復活させることができるため、シードのバックアップさえ取っておけば良い。

ここから派生して、階層的決定性ウォレット、というものも存在する。

ウォレットのまとめ

たくさんの秘密鍵を管理するのは、難しい。

トランザクションの詳細

トランザクションは、上の方でざっと説明したが、ここではもうちょっと詳しく説明してみる。

トランザクションのインプットになる部分

インプットとは、送金する人が、自分の資産から幾らかの金額を、トランザクションに含めるということである。

ブロックチェーンでは、資産は、過去の全取引の、ブロックチェーンの中に、自分の資産が埋まっている、という認識。

この過去のブロックのことを、UTXOと呼ぶ。このUTXOのアウトプットにあるもののうち、自分に向けられているものが自分の資産と言える。

ブロックチェーンをスキャンして、ユーザーに属している全てのUTXOをかき集めて、インプットに充てる。

どのブロックをどう割り当てるかは、ウォレットによって自動的に実行される。

この感じは、ポテトチップスを同じグラムに割り当てる過程ににてると個人的には思う。

このブロックは、分割することができない。

例えば、1BTC払いたいという状況で、100BTCが自分に向けられているUTXOがあったとする。

このブロックを1BTCの支払いに充てるには、まずこのUTXOを全てインプットに充てる必要がある。

しかし、これでは99BTCの損である。これを解決するために、「おつり」という形で、自分に向けて、送金する。

こうすることで、ブロックを分割することなく、1BTCを払うことができる。

また先ほど述べた手数料は、明確にはトランザクションにかかれない。

インプットの合計からアウトプットの合計を除いた額が自動的に手数料になる。

よって、「おつり」を入れるのを忘れてしまうと、そのぶんがごっそり手数料として取られてしまう。

ノードの役割

ノードには、4つの役割が存在する。

  1. wallet
  2. miner
  3. フルブロックチェーン
  4. ルーティングノード

これらのうち、どの機能を持っているかは、使用するアプリケーションによって異なる。

例えば、ビットコインコアでは、全ての機能を持っているが、軽量ウォレットでは、walletとルーティングノードの機能しか持っていない。

トランザクションプール

トランザクションは、それが承認されているかどうかに関わらず、絶えず入ってくる。

この未承認のトランザクションを貯めておくための、一時的な領域もある。

また、各トランザクションは、それぞれ、トランザクションインプットを持っており、もしこのインプットとなるブロックが まだ自分の元に来ていない場合、オーファントランザクションとなり、これまた別の領域に保存される。

マイニング

マイニングとは、上でも述べたように、安全性を保証するためのものである。

ブロックチェーンとは、その時の計算リソースに対して、10分間でハッシュ値が計算できるように調節されている。(2016ブロックに1回、それまでにかかった時間を合計して、1ブロックあたりの平均時間が10分になるように調節される)

これはdifficultyと呼ばれており、最初の何桁かが0になる時の桁を表している。

マイナーはトランザクションから、任意のトランザクションを取り出し、それをハッシュ化する。

その際に、引数のようなものとして、nonceを与える。

difficultyを満たすnonceを見つけることが、マイニングという行為の本質である。

欲しい値が得られた時点で、そのトランザクションはブロックの一部となり、ブロックチェーンとして正式に認められることになる。

しかし、difficultyが大きくなるにつれ、その値が出る確率はどんどん低くなっていく。

以下はその例。

(hello, worldという文字列をハッシュ化する。)

#python2
import hashlib

def check_hash(hash_text):
    for i in range(1):
        if hash_text[i] != "0":
            return False
    return True

plain_text = "hello world"
nonce = 0

while True:
    input_text = plain_text + str(nonce)
    hash_text = hashlib.sha256(input_text).hexdigest()

    if check_hash(hash_text) == True:
        print "!!!!!!!!!!!!!!"
        print "nonce is " + str(nonce) + " : hash is " + hash_text
        break
    else:
        print "nonce is " + str(nonce) + " : hash is " + hash_text
        nonce += 1

for i in range(1):のrangeの中身が最初の何桁かを表している。

1桁の場合

# nonce is 0 : hash is f9684703170819cff074d756ac8f7e44cb82c8638c51ea05e359425441100e6d
# nonce is 1 : hash is 916e14036f2d86a479ab16a3f2cffaf73a5419d12576497cc2d837fb423571a5
# nonce is 2 : hash is f93c20b30171d10e773dc2a2d8ed59524b25baddf381b83fcc4ec40f50bedb33
# nonce is 3 : hash is 47697e8ff239f6cb73b7afafb8c82cc85a4f57c67bc7c3a55516cdd998a6f8c6
# nonce is 4 : hash is f8220bacb0bf5bd8ca33a890184b66b35fb64647274b4b9fb4ff90e68f77a5a7
# nonce is 5 : hash is 3445b50a09c46b3dee912cd1b8dc9eaa4e756a82b417d97615b92d5cce04d1dd
# nonce is 6 : hash is a51c576ed146f5517946f646f8e42d304e08ef2d0b104f442e1d90be8dc34b54
# nonce is 7 : hash is 8708774dc4759b52464ce4b1c44bc059b70e4853124490e452388521490a3001
# nonce is 8 : hash is a8ea76a5392acf8b2b8bbf1c3fbb0f713423171cbd3267de285fcf8dd47d5d72
# nonce is 9 : hash is 7b1d4afd3ec2b09b18cdde9fc365296836047623c862a542532bdccc48d11121
# nonce is 10 : hash is e76b8bcf9184e2bbc7fd01b8e0c8dab1ea25e8bde5ede32958b7084ffe7ccddb
# nonce is 11 : hash is 8f16ca3820ad6f3d5e5ba44bcf5f794b2283f98761213ef675d443320ecb72f7
# nonce is 12 : hash is 8a4886dec53f9606bdc73da8e58d62cc472794fd9871a4e070bccdbac2765f3d
# !!!!!!!!!!!!!!
# nonce is 13 : hash is 0bb3907e937a4fc23b2a136b9bc23e9342e12c53737575c31254027daf35b632

2桁の場合

# nonce is 152 : hash is 04fcb9cb0efdc10718b84b0a469742bdc24b3276d9e84909625fc3d4bd166707
# nonce is 153 : hash is eff516c8fa3e14fb270adcba49e3d663d18cc5fb74458eb08ab05f2b28572225
# nonce is 154 : hash is c6e1ab974cd3fa025f75cf46b70c75b6349c74b4729976ab6b19b4fa3e6d3e41
# nonce is 155 : hash is 925124cc6fd6ff728597cb3d479ba67587022755ba6f8900c4aec35bca57f4e8
# nonce is 156 : hash is 607da6903ddaa0906334fac8f4a303c85ac2a1ea66a2ddd6fa176ad82112149f
# nonce is 157 : hash is 3b812d179789bcafe3ad79cba506cb8e8aae7a0cf04983af6235ebfd9661e0a1
# nonce is 158 : hash is 550db6ca8e22b639ee4607b45cc0723adf236952d4f0deb2697d145f2afea48f
# nonce is 159 : hash is 38f0699d381bcf63db9f84b17d2feeab9c95ae61a3a54d5a86af3402b4080673
# !!!!!!!!!!!!!!
# nonce is 160 : hash is 0085155c6a2b306dcb8387dcbd7dd6c2fbcaf5b6735e3fd58c24914c7b909c13

3桁の場合

# nonce is 6730 : hash is 92f6b31d417d7cf10d80352872a18f64a5ec1ec21055609260339b39003e158f
# nonce is 6731 : hash is e6997f33445c791fffdd1416161d4333f75eeb328d466b4b9db7d2afc91c0155
# nonce is 6732 : hash is fea9bb649e89ef5dc5696da8fd5103f135f492c555c5232233ab5526600c3219
# nonce is 6733 : hash is 10aa58ebbe2bdf6dfce81cb229ae02b8cc6cb513326bc361dc42e0d69597d293
# nonce is 6734 : hash is 2218dea4148d9fe8a2eca2b84e5d3914439a120d86fe2a96aa2438eec249f0dd
# nonce is 6735 : hash is 3d219d02b9ecda6964a24e2d23c44db11433288ce5f8c31ff23f92379e9ea383
# nonce is 6736 : hash is 3ae409798d0259a88b56e84e12fbc5e4d8589c564b6025151366cd2fe3102720
# nonce is 6737 : hash is 1a954fb3adbaa93baa05dc06ec82e30b251389ed375612bd146f0ac9847d1c13
# nonce is 6738 : hash is bd028ce7d2d26599646a7d5a06c78e69603d0f70cf237a217c6efa564a4ab4f3
# nonce is 6739 : hash is 3d016fb7aa3329d721fc0bf3b4034d2c55982680632a19f6fc200497be94f3f3
# nonce is 6740 : hash is d38b9929886509bf92889358f099e0d123daa84dd9df1181beab985a69513133
# nonce is 6741 : hash is a121a2cbfb583a0975512fb53694ffcdd97b30f98dc36ba6bec3734c2a24f57a
# !!!!!!!!!!!!!!
# nonce is 6742 : hash is 000fd9024e22437d38075ad87a7ca2649e66384ee67943a66eef482f5fe437c7

4桁の場合

# nonce is 49960 : hash is 2b5ff794726eb6d5faf6a9ce2d40646ad1816e5186299b1b471d158f8d3ebf86
# nonce is 49961 : hash is 78c64ab9aaae1807c64566fe446f4502cdffe9a7482510c4483ce7699bf35f42
# nonce is 49962 : hash is ecdcddbc381f36d9583ff25625f63c5f9f16ffde5edf0fdd4de5c0779da9fc52
# nonce is 49963 : hash is cda15d4524b5c9104b0f48b50fe78c85d9cc72437e519e20b6426b02f1f43728
# nonce is 49964 : hash is 21e9b9e07878f6b869be53b36f1fdd0d5af4624d205f992687d3f9e53e9abfc2
# nonce is 49965 : hash is 176bf9f27f121a18183b633c6de1dd7bbdbbf138e5f0dcc020218e653ca22556
# nonce is 49966 : hash is 35c0817e2db30432e8b853188cde2c23d04838361569bdd67e0e3fd1d3c2098b
# !!!!!!!!!!!!!!
# nonce is 49967 : hash is 00004921c6f7acd81acd24a477fd29d1effeb58ba6943007e63420a6d2b0e973

5桁の場合

# nonce is 503547 : hash is 72105ef09136a4022fabfe8d771e126b17047b953e487dd41c1d29ab6e23d0bd
# nonce is 503548 : hash is bc405f0131a04f12f0275acb5052cc4137e79a76fda9dcd81ad502daa92d392d
# nonce is 503549 : hash is d269312f113c96a263b822a0223fd7f73adfbe29f76dd4a1aa62d053a02815a7
# nonce is 503550 : hash is 1d524f9a319b7f2ad742914a43306e33e2c98c8fcc6ab06172084e23d5313356
# nonce is 503551 : hash is d07cbebe9b10047ce8b9ac07446411f69f5e3ddc7d935a23b0d64ed4400e41db
# nonce is 503552 : hash is 2d3580071146ef5b30d8293d02fc770d6a7a575358ffdcd6f8b71959a1a48a68
# nonce is 503553 : hash is 327a8027379ba576bf7d80fc0e9edead5f9b955cf304546e6b2288d1746dd6e2
# nonce is 503554 : hash is 69b26875cc7451bc58ac31b43dcb800455b164a7f6e4eb46f079965c14d955da
# !!!!!!!!!!!!!!
# nonce is 503555 : hash is 0000078c6b46b4256d8383f2d456d6e0720e73d65c58dda6bddb62889c2ccadd

このように、一個difficultyが上がるだけで、爆発的に計算量が増える。

今回の例では、最初の何桁が0というのをdifficultyに用いたが、実際は、

ある値(difficulty)より小さなハッシュ値である、ということが条件になっている。

また、SHA256を二重に計算している。

マイナーはまず、任意のトランザクションをたくさん選ぶ。

それに加えて、マイニング報酬という、特殊なインプットをそのトランザクションをそこに加える。

このようにしてできた文字列の塊(jsonぽい感じ)を、上のように、マイニングする。

そして、nonceを求めることに成功したマイナーは、その成功を他のマイナーに知らせ、マイニング報酬と、トランザクション手数料の両方を総取りすることができる。

他のマイナーの成功を知らされたマイナーは、それを検証したのち、次のブロックのマイニングに取り掛かる。

これがproof of workである。

マイニングとハッシュ化競争

2009->0.5MH/sec - 8 MH/sec(16倍)

2010->8MH/sec - 116GH/sec(14500倍)

2011->16GH/sec - 9TH/sec(562倍)

2012->9TH/sec - 23TH/sec(2.5倍)

2013->23TH/sec - 10PH/sec(450倍)

2014->10PH/sec - 150PH/sec in August(15倍)

ブロックチェーンの安全性について

トランザクションや、ブロックは、それぞれのノードで独立に検証される。その過程において、もしそれが不正なものであった場合、破棄され、他のノードに伝わることはない。

また、マイナーが不正なトランザクションを含めないのは、このルールがあるためである。

また、不正なトランザクションを含めることは、多大な計算リソースが必要になる。

その計算リソースを不正のために使うより、報酬を得るほうが、得という論理でブロックチェーンは安全に守られている。

まとめ

ブロックチェーンは計算の暴力