사용 스크립트가 스크립트의 조건을 충족하려면 실행 후 스택에 무엇을 남겨야합니까?

Dec 07 2020

저는 Advanced Bitcoin Scripting에 대한 Andreas Antonopoulos 프레젠테이션 을 보고있었습니다 .

Andreas의 예에서 스크립트의 조건을 충족시키기 위해 스크립트가 실행 된 후 TRUE (다른 것은 없음)를 스택에 남겨 두어야한다는 것이 나타납니다. 이것도 여기 에 대해 문의 했습니다 .

따라서 일부 opcode (예 : EQUAL, CHECKSIG, CHECKMULTISIG)에 경쟁하는 opcode (예 : EQUALVERIFY, CHECKSIGVERIFY, CHECKMULTISIGVERIFY)가있는 VERIFY 접미사가 있습니다. 스택에 TRUE를 남겨 두는 대신 이러한 VERIFY opcode는 "조건부 연산자의 결과가 TRUE 인 경우 스크립트 실행을 계속"하지만 "TRUE를 스택으로 다시 푸시하지 않고 단순히 실행을 계속합니다". 이러한 VERIFY opcode는 redeem 스크립트의 실행이 TRUE TRUE TRUE라고 말하는 대신 스택에 TRUE (다른 것은 없음)를 남겨 두도록하는 데 사용할 수 있습니다.

그러나이 Bitcoin Core PR 검토 클럽 세션에서 Pieter Wuille은 다음과 같이 말했습니다 (패러 프레이징).

CLEANSTACK의 경우 0이 아닌 단일 요소가 포함 된 스택이 있어야합니다. CLEANSTACK없이 여러 요소가있는 비어 있지 않은 스택은 맨 위 요소가 0이 아닌 한 괜찮습니다.

두 가지 질문이 있습니다.

  1. 아마도 TRUE는 1과 동일하고 FALSE는 0과 동일합니까?

  2. FALSE로 평가되는 opcode는 즉시 실패하고 실행이 종료됩니까? 따라서 비 CLEANSTACK을 사용하면 FALSE가 즉각적인 실패를 초래하고 최종 TRUE를 평가하지 않으므로 TRUE FALSE TRUE 패스의 결과 스택을 볼 수 없습니다. 그러나 TRUE 3 TRUE 5 스택을 볼 수 있으며 이는 비 CLEANSTACK으로 전달됩니다. (CLEANSTACK은 결과 스택에 단일 요소가 있어야하므로 CLEANSTACK으로 실패합니다.)

답변

3 MichaelFolkson Dec 07 2020 at 20:42

IRC 및 sanket1729에서이 질문에 답 해주신 harding에게 감사드립니다.

아마도 TRUE는 1과 동일하고 FALSE는 0과 동일합니까?

TRUE는 0이 아닌 값입니다. 이것은 확인 후 스택에서 값을 팝하지 않는 이전 OP_NOPx opcodes와 관련된 스크립트에서 자주 사용됩니다. 예를 들어, 특정 높이 이후에 채굴자가 사용할 수있는 스크립트는 다음을 사용할 수 있습니다. <locktime> OP_CLTV; CLTV가 실패하면 트랜잭션이 유효하지 않습니다. 통과하면 스택에 0이 아닌 값이 남아 있으면 스크립트가 통과 할 수 있습니다.

FALSE로 평가되는 opcode는 즉시 실패하고 실행이 종료됩니까? 따라서 비 CLEANSTACK을 사용하면 FALSE가 즉각적인 실패를 초래하고 최종 TRUE를 평가하지 않으므로 TRUE FALSE TRUE 패스의 결과 스택을 볼 수 없습니다. 그러나 TRUE 3 TRUE 5 스택을 볼 수 있으며 이는 비 CLEANSTACK으로 전달됩니다. (CLEANSTACK은 결과 스택에 단일 요소가 있어야하므로 CLEANSTACK으로 실패합니다.)

CLEANSTACK없이 중요한 것은 실행이 끝날 때 스택의 최상위 값입니다. 스택 아래에있는 것은 중요하지 않습니다.

CLEANSTACK은 P2SH의 표준 규칙이지만 Segwit v0 ( BIP141 사양 ) 및 Tapscript, SegWit v1 ( BIP342 사양 , 규칙 4, ii)에 대한 합의 규칙입니다.

여기서 "실패"라는 단어는 모호합니다. 서로 다른 opcode가 실패 할 수있는 여러 가지 방법이 있습니다. 예를 들어 OP_CHECKSIG가 실패하면 0을 스택에 푸시합니다. 그러나 OP_CHECKSIGVERIFY가 실패하면 전체 스크립트가 실패합니다. OP_0 OP_0 OP_1 만 사용하여 스택에 TRUE FALSE FALSE를 넣을 수 있습니다.

EQUALVERIFY, CHECKSIGVERIFY, CHECKMULTISIGVERIFY와 같은 VERIFY opcode 중 일부는 실패시 즉시 종료되지만 비 VERIFY 동등 코드는 그렇지 않습니다.

중요한 것은 스크립트 평가가 끝날 때의 스택 상태입니다. 예를 들어 OP_CHECKSIG 다음에 OP_IF OP_PUSHNUM1 OP_ELSE OP_PUSHNUM2 OP_ENDIF를 수행 할 수 있습니다. 예를 들어 서명이 성공하면 하나의 분기를 가져옵니다. 실패하면 다른 분기를 선택합니다 (이는 모범 사례로 간주되지 않으며 일반적으로 수행해서는 안됩니다.)

CLEANSTACK은 사람들이 scriptSig 또는 감시 데이터에 많은 쓰레기를 넣도록하여 가단성을 방지하려는 시도입니다. 사용되지 않는 스택에 많은 데이터를 푸시 할 수 있고 스크립트가 올바르게 평가하는 것을 방해하지 않기 때문입니다. (Pre-segwit, 이것은 txid 가단성에 영향을 주며 표준 정책 규칙으로 시행되었습니다. segwit에서는 합의 규칙이므로 더 이상 가능하지 않습니다.)