Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Bitcoin

Bitcoin 1枚まとめ

Bitcoin は2008年にSatoshi Nakamotoが論文で提案し、2009年1月に稼働を始めた最初のブロックチェーン。システムとしてのBitcoin(プロトコル)と、その上で発行される通貨単位のbitcoin(BTC)を区別して書くことがある。

最小単位は satoshi(1 BTC = 108 satoshi)。

ここではBitcoinの構成要素を、鍵とアドレス → トランザクション → マイニングと発行の順に見ていく。

鍵とアドレス

公開鍵暗号とデジタル署名

トランザクションには「アドレスの持ち主が」「この内容で」作ったことの証明が必要。それがないと、中継するノードやマイナーが内容を書き換えられてしまう。そこで デジタル署名(digital signature) を付ける。

  1. 送金者は 秘密鍵(private key) と 公開鍵(public key) のペアを作る

  2. 秘密鍵でトランザクションの要約に署名する

  3. トランザクションに署名と公開鍵を載せる

  4. 誰でも公開鍵を使って署名を検証できる

検証者は秘密鍵を知らなくても「この署名を作れるのは公開鍵に対応する秘密鍵の持ち主だけ」「署名された内容と受け取った内容が一致する」ことを確認できる。

BitcoinはECDSA(楕円曲線デジタル署名アルゴリズム)を採用している(2021年のTaprootアップグレード以降はSchnorr署名も使える)。

秘密鍵・公開鍵・アドレスの関係

各矢印は一方向にしか計算できない。公開鍵から秘密鍵は求められず、アドレスから公開鍵も求められない。

要素内容
秘密鍵256bitの乱数。1≤k<n1 \le k < n(nn は曲線の位数で 2256 よりわずかに小さい)
公開鍵秘密鍵から楕円曲線上の演算で計算した点 (x,y)(x, y)
アドレス公開鍵をハッシュ化し、人が扱いやすい文字列にエンコードしたもの。口座番号のような役割

2256≈1.16×10772^{256} \approx 1.16 \times 10^{77} は非常に大きく、乱数で作った秘密鍵が他人と重複する確率は事実上ゼロ。ただし疑似乱数生成器が弱いと推測されてしまうため、暗号論的に安全な乱数生成器(CSPRNG)を使う必要がある。

楕円曲線

Bitcoinは secp256k1 という楕円曲線を使う。

y2≡x3+7(modp),p=2256−232−977y^2 \equiv x^3 + 7 \pmod p, \quad p = 2^{256} - 2^{32} - 977

実数上ではなく素数 pp を法とする有限体 Fp\mathbb{F}_p 上で定義されているため、グラフにすると点がばらばらに散らばった模様になる。

曲線上の点には次の演算が定義されている。

  • 加算 P+QP + Q:PP と QQ を通る直線が曲線と交わる3点目を、xx 軸に関して反転した点

  • 2倍 P+PP + P:PP における接線を使って同様に求める

  • スカラー倍 kPkP:加算を kk 回繰り返す(実際には2倍算と加算の組み合わせで O(log⁡k)O(\log k) 回で計算できる)

  • 単位元:無限遠点 OO

公開鍵は、あらかじめ決められた生成元 GG を秘密鍵 kk 倍した点 K=kGK = kG として計算する。kk から KK は高速に計算できるが、KK と GG から kk を求める問題(楕円曲線離散対数問題, ECDLP)は現実的な時間では解けない。

x = 0xf028892bad7ed57d2fb57bf33081d5cfcf6f9ed3d3d7f159c2e2fff579dc341a
y = 0x7cf33da18bd734c600b96a72bbc4749d5141c90ec8ac328ae52ddfe2e505bdb
曲線上にあるか: True

アドレスの生成

公開鍵からアドレスを作る手順(P2PKHアドレスの場合):

  1. 公開鍵をシリアライズする

    • 非圧縮形式:04 + xx(32バイト)+ yy(32バイト)

    • 圧縮形式:yy が偶数なら 02、奇数なら 03 + xx(32バイト)。xx が決まれば yy の候補は2つ(偶数と奇数)に絞られるため、yy の偶奇だけで復元できる

  2. RIPEMD160(SHA256(公開鍵)) で160bitの 公開鍵ハッシュ を作る。2種類のハッシュ関数を重ねるのは、片方に脆弱性が見つかっても安全性を保つため

  3. Base58Check でエンコードする

Base58 は、Base64から見間違えやすい6文字(0, O, l, I, +, /)を除いた58文字でバイナリを表現するエンコード方式。Base58Check はさらに

  • 先頭に種類を表すバージョンバイト(通常のアドレスは 0x00 で、エンコード後は 1 から始まる)

  • 末尾にダブルSHA-256の先頭4バイトのチェックサム

を付ける。チェックサムにより、アドレスの打ち間違いを検出できる。

非圧縮公開鍵: 04f028892bad7ed57d2f...  アドレス: 1424C2F4bC9JidNjjTUZCbUxv6Sa1Mt62x
圧縮公開鍵: 03f028892bad7ed57d2f...  アドレス: 1J7mdg5rbQyUHENYdx39WVWK7fsLpEoXZy

同じ秘密鍵でも、公開鍵の形式(圧縮・非圧縮)によってアドレスが変わる点に注意。現在は圧縮形式が標準。

アドレスの種類はバージョンバイトや形式によって見分けられる。

種類形式先頭導入
P2PKHBase58Check1初期
P2SHBase58Check32012年(BIP-16)
P2WPKH / P2WSH(SegWit v0)Bech32bc1q2017年
P2TR(Taproot, SegWit v1)Bech32mbc1p2021年

ECDSA署名

秘密鍵 kk、署名対象のメッセージハッシュ zz に対して、署名 (r,s)(r, s) は次のように作る(以下の計算はすべて  mod n\bmod n)。

  1. 署名ごとに新しい乱数 k′k' を選ぶ

  2. R=k′GR = k'G を計算し、r=Rx mod nr = R_x \bmod n

  3. s=k′−1(z+rk) mod ns = k'^{-1}(z + r k) \bmod n

検証者は公開鍵 KK、zz、(r,s)(r, s) から

Q=(zs−1)G+(rs−1)KQ = (z s^{-1}) G + (r s^{-1}) K

を計算し、Qx≡r(modn)Q_x \equiv r \pmod n なら署名は有効と判定する。実際、K=kGK = kG を代入すると

Q=s−1(z+rk)G=k′G=RQ = s^{-1}(z + r k) G = k' G = R

となり、秘密鍵と内容の両方が正しいときだけ一致する。

署名 r = 0x120203e2fb6bcdd349 ...
正しいメッセージ: True
改ざんされたメッセージ: False
別人の公開鍵: False

ウォレット

ウォレット は秘密鍵を管理し、トランザクションを作成・署名するソフトウェア(またはハードウェア)。ウォレットの中にビットコインそのものが入っているわけではない。ビットコインはブロックチェーン上のUTXOとして存在し、ウォレットが持っているのはそれを動かすための鍵である。

プライバシーのため、同じアドレスを使い回さず取引ごとに新しいアドレスを使うのが望ましい。そのため、ウォレットは多数の鍵を管理する必要がある。

種類鍵の生成方法バックアップ
非決定性ウォレット鍵を1つずつ独立に乱数生成すべての鍵を保存する必要がある
決定性ウォレット1つのシード値から鍵を順に導出シード値だけ保存すればよい
HDウォレット(BIP-32)シード値から木構造状に鍵を導出シード値だけ保存すればよい

現在は HD(Hierarchical Deterministic)ウォレット が標準。親鍵と chain code から子鍵を導出し、用途ごとに枝を分けられる(導出経路は BIP-44 で m/44'/0'/0'/0/0 のように標準化されている)。拡張公開鍵(xpub)を使えば、秘密鍵なしで受取用アドレスだけを生成することもできる。

ニーモニックコード(BIP-39)

シード値をそのまま覚えたり書き写したりするのは大変なので、2048語の単語リストから選んだ12語または24語で表す。これを ニーモニックコード(シードフレーズ、リカバリーフレーズ)と呼ぶ。

  • 12語の場合、204812=21322048^{12} = 2^{132} 通りで、128bitのエントロピー + 4bitのチェックサムに相当する

  • ニーモニックと任意のパスフレーズをPBKDF2(HMAC-SHA512を2048回)に通して512bitのシード値を作る

シードフレーズを知られるとすべての鍵を奪われるため、オフラインで厳重に保管する。

ウォレットの種類(カストディアル/ノンカストディアル、ハードウェアウォレット、マルチシグ、MPCなど)については別途まとめる。

トランザクション

構造

Bitcoinのトランザクションは入力(vin)と出力(vout)のリストからなる。以下は Mastering Bitcoin に出てくる、AliceがBobに0.015 BTCを支払うトランザクションをデコードしたもの。

{
  "version": 1,
  "locktime": 0,
  "vin": [
    {
      "txid": "7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18",
      "vout": 0,
      "scriptSig": "3045022100884d142d...[ALL] 0484ecc0d46f1918...",
      "sequence": 4294967295
    }
  ],
  "vout": [
    {
      "value": 0.01500000,
      "scriptPubKey": "OP_DUP OP_HASH160 ab68025513c3dbd2f7b92a94e0581f5d50f654e7 OP_EQUALVERIFY OP_CHECKSIG"
    },
    {
      "value": 0.08450000,
      "scriptPubKey": "OP_DUP OP_HASH160 7f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a8 OP_EQUALVERIFY OP_CHECKSIG"
    }
  ]
}
  • 入力:使用するUTXOを txid(どのトランザクションの)と vout(何番目の出力か)で指定し、それを使う権利を証明する アンロッキングスクリプト(scriptSig、署名と公開鍵)を付ける

  • 出力:金額と、その出力を使うための条件である ロッキングスクリプト(scriptPubKey)を指定する

  • 入力の金額や手数料は記載されていない。参照先のUTXOを見れば分かるため

トランザクション全体をシリアライズしてダブルSHA-256したものが txid になる。

送金とは「ウォレットからウォレットへコインを送る」ことではなく、ブロックチェーン上のコインに付いている鍵(ロッキングスクリプト)を付け替えることだと解釈できる。

Bitcoin Script

ロッキングスクリプトとアンロッキングスクリプトは Script というスタックベースの言語で書かれる。Forthに似た逆ポーランド記法で、ループがない(チューリング完全でない)ため、必ず有限時間で停止する。

検証時には、アンロッキングスクリプトとロッキングスクリプトを連結して左から実行し、最後にスタックの一番上が真であれば使用を認める。

最も標準的な P2PKH(Pay-to-Public-Key-Hash) の場合:

<署名> <公開鍵> | OP_DUP OP_HASH160 <公開鍵ハッシュ> OP_EQUALVERIFY OP_CHECKSIG
└ アンロッキング ┘ └──────────────── ロッキング ────────────────┘
ステップ実行する要素スタック(右が上)
1<署名>署名
2<公開鍵>署名, 公開鍵
3OP_DUP(先頭を複製)署名, 公開鍵, 公開鍵
4OP_HASH160(先頭をハッシュ化)署名, 公開鍵, HASH160(公開鍵)
5<公開鍵ハッシュ>署名, 公開鍵, HASH160(公開鍵), 公開鍵ハッシュ
6OP_EQUALVERIFY(一致しなければ失敗)署名, 公開鍵
7OP_CHECKSIG(署名を検証)TRUE

ロッキング側は宛先の公開鍵そのものではなく、アドレスから取り出せる公開鍵ハッシュだけを知っていればよい。

Bobが署名: True
Malloryが自分の鍵で署名: False
MalloryがBobの公開鍵を騙る: False

トランザクションの種類

種類ロッキングスクリプトの内容用途
P2PK(Pay-to-Public-Key)公開鍵初期のcoinbase出力
P2PKH(Pay-to-Public-Key-Hash)公開鍵ハッシュ標準的な送金
マルチシグm-of-n の公開鍵複数人の署名が必要な送金(例:3人中2人の署名)
P2SH(Pay-to-Script-Hash)スクリプトのハッシュ複雑な条件を送金者に意識させずに使う。使用時に元のスクリプトを提示する
OP_RETURN任意データ(最大80バイト)支払い以外の用途(存在証明など)。使用不可能な出力になる
P2WPKH / P2WSHSegWit版のP2PKH / P2SH署名データをwitness領域に分離
P2TR(Pay-to-Taproot)Schnorr公開鍵(+スクリプトツリー)署名の集約、条件分岐のプライバシー向上

手数料とブロックへの格納

トランザクションの手数料は「入力の合計 − 出力の合計」で、マイナーの報酬になる。ブロック容量に上限があるため、マイナーは サイズあたりの手数料が高いトランザクションを優先して選ぶ(→P2Pネットワーク)。

マイニングと発行

Coinbaseトランザクション

ブロックの最初のトランザクションは、マイナーが報酬を受け取るための特別な coinbaseトランザクション にするルールになっている。

  • 参照するUTXOがない(新規発行なので)。入力の txid は全ビット0

  • アンロッキングスクリプトの代わりに、2〜100バイトの任意データを入れられる(現在は先頭にブロック高を入れる決まりがある)

  • 出力には ブロック報酬(新規発行分)+ ブロック内のトランザクション手数料の合計 を指定する

  • coinbaseの出力は100ブロック経過するまで使えない(チェーンの組み換えで無効になる可能性があるため)

最初のブロック(Genesisブロック, 2009年1月3日)のcoinbaseには、英タイムズ紙の見出し「The Times 03/Jan/2009 Chancellor on brink of second bailout for banks」が埋め込まれている。これはGenesisブロックがその日付より前に作られていないことの証明であり、既存の金融システムへの問題意識の表明とも解釈されている。

マイニング

マイナーはブロックヘッダーのハッシュが難易度ターゲット未満になるnonceを探す(→コンセンサス)。

nonceは4バイト(約43億通り)しかなく、現在の難易度では全部試しても見つからないことが多い。その場合、coinbaseの任意データ領域(extra nonce)やタイムスタンプを変えてマークルルートを変化させ、再びnonceを探索する。

現在のネットワーク全体のハッシュレートは数百EH/s(1020 ハッシュ/秒のオーダー)に達しており、個人がCPUで採掘して報酬を得るのは事実上不可能。マイニングはASIC(専用チップ)とマイニングプール(多数のマイナーで計算を分担し報酬を分け合う)が主流になっている。

発行スケジュールと半減期

ブロック報酬は 210,000ブロック(約4年)ごとに半減 する。

期間ブロック高ブロック報酬
2009〜20120〜50 BTC
2012〜2016210,000〜25 BTC
2016〜2020420,000〜12.5 BTC
2020〜2024630,000〜6.25 BTC
2024〜2028840,000〜3.125 BTC

報酬はsatoshi単位で切り捨てられるため、2140年頃に新規発行が止まり、総発行量は約2,100万BTCで上限に達する。その後のマイナーの収入は手数料のみになる。

半減回数: 33, 総発行量: 20,999,999.97690000 BTC
<Figure size 600x350 with 1 Axes>

発行上限を固定し、発行ペースを徐々に落とすことで、早期参加者へのインセンティブと希少性を両立させている。

プロトコルのアップグレード

Bitcoinのルール変更は、互換性の観点から2種類に分けられる。

種類内容例
ソフトフォークルールを厳しくする変更。旧ノードからも新ルールのブロックは有効に見えるため、後方互換性があるSegWit, Taproot
ハードフォークルールを緩める・変える変更。旧ノードは新ルールのブロックを無効と判断するため、チェーンが分裂しうるBitcoin Cash の分岐(2017年)

主なアップグレード:

  • SegWit(Segregated Witness, 2017年):署名データ(witness)をトランザクション本体から分離。署名の改変でtxidが変わる問題(トランザクション展性, malleability)を解決し、実質的なブロック容量も増えた(ブロックの上限を1MBから「4M weight units」に変更)。Lightning Networkの前提にもなった

  • Taproot(2021年):Schnorr署名とMAST(Merkelized Alternative Script Trees)を導入。複数の署名を1つに集約でき、複雑な条件付き送金も通常の送金と見分けにくくなった

Taprootで拡張されたwitness領域を利用して、satoshiに通し番号を付けて画像などのデータを紐づける Ordinals(Bitcoin上のNFT)や、それを使ったトークン規格 BRC-20 といった使い方も登場している。

Bitcoinの決済速度の限界を補うLightning Networkについては Layer 2 を参照。