용어집 / 프로토콜과 업그레이드
OP_CHECKSIGADD
- OP_CHECKSIGADD란 무엇입니까?
- OP_CHECKSIGADD는 tapscript 안에서 서명을 키 하나씩 세며, 기존의 다중서명 opcode를 일괄 검증과 향후 키 유형을 모두 처리할 수 있는 검사로 대체합니다.
BIP-342에 명시되어 있습니다.
이 opcode는 스택 항목 세 개, 즉 서명, 누적된 개수, 공개 키를 받아 개수를 그대로 또는 하나 늘려 다시 푸시합니다. BIP-342는 여기에 opcode 186을 배정하면서 동시에 OP_CHECKMULTISIG를 비활성화했으므로, 모든 Taproot 스크립트 다중서명은 이 방식으로 작성됩니다. 실질적인 이점은 임계값 정책이 더 이상 20개의 키에서 멈추지 않는다는 것입니다.
작동 방식
tapscript의 임계값은 서명 검사가 이어지면서 그 사이로 집계값이 전달되는 사슬과 마지막의 비교로 이루어집니다.
풀어 쓰면 3개 중 2개는 다음과 같습니다. 첫 번째 공개 키를 푸시하고, OP_CHECKSIG, 두 번째를 푸시하고, OP_CHECKSIGADD, 세 번째를 푸시하고, OP_CHECKSIGADD, 2를 푸시하고, OP_NUMEQUAL을 실행합니다. 실행은 왼쪽에서 오른쪽으로 진행됩니다. OP_CHECKSIG는 스택에 1 또는 0을 남기고, 각 OP_CHECKSIGADD는 공개 키를 하나 꺼내고, 그 누적 합계를 꺼내고, 이 키에 대해 제시된 서명을 꺼낸 뒤, 서명이 검증되면 합계에 1을 더해 다시 푸시합니다. 마지막 비교가 충분한 수가 검증되었는지를 결정합니다.
참여하지 않는 서명자는 서명 대신 빈 바이트 문자열을 제공합니다. opcode는 이를 보고 해당 자리를 서명되지 않은 것으로 처리하여 집계값을 그대로 반환하며, 이는 위트니스에서 1바이트만 소모합니다. 이것이 메커니즘의 전부이며, 원래 구현의 off-by-one 버그 때문에 OP_CHECKMULTISIG가 요구하던 더미 스택 항목을 없앱니다.
키 하나를 서명 하나와 대조한다는 점에서 두 가지 결과가 따릅니다. 검증을 일괄 처리할 수 있게 됩니다. 노드는 후보 키를 순서대로 시험하는 대신 블록 안의 모든 Schnorr 서명을 하나의 집계 검사에 넣을 수 있으며, 이는 Taproot 검증 속도 향상의 상당 부분을 차지합니다. 그리고 키의 개수는 opcode에 하드코딩된 상한이 아니라, 검증하는 서명마다 50개의 가중치 단위를 소모하는 tapscript 검증 예산에 의해 제한됩니다.
사용되는 곳
OP_CHECKSIGADD는 서명자가 둘 이상 필요한 모든 Taproot 스크립트에 나타나며, 지갑 소프트웨어에서는 보통 원시 스크립트가 아니라 디스크립터를 뜻합니다.
Bitcoin Core는 이를 tr() 디스크립터 안의 multi_a 및 sortedmulti_a 프래그먼트로 노출하므로, 세 개의 키로 이루어진 정족수는 tr(internalkey,multi_a(2,KEY1,KEY2,KEY3))로 작성되고 소프트웨어가 opcode 사슬을 대신 생성합니다. Miniscript도 같은 방식으로 처리하며, Taproot 정책을 지원하는 하드웨어 장치는 그 배치를 미리 알 필요 없이 이러한 스크립트에 서명합니다.
이 설계는 정족수를 구성하는 방식도 바꿉니다. 세 개의 키를 모두 담은 잎 하나 대신, taptree에 가능한 각 쌍마다 두 개의 키로 된 잎을 세 개 따로 담을 수 있고, 그러면 지출 시 실제로 서명한 쌍만 드러납니다. 이는 스크립트 잎이 더 드는 대신 위트니스에서 공개 키 하나를 아끼며, 지출마다 전체 키 집합을 공개하는 것보다 실질적인 프라이버시 개선입니다.
OP_CHECKSIGADD vs OP_CHECKMULTISIG
OP_CHECKSIGADD와 OP_CHECKMULTISIG는 모두 키 집합에 대해 서명을 세지만, Taproot 잎에서 작동하는 것은 둘 중 하나뿐입니다. OP_CHECKMULTISIG는 레거시 및 SegWit 버전 0 스크립트에서 여전히 완전히 유효하므로, 수년간 사용되어 온 bc1q 다중서명은 영향을 받지 않고 마이그레이션도 필요하지 않습니다.
tapscript 안에서는 OP_CHECKMULTISIG와 OP_CHECKMULTISIGVERIFY가 완전히 비활성화됩니다. 적용 범위 외에도 세 가지 차이가 중요합니다. 예전 opcode는 스크립트당 공개 키를 20개로 제한하지만 새 opcode에는 그런 숫자가 없고, 예전 opcode는 스택에 추가 더미 항목을 요구하며 BIP-147이 이후 이를 합의 규칙으로 빈 값으로 강제했고, 예전 opcode는 각 서명이 어느 키에 속하는지 검증자가 미리 알 수 없어 일괄 검증할 수 없습니다.