비트코인은 세계에서 처음으로 본 스마트 계약 프로그래밍 언어를 제공했습니다. 이 언어는 스크립트(Script)라고 불리며, 사용자가 코인을 사용할 수 있는 다양한 조건을 인코딩할 수 있게 해줍니다. 하지만 이것은 혁신적인 개념이었지만, 특히 더 복잡한 지출 조건에 대해서는 사용하기 쉽지 않습니다. 복잡한 계약을 작성하는 것과 계약이 의도한 대로 작동하는지 검증하는 것은 모두 인간의 오류에 취약합니다. 그러나 특히 돈이 걸려 있는 상황에서는 조건의 올바른 해석이 가장 중요합니다.
지난 1년 동안 블록체인 엔지니어인 앤드류 포엘스트라, 피터 윌레, 상켓 칸잘카르가 이를 개선하기 위해 노력했습니다. 스크립트를 본질적으로 단순화하여 그들의 “새로운” 프로그래밍 언어인 “미니스크립트(Miniscript)”는 복잡성을 추상화하고 비트코인 프로그래밍을 모든 관련자에게 더 쉽고 안전하게 만들어야 합니다.
“미니스크립트는 이론적으로 스크립트보다 더 제한적입니다,” 블록스트림의 연구 책임자이자 미니스크립트 공동 설계자인 앤드류 포엘스트라가 비트코인 매거진에 말했습니다. “하지만 사람들이 실제로 스크립트를 사용하는 모든 것을 할 수 있습니다.”
스크립트
시작해 보겠습니다.
모든 비트코인 거래는 입력과 출력이라는 두 가지 주요 부분으로 구성됩니다. 입력은 코인을 “잠금 해제”하고 출력은 다시 “잠금”하여 이후 거래 입력에서 어떤 조건 하에 잠금 해제가 가능한지를 지정합니다. 이러한 요구 사항에는 유효한 암호화 서명이 포함되지만, 더 많은 가능성이 있습니다. 예를 들어, 코인을 사용하기 전에 특정 시간이 지나야 하거나 특정 비밀 번호가 포함되어야 할 수 있습니다.
거래의 이 코드는 비트코인을 위해 특별히 설계된 프로그래밍 언어인 스크립트로 생성됩니다. 스크립트는 1960년대에 발명된 포스(Forth)라는 프로그래밍 언어에서 영감을 받았으며, 원래는 라디오 망원경을 작동시키기 위해 설계되었습니다. 그러나 스크립트는 비트코인에 더 적합하도록 조정되었습니다.
예를 들어, 스크립트에는 “루프”를 만드는 명령어(opcode)가 없습니다. 이 언어는 동일한 계산을 무한히 수행하는 것을 지원하지 않습니다. 비트코인에서는 동일한 계산을 무한히 수행할 필요가 없기 때문입니다. 비트코인 노드는 실제로 거래를 계산하지 않고 거래를 검증합니다. (이유에 대한 더 기술적인 설명은 블록스트림 엔지니어 러셀 오코너의 이 게시물을 참조하십시오.)
스크립트는 또한 “유형이 없습니다.” 이는 계산의 결과가 여러 가지 방법으로 해석되고 사용될 수 있음을 의미합니다. 예를 들어, 유효한 서명의 결과는 “참”일 수 있지만, “참”은 다시 숫자 “1”로 해석되고 이후 수학 방정식에서 사용될 수 있습니다: “참” 더하기 “참”은 “2”가 되며, 이는 예를 들어 최소 두 개의 유효한 서명이 필요할 경우 충분한 서명이 제공되었음을 의미할 수 있습니다.
이것은 이 기사에서 스크립트의 가장 중요한 속성으로 이어집니다: “이해하기 어렵다”는 것입니다. 이는 본질적으로 계산 결과가 여러 가지 방법으로 해석될 수 있음을 의미합니다. 예를 들어, 서명이 유효하지 않더라도 스크립트는 거래가 다른 이유로 여전히 유효하도록 작성될 수 있습니다.
“비트코인 스크립트에는 정말 터무니없는 일을 하는 opcode가 있습니다,” 포엘스트라가 설명했습니다. “예를 들어, 서명을 참/거짓 값으로 해석하고, 그에 따라 분기하고; 그 부울 값을 숫자로 변환한 다음 스택에 인덱싱하고, 그 숫자를 기반으로 스택을 재배열합니다. 그리고 이렇게 하는 특정 규칙은 정말 미친 것입니다.”
이로 인해 스크립트는 작업하기 어려울 수 있습니다. 특히 코인을 지출(“잠금 해제”)하기 위한 요구 사항이 더 복잡해질 경우, 거래 작성자는 의도하지 않게 코드를 포함시켜 코인이 의도한 것과 다른 조건에서 지출될 수 있도록 할 수 있습니다. 반대로, 거래의 수신자는 이러한 특성을 알아차리지 못하고 공격자에게 코인을 잃을 수 있습니다.
문제의 구체적인 예
다음은 이러한 문제가 스크립트의 유용성을 제한하는 방법에 대한 구체적인 예입니다.
블록스트림 그린 지갑은 표준 “공동 서명” 설정을 가지고 있습니다. 지갑 사용자는 두 개의 키 중 하나를 제어하고 블록스트림은 다른 하나를 제어합니다. 자금은 두 가지 방법으로 지출될 수 있습니다. 첫째, 사용자가 코인을 지출하고 싶을 때마다 거래에 서명하고 블록스트림도 서명해 달라고 요청합니다. 블록스트림은 일반적으로 이를 수행하지만, 사용자가 이메일 확인과 같은 이차 수단을 통해 거래를 정말로 하기를 원하는지 확인해야 할 수도 있습니다. 그러나 블록스트림 측에서 문제가 발생할 수 있습니다. 예를 들어, 회사가 사라지거나 키를 잃어버리거나 다른 이유로 서명할 수 없을 수 있습니다. 그런 경우, 사용자는 비트코인을 지출할 수 있는 대체 솔루션을 여전히 가지고 있습니다: 타임락이 만료된 후, 미리 정해진 시간이 지나면 유효한 거래를 생성할 수 있습니다. 아마도 한 달이 될 것입니다.
이것은 잘 작동하지만, 또한 제한적입니다. 사용자는 설정의 끝에서 더 많은 유연성을 추가하고 싶더라도 비트코인의 스마트 계약 잠재력을 더 이상 사용할 수 없습니다.
“현재 그린은 모든 고객을 위해 사용되는 고정된 스크립트를 가지고 있으며, 기본적으로 단순한 다중 서명입니다,” 포엘스트라가 말했습니다. “하지만 우리는 스크립트가 무엇을 말하는지에 대해 신경 쓸 필요가 없습니다. 우리가 신경 쓰는 것은: 특정 타임아웃 이전에 우리의 서명 없이 코인을 지출할 수 없다는 것입니다. 사용자가 우리와 함께 어떤 미친 정책을 사용하고 싶다면, 우리가 신경 쓰는 그 한 가지 조건이 충족되는 한 지원할 수 있어야 합니다.”
예를 들어, 사용자는 사랑하는 사람들이 1년이 지난 후 코인을 지출할 수 있도록 허용하고 싶을 수 있습니다. 또는 사용자가 실제로 회사이고, 이사회 구성원 3명 중 2명이 함께 코인을 지출할 수 있는 다중 서명 설정을 만들고 싶어할 수도 있습니다(블록스트림과 함께).
현재, 기술적으로 비트코인 스크립트를 사용하여 이를 수행할 수 있습니다. 그러나 사용자가 사용자 정의 설정을 설계해야 하며, 블록스트림도 이 사용자 정의 설정에 참여해야 합니다.
“하지만 사용자가 임의의 스크립트를 제공하면, 우리가 신경 쓰는 그 한 가지 조건이 충족되었는지 여부를 판단하는 것은 불가능합니다. 왜냐하면 모든 스크립트 동작의 총 집합이 정말 복잡하기 때문입니다,” 포엘스트라가 설명했습니다. “예를 들어, 스크립트가 서명을 받는 것처럼 보인다면, 사용자가 비서명(non-signature)을 제공할 경우 어떤 일이 발생하는지 생각해야 합니다. 그것이 코인을 지출하도록 속일 수 있을까요?”
미니스크립트
지난 1년 동안 미니스크립트는 포엘스트라, 블록스트림 코어 기술 엔지니어 피터 윌레, 블록스트림 인턴 상켓 칸잘카르에 의해 설계되었습니다. (미니스크립트는 공식적으로 블록스트림 제품은 아닙니다.)
간단히 말해, 미니스크립트는 스크립트의 “단순화된” 버전입니다: 사용하기 쉽고 인간이 검증하기 쉬운 “스크립트 도구 키트”에서 선택된 “도구”입니다. 이 도구들은 스크립트로 할 수 있는 거의 모든 것을 가능하게 하도록 신중하게 선택되었습니다. 따라서 미니스크립트의 한 줄은 여전히 유효한 스크립트의 한 줄이지만, 코드의 예기치 않은 결과를 방지하여 인간 오류를 본질적으로 피합니다.
위의 문제 예를 들어, 미니스크립트를 사용하면 사용자가 블록스트림이 그 한 조건이 충족되었는지 쉽게 확인할 수 있도록 설정을 설계할 수 있습니다. 구체적으로, 블록스트림은 자금이 서명하거나 한 달이 지나야만 지출될 수 있다는 것을 확인할 수 있습니다 — 사용자의 설정 끝에서 추가 타임락이나 다중 서명 또는 기타 조건이 포함되더라도 상관없이. 미니스크립트를 사용하면 블록스트림의 끝을 무시할 수 있는 예기치 않은 특성이 발생할 수 없습니다.
미니스크립트는 사실 매우 직관적이고 예측 가능하여, 설정을 항상 결정 트리로 변환할 수 있습니다: 설정의 시각화(“그림 인코딩”)로, 매우 이해하기 쉽습니다.
아래의 시각화는 예를 들어, 세 명의 사용자 중 두 명이 코인을 이동시키기 위해 서명해야 하는 설정을 보여줍니다. 백업 옵션으로, 코인은 비상 키로 이동할 수 있지만, 일정 시간이 지나야만 가능합니다.
“미니스크립트를 사용하면 블록스트림이 더 복잡한 설정에 참여하기가 쉬워집니다. 우리는 스크립트를 트리로 디코딩한 다음, 트리의 모든 리프를 확인하며 (a) 이 리프에 타임아웃 조건이 있습니까? 또는 (b) 이 리프가 우리의 서명을 요구합니까?”라고 포엘스트라가 말했습니다.
두 질문 모두에 대한 답이 “예”라면, 블록스트림은 참여할 수 있습니다.
미니스크립트 사용
미니스크립트는 진행 중인 작업이지만, 초기 버전이 출시되어 사용 준비가 완료되었습니다.
미니스크립트를 작성하는 과정을 더욱 쉽게 만들기 위해, 윌레는 “정책 언어”도 설계했습니다. 정책 언어는 사실상 자체 프로그래밍 언어와 같습니다. 코인을 지출할 수 있는 조건을 이 정책 언어로 프로그래밍한 후, 이를 미니스크립트로 컴파일(“변환”)할 수 있으며, 따라서 유효한 스크립트로 변환되어 비트코인 거래 출력에 포함될 수 있습니다.
이 정책 언어의 큰 추가 이점은 스크립트가 실제로 인코딩하는 내용에 따라 가능한 가장 효율적인 미니스크립트 버전으로 자동으로 컴파일된다는 것입니다.
“미니스크립트에 대한 점은 기본적으로 스크립트라는 것입니다… ‘또는’을 쓰는 다양한 방법이 많고, ‘그리고’를 쓰는 방법도 많으며, 그 중 일부는 다른 것보다 더 효율적입니다,” 포엘스트라가 말했습니다. “정책 언어는 ‘또는’ 하나, ‘그리고’ 하나 등 하나만 있으며, 피터 [윌레]는 이를 미니스크립트로 변환하는 매우 최적화된 컴파일러를 작성했습니다.”
이것은 단지 이론적인 개념이 아닙니다. 현재 미니스크립트와 컴파일러의 버전이 최종 버전은 아니지만, 블록스트림은 내부적으로 그 개발 분기에서 리퀴드 사이드체인 기능 소프트웨어를 위해 이를 사용하고 있습니다. (포엘스트라는 윌레의 최적화 컴파일러 사용이 블록스트림의 원래 “수작업” 스크립트에 비해 22바이트를 절약했다고 지적했습니다.) 윌레는 누구나 사용할 수 있는 미니스크립트 컴파일러에 대한 정책 언어의 데모 버전을 http://bitcoin.sipa.be/miniscript/에서 호스팅하고 있습니다.