‘Mastering Bitcoin 2nd’ 세미나 10, 7장. Advanced Transactions and Scripting 2/2
Scripts with Flow Control (Conditional Clauses)
Bitcoin implements flow control using the IF, ELSE, ENDIF, and NOTIF opcodes. Additionally, conditional expressions can contain boolean operators such as BOOLAND, BOOLOR, and NOT.
Script는 조건 선택문을 작성할 수 있도록 IF, ELSE, ENDIF, NOTIF, BOOLAND, BOOLOR, NOT 연산자를 제공합니다. 이 연산자들을 사용해서 실행 흐름을 조건에 따라 제어할 수 있습니다.
Script는 스택 기반 언어이기 때문에 조건이 IF 연산자 앞에 나와야 함에 주의를 기울입니다.
Conditional Clauses with VERIFY Opcodes
VERIFY로 끝나는 연산자들로도 조건 선택문을 작성할 수 있습니다. 이러한 연산자들은 조건이 만족할 경우에만 선택적(optional)으로 실행되어야 하는 실행 흐름을 작성할 수 있습니다.
예) EQUALVERIFY
- HASH160 <expected hash> EQUALVERIFY <Bob’s Pubkey> CHECKSIG
- 잠금 스크립트가 위와 같은 경우 동일한 결과를 얻을 수 있는 스크립트를 IF 연산자를 사용하는 조건 선택문으로 작성할 수 있습니다.
- HASH160 <expected hash> EQUAL IF <Bob’s Pubkey> CHECKSIG ENDIF
- 해제 스크립트는 아래와 같이 작성됩니다.
- <Bob’s Sig> <hash pre-image>
- 해제 스크립트와 잠금 스크립트를 결합해서 순차적으로 실행하면 <Bob’s Sig>와 <hash pre-image>가 순차적으로 스택에 추가되고, <hash pre-image>를 꺼내서 HASH160을 실행하고 그 결과를 스택에 추가합니다. 그리고 <expected hash>를 스택에 추가하고, EQUAL을 실행하기 위해 <expected hash>와 <hash pre-image>의 HASH160값을 스택에서 꺼냅니다. 이 두 값이 같으면 1을 스택에 추가합니다. 그리고 1을 스택에서 꺼내서 조건 선택문을 실행합니다. 조건이 1이니까 IF 연산자가 실행됩니다.
- 잠금 스크립트가 위와 같은 경우 동일한 결과를 얻을 수 있는 스크립트를 IF 연산자를 사용하는 조건 선택문으로 작성할 수 있습니다.
Using Flow Control in Scripts
UTXO의 잠금 스크립트에 조건식을 작성할 수 있습니다. 잠금 스크립트의 어떤 경로가 실행될 지는 해제 스크립트에 의해 결정됩니다.
예) 앨리스나 밥 중에 누구라도 하나가 서명하면 잠금 해제될 수 있도록 하려고 합니다. 잠금 스크립트는 다음과 같이 작성됩니다. 조건은 해제 스크립트로 제공되어야 합니다.
- IF <Alice’s Pubkey> CHECKSIG ELSE <Bob’s Pubkey> CHECKSIG ENDIF
- 앨리스의 서명에 의해 잠금 해제 하려면 IF 문이 실행되어야 하기 때문에 조건은 1이 되어야 합니다. 이 경우 해제 스크립트는 다음과 같이 작성되어야 합니다.
- <Alice’s Sig> 1
- 밥의 서명에 의해 잠금 해제 하려면 ELSE 문이 실행되어야 하기 때문에 조건은 0이 되어야 합니다.
- <Bob’s Sig> 0
- 앨리스의 서명에 의해 잠금 해제 하려면 IF 문이 실행되어야 하기 때문에 조건은 1이 되어야 합니다. 이 경우 해제 스크립트는 다음과 같이 작성되어야 합니다.
조건 선택문은 조건문 내에 또 다른 조건 선택문을 작성할 수 있습니다. 이를 사용해 복잡한 계층을 갖는 조건 선택문을 작성할 수 있습니다.
예) Timelock을 갖는 다중 서명
-
12345678910IFIF2ELSE<30 days> CHECKSEQUENCEVERIFY DROP <Abdul the Lawyer's Pubkey> CHECKSIGVERIFY 1ENDIF<Mohammed's Pubkey> <Saeed's Pubkey> <Zaira's Pubkey> 3 CHECKMULTISIGELSE<90 days> CHECKSEQUENCEVERIFY DROP <Abdul the Lawyer's Pubkey> CHECKSIGENDIF
- 이 스크립트는 세 개의 실행 경로를 가집니다. 경로에 따른 스크립트는 다음과 같습니다.
- 2 <Mohammed’s Pubkey> <Saeed’s Pubkey> <Zaira’s Pubkey> 3 CHECKMULTISIG
- 2-of-3 다중 서명이 유효해야 함
- <30 days> CHECKSEQUENCEVERIFY DROP <Abdul the Lawyer’s Pubkey> CHECKSIGVERIFY 1 <Mohammed’s Pubkey> <Saeed’s Pubkey> <Zaira’s Pubkey> 3 CHECKMULTISIG
- 30일의 Timelock 조건을 만족하고, Abdul의 서명과 1-of-3의 다중 서명이 유효해야 함
- <90 days> CHECKSEQUENCEVERIFY DROP <Abdul the Lawyer’s Pubkey> CHECKSIG
- 90일의 Timelock 조건을 만족하고 Abdul의 서명이 유효해야 함
- 2 <Mohammed’s Pubkey> <Saeed’s Pubkey> <Zaira’s Pubkey> 3 CHECKMULTISIG
- 각각의 경우에 해제 스크립트는 다음과 같이 작성되어야 함
- 0 <Mohammed’s Sig> <Zaira’s Sig> 1 1
- 앞의 0은 CHECKMULTISIG의 버그를 위해 사용
- 끝의 1 1은 IF..IF를 실행하기 위한 조건
- 0 <Saeed’s Sig> <Abdul’s Sig> 0 1
- 끝의 0 1은 IF..ELSE를 실행하기 위한 조건
- <Abdul’s Sig> 0
- 끝의 0은 ELSE를 실행하기 위한 조건
- 0 <Mohammed’s Sig> <Zaira’s Sig> 1 1
- 이 스크립트는 세 개의 실행 경로를 가집니다. 경로에 따른 스크립트는 다음과 같습니다.
Segregated Witness(세그윗)
세그윗은 한 장의 일부로 다루기에는 그 양이 방대하고 어렵습니다. 본문 내용 수준으로 이해하는 것을 목표로 읽어나가고 좀 더 깊이 이해하고자 하시는 분은 관련 BIP 내용들을 좀 더 상세히 읽어보도록 합니다.
Segregated Witness (segwit) is an upgrade to the bitcoin consensus rules and network protocol, proposed and implemented as a BIP-9 soft-fork that was activated on bitcoin’s mainnet on August 1st, 2017.
세그윗은 합의 규칙과 네트워크 프로토콜에 대한 업그레이드로 2017년 8월에 메인넷에서 활성화된 소프트 포크입니다. 소프트 포크는 하위 버전과 호환되는 업그레이드입니다. 하위 버전과 호환되지 않는 업그레이드는 하드 포크라고 합니다.
일반적으로 소프트 포크는 업그레이드 하지 않은 노드들이 변경 사항을 무시하게 함으로 하위 호환성을 유지합니다. 세그윗도 이 방법을 택하고 있습니다.
In the context of bitcoin, a digital signature is one type of witness, but a witness is more broadly any solution that can satisfy the conditions imposed on an UTXO and unlock that UTXO for spending. The term “witness” is a more general term for an “unlocking script” or “scriptSig.”
witness는 증인으로 번역되는데 비트코인 시스템에서는 서명이 이에 해당합니다. 비트코인 시스템에서 서명은 트랜잭션 입력의 해제 스크립트로 작성되기 때문에 witness를 해제 스크립트라고 생각해도 됩니다. 세그윗은 이름 그대로 witness를 분리해 내자는 것으로 트랜잭션 입력에서 해제 스크립트를 분리하자는 것입니다. 분리된 해제 스크립트들은 트랜잭션 데이터로 한꺼번에 모아서 작성됩니다.
Why Segregated Witness?
세그윗과 관련된 BIP들(BIP-141, BIP-143, BIP-144, BIP-145, BIP-173)의 갯수만 봐도 세그윗으로 가는 길이 순탄하지 않았음을 예상할 수 있습니다. 실제로도 세그윗 활성화를 두고 엄청난 논란이 있었습니다. 이러한 어려움과 논란을 해쳐가면서까지 세그윗을 하려고 했다는 것은 그 만큼 얻는 것도 많다는 것이겠죠.
Segregated Witness is an architectural change that has several effects on the scalability, security, economic incentives, and performance of bitcoin:
- Transaction Malleability
- By moving the witness outside the transaction, the transaction hash used as an identifier no longer includes the witness data.
- 트랜잭션 밖으로 witness를 옮긴 것은 아닙니다. 현재 버전에서는 아니지만 미래 버전에서는 그렇게 할 수도 있습니다. 세그윗은 그러한 가능성을 열어둔 것입니다.
- 세그윗 이전 비트코인 시스템은 트랜잭션 해시를 생성하는 데 문제가 있었습니다.
- 트랜잭션 해시를 생성하는데 해제 스크립트를 포함했는데, 이렇게 할 경우 트랜잭션 내용은 바뀌지 않으면서 트랜잭션 해시만 변경할 수 있는 문제가 있었습니다. 이런 문제를 트랜잭션 가변성 문제라고 합니다.
- 트랜잭션 가변성 문제를 해결하지 않고는 결제 채널과 같은 좀 더 발전된 트랜잭션 처리로 넘어가기가 매우 어렵게 됩니다.
- By moving the witness outside the transaction, the transaction hash used as an identifier no longer includes the witness data.
- Script Versioning
- 세그윗은 버전 번호를 사용해서 스크립트 처리 방식의 변경에 유연하게 대응할 수 있도록 합니다. 버전 번호는 잠금 스크립트의 첫 번째 요소(OP_0과 같이)로 작성됩니다.
- OP_0은 0 값을 스택에 추가하는 연산자로, 버전 0을 나타냅니다.
- 세그윗은 버전 번호를 사용해서 스크립트 처리 방식의 변경에 유연하게 대응할 수 있도록 합니다. 버전 번호는 잠금 스크립트의 첫 번째 요소(OP_0과 같이)로 작성됩니다.
- Network and Storage Scaling
- 트랜잭션은 블록 용량과 처리의 상당 부분을 차지하고, 해제 스크립트는 트랜잭션 용량과 처리의 상당 부분을 차지합니다.
- 블록 크기가 제한된 비트코인 시스템에 있어 트랜잭션 크기를 줄인다는 것은 더 많은 트랜잭션을 처리할 수 있음을 의미합니다.
- 트랜잭션은 블록 용량과 처리의 상당 부분을 차지하고, 해제 스크립트는 트랜잭션 용량과 처리의 상당 부분을 차지합니다.
- Signature Verification Optimization
- 자세한 내용은 BIP-143을 참조합니다.
- Offline Signing Improvement
- Segregated Witness signatures incorporate the value (amount) referenced by each input in the hash that is signed.
- 서명 해시에 수량을 포함합니다.
- 일반적으로 지갑들은 서명 전에 입력으로 작성된 수량을 확인합니다. 수량이 올바른지는 입력이 참조하는 UTXO를 통해 확인합니다. UTXO에 접근하려면 온라인 상태여야 합니다.
- 세그윗은 UTXO를 통한 서명 확인 없이 사용자가 직접 작성한 수량을 서명 해시에 포함해서 서명합니다.
- 서명 검증 시에 수량이 잘 못된 경우 유효하지 않은 서명으로 처리합니다.
- 서명 시에 수량 확인의 책임을 서명 검증 시의 책임으로 옮긴 것입니다.
- 서명 검증 시에 수량이 잘 못된 경우 유효하지 않은 서명으로 처리합니다.
- 서명 해시에 수량을 포함합니다.
- Segregated Witness signatures incorporate the value (amount) referenced by each input in the hash that is signed.
How Segregated Witness Works
이래 인용한 본문 내용을 주의를 기울여 여러 번 반복해서 읽습니다.
At first glance, Segregated Witness appears to be a change to how transactions are constructed and therefore a transaction-level feature, but it is not. Rather, Segregated Witness is a change to how individual UTXO are spent and therefore is a per-output feature.
A transaction can spend Segregated Witness outputs or traditional (inline-witness) outputs or both. Therefore, it does not make much sense to refer to a transaction as a “Segregated Witness transaction.” Rather we should refer to specific transaction outputs as “Segregated Witness outputs.”
When a transaction spends an UTXO, it must provide a witness. In a traditional UTXO, the locking script requires that witness data be provided inline in the input part of the transaction that spends the UTXO. A Segregated Witness UTXO, however, specifies a locking script that can be satisfied with witness data outside of the input (segregated).
To an old wallet or node, a Segregated Witness output looks like an output that anyone can spend. Such outputs can be spent with an empty signature, therefore the fact that there is no signature inside the transaction (it is segregated) does not invalidate the transaction.
Segregated Witness Output and Transaction Examples
세그윗은 세그윗 이전의 스크립트 유형 별로 대응되는 스크립트 유형을 제공합니다.
- p2pkh – p2wphk
- p2wphk 잠금 스크립트는 다음과 같이 작성합니다.
- OP_0 <20-byte hash>
- OP_0은 세그윗 버전입니다.
- <20-byte hash>는 공개키 해시입니다.
- OP_0 <20-byte hash>
- Script는 스택 기반 실행 언어이기 때문에 잠금 스크립트가 실행되면 스택의 상단에는 <20-byte hash>가 있게 됩니다.
- 스택 최상단 값이 0이 아니면 참으로 평가하기 때문에 세그윗을 지원하지 않는 노드들은 세그윗 지원 UTXO에 대해서는 검증하지 않는 것과 같습니다.
- ‘서명의 유효성을 검증하지 않는다’고 하니 세그윗 지원 UTXO의 경우 ‘아무나 사용하면 어떻게 하나?’라는 우려가 생기지요?
- 비트코인 네트워크의 대다수 노드가 세그윗을 지원하지 않을 경우를 생각해 보면 그 심각성이 더 커보일 수 있습니다. 실제로 세그윗 활성화 이전에 이것을 걱정하는 사람들이 많이 있었습니다. 여기에서는 잘 해결되었다 정도만 확인하고 넘어가도록 합니다.
- ‘서명의 유효성을 검증하지 않는다’고 하니 세그윗 지원 UTXO의 경우 ‘아무나 사용하면 어떻게 하나?’라는 우려가 생기지요?
- 스택 최상단 값이 0이 아니면 참으로 평가하기 때문에 세그윗을 지원하지 않는 노드들은 세그윗 지원 UTXO에 대해서는 검증하지 않는 것과 같습니다.
- 세그윗을 지원하지 않는 지갑에서 작성된 트랜잭션은 세그윗 규칙을 따르지 않기 때문에 세그윗 지원 노드에서는 스크립트 실행이 실패하게 되어 유효하지 않은 것이 됩니다.
- 세그윗을 지원하지 않는 지갑을 사용하는 수신자 주소로 세그윗 지원 지갑에서 비트코인을 보낼 경우, 수신자는 그 비트코인을 자신의 지갑에서 사용할 수 없게 됩니다.
- 세그윗 지원 지갑을 사용해서 이러한 문제를 피하도록 합니다.
- 세그윗을 지원하지 않는 지갑을 사용하는 수신자 주소로 세그윗 지원 지갑에서 비트코인을 보낼 경우, 수신자는 그 비트코인을 자신의 지갑에서 사용할 수 없게 됩니다.
- p2wphk 잠금 스크립트는 다음과 같이 작성합니다.
- p2sh – p2wsh
- p2wsh 잠금 스크립트는 다음과 같이 작성합니다.
- OP_0 <32-byte hash>
- <32-byte hash>는 Redeem Script의 SHA256 해시 입니다.
- OP_0 <32-byte hash>
- p2wsh 잠금 스크립트는 다음과 같이 작성합니다.
Upgrading to Segregated Witness
세그윗 지원 지갑과 그렇지 않은 지갑 사이에 고려해야 할 문제들과 그것들을 어떻게 다룰 수 있는지를 설명합니다. 가볍게 본문을 읽어 나갑니다.
Segregated Witness addresses
P2WPKH는 BIP-173에 정의된 Bech32라는 새로운 주소 형식을 사용합니다.
A segwit bech32 string is up to 90 characters long and consists of three parts:
- The human readable part
- This prefix “bc” or “tb” identifying mainnet or testnet.
- The separator
- The digit “1”, which is not part of the 32-character encoding set and can only appear in this position as a separator
- The data part
- A minimum of 6 alphanumeric characters, the checksum encoded witness script
Transaction identifiers
세그윗 트랜잭션은 두 개의 Id를 갖습니다. witness 데이터 없이 만들어지는 txid와 witness 데이터를 포함해서 만들어지는 wtxid. txid는 witness 데이터를 포함하지 않기 때문에 트랜잭션 가변성 문제가 발생하지 않습니다.
Economic Incentives for Segregated Witness
After Segregated Witness, the transaction fees align with the incentive to minimize new UTXO creation by not inadvertently penalizing transactions with many inputs.
세그윗은 비트코인 네트워크에서 가장 비용이 높은 자원에 해당하는 UTXO set을 줄이는 방향으로 인센티브가 작동하도록 합니다.