チェーン束縛署名
ZooBC の署名は 1 つのチェーンでしか有効ではありません。トランザクションに署名する前に、ウォレットはチェーンのジェネシスハッシュを含むダイジェストを計算します。そのため、testnet で署名された支払いは、同じ鍵がすべてのチェーンで同じアドレスになるにもかかわらず、mainnet や devnet では検証に通りません。同じ束縛が、ノード間の接続とチェーン外で署名されたメッセージも守っています。
ダイジェスト
署名者が生のトランザクションのバイト列に署名することは決してありません。署名するのは次のダイジェストです。
digest = SHA3-256("ZBC-TX" ‖ genesis hash ‖ unsigned transaction bytes)
transaction hash = SHA3-256(unsigned transaction bytes ‖ signature)
transaction id = the first 8 bytes of the transaction hash, little-endian
タグ "ZBC-TX" は、そのダイジェストがトランザクションのものであることを示します。他の署名付きの操作は別のタグを使います(後述)。ジェネシスハッシュが署名を 1 つのチェーンに結び付けます。受け入れられるのはこのチェーン束縛ダイジェストだけで、チェーンを含まない素のバイト列に対する署名は、どのチェーンでも拒否されます。署名手順の全体は トランザクションへの署名 を参照してください。
ジェネシスハッシュはチェーンの身元
ジェネシスハッシュは、チェーンの最初のブロックのハッシュです。チェーンのジェネシス設定から導かれるため、その設定の確定済みの値を 1 つでも変えると新しいハッシュ、つまり別のチェーンになります(ジェネシスブロック を参照)。ZooBC のどこにも、独立したネットワーク ID のバイトはありません。ジェネシスハッシュがチェーンの唯一の身元です。devnet、testnet、mainnet はそれぞれ独自のジェネシスハッシュを持ち(devnet、testnet、mainnet を参照)、再立ち上げされたテストネットワークは新しいジェネシスハッシュを得ます。
ノードは自分のチェーンの genesis_hash と signing_version を情報ルート /api/v1/node/info で報告するため(ノード API を参照)、ウォレットやツールはどのチェーンのために署名しているかを知ることができます。
チェーンをまたぐリプレイ
testnet で支払いが署名され、誰かがそれを mainnet にコピーしたとします。mainnet のノードは mainnet のジェネシスハッシュでダイジェストを計算するため異なる値を得て、署名は検証に通りません。トランザクションは「このチェーン用に署名されていない」として拒否されます。金額は関係なく、ウォレットが何かを付け加える必要もありません。
同じ鍵はすべての ZooBC チェーンで同じアドレスになり、あるチェーンで資金を受け取ったアドレスも、別のチェーンでは残高ゼロと表示されるだけです。だからこそ束縛が重要なのです。束縛がなければ、あるチェーンで行った支払いを別のチェーンにコピーして、そこでコインを動かせてしまいます。
すべてのアカウントタイプ、すべての署名者
ZooBC のアカウントは、ZooBC 独自の Ed25519 鍵、Bitcoin や Ethereum の鍵など、さまざまな種類の鍵で管理できます(鍵とアカウントタイプ を参照)。どのアカウントタイプも同じチェーン束縛ダイジェストに署名します。一部は、元のチェーンの署名方式が求めるとおり、先にそれをハッシュし直します(たとえば Ethereum 形式の鍵はその Keccak-256 ハッシュに署名します)。マルチシグネチャ アカウントの参加者は、内部のトランザクションのチェーン束縛ダイジェストに署名します。
他の署名付きの操作は、それぞれ独自のダイジェストを使い、それらもチェーンに束縛されています。アカウントグループをリンクしたり管理したりするための同意("ZBC-GROUP-LINK"、"ZBC-GROUP-CONTROL")、複数当事者によるエスクローの共同署名、そしてノードのプール内の保留中トランザクションを取り消す要求("ZBC-CANCEL")です。
ノードとメッセージ
チェーンへの束縛はトランザクションにとどまりません。
- ピアのハンドシェイク。 2 つのノードが接続するとき、ハンドシェイクはノード鍵で署名され、ジェネシスハッシュを運びます。別のチェーンのピアは "Genesis hash mismatch" として拒否されるため、あるチェーンのノードが別のチェーンのノードとピアになることはありません。
- 署名付きメッセージ。 ツールでチェーン外で署名されたメッセージは、ダイジェスト SHA3-256("ZBC-MSG-v2" ‖ genesis hash ‖ message) を使うため、devnet で署名されたメッセージが testnet や mainnet で検証に通ることはありません(署名付きメッセージと暗号化メッセージ を参照)。
プロトコルの中ではレシートが例外です。レシートはチェーンを指定しないため、それ自体はチェーンへの束縛を持ちません。ただし、高さとハッシュで参照ブロックを指定しており、バリデーターがそれを確認します。