償還スクリプトがスクリプトの条件を満たすために、実行後にスタックに何を残さなければなりませんか?
私は、高度なビットコインスクリプティングに関するこのアンドレアスアントノプロスのプレゼンテーションを見ていました。
Andreasの例から、引き換えスクリプトがスクリプトの条件を満たすには、実行後にスタックにTRUE(および他には何も)を残さないようにする必要があるようです。こちらもお問い合わせいただきました。
したがって、一部のオペコード(EQUAL、CHECKSIG、CHECKMULTISIGなど)に競合するオペコード(EQUALVERIFY、CHECKSIGVERIFY、CHECKMULTISIGVERIFYなど)が含まれるようなVERIFYサフィックスがあります。スタックにTRUEを残す代わりに、これらのVERIFYオペコードは「条件演算子の結果がTRUEの場合、スクリプトの実行を継続します」が、「そのTRUEをスタックにプッシュバックせず、単に実行を継続します」。これらのVERIFYオペコードを使用して、償還スクリプトの実行がTRUE TRUE TRUEと言うのではなく、スタックにTRUE(および他には何も)を残さないようにすることができます。
ただし、このビットコインコアPRレビュークラブセッションで、 Pieter Wuilleは次のように述べています(言い換え):
CLEANSTACKの場合、ゼロ以外である必要がある単一の要素を含むスタックが必要です。CLEANSTACKがない場合、最上位の要素がゼロ以外である限り、複数の要素を含む空でないスタックは問題ありません。
2つの質問があります:
おそらくTRUEは1に相当し、FALSEは0に相当しますか?
FALSEと評価されたオペコードは、即座に失敗して実行を終了しますか?したがって、CLEANSTACK以外の場合、結果としてTRUE FALSE TRUEパスのスタックが表示されることはありません。これは、FALSEがすぐに失敗し、最終的なTRUEを評価しないためです。ただし、たとえばTRUE 3 TRUE 5のスタックが表示される可能性があり、これは非CLEANSTACKで合格します。(CLEANSTACKは結果のスタックに単一の要素を持たなければならないため、CLEANSTACKでは失敗します)。
回答
編集のためにIRCとsanket1729でこの質問に答えてくれてありがとう。
おそらくTRUEは1に相当し、FALSEは0に相当しますか?
TRUEは、ゼロ以外の値です。これは、検証後に値をスタックからポップしない以前のOP_NOPxオペコードを含むスクリプトでよく使用されます。たとえば、特定の高さの後にマイナーが使用できるスクリプトでは、次のものを使用できます<locktime> OP_CLTV
。CLTVが失敗した場合、トランザクションは無効です。合格した場合、スタックにゼロ以外の値が残っていると、スクリプトが合格します。
FALSEと評価されたオペコードは、即座に失敗して実行を終了しますか?したがって、CLEANSTACK以外の場合、結果としてTRUE FALSE TRUEパスのスタックが表示されることはありません。これは、FALSEがすぐに失敗し、最終的なTRUEを評価しないためです。ただし、たとえばTRUE 3 TRUE 5のスタックが表示される可能性があり、これは非CLEANSTACKで合格します。(CLEANSTACKは結果のスタックに単一の要素を持たなければならないため、CLEANSTACKでは失敗します)。
CLEANSTACKなしで重要なのは、実行終了時のスタックの最上位値です。スタックのさらに下にあるものは重要ではありません。
CLEANSTACKはP2SHの標準ルールですが、Segwit v0(BIP141仕様)およびTapscript、SegWit v1(BIP342仕様、ルール4、ii)のコンセンサスルールです。
ここでは「失敗」という言葉が曖昧です。さまざまなオペコードが失敗する可能性のあるさまざまな方法があります。たとえば、OP_CHECKSIGが失敗した場合、スタックに0をプッシュするだけです。ただし、OP_CHECKSIGVERIFYが失敗すると、スクリプト全体が失敗します。OP_0 OP_0 OP_1だけを使用して、スタックにTRUE FALSEFALSEを置くことができます。
EQUALVERIFY、CHECKSIGVERIFY、CHECKMULTISIGVERIFYなどの一部のVERIFYオペコードは、失敗するとすぐに終了しますが、VERIFY以外のオペコードは終了しません。
重要なのは、スクリプト評価終了時のスタックの状態です。たとえば、OP_CHECKSIGの後にOP_IF OP_PUSHNUM1 OP_ELSE OP_PUSHNUM2 OP_ENDIFを実行できます。たとえば、署名が成功した場合は、1つのブランチを取得します。失敗した場合は、別のブランチを使用してください(ただし、これはベストプラクティスとは見なされないため、通常は実行しないでください)。
CLEANSTACKは、scriptSigまたは目撃者のデータに大量のジャンクを入れさせることにより、順応性を防ぐ試みです。使用されることのない大量のデータをスタックにプッシュするだけで、スクリプトが正しく評価されるのを妨げることはないからです。(pre-segwit、これはtxidの可鍛性に影響を与え、標準ポリシールールとして適用されました。segwitでは、コンセンサスルールであるため、これは不可能になりました)