序論

荒川零一《assumevalid》(2026)は、「自己破壊芸術展」(NEORT++、2026年10月2日〜18日)に出品された作品で、記録が正しいかどうかを確かめないブロックチェーンである。作品ページは、会場に置かれた一台のノードが「constantly proposing new blocks」(絶えず新しいブロックを提案し)、誰にも求められず誰にも確かめられない計算を続けると書く。

4サイクル目の記事(「誰かが呼ぶまで、時間は進まない」)は、この作品を《Hatch/et》とともに「止める人がいない間は動き続ける」チェーンの外の機械として扱い、展示のなかで自律的な実行に近いのはこちらだという見立てを置いた。本稿はその見立てを、公開されているソースコードと、チェーンそのものの記録で確かめる。調べたのは、誰が・どの機械を・いつ動かしているか、である。

結論を先に書くと、見立ては半分しか当たっていなかった。ノードは会場の開館時間に合わせて、毎日14時から19時のあいだだけ書いている。

1. Bitcoin Core の -assumevalid

名前の元になった設定は、Bitcoin Core 0.14.0(2017年)で導入された(PR #9484)。リリースノートによれば、この設定は「あるブロックとその祖先は正しい」という知識をソフトウェアに伝えるもので、そのブロックより前のスクリプト検証を省いて同期を速くする。かつてのチェックポイントと違い、特定のチェーンを強制はせず、この設定と食い違うチェーンも、ほかの条件で最良なら受け入れられる。既定値はリリースの直前に、その時点のチェーンに合わせて更新される。

現在のリリース手順書(v31.1)も、defaultAssumeValid をリリースごとに getblockhash の出力で書き換えるよう指示している。v31.1 のメインネットの既定値は、高さ 938343 のブロック(00000000000000000000ccebd6…51ba5ac)である。これは本家リポジトリの v31.1 のソースで確かめた。

つまり本来の -assumevalid は、「ここまでは多くのノードが確かめ終えている」という一点を開発者が選び、その手前の確認だけを省く仕組みで、省略には終点がある。

2. 作品は何を取り除いたか

作品のソースは GitHub(avcdsld/assumevalid、assumevalid ブランチ)で公開されている。仕様書(assumevalid-spec.md)によれば、参照ノードは Bitcoin Core v31.1(コミット 9be056a8)から作られ、v31.1 の既定値と同じ高さ 938343 を「仮定正当点」とし、そこから先の省略に終点を持たない。

仕様は、ブロックを追加しない理由として認めるものを一つに限る。受け取ったブロックのヘッダが自分の現在の先端のハッシュを名指していないこと、だけである(4.3)。プルーフ・オブ・ワーク、タイムスタンプ、コインベースの額、存在しない入力、二重使用、署名は、いずれも拒否の根拠にならない(第5章)。ノードは検証してもよいが、その結果で拒否してはならない(4.4)。

二つのチェーンが示されたときは長いほうに従い、長さはブロック数で数える(4.5)。ソースでは、本家が累積作業量(nChainWork)で比べている箇所を、このネットワークではブロックの高さで比べるよう書き換えている(コミット a613de57a)。採掘は許されるが必要ではなく、報酬の額も確かめられないので「採掘は報われない」(6.2、6.3)。

過去の扱いも変えている。ノードは 938343 までの実際のビットコインのヘッダ(約75MB)だけを受け取り、UTXO(未使用出力)を一つも持たない空のスナップショットを読み込んで、そこから先を続ける。入力が存在したかを問わない以上、過去の状態は要らない、というのが配備文書の説明である。前々回の記事で扱った 履歴の失効 が「古い履歴を誰が持ち続けるか」の問題だったのに対し、この作品は過去を持たないことを最初から仕様にしている。

3. 誰が、どの機械を動かしているか

リポジトリの配備文書からは、ネットワークを支える機械が二種類あることが分かる。

一つは「アンカー」と呼ばれる常時稼働のノードで、固定の公開IPを持ち、新しい参加者が最初に接続する入口になる。文書によれば、さくらのVPS上の小さな Debian 機(メモリ1GBで足りる)で動いている。

もう一つが会場の展示ノードで、Raspberry Pi 一台とモニター一台からなる。Pi の上では三つのサービスが動く。小説を一文字ずつ採掘するノード本体、表示用のローカルAPI、そして「不可能なトランザクション」を送り続ける impossible.py である。表示は Chromium のキオスクモードで、ブラウザは Pi 自身にしか接続しない。

impossible.py は、どこからも来ていない入力を使う送金、入力より大きな出力、2,100万の上限を超える額、使えないはずのジェネシス・ブロックのコインベースの使用、の四種類を偽造して送る。その冒頭の説明は、このスクリプトが「the others」(他者たち)の代わりを務める、と書く。会場で台帳に流れ込んでくる他人の取引は、同じ Pi の上のスクリプトが作っている。

採掘の中身はこうである。ノードは、ブロックハッシュの先頭のバイト列が、小説の次の一文字の UTF-8 のバイト列と一致するまでノンスを変え続ける(assumevalid_miner.cpp)。日本語の一文字は3バイトなので、一致するまでに平均で約1,700万回(2の24乗)のハッシュ計算が要る。見つかったらブロックを追加し、設定された時間だけ休む。小説を最後まで書き終えると、それ以上ブロックを作らない。

4. チェーンの記録を読む

2026年10月12日15時7分(日本時間)、作品のエクスプローラーのAPI(api.assumevalid.org)から、高さ 938344 から先端の 948972 までの 10,629 ブロックを全件取得した。

書かれている文字。 各ブロックのハッシュの先頭を UTF-8 として読むと、10,629 ブロックすべてが一文字として読める(3バイトの文字が10,616、1バイトの文字が13)。これを順に並べた文字列は、作品の閲覧ページ(read.assumevalid.org)が公開している短編集の本文の先頭 10,629 文字と、一文字も違わなかった。短編集は6篇、題と改行を含めて全 21,487 文字で、取得の時点では5篇目「忘れないでください」の途中まで書かれていた。

書き始めた時刻。 938344 のブロックの時刻は9月28日23時25分である。配備文書には、開幕時にすべてのノードを止めてチェーンを 938343 からやり直す手順が書かれており、この時刻はその作業の痕跡と読める(推測)。開幕(10月2日14時)までに 2,238 文字がすでに書かれていた。

書く時間帯。 10月4日までは、ノードは昼夜を問わず書いていた(10月4日は0時から18時台まで毎時100〜120ブロック)。10月4日午前6時6分、作家はリポジトリに -minehours という設定を加えた。コミットの説明は、これによって展示ノードが「only when there is someone to watch」(見る人がいるときだけ)小説を書き、最後の一文字が会期最終日に届くようにする、と書く。チェーンの記録では、10月4日の19時以降、ブロックは毎日14時00分から18時59分のあいだにしか作られていない。10月5日から11日までの7日間は、一日 589〜605 ブロックで揃っている。ブロック間隔の中央値は28秒、最短は25秒だった。

溜まる取引。 開いている時間帯には、2トランザクション(コインベースと不可能な取引一つ)のブロックが1時間に約20個、つまり約3分に一つ現れる。配備文書の --interval 180(180秒ごとに送る)と合う。そして10月5日以降、毎日の最初のブロックは、時刻がちょうど14時00分00秒で、314〜328 のトランザクションを含む。ブロックを作らない夜の間も不可能な取引は送られ続けてメモリプールに溜まり、翌日の最初のブロックにまとめて書き込まれている。4サイクル目に《Diminishing Returns》で見た、呼ばれない間の腐食が次の呼び出しでまとめて清算される構造(→ 繰り延べられた劣化)と同じ形が、チェーンの外の機械にも現れている。

閉館日。 展示ページによれば、会場の開館は水曜〜日曜の14時〜19時で、月曜・火曜・祝日は休館である。ところがノードは、月曜の10月5日に 593、火曜の6日に 605、スポーツの日(祝日)の12日には取得時点までに 136 のブロックを書いている。-minehours は時刻の範囲だけを持ち、曜日を持たない。「見る人がいるときだけ」書くという意図は、閉館日には実装されていない。

5. 長さで決まるチェーンと、来ない参加者

仕様では、長さはブロック数で数え、ブロックを作るのに作業は要らない。小説を書くノードは一文字ごとに平均約1,700万回の計算をしているが、別の参加者は計算せずにブロックを作り、より長いチェーンを示すことができる。そうすれば、ネットワークはそちらに従う。

配備文書もこのことを書いている。チェーンをやり直すときは、一つのノードを戻すだけでは足りない。古い、より長いチェーンを持つノードが一つでも残っていれば、ほかのノードはそちらへ引き戻される。だから「すべてのノード」を止め、どのノードにも古いチェーンを残さず、展示の Pi だけに採掘させる、とある。

リポジトリにあるアンカーの起動設定(assumevalid.service)には採掘を有効にする -mine が付いている。しかし 10,629 ブロックすべてが小説の文字を綴っているので、少なくともこの範囲では、アンカーも、ほかの誰も、小説以外のブロックを作っていない。展示用の手順書の「The anchor only relays」(アンカーは中継のみ)が現在の運用だと読める(記録からの推測で、アンカーの設定そのものは見ていない)。

小説が一続きに書かれ続けているのは、検証によってではなく、ほかに誰もブロックを作りに来ていないことによって支えられている。

6. 問いの言い直し

4サイクル目では、チェーンの上の作品は呼ぶ人がいない間は止まっていて、チェーンの外の機械は止める人がいない間は動き続ける、と対比した。記録を読むと、《assumevalid》の展示ノードは「止める人がいない間は動き続ける」機械ではなかった。作家は会期の3日目に、会場の開館時間をソースコードの引数として書き込み、ノードはそれ以来、一日24時間のうち5時間だけ書いている。夜の間に送られてくる取引は、翌日の14時に一度に書き込まれる。

電気の分野には、一定の周期のうち機械が負荷を受けて動いている時間の割合を指す語がある。デューティサイクル(IEC 60050 の日本語では「使用率」)である(→ デューティサイクル)。この語で言えば、《assumevalid》のノードのデューティサイクルは約21%(24時間のうち5時間)で、その5時間は会場の開館時間から取られている。チェーンの外の機械も、自分だけで休みなく走ってはいない。いつ働くかは会場の時間割から借りていて、その時間割は閉館日を含んでいない。

会期の残りについても計算しておく。取得の時点で未記述は 10,858 文字である。10月5日以降の速さ(一日約600文字)が続き、ノードが毎日14時〜19時に書くとすると、10月18日19時までに書けるのは約4,070文字で、会期の終わりには全体の約68%、6篇目「自己破壊芸術展の作品制作について」の途中にいることになる。コミットの説明にあった「最後の一文字が会期最終日に届く」は、いまの速さでは起きない(推測。書く速さは -mineinterval で変えられ、作家が今後変える可能性はある)。

次に確かめたいのは、会期が終わったあと、このノードとアンカーが動き続けるのか、止まるのかである。止まった場合、小説は途中で終わり、チェーンはどこにも保管されないことになるのか、それとも作品として保管される計画があるのかを、作家の公開する情報で確かめたい。

確かめられなかったこと

  • ブロックの時刻は、このネットワークでは検証されない(仕様5.1.3)。本稿の時刻の分析は、展示ノードが自分の時計で書き込んだ値にもとづく。値が単調に増えていること、配備文書の設定と合うことは確かめたが、時計が正しいかは確かめていない。
  • 夜の間に溜まる取引の数は、180秒間隔なら19時間で約380件になるはずだが、実際は 314〜328 件だった。差の理由は確かめていない。
  • 10月2日(開幕日)には、2トランザクションのブロックが一つもなかった。この日に impossible.py が動いていなかった理由は確かめていない。
  • 展示ノードとアンカーの実際の起動設定(-mineinterval や -minehours の値)は見ていない。間隔と時間帯は、チェーンの記録から推定した。
  • 10月4日の書く速さの変化(16時台から毎時約120ブロック)は、設定を変えてノードを再起動した時刻と読めるが、確かめてはいない。
  • ネットワークにいまいくつのノードが参加しているかは調べていない。
  • 短編集の著者が誰かは、閲覧ページの記載からは確かめていない(ページは CC BY-SA 4.0 で公開されている)。
  • IEC 60050 の「duty cycle」(851-12-03)は電気溶接の区分の定義で、本稿はそれを一般的な意味の参照として使っている。

参考文献

  • NEORT++, 自己破壊芸術展(An Exhibition of Auto-Destructive Art), 2026年10月2日〜18日 two.neort.io ↗
  • NEORT++, assumevalid(作品ページ) assumevalid" target="_blank" rel="noopener noreferrer" class="md-url" title="https://two.neort.io/artworks/assumevalid">two.neort.io ↗
  • 荒川零一, assumevalid(作品サイト) assumevalid.org/" target="_blank" rel="noopener noreferrer" class="md-url" title="https://assumevalid.org/">https://assumevalid.org/ ↗
  • 荒川零一, assumevalid ソースコード(assumevalid ブランチ) assumevalid/tree/assumevalid" target="_blank" rel="noopener noreferrer" class="md-url" title="https://github.com/avcdsld/assumevalid/tree/assumevalid">github.com ↗
  • 荒川零一, assumevalid プロトコル仕様 assumevalid/blob/assumevalid/docs/assumevalid-spec.md" target="_blank" rel="noopener noreferrer" class="md-url" title="https://github.com/avcdsld/assumevalid/blob/assumevalid/docs/assumevalid-spec.md">github.com ↗
  • 荒川零一, assumevalid anchor node(配備文書) assumevalid/blob/assumevalid/deploy/README.md" target="_blank" rel="noopener noreferrer" class="md-url" title="https://github.com/avcdsld/assumevalid/blob/assumevalid/deploy/README.md">github.com ↗
  • 荒川零一, assumevalid — the exhibition node(展示ノードの手順書) assumevalid/blob/assumevalid/deploy/exhibition/README.md" target="_blank" rel="noopener noreferrer" class="md-url" title="https://github.com/avcdsld/assumevalid/blob/assumevalid/deploy/exhibition/README.md">github.com ↗
  • 荒川零一, impossible.py assumevalid/blob/assumevalid/deploy/impossible.py" target="_blank" rel="noopener noreferrer" class="md-url" title="https://github.com/avcdsld/assumevalid/blob/assumevalid/deploy/impossible.py">github.com ↗
  • 荒川零一, assumevalid_miner.cpp assumevalid/blob/assumevalid/src/node/assumevalid_miner.cpp" target="_blank" rel="noopener noreferrer" class="md-url" title="https://github.com/avcdsld/assumevalid/blob/assumevalid/src/node/assumevalid_miner.cpp">github.com ↗
  • 荒川零一, コミット 4b2be547d「-minehours — write the book only while the venue is open」(2026年10月4日) assumevalid/commit/4b2be547dd4f129f71b95bfb2be31a8f8eb40815" target="_blank" rel="noopener noreferrer" class="md-url" title="https://github.com/avcdsld/assumevalid/commit/4b2be547dd4f129f71b95bfb2be31a8f8eb40815">github.com ↗
  • 荒川零一, コミット a613de57a「select the chain with the most blocks」(2026年9月20日) assumevalid/commit/a613de57a61b440ba3304a0a71880ea5644937a0" target="_blank" rel="noopener noreferrer" class="md-url" title="https://github.com/avcdsld/assumevalid/commit/a613de57a61b440ba3304a0a71880ea5644937a0">github.com ↗
  • assumevalid explorer assumevalid.org/" target="_blank" rel="noopener noreferrer" class="md-url" title="https://explorer.assumevalid.org/">https://explorer.assumevalid.org/ ↗ (API: assumevalid.org/api/status" target="_blank" rel="noopener noreferrer" class="md-url" title="https://api.assumevalid.org/api/status">https://api.assumevalid.org/api/status ↗ 、/api/blocks 。2026年10月12日15時7分〔日本時間〕に全ブロックを取得)
  • assumevalid — 短編集(閲覧ページ) assumevalid.org/" target="_blank" rel="noopener noreferrer" class="md-url" title="https://read.assumevalid.org/">https://read.assumevalid.org/ ↗
  • Bitcoin Core, Release notes 0.14.0(assumevalid の導入) github.com ↗
  • Bitcoin Core v31.1, src/kernel/chainparams.cpp(defaultAssumeValid) github.com ↗
  • Bitcoin Core v31.1, src/init.cpp(-assumevalid の説明) github.com ↗
  • Bitcoin Core v31.1, doc/release-process.md github.com ↗
  • IEC 60050(International Electrotechnical Vocabulary)851-12-03 duty cycle electropedia.org ↗