Bitcoin 1.01 — 設計上の決定
この文書はプロジェクトで下された決定の記録である。決定が変われば、ここも更新される。状態タグ:実装済み コード化・テスト済み · 決定済み 合意済み・未実装 · 未解決 まだ完全には解決していない。
コマンド名、ファイル名、コード上の識別子(kaz、dugum、src/zincir.hpp など)はトルコ語の単語である。プログラムと一致させるため、ここでもそのまま記す。
0. 物語
Bitcoin 1.01 は、アーキテクチャを改め、通信も可能にした版である。ウェブサイト、ホスティング、ドメイン名、第三者のサーバーのいずれも必要としない。唯一の「サーバー」はプロジェクト所有者自身のコンピュータであり、それさえネットワークの動作には必須ではない。
1. ハッシュ:ORION ファミリー 実装済み
- 独自の発明ではない。SHA-3 の心臓部である Keccak-f[1600] 置換を使う。
- パラメータ:容量 1024 ビット(SHA3-512 と同じ)、レート 72 バイト。
- ORION-1024:ブロックの指紋、1024 ビット(16 進 256 文字)。一般的な安全性 512 ビット。
- ORION-512:取引 ID とマークルノード、512 ビット。
- タグ(すべての呼び出しの先頭):
[長さ] "orion-stars-up-my-sleeve/" + 用途用途:blok、islem、genesis-kaydi、merkle-yaprak、merkle-ic、adres… - 透明性:ORION-512 の結果は、同じ入力に対する公式の SHA3-512 の結果と完全に一致する。
- コードは公式の SHA3-512 / SHAKE256 の値と、独立した Python 製 Keccak 実装で検証した。
注:SHAKE-256 の出力を 1024 ビットに伸ばしても、安全性は 256 ビットを超えない。安全性を高めるのは容量を 1024 ビットに上げることであり、ORION はそれを行う。
2. 2 の平方根 実装済み
- √2 のビットはプログラム内でライブラリなしに計算する。別ファイルは不要である。
- 第 0 ビット=2 進小数点の直後の最初のビット。最初の 64 ビットは
6a09e667f3bcc908(SHA-256 と SHA-512 の最初の初期値と同じ)。 - ジェネシス:ビット [0, 2048)。
- 期定数:半減期(1,050,000 ブロック、約 4 年)ごとに、√2 の次の 1024 ビットがチェーンのルールに加わる:
ブロックハッシュ = ORION-1024("blok", ヘッダー || 期定数)。投票は不要で、すべての機器が同じ結果を計算する。(以前の「コイン保有者 50% の承認」案に代わるもの。) - √2 は秘密ではない。√2 から秘密鍵を生成することはない。
3. 3x+1(象徴) 実装済み
- すべてのブロックヘッダーに
collatzフィールドがある=(高さ+27)が 1 に至るまでの手数。 - ジェネシスではこれが 27:111 手、途中の最大値は 9232。
- ジェネシスの採掘は nonce = 27 から始まる。
- 安全性には何の役割もない。チェーンの「鼓動」のような署名である。
4. ブロックヘッダー 実装済み
228 バイト、リトルエンディアン:
| フィールド | バイト | 説明 |
|---|---|---|
| バージョン | 4 | 101 |
| 高さ | 8 | |
| 前ブロックのハッシュ | 128 | ORION-1024 |
| マークルルート | 64 | ORION-512 |
| 時刻 | 8 | Unix 秒(UTC) |
| target_bits | 4 | 圧縮表記のターゲット |
| nonce | 8 | |
| collatz | 4 | 3x+1 の手数 |
- マークル:葉と内部ノードは異なるタグを使う。ノードが奇数個残ったとき、最後のノードは複製せず、そのまま 1 段上へ持ち上げる(ビットコインの CVE-2012-2459 の不具合を避けるため)。
- ある取引がブロックに含まれることは、log2(n) 段の短い証明で示せる。
5. ジェネシス 実装済み
- 前ブロックのハッシュ:√2 の最初の 1024 ビット(「チェーンの前に √2 があった」)。
- 記録:
"orion-stars-up-my-sleeve"+ √2 の最初の 2048 ビット。使用可能な出力はない。 - 時刻:2026-10-23 20:12:00 イスタンブール =
1792775520。 - ターゲット:
0x7E00FFFF(平均 2^24 回の試行)。 - Nonce:
599548。 - ハッシュ:
000000729d827999fbaab777aab0bba8e6cfdf7646af1d78acea54300463226189321ff01b097953e6f0b246c797640da04bf1a7aa438819fa0799d7bc5e591ee523e85b4fa14845a45ad6adcce7191847621a639f2b424fca9b6fd14b3ed30823d185728d56b886e04d8b21922e81fbb4e35fecec2f71d39d6a16129a069659
6. 通貨、時間、難易度 実装済み
- 目標ブロック間隔:120 秒。
- ASERT、毎ブロック(ビットコインキャッシュの aserti3-2d 規則の整数演算を 1024 ビットのターゲットに適用):
ターゲット = アンカーのターゲット × 2^((実経過時間 − 120 × ブロック差) / 7200)- 半減時間 2 時間:チェーンが 2 時間遅れるとターゲットは 2 倍(採掘が容易に)、 2 時間進むと半分になる。
- 2^x には 3 次多項式を使う。最悪の相対誤差は 0.012%(実測)。結果は独立した Python 参照実装と完全に一致する。
- アンカー=第 1 ブロック。 ジェネシスからネットワーク開始日までの期間が難易度を狂わせない。
- 第 1 ブロックのターゲット=ジェネシスのターゲット
0x7E00FFFF(2^24 回の試行)。 - 最も易しい限界:
0x7F00FFFF(2^16 回の試行)。
- ブロック報酬:10 コイン。1,050,000 ブロックごとに半減する。これは √2 の期定数が変わる時点と同じである。総発行量:20,999,989.8635 コイン(ジェネシスに報酬がないため 2100 万をわずかに下回る)。
- 1 コイン = 100,000,000 最小単位。
- タイムスタンプ規則(ビットコインと同じ):直近 11 ブロックの中央値より大きく、機器の時計より最大 2 時間先まで。
6b. ブロック、ファイル、マイニング 実装済み
- ブロック=ヘッダー(228 バイト)+取引数(4 バイト)+取引。本体は最大 4 MB。
- 保存ファイル:
<データ>/ana/bloklar.dat(データフォルダは第 17 節)、ブロックごとに"ORN1" | 長さ | ブロック。プログラムは起動のたびに、すべてのブロックを署名も含めて最初から検証する。ファイル末尾が途中で切れている場合(停電など)、修復するのはチェーンに書き込むkazコマンドだけである。まずbloklar.dat.yedekを作り、それから健全な部分まで切り詰める。読み取り専用のコマンドはファイルに触れない。 - フェーズ 2 の試験用チェーン(本体には報酬記録しかなかった)は、フェーズ 3 の初回起動時に削除されず
<データ>/ana_faz2_eskiフォルダへ移される。ジェネシスは同じである。 - マイナー:全コア、途中状態を保持した Keccak(ヘッダーの変化しない先頭 216 バイトは一度だけ処理)、先頭 72 バイトでの早期比較。見つかったブロックはすべて通常の経路でも改めて検証する。nonce の探索は 27 から始まる。
- Keccak-f[1600] は展開(アンロール)した形で書かれ、コードは
araclar/keccak_uret.pyによって FIPS 202 の式から生成される。シングルコアの速度は約 3.7 倍になった。 - ブロックと取引のすべての規則は
src/zincir.hppの冒頭に 1 つずつ書かれている。 - フォーク(2 人のマイナーが同時にブロックを見つけること)と「最も多くの仕事を含むチェーン」規則は、ネットワークとともにフェーズ 4 で導入された。
7. 鍵、アドレス、署名 実装済み
- 署名:SLH-DSA-SHAKE-256s(NIST FIPS 205)、ゼロから実装。
- 公開鍵 64 バイト、秘密鍵 128 バイト、署名 29,792 バイト。多回使用可能(鍵ごとに 2^64 署名が上限)。
- NIST 公式の ACVP テストベクトルで検証済み:鍵生成 10/10、署名 28/28(決定的・ランダム化、内部・外部インターフェース)、検証 28/28(意図的に壊した署名を含む)。ベクトルは
testvektor/slhdsa_shake256s.txt、出典は NIST のusnistgov/ACVP-Serverリポジトリ、変換スクリプトはaraclar/acvp_donustur.py。bitcoin101 nist-testですべて実行できる。 - 署名では FORS 木とハイパーツリーの各層を全コアに分けて計算する。
- ウォレットの署名は「ヘッジ付き」(ランダム化):署名ごとに OS から新しい 32 バイトの乱数を得る。
- コンテキスト文字列(FIPS 205 の "context"):
orion-stars-up-my-sleeve/islem。
- 真の乱数:Windows では
BCryptGenRandom、Linux ではgetrandom()。失敗するとプログラムは停止し、弱い乱数に頼ることは決してない。std::random_deviceは使わない。 - ウォレット:256 ビットのマスターシークレット 1 つ。アドレス番号 i について
t = ORION-1024("cuzdan-tohum", マスターシークレット || i)、SK.seed = t[0..32)、SK.prf = t[32..64)、PK.seed = t[64..96)。 1 つのバックアップ(16 進 64 文字)ですべてのアドレスを復元できる。おつりは毎回新しいアドレスへ送られる。- ウォレットファイルはパスワードで暗号化される(第 14 節)。
- アドレス=768 ビット=
ORION-1024("adres", 公開鍵)の出力の先頭 768 ビット(先頭 384+末尾 384 ビットは公開。「中間」にある 256 ビットの秘密シードは決して公開されない)。 - アドレス表記:
"orn" + Base58(アドレス || チェックサム)、チェックサム=ORION-512("adres-kontrol", アドレス)の先頭 4 バイト。 140 文字。1 文字でも打ち間違えるとアドレスは拒否される。 - √2 座標(象徴):アドレスの先頭 48 ビットを、そのアドレスが √2 の中で「住む」ビット位置として表示する。
7b. 取引と UTXO 実装済み
- 取引は 2 種類:報酬取引(各ブロックの最初、入力なし、高さを含む)と通常取引。
- 取引 ID(txid)=
ORION-512("islem", 本体)、署名は含まない。したがって署名によって ID を変えることはできない。一方、マークル木には署名を含む完全な ID("islem-tam")が入る。ブロックはすべてにコミットする。 - 同じアドレスからの複数の入力は1 つの署名を共有する(署名 1 つが約 30 KB なので重要)。
- 署名されるメッセージ=
ORION-512("imza-mesaji", txid || 使用される各出力の金額とアドレス)。 - 各取引には最大 80 バイトのメモ欄がある(将来の √2 公開投稿の基礎)。
- 規則(
src/zincir.hpp):出力は UTXO 台帳になければならない。報酬出力は 100 ブロック成熟するまで使えない。署名の公開鍵は使用されるアドレスのものでなければならない。すべての SLH-DSA 署名が有効でなければならない。使われない署名記録があってはならない。出力 ≤ 入力(差額が手数料)。報酬取引 ≤ ブロック報酬+手数料合計。 - 手数料ポリシー:1000 バイトあたり 1000 単位(0.00001 コイン)。署名 1 つの取引は約 30 KB なので、手数料は約 0.0003 コイン。これはコンセンサス規則ではなく、プールの受け入れ規則である。
- 保留プール(
<データ>/ana/bekleyen.dat、最大 32 MB / 5000 取引、第 17 節):まだブロックに入っていない取引。現時点では承認済みの出力しか使えない(未承認のおつりは次のブロックを待つ)。kazはブロックごとにプールを読み直し、別の端末からgonderで追加された取引は次のブロックに入る。 - バージョン 2 の取引(HTLC 出力、請求・返金の経路):第 16a 節。
- 量子に関する注:アドレスから公開鍵へたどることは、768 ビットの ORION 原像を見つけることを意味する。署名はもともとハッシュだけに依存しており、ショアのアルゴリズムが狙う楕円曲線は存在しない。
7c. テストネットワーク(--lab) 実装済み
- どのコマンドの末尾にも
--labを付けると、別のネットワーク(<データ>/lab)で動く。難易度は最も易しい限界にあり、採掘はほぼ一瞬で終わる。100 ブロックの成熟規則は同じだが、101 ブロックが数秒で採掘される。 - テストも同じラボネットワークを使う。
8. メッセージ 決定済み
8a. 公開投稿 — √2 符号化
- アルファベット:64 文字、6 ビット。トルコ語アルファベットの 29 文字+q+x+空白=32、これに最もよく使われる記号・数字 32 個を加えて 64。
- √2 辞書:√2 の最初の 2^21 = 2,097,152 ビット。
- 測定(実際の計算):
- 1 文字(6 ビット):64 通りすべてが最初の 452 ビット以内に現れる。
- 2 文字(12 ビット):4,096 通りすべてが最初の 32,218 ビット以内に現れる。
- 3 文字(18 ビット):262,144 通りの 99.969% が最初の 2^21 ビット以内に現れる。欠けるのは 81 通りだけ。
- 4 文字(24 ビット):現れるのは 11.7% だけなので使わない。
- 形式:メッセージを 3 文字ずつに分け、各片について
[2 ビットの種別][位置]:- 3 文字 → 21 ビットの位置
- 見つからなければ 2+1 文字に分ける(15 ビットと 9 ビットの位置)。
- 正直なコスト:3 文字の片は 18 ビットではなく 23 ビットで書かれる(約 28% 長い)。情報理論上、ランダムな列の中の位置を書くには、探す片と同じだけの容量が要る。これは圧縮ではなく象徴的な符号化であり、暗号化ではまったくない。鍵を見た者は誰でも読める。
- よく使う単語の短縮コード(ハフマン風の辞書):フェーズ 7 で検討する。
8b. 個人間の直接メッセージ
- 鍵交換:ML-KEM-1024(NIST FIPS 203)。
- 暗号化:256 ビット鍵による認証付き共通鍵暗号(AES-256-GCM または Keccak ベースの構成。フェーズ 7 で選ぶ)。
- メッセージはチェーンに書かれない。ピアツーピアネットワークで中継され、受信者がオフラインなら、公開ノードが暗号化されたまましばらく保持する。
9. ネットワーク構成 実装済み
コマンドは 1 つ:bitcoin101 dugum。ピアとの接続、同期、ブロックと取引の中継、採掘(--kaz)、エクスプローラーがすべて同じプログラムで動く。ドメイン名、ホスティング、第三者のサーバーは不要である。
ピア同士が互いを見つける方法
| 経路 | 方法 | 追加設定 |
|---|---|---|
| 同じ Wi-Fi / 有線の家庭内ネットワーク | 30 秒ごとの UDP 10101 ブロードキャスト。見つかったノードへ自動で TCP 接続 | なし(ファイアウォールの許可) |
| シードコンピュータ | tohumlar.txt にある IP:ポートへ直接 TCP 10102 | シード側でのポート転送 |
| アドレス共有 | 各ピアは知っているアドレスを共有する(ADRESLER メッセージ)。<データ>/ana/esler.txt に保存。インターネット上のピアからはローカル/プライベートアドレスやドメイン名を受け付けない。リストは接続ごとに 1 回だけ受け取る。シードが停止していてもノード同士は接続する | なし |
| 手動 / 招待 | --baglan IP:ポート。bitcoin101 davet がこのコンピュータのアドレスを表示する | なし |
| IPv6 | 待ち受けソケットは IPv4+IPv6 の同時対応(デュアルスタック) | 多くの場合なし |
| インターネットなし | スマートフォンのテザリングや同じスイッチにつないだコンピュータは同じローカルネットワーク上にあり、自動探索がそこでも働く。クライアント同士を隔離する機器(AP アイソレーション)では動かない | 機器による |
未実装:Bluetooth、Wi-Fi Direct、Tor、ルーターでの自動ポート開放(UPnP/PCP)。今後追加できる。
プロトコル(TCP、各メッセージは "O101" | 種別 | 長さ | 内容、テストネットワークでは "OLAB"):
SELAM(バージョン、ノード ID、待ち受けポート、高さ、総仕事量、先端ハッシュ、時計)、BASLIK_ISTE/BASLIKLAR(最大 500)、
BLOK_ISTE/BLOK(最大 16)、ISLEM、ADRES_ISTE/ADRESLER、PING/PONG。プロトコルバージョン 2(HTLC の規則を知るノード)。プロトコル 1 のピアは HTLC が有効になるまで受け入れる(第 16a 節)。
同期(「ヘッダー優先」):
- ピアの総仕事量がこちらより多ければ、ロケーターリスト(先端から 10 ブロック戻り、その後は倍々に、最後にジェネシス)でヘッダーを要求する。
- ヘッダーは共通ブロック以降、すべてのヘッダー規則(ASERT、中央値時刻、3x+1、プルーフ・オブ・ワーク)で検証する。
- 分岐の総仕事量がこちらより厳密に多い場合にのみ、ブロックをダウンロードしてチェーンを置き換える。同じなら先に見たほうが残る。
- 置き換え中に 1 つでも無効なブロックがあれば、チェーンと UTXO 台帳は元の状態に戻り、そのピアは切断される。
- 巻き戻されたブロック内の取引は(まだ有効なら)保留プールに戻る。
総仕事量:ブロックごとに 2^(1024 − 8·(指数−3)) / 仮数(整数、最大 2^120)。総仕事量が最も多い有効なチェーンが勝つ。
自己防衛:無効なブロック/ヘッダー/取引を送ってきたピアは切断され、1 時間は再接続しない。送信接続は最大 8、受信接続は最大 64。メッセージは最大 6 MB。180 秒間沈黙したピアは閉じる。ピアの時計との差が 20 分を超えると警告する(ブロックは最大 30 分先の日時まで許されるので、時計は正確でなければならない。第 13 節)。
ファイルの安全:チェーンに書き込めるのは同時に 1 つのプログラムだけ(yazici.kilit、OS のロック。プログラムが異常終了しても自動で解除される)。gonder コマンドは共有ファイルに書かず、gelen/ フォルダに別ファイルとして置く。動作中のノードがそれを拾い、検証して中継する。
シードコンピュータ:プロジェクト所有者のコンピュータ。設定:TOHUM_KURULUMU.md(ファイアウォール、スリープ、ポート転送、CGNAT の確認)。
10. エクスプローラー 実装済み
- ノード内蔵の読み取り専用ウェブサーバー。既定は
http://127.0.0.1:10103(このコンピュータのみ)。--web-genelを付けると外部からも開ける(シードコンピュータ)。 - 5 秒ごとに自動更新される 1 ページ:概要カード、最新ブロック、保留中の取引、接続中のピア、検証パネル。ブロック・取引・アドレスの詳細ページ。高さ、ハッシュの先頭、
orn…アドレスで検索できる。 - JSON API:
/api/ozet、/api/blok/<n|hash>、/api/islem/<ID>、/api/adres/<アドレス>、/api/bekleyen、/api/esler、/api/baslik/<n>。 - 独立した検証:
/api/baslik/<n>は生のヘッダーと SHA3-512 の入力を返す。ブロックハッシュの前半は、任意の SHA3-512 ツールで計算して比較できる(テスト済み:Python のhashlibと完全に一致)。 - 安全性:GET のみ。ユーザーデータ(メモ)は常に
textContentで書き込む(HTML として解釈されない)。厳格な Content-Security-Policy。同時接続は最大 64、リクエストは 8 KB、タイムアウト 15 秒。 - 限界:ドメイン名がないので HTTPS はない。内容は途中で改ざんされうるため、自分のノードと照合することが肝心である。
- 誰でも API からデータを取得し、自分のディスク、サーバー、ウェブサイトに保存できる。
11. アーカイブ報酬(悪用に強い設計) 決定済み/一部未解決
2 種類の攻撃を想定して設計した:
- シビル:1 人が 1,000 台の偽の「機器」を見せかける。
- スパム:誰かが自分宛てに何千もの取引を送って報酬を膨らませる。
規則:
ステーク:アーカイバーになるには、最低 T コインを 5,040 ブロック(約 1 週間)ロックする。
抽選:毎ブロック、前ブロックのハッシュを使い、ステークに比例して 8 人のアーカイバーを選ぶ。ステークを 10 個の ID に分けても収益は増えない。収益はステークに正比例するからである。したがってシビル攻撃は意味をなさない。
アクセス証明(質問):選ばれた各アーカイバーには、同じくブロックハッシュからランダムに選んだ過去のブロックと、そのブロック内の取引について問いが出される。そこには公開鍵の記録も含まれる。これが「公開鍵の保管庫」をマイニングの一部にする仕組みである。答え=その取引そのもの+マークル証明。誰でも古いブロックヘッダーと照らして検証できる。データを保持していない者は答えられない。
期限:答えは 10 ブロック以内にチェーンに入らなければならない。答えなかったアーカイバーはステークのわずかな割合(1%)を失う。したがって「登録だけしてデータを持たない」と損をする。
報酬関数:
プール(ブロック) = 0.05 × ブロック補助金 + 0.20 × ブロック内の取引手数料 選ばれた者 1 人の取り分 = プール / 8 期待収益_i ≈ プール × (ステーク_i / ステーク合計)- 取引数が増えるほど手数料が増え、プールも大きくなる。
- アーカイバーが増えるほど 1 人あたりの取り分は小さくなるが、プール全体は増えない。したがって偽のアーカイバーを加えても報酬の総額は増えない。
- スパムは割に合わない:プールは実際に支払われた手数料だけでできている。自分宛てに取引を送る者は、よくて収支ゼロである。
未解決:記録がインターネット上で本当に「公開アクセス可能」であることは、チェーン上で決定的には証明できない。これは世界的にも解決されていない問題である。アーカイバー登録時にネットワークアドレスを申告し、ノードはそこからランダムなデータを要求する。ただし、これは規則ではなく評判のシグナルである。
12. ロードマップ
| フェーズ | 作業 | 状態 |
|---|---|---|
| 1 | ORION ハッシュ、√2 生成器、3x+1、ブロックヘッダー、マークル、ジェネシス | 完了 |
| 2 | ブロックのディスク保存、ASERT、マルチコア採掘、チェーン検証 | 完了 |
| 3 | SLH-DSA(FIPS 205 テストベクトルで検証)、ウォレット、アドレス、取引、UTXO | 完了 |
| 4 | ネットワーク:Wi-Fi 探索、シード、アドレス共有、同期、フォーク、取引の中継、エクスプローラー | 完了 |
| 5 | 51% 対策、ウォレット暗号化(Argon2id+ChaCha20-Poly1305)、Windows / Android アプリ | 完了 |
| 5b | ブリッジ:ビットコインとの HTLC アトミックスワップ(バージョン 2 の取引、メインネットでは #150 で有効化) | 完了 |
| 5c | 共有時の安全性と堅牢化(第 17 節) | 完了 |
| 6 | ピア間の暗号化接続(ML-KEM)、署名付きシード告知、UPnP/PCP、本物の Android APK、未承認のおつりの使用 | |
| 7 | 公開投稿(√2)、個人メッセージ(ML-KEM)、アーカイブ報酬 | |
| 8 | 科学レイヤー:報酬の半分による医薬品候補のスクリーニングと材料探索(BILIM_KATMANI.md。マイニングの式は第 9 節、ラボのページは araclar/) | 草案 |
13. 51% 攻撃への対策 実装済み
正直な現状:プルーフ・オブ・ワークを使うチェーンは、計算能力の過半を握った者に対して完全には守れない。ビットコインも同様である。できるのは、攻撃を非常に高くつかせ、被害を限定し、利用者に早めに警告することである。これらの対策は src/zincir.cpp(catal_politikasi)と src/dugum.cpp にある。
| 対策 | 規則 | 何に対して |
|---|---|---|
| 短いフォーク | 6 ブロック以下のフォークは通常の規則:総仕事量が厳密に多いチェーンが勝つ | 自然なフォークを妨げないため |
| 深いフォークへのペナルティ | 深さ 6 < d ≤ 100 のフォークでは、新しい分岐は古い分岐の仕事量の少なくとも d/6 倍を含まなければならない | 密かに採掘して一気に公開されるチェーン |
| ファイナリティ | 100 ブロックより深いフォークは決して自動では受け入れない | 履歴の書き換え(二重支払い) |
| タイムスタンプの盾 | ブロック時刻は最大 30 分先まで(ビットコインでは 2 時間) | 時刻を操作して難易度を下げること |
| 報酬の成熟 | 採掘報酬は 100 ブロックの間使えない | 攻撃者が得たものをすぐに持ち逃げすること |
| マイナーの分布 | 直近 100 ブロックの半分超を 1 つのアドレスが採掘したら警告(ログ+アプリ) | 中央集権化を可視化するため |
| 時計の警告 | ピアの時計が 20 分以上ずれていたら警告 | 誤った時計がファイナリティと時刻の規則を壊すこと |
深いフォークへのペナルティの意味:攻撃者の計算能力の割合を q、誠実なマイナーの割合を 1−q とする。同じ時間に攻撃者は q、誠実なマイナーは 1−q の割合で仕事を生み出す。d ブロックを巻き戻すには q/(1−q) ≥ d/6 が必要になる:
| 巻き戻すブロック数 | 必要な仕事量の比 | 攻撃者に必要な割合 |
|---|---|---|
| 6 | 1 倍(通常の規則) | > 50% |
| 12 | 2 倍 | ≥ 67% |
| 30 | 5 倍 | ≥ 83% |
| 60 | 10 倍 | ≥ 91% |
| 101 以上 | — | 自動では不可能 |
代償(正直に):これらの規則は各ノード自身のローカル規則である。100 ブロックより長くネットワークから切り離され、別のチェーンで進んだノードは、戻ってきても自動ではメインチェーンに切り替わらない(警告を出す。veri フォルダを手動でバックアップし、チェーンを最初からダウンロードし直せば解決する)。最初から同期する新しいノードは影響を受けない。巻き戻すべきブロックを持っていないからである。また、過半を握った者は新しい取引を検閲できる。これらの規則が難しくするのは過去の書き換えだけである。
利用者への推奨(アプリのセキュリティページにも記載):少額の支払いでは 6、多額では 30、非常に多額では 100 の承認を待つこと。
14. ウォレットの暗号化とパスワード規則 実装済み
- 規則は NIST SP 800-63B-4 に従う(
src/sifre_kurali.cpp):単独で使うパスワードは 15 文字以上、256 文字以下(規格は少なくとも 64 文字まで許すことを求める)。空白、トルコ語の文字、絵文字も使える(Unicode NFC に正規化)。 大文字・数字・記号の必須要件はなく、定期的な変更の強制もない(規格はこれらを禁じている)。その代わり、既知・流出済みのパスワードやパターンのリスト(bitcoin、orion、şifre、qwerty、123123、チーム名…)、繰り返しのパターン、連続した並びを拒否する。アプリは入力中にリアルタイムで確認し、推定強度を表示する。 - 鍵導出:Argon2id(RFC 9106)、メモリ 64 MiB、3 パス、4 レーン、16 バイトのランダムなソルト。メモリを要するため、GPU や専用ハードウェアによる総当たりを非常に高くつかせる。RFC 9106 の公式テストベクトルと
argon2-cffiで 9/9 一致。 - 暗号化:ChaCha20-Poly1305(RFC 8439)、12 バイトのランダムな nonce。ファイル形式、Argon2 の設定、ソルトは「追加認証データ」(AAD)として結び付けられ、ファイルが 1 バイトでも変われば開けない。誤ったパスワードでは認証タグが一致しないため、マスターシークレットが誤って復号されることは決してない。
- ファイル(
<データ>/ana/cuzdan.dat、Windows では%LOCALAPPDATA%\Bitcoin101、第 17 節):BITCOIN101-CUZDAN 2 kdf argon2id 65536 3 4 <ソルト> sir <nonce> <暗号化されたマスターシークレット+タグ> adres <番号> <公開鍵> (パスワードなしで残高を見られるように) - パスワードとマスターシークレットは処理後にメモリから消去する(
guvenli_sil)。ロックが外れるのは署名・バックアップのときだけで、1 回のリクエストの間に限られる。 - 古い(フェーズ 3〜4 の)暗号化されていないウォレットも引き続き動く。アプリは黄色の警告でパスワードの設定を勧める(
bitcoin101 cuzdan sifreleコマンドもある)。 - 規則:パスワードを忘れると取り戻せない。復元の唯一の手段は紙に書いた 64 文字のマスターシークレットである。量子に関する注:グローバーのアルゴリズムは共通鍵の強度を最大で半分にする。256 ビットの鍵には 128 ビットの量子安全性が残る。弱点はパスワードそのものであり、だから長い文章が推奨される。
15. アプリ(Windows と Android) 実装済み
構成(ビットコインコアと同じ考え方:コアとインターフェースを 1 つのプログラムに):
bitcoin101(.exe) ── チェーン、ピア、採掘、ウォレット(C++ コア)
├─ 127.0.0.1:10104 アプリのインターフェース(この機器のみ) ── Edge の「アプリウィンドウ」/ スマートフォンのブラウザ / インストール済み PWA
├─ 127.0.0.1:10103 エクスプローラー(読み取り専用。--web-genel で外部へ)
└─ 0.0.0.0:10102 ピア(P2P)
- Windows:
bin\bitcoin101.exeをダブルクリックする(コマンドなしで実行する)とコアが起動し、Microsoft Edge のアドレスバーのないアプリウィンドウが開く(Edge がなければ既定のブラウザ)。プログラムは独自のアイコンとバージョン情報付きでビルドされる(src\bitcoin101.rc)。Edge の「このサイトをアプリとしてインストール」でスタートメニューとタスクバーに追加できる。黒いコンソールウィンドウはコアそのもので、閉じるとプログラムが終了する。 - Android:同じ C++ コアを Termux 内でビルドする(
ANDROID.md)。インターフェースはスマートフォンのブラウザで開き、「ホーム画面に追加/アプリをインストール」でアイコン付きのアプリになる。本物の APK(Play ストア形式のパッケージ)はこのフェーズにはない。この開発環境では Android SDK をダウンロードできなかったためで、フェーズ 6 で Android Studio を使って作る。 - デザイン:ビットコインコアの構成(概要、送金、受取、取引+ステータスバー)を Windows 11 の Fluent の見た目で: Segoe UI Variable 書体、Windows 11 の色調、左のナビゲーションバーと選択項目の強調線、角丸 8 px のカード、ライト/ダークテーマ(システムに従う)、スマートフォンでは下部ナビゲーションバー。ページ:概要、送金、受取、取引、採掘、ネットワーク、チェーン(エクスプローラーへ接続)、セキュリティ、ブリッジ、設定。
- アイコン(
araclar/simge_uret.py、DejaVu Sans Bold):スペインの赤の地(#E60026、下に向かって濃くなる)、白い √2、そして根号の左の突起の上、根の次数を書く位置(³√ のように)に、黄色(#F1BF00)のコインに赤い ₿。アイコンは「₿√2」と読める。アプリ用 PNG はsrc/uygulama_simge.hpp、Windows のアイコンはsrc/bitcoin101.ico(16〜256 px)。ブラウザのキャッシュ対策として、アイコンの URL にはバージョンの接尾辞が付く(/simge-192.png?s=2)。 - セキュリティ:
- インターフェースは
127.0.0.1にのみバインドされ、ネットワーク上の別の機器からは開けない。 - 24 バイトのランダムなトークン。
X-Jetonヘッダーのない/c/...リクエストは拒否される(定数時間比較)。他のウェブサイトはブラウザ経由でこのヘッダーを送れず(CORS)、トークンも読めない。フェーズ 5c 以降、トークンはページに埋め込まれない(第 17 節)。このコンピュータの他のユーザーやプログラムが、ページをダウンロードして知ることはできない。 HostとOriginヘッダーを検査する(DNS リバインディングとクロスサイトリクエストフォージェリ対策)。- 厳格な Content-Security-Policy、フレーム内表示の禁止(
frame-ancestors 'none'、X-Frame-Options: DENY)、nosniff。ユーザーデータは常にtextContentで書き込む。 - マスターシークレットが表示されるのは、ウォレット作成時と、パスワードを入力して「バックアップ」を求めたときだけである。送金、バックアップ、パスワード変更は毎回パスワードを求める。
- ブリッジのページで mempool.space が有効なときは、スワップの BTC アドレスと取引だけを mempool.space に問い合わせる(第 16c 節)。
- エンドツーエンドで試験済み(
araclar/uygulama_testi.py、44/44):外部の Host/Origin、トークンなし・誤ったトークンのリクエスト、弱いパスワード、誤ったパスワード、不正なアドレスは拒否され、作成、採掘、送金、パスワード変更は動作する。フェーズ 5c での追加:ページにトークンがないこと、応答ごとに異なる CSP nonce、3 回目の誤入力以降の待機(429)、送金の署名中もノードが応答し続けること。
- インターフェースは
- API(ローカル、トークン必須):
GET /c/durum、/c/guvenlik、/c/ag。POST /c/sifre-kontrol、/c/olustur、/c/geri-yukle、/c/sifrele、/c/sifre-degistir、/c/yedek、/c/alma-adresi、/c/gonder、/c/madencilik、/c/baglan。エクスプローラーの/api/...エンドポイントも同じアドレスから読める。 - ブリッジ API(ローカル、トークン必須。第 16 節):
GET /c/takaslar。POST /c/takas/baslat、/teklif-coz、/katil、/kabul、/kilitle、/btc-fon、/btc-talep、/sir、/talep、/iade、/btc-iade、/yayinlandi、/gizle。
16. ビットコインブリッジ:HTLC アトミックスワップ 実装済み
なぜ金庫型にしないのか:チェーン間ブリッジは、暗号資産の歴史で最も多くの資金が失われた場所である(Ronin、Wormhole、
Nomad…)。共通の原因は、ロックされた資金が少数の鍵や 1 つのコントラクトが管理する金庫に置かれていることにある。
Bitcoin 1.01 はその代わりにアトミックスワップを使う。金庫も仲介者もサーバーもない。コード:src/takas.*(流れ)、
src/btc.*(ビットコインの取引)、src/secp256k1.*(ビットコインの署名)、src/sha256.*。
役割:開始者(Ali)は 1.01 を渡して BTC を受け取る。秘密の値 s は彼のウォレットから生まれる。参加者(Ayşe)は BTC を渡して 1.01 を受け取る。
流れ(アプリの「ブリッジ」ページ):
- Ali がオファーを作る。オファーコード(
b101-teklif-…、Base58+ORION チェックサム):H = SHA-256(s)、Ali の BTC 公開鍵、金額、T1(1.01 のタイムアウト)、T2(BTC のタイムアウト)、ネットワーク。コードに秘密の情報は含まれず、どんな経路で渡してもよい。 - Ayşe がコードを貼り付けると、アプリが条件を表示する。承諾すると承諾コード(
b101-kabul-…)が出る。Ayşe の新しい 1.01 アドレスと BTC の返金用の鍵である。Ayşe はこれを Ali に渡す。 - Ali が承諾コードを貼り付けると、1.01 が HTLC にロックされる(「s を示した Ayşe が受け取る。T1 以降は Ali が取り戻す」)。
- Ayşe のノードはチェーン上のロックを自分で見つけ、オファーと照合し(H、受取人、金額、T1)、十分な承認を待つ。そのあとで初めて BTC アドレスが表示され、Ayşe はどのビットコインウォレットからでもこの P2WSH アドレスへ BTC を送る。
- Ali のコアは資金提供取引を解読し、正しいアドレスに十分な額が送られたことを確認する。1 承認以上を得たのち、 BTC の請求取引に署名する。この取引のウィットネスで s が明らかになる。
- Ayşe のコアはその取引から s を取り出し(SHA-256 で検証し)、1.01 を請求する。
- キャンセル:Ayşe は T2 以降に BTC を、Ali は T1 以降に 1.01 を取り戻す。
期限と安全余裕(takas.cpp):
| メインネット | テストネットワーク | |
|---|---|---|
| T1(オファーの時点から) | 24 / 48 / 72 時間 | 最低 4 分 |
| T2 | T1 の期間の半分 | 同じ |
| T1 − T2、および承諾時に残る T2 の最低値 | 6 時間 | 1 分 |
| Ayşe が BTC を送る前に待つ 1.01 の承認数 | 6 | 1 |
| Ali が BTC を受け取る最終期限 | T2 − 2 時間 | T2 − 期間の 1/8 |
| Ayşe が BTC を送る最終期限 | オファーと T2 の中間 | 同じ |
| BTC の最低額 | 0.0001 BTC | 同じ |
Ali の遅れは許されない。T2 の間際に s を明かすと、Ayşe は BTC の返金と 1.01 の請求の両方ができてしまう。 Ali は未承認の資金提供取引で請求することもできない(資金提供取引が差し替えられると、s が無駄に明かされる)。
16a. 1.01 側:バージョン 2 の取引(コンセンサス規則の変更)
- 形式は
src/islem.hppの冒頭にある。入力にはyol(経路:0 通常、1 請求+32 バイトの原像、2 返金)、出力にはtür(種別:0 アドレス、1 HTLC:ロック H、受取アドレス、返金アドレス、タイムアウト)が加わった。バージョン 1 の取引はそのまま有効である。 - 規則(
src/zincir.hpp):請求には SHA-256(原像) = H かつ署名が受取人のものであること。返金にはブロックの中央値時刻 (直近 11 ブロック)≥ タイムアウトかつ署名が返金アドレスのものであること。HTLC は通常の経路で、通常の出力は請求・返金の経路では使えない。バージョン 1 の取引に HTLC は含められない。原像はちょうど 32 バイト(ビットコイン側のOP_SIZE 32と同じ。一方のチェーンでは有効で他方では無効な s によってスワップを壊すことはできない)。 - バージョン 2 では、署名されるメッセージが使用される HTLC のすべてのフィールドを含む(
"imza-mesaji-2"タグ)。 - 有効化:メインネットでは #150(規則を追加したときチェーンは #111 だった)、テストネットワークでは #1。ネットワーク上の全員が更新する必要がある。古いバージョンはバージョン 2 の取引を含むブロックを拒否する。ピアプロトコルは 2 に上がり、プロトコル 1 のピアは有効化までは(警告付きで)受け入れ、その後は切断する。バージョン 2 の取引は古いピアには中継しない。
- ウォレット:HTLC は使用可能残高に含まれない。返金アドレスが自分のものは「スワップでロック中」と表示される。履歴には
takas-kilit、takas-talep、takas-iadeの種別がある。チェーンエクスプローラーは HTLC 出力と明かされた s を表示する。 - s と BTC の鍵はスワップ番号を使ってマスターシークレットから導出される(
cuzdan.hpp)。別途バックアップする必要はない。
16b. ビットコイン側
- HTLC のウィットネススクリプト(P2WSH、segwit v0):
OP_IF OP_SIZE 32 OP_EQUALVERIFY OP_SHA256 <H> OP_EQUALVERIFY <Ali の鍵> OP_ELSE <T2> OP_CHECKLOCKTIMEVERIFY OP_DROP <Ayşe の鍵> OP_ENDIF OP_CHECKSIG請求のウィットネスは
<署名> <s> 01 <スクリプト>、返金のウィットネスは<署名> <> <スクリプト>、返金取引ではnLockTime = T2。ビットコインはタイムロックを直近 11 ブロックの中央値時刻に対して適用する(BIP 113)。返金が受け入れられるのは T2 の約 1 時間後である。 - ゼロから実装:SHA-256 / HMAC-SHA256、secp256k1 ECDSA(RFC 6979 の決定的 nonce、low S、DER)、segwit の取引形式、 BIP 143 の署名ハッシュ、bech32 / bech32m アドレス、Base58Check。手数料=vバイト × sat/vB で、出力から差し引く。
- 支払先アドレスとして P2PKH、P2SH、P2WPKH、P2WSH、P2TR を受け付ける。まだ定義されていない segwit バージョン(v2 以上)は拒否する。現在はそこへ送られた資金を誰でも使えてしまうからである。
- secp256k1 の秘密スカラー倍算はモンゴメリーラダーで行うが、libsecp256k1 ほどの定数時間性はない。量子に関する注:ビットコイン側は ECDSA であり、ショアのアルゴリズムには耐えない。鍵はスワップごとに新しく、数時間しか使わない。
16c. ビットコインチェーンの読み取りと送信
- コアはビットコインノードに接続しない。mempool.space が有効なとき(ブリッジのページで無効にできる。既定は有効)、アプリウィンドウは HTLC アドレス、資金提供取引、それを使う取引、手数料の目安をそこから読み、署名済みの取引をそこへ送る。
HTTPS はブラウザが扱うので、C++ 側に TLS は不要である。この許可は CSP でアプリのページにだけ与えられる(
connect-src 'self' https://mempool.space)。サービスワーカーは他のオリジンへのリクエストに関与しない。 - コアが信用しないもの:すべての生の取引を自分で解読し、資金が正しいスクリプトへ十分な額で送られたこと、s が H を開くことを自分で確かめる。信用するもの:mempool.space が報告する承認数。mempool.space は資金を盗めないが、問い合わせたアドレスと IP を知り、誤った承認数を報告しうる。多額の場合は自分のビットコインノードで承認を確認すること。
- 無効にしたときはすべて手作業になる。資金提供取引と相手の請求取引の生データ(または s)を貼り付け、署名済みの取引をコピーして好きなツールで送信する。
- 記録:
<データ>/<ネットワーク>/takaslar.txt(1 行に 1 つの JSON)。秘密の情報は含まない。
16d. 検証
bitcoin101 test、第 17〜18 部:SHA-256(FIPS 180-4)、HMAC(RFC 4231)、既知の ECDSA テスト値、BIP 173/350 のアドレスベクトル。HTLC スクリプト、P2WSH アドレス、請求・返金取引は独立した Python ライブラリ embit と、署名は python-ecdsa とバイト単位で一致する(開発中に 203 個のランダムな鍵でも比較した)。1.01 の規則(誤った s、誤った鍵、早すぎる返金、有効化前、バージョン 1 での HTLC)と、2 つのウォレットによる完全なスワップ+キャンセルのシナリオ。araclar/kopru_testi.py:2 つの Bitcoin 1.01 ノード+Bitcoin Core 31.1 regtest によるエンドツーエンド、41/41。 Bitcoin Core は請求取引を受け入れ、BTC は受取人に届いた。返金取引は中央値時刻が T2 に達する前は "non-final" として拒否し、その後受け入れた。Ayşe は Core が採掘した取引から s を取り出して 1.01 を受け取った。1.01 の返金は T1 以降に機能した。- mempool.space testnet4 API の応答形式は読み取り専用の問い合わせで確認し、アプリウィンドウはヘッドレスの Edge で実行した(ページ、監視、CSP)。
16e. 正直な現状と限界
- 本物の BTC(メインネットや testnet4)でのスワップはまだ行っていない。ビットコイン側は regtest 上で本物の Bitcoin Core を相手に試験した。最初の本番スワップは testnet4 で、その後メインネットで少額から行うこと。
- 本番のスワップでは、相手も同じネットワークで同期済みの Bitcoin 1.01 ノードを動かす必要がある(ロックを自分の目で確かめるため)。
tohumlar.txtにはまだ公開シードがない。同じローカルネットワーク、--baglan IP:ポート、またはシードの設定が必要である。 - スワップの間、1.01 チェーンではブロックが生成され続けなければならない。承認と中央値時刻はブロックとともに進む。誰も採掘しなければ、Ayşe の請求は T1 までに承認されない。ネットワークで唯一のマイナーがあなたなら、スワップの間は採掘を続けること。
- オファーと承諾のコードは手作業で渡す(フェーズ 7 の個人メッセージが入れば、アプリ内から送れるようになる)。
- Android 用の既製の
android/bitcoin101-arm64は古い版である。Termux でandroid/termux_derle.shを使ってビルドし直す必要がある。 - ライトコインは同じスクリプトで追加できる(アドレスの接頭辞とネットワーク設定)。イーサリアムには別のコントラクトが要る。
- 試験的な上限(フェーズ 5c):本物の BTC(ビットコインのメインネット)を使うスワップは 1 回あたり最大 0.01 BTC
(
GERCEK_BTC_EN_FAZLA)。理由:1.01 側の承認の安全性は、ネットワーク全体の採掘能力に等しい。ネットワークが小さいうちは、悪意ある Ali が、Ayşe が BTC を送ったあとで自分の 1.01 のロックを取り戻す、より長い分岐を採掘できてしまう。ブリッジのページはメインネットでこれを明記している。ネットワークが成長すれば上限は外せる。
17. フェーズ 5c:共有時の安全性と堅牢化 実装済み
プログラムを他の利用者と共有する前に行ったセキュリティ点検(2026-10-26)の結果のうち、実装したもの。ジェネシスと難易度の下限は意図的に変更していない。ローンチ時にともに決める(下記「意図的に残した課題」)。
データフォルダと共有
| 対策 | 詳細 |
|---|---|
| データはユーザープロファイルに | Windows は %LOCALAPPDATA%\Bitcoin101\{ana,lab}、Linux/Termux は ~/.bitcoin101(src/sistem.*)。プログラムフォルダを共有してもウォレットは含まれない。プロファイルフォルダは Windows の他のユーザーから閉じられている。POSIX ではフォルダ 0700、ウォレット 0600。 |
| 自動移行 | 古い veri\ は初回起動時に移される。新しい場所に実データ(チェーン、ウォレット、スワップ)があれば何も上書きしない。古い版が開いていて移行が途中で止まった場合、プログラムは停止する(空のフォルダで起動して「ウォレットが消えた」と思わせないため)。同じドライブ内で移したフォルダは元の場所の緩い権限を引き継ぐため、移行後に権限をリセットしてプロファイルフォルダから継承させる(izinleri_devral、icacls /reset /T と同じ)。5c の最初の版で移されたフォルダは起動時に修復される。 |
| UTF-8 コードページ | src/bitcoin101.manifest(activeCodePage UTF-8、asInvoker)。MinGW では std::ifstream が狭い文字列のパスをシステムのコードページで、std::filesystem::path は UTF-8 で解釈する。トルコ語の文字を含むユーザーフォルダ(C:\Users\Gökçe)で両者を一致させるために必要。マニフェストが効かない場合(Windows 10 1903 より前)は短い(8.3 形式の)パスを使う。 |
| 共有パッケージ | paketle.bat:許可リストに基づく zip。ウォレット/チェーン/トークン/ピアのファイルや平文のマスターシークレット行が見つかれば停止する。SHA256SUMS.txt。imzali で SLH-DSA 署名。 |
| ファイル署名 | bitcoin101 imzala / imza-dogrula:メッセージ=ORION-512("dosya-imzasi", SHA-256(ファイル))、コンテキスト orion-stars-up-my-sleeve/dosya。--adres で期待する署名者を確認する。 |
| プログラムファイルの点検 | プログラムまたはデータのフォルダが Everyone / Authenticated Users / Users から書き込み可能なら、セキュリティページで警告する(baskalari_yazabilir)。C:\ 直下のフォルダは既定でこうなっている。 |
| バージョンとハッシュ | アプリの「設定 → 情報」:バージョン、プログラムの SHA-256、データフォルダ。bitcoin101 surum。ピアは SELAM の省略可能な最後のフィールドでバージョンを伝える(古い版は余分なバイトを無視する)。ネットワークページに表示される。 |
ウォレットとローカルインターフェース
| 対策 | 詳細 |
|---|---|
| トークンはページに置かない | プログラムは .../#jeton=<16 進 48 文字> でウィンドウを開く。ページはトークンを受け取り、ブラウザのサイト専用ストレージに書き込み、アドレスバーから消す。トークンは <データ>/uygulama.jeton に保存され続ける(2 回目のダブルクリックやインストール済み PWA のため)。更新するには、プログラムを閉じた状態でファイルを削除する。 |
| 誤ったパスワードの待機 | 3 回間違えたあとは、誤入力のたびに待ち時間が倍になる(5 秒 → 5 分)。待機中は正しいパスワードも試さない(429)。セキュリティページで警告。 |
| ウォレットのワーカー | /c/... リクエストは別スレッドで処理する。Argon2id と SLH-DSA(鍵生成、署名)の実行中はチェーンのロックを手放し(Cuzdan::agir_is_kancasi)、その間はウォレット自身のデータだけを使う。ネットワークとマイナーは止まらない。各リクエストの後、マスターシークレットはメモリから消去される。 |
| チェックサム付きバックアップ | 72 文字=16 進 64 文字のマスターシークレット+ORION-512("ana-sir-kontrol", シークレット) の先頭 4 バイト。紙から 1 文字でも書き間違えると復元は拒否される(以前は黙って別の空のウォレットが開いていた)。古い 64 文字のバックアップも受け付ける。 |
| シークレットをコマンドラインに置かない | cuzdan geri-yukle はシークレットを画面に表示せずに尋ねる(コマンドラインはプロセス一覧や PowerShell の履歴ファイルに残るため)。 |
| 暗号化前のコピーを残さない | 暗号化されていないウォレットを暗号化すると、古いファイルと暗号化前の .yedek コピーはゼロで上書きして削除される(コンソールでもアプリでも同じ)。 |
| NFC | パスワードは C++ 側でも NFC に正規化する(Latin-1+ラテン文字拡張 A の合成、トルコ語を含む)。合成できない結合アクセント記号は新しいパスワードでは拒否する。古いパスワードでは、ロック解除時にまず NFC、だめなら元の形を試す。 |
| CSP nonce | インラインスクリプトは応答ごとに異なるランダムな nonce で実行される。script-src 'unsafe-inline' は削除した。 |
| メモリ | アプリの接続を閉じる際、リクエスト(パスワード)と応答(マスターシークレットの可能性がある)のバッファを消去する。 |
ネットワーク(P2P)とエクスプローラー
| 対策 | 詳細 |
|---|---|
| 違反の分類 | islem_dogrula(..., bool* ihlal):壊れた署名、使用される出力に属さない鍵、形式の誤り、入力を超える出力など状態に依存しない誤りは違反とし、送ってきたピアを禁止する。出力がない/使用済み、未成熟、タイムアウト未到来、規則が未有効、未知のバージョンは違反としない(ピアが別の分岐や新しい版を見ている可能性がある)。 |
| IP の禁止 | 禁止したピアの IP は、1 時間は受信接続としても受け付けない(127.0.0.1 を除く)。同じ IP からの受信ピアは最大 4。 |
| 取引の速度制限 | 1 つのピアから検証する取引は毎分最大 120。 |
| 署名キャッシュ | 有効な署名は完全な ID(本体+署名)でキャッシュする。プールとマイナーが同じ取引を再検証するとき、SLH-DSA を計算し直さない。使用される出力の内容は txid によって固定されているので安全である。 |
| 保留プールの上限 | 最大 32 MB / 5000 取引。var_mi / harcandi_mi は集合を使って O(log n)。 |
| 段階的な同期 | まず、分岐の仕事量がポリシーを満たす最短の接頭部分をまとめて適用し(必要なら再編成)、残りのブロックは届くたびに 1 つずつ追加する。未検証のブロックは最大 128 MB のバッファで待つ(以前は 500 × 4 MB = 2 GB)。 |
| アドレスの選別 | ADRESLER は接続ごとに 1 回だけ受け付ける。数値の IP のみ。インターネット上のピアからはローカル/プライベートアドレス(127/8、10/8、192.168/16、100.64/10、fc00::/7 など)を受け取らない。UDP 探索はローカルアドレスからのみ。アドレス帳が満杯になると、一度も接続できなかった項目を外す。 |
| ネットワークグループの多様性 | ピアから知ったアドレスへの送信接続は、各 /16(IPv6 は /32)グループから最大 1 つのピアを選ぶ(エクリプス攻撃対策)。シードと手動で与えたアドレスはこの制限を受けない。 |
| 接続プールの分離 | ウォレットのインターフェース(16)とエクスプローラー(64、IP あたり 8)は別。--web-genel を有効にしても、外部からの遅い接続でウォレットが固まることはない。 |
| ピアの IP を隠す | エクスプローラーの /api/esler の応答では、外部からのリクエストに対してアドレスを "gizli"(非公開)と表示する。 |
| インデックス | チェーンはアドレス → 出力、出力 → 使用者のインデックスを持つ(再編成時には巻き戻す)。取引・ブロックの接頭辞検索、アドレスページ、ウォレットの残高と履歴は、もはやチェーンを最初から走査しない。 |
採掘の保護
メインネットでの採掘は、少なくとも 1 つのピアが接続し、同期が終わり、より多くの仕事量を示すピアがいないときに動く。ピアがいなくなると待機する。理由:ネットワークにつながっていない新しいコンピュータは、難易度が低いうちは数秒で
100 ブロック以上の独自のチェーンを採掘してしまい、ファイナリティ規則(第 13 節)のため二度と自動ではメインチェーンと合流しない。ネットワークの最初の/唯一のノードには --tek-basina(アプリでは「ピアなしでも採掘」)がある。
kaz コマンドは、このフラグなしではメインネットで動かない。テストネットワークには制限がない。
ビルド
-fstack-protector-strong -D_FORTIFY_SOURCE=2。Windows では --dynamicbase --nxcompat --high-entropy-va、Termux では
-fPIE -pie -z relro -z now。bitcoin101 fuzz:取引、ブロック、HTTP、JSON、ビットコインの取引、アドレス、オファーコードの各パーサーに壊れたデータを与える。正しく解読できた取引・ブロックは、まったく同じ形で書き戻せなければならない。開発中に -D_GLIBCXX_ASSERTIONS(配列の境界検査)付きで 600 万件の入力を与え、クラッシュも不整合もなかった。
検証:bitcoin101 test 第 19〜20 部(バックアップのチェックサム、NFC、アドレスの選別、CSP nonce、暗号化前のコピーの削除、違反の分類、署名キャッシュ、インデックスの整合性と再編成後のインデックス)。araclar/uygulama_testi.py 44/44。偽造署名付きの取引を送るピアが切断されることを生の P2P クライアントで、採掘の待機を 2 つの一時的なメインネットノードで、手作業で確かめた。
意図的に残した課題
- ジェネシス/難易度の下限:メインネットは #249 で難易度の下限(2^16)にあり、予定から大きく遅れている。ローンチ時に、新しいジェネシス、引き上げた下限、ローンチブロックへのアンカーをともに決める。
- 暗号化された P2P(ML-KEM-1024+X25519):フェーズ 6。現在、ピア間の通信は暗号化されていない(内容はもともと公開のチェーンであり、問題はプライバシーと中間者である)。
- コード署名(Authenticode):証明書が必要。当面は SHA-256+SLH-DSA のファイル署名で代える。
- 規模:チェーン全体が RAM 上にあり、起動のたびにすべての署名を最初から検証している。ディスクベースのブロック保存とチェックポイント(assumevalid に類するもの)が必要である。
- Android 用の既製の
bitcoin101-arm64は古い版で、共有パッケージには含めない。Termux でのビルドはこの環境では試せなかった(Linux のコンパイラがない)。POSIX のコード経路はスマートフォン上でtestによって検証する必要がある。
