블록체인 확장성 솔루션 시리즈 2–3 :: Plasma Cash
Ji-Hyeok Choy (Jihyeok Choy)
Gyeo-Re Han (Han Geore)
Hyun-Cheol Gong (Hyun Cheol Gong)
Seoul Nat’l Univ. Blockchain Academy Decipher(@decipher-media)
서울대학교 블록체인 학회 ‘디사이퍼(Decipher)’에서 블록체인의 스케일링 솔루션에 관한 글들을 시리즈로 연재합니다. 시리즈의 두 번째 주인공은 이더리움의 “Plasma: Scalable Autonomous Smart Contracts” 입니다. 2–1. 플라즈마 Overview, 2–2. 플라즈마 — Q&A 및 플라즈마 MVP (Minimum Viable Plasma) 코드 리뷰, 2–3. 플라즈마 캐시로 나누어 설명합니다.
앞선 두 글에서, 우리는 플라즈마의 전체적인 구조, 공격 상황, 주요 질의 응답 그리고 실제 구현 상황까지 살펴보았다. 그러나 앞선 글에서 언급된 Sybil Attack처럼 플라즈마의 현 시스템으로는 막을 수 없는 이슈들이 존재한다. 이에 ‘플라즈마 캐시’란 기존 플라즈마 모델의 문제점을 개선한 플라즈마의 개선안이다. 글의 도입에서는, 플라즈마 캐시가 짚은 플라즈마 모델의 문제점을 알아볼 것이다. 그 문제들을 플라즈마 캐시가 어떻게 해결하고자 했는지와 함께 플라즈마 캐시의 주요 특성에 대해 분석하겠다. 본 글에 앞서, 플라즈마 캐시는 구체화되지 않은 프로젝트임을 밝힌다. 따라서 구현체가 없으므로 코드 리뷰는 생략하며, 글의 마지막에선 플라즈마 캐시의 맹점들과 아직 해결해야 할 이슈들에 대해 알아보도록 하겠다.
기존 플라즈마 모델의 한계점
기존 플라즈마 모델에서 가장 중요한 문제로 꼽는 것은 세 가지이다. 첫 번째는 검증에 필요한 리소스가 너무 많다는 것, 두 번째는 거래 승인의 과정이 복잡하다는 것이며 마지막은 operator의 부정 행위에 대해선, exit으로 대처할 수 밖에 없다는 것이다. 각각에 대해 살펴보도록 하자.
1. 무거운 검증
플라즈마 체인은 아래 그림과 같이 계층 형태의 구조로 이루어져있으며, 각 체인은 독자적인 합의 방식을 가질 수 있다.
독자적인 구조를 가질 수 있단 것은, PoS뿐만이 아니라 한 집단에 의해 체인이 관리되는 PoA 합의 방식도 가질 수 있단 것이다. 앞선 글에서 이야기한 바와 같이, 다소 중앙화 되어있는 합의 방식이 채택 되었음에도 플라즈마 체인의 안정성을 보장할 수 있는 이유는 Challenging 시스템에 있다. 누군가 부정한 출금을 시도했을 때, 체인을 관찰하고 있는 어느 누구라도 해당 출금이 부정함을 증명하여 부정 출금을 막을 수 있다. 이러한 장점 덕에, 플라즈마는 무한한 확장을 꿈꿀 수 있다. 그러나 역설적이게도, 이러한 확장성이 검증의 자율성을 헤치며 도리어 무한한 확장성의 발목을 잡는다.
Depth가 3인(위 그림 참고) 체인의 경우를 살펴보자. 편의상 해당 체인을 P-chain이라고 하자. P-chain에서 만들어진 tx이 유효한 tx임이 확정되려면, Rootchain까지 해당 정보가 올라간 것을 확인한 후 서명을 해야 한다. 다시 말해, Rootchain까지의 모든 부모 체인들(P-chain의 직계 depth2 부모 체인과 그의 직계 depth1 부모 체인)을 거래 당사자가 계속 지켜보고 있어야 한단 것이다.
만약, P-chain에서 누군가 부정한 출금을 시도한다면, 상황은 더욱 복잡해진다. Simple Withdrawal의 경우, 출금 신청자는 상위 체인 어디로든 출금을 신청 할 수 있다. 이는, 출금 신청자가 부정 출금을 시도 할 때, 공격 경로가 그 만큼 다양해지는 것이다. 부정 출금을 막기위해 해당 체인의 참여자는 Challenging을 해야 한다. 이 때, 성공적인 Challenging 뿐만이 아니라 그 행위 자체를 시도하기 위해서는, P-chain과 출금 목적지 체인의 정보를 모두 가지고 ‘관찰’하고 있어야 한다. 이것이 의미하는 바는, P-chain이 부정 출금으로부터 안전하기 위해선, P-chain과 Simple Withdrawal 목적지가 될 수 있는 P-chain의 모든 조상 체인들의 데이터를 가지고 있고 ‘관찰’ 또한 하고 있어야 한다.
플라즈마 체인을 이용한 Dapp이 있다고 했을 때, 이 Dapp의 기능이 추가되거나 이용자가 많아질수록(확장될수록) Depth가 큰 체인은 계속해서 생길 것이다. 기존 플라즈마 모델에선 위의 이유로 인해 확장성이 커질수록 ‘관찰’ 비용은 엄청나게 증가한다.
2. 불편한 거래
기존 플라즈마 모델의 두 번째 문제는 거래 승인의 과정이 복잡하다는 것이다. 기존 거래 과정을 다시 한 번 살펴보자. A -> B로의 거래가 있을 때,
- A가 A->B의 거래를 생성한다.
- 해당 거래를 operator에게 전달한다.
- operator는 P-chain에서 해당 거래 내용을 담은 블록을 생성한다.
- 부모 chain으로 해당 내용을 올리며, 결과적으로 Rootchain까지 내용이 올라가게 된다.
- A는 해당 사실을 확인하고 서명하여 B에게 전달한다.
- B 역시 Rootchain을 확인하고 사인을 한다.
- 둘다 사인하고 사인 트랜잭션이 블록에 담기면 트랜잭션은 유효해진다.
위 과정은 필요하나, 사용자 입장에서 번거롭다. 더군다나, 거래의 마지막 결정권은 마지막 사인을 하는 사람에게 있기 때문에, Free Option Problem과 같은 문제 역시 생기게 된다. 물론 이는 Lightning Network의 방법을 차용하면 어느 정도 도움이 될 수 있다고 이전 글에서 서술되었으나, 이 역시 불편함을 야기한다.
3. 대응책의 부재
PoA 플라즈마 체인에서 아래의 어택 상황을 가정하자.
- Operator가 자신에게 9999PETH를 주는 부정한 거래 생성
- 해당 정보를 통해 exit을 요청
단순한 공격 상황이지만, 기존 모델에선, 참여자는 이 공격 상황을 직접적으로 방어할 수 없었다. 대신, 참여자는 operator와 같이 출금 요청을 한다. 여러 출금 요청이 들어온 경우, 앞선 글에서 보았듯이 플라즈마는 우선 순위가 높은 거래부터 출금을 시켜준다. 이때, 이 우선 순위란 utxo의 ‘나이’라고 볼 수 있다. Operator의 부정한 거래보다 참여자가 소지한 utxo가 먼저 생성되었기 때문에 같이 출금 신청을 할 경우, 참여자의 자금부터 출금이 되어 operator의 부정한 출금 요청은 잔액 부족으로 실패하게 된다.
참여자는 공격으로부터 자금을 보호할 수는 있지만, 참여 중이었던 네트워크는 마비된다. 만일, 이 네트워크와 교류가 많은 이웃 네트워크가 있다고 한다면, 피해는 확산 될 것이다. 가장 좋은 방법은, operator의 부정 출금을 맞출금으로 대응하는 것이 아닌, 해당 출금을 취소시키는 것이다. 이에 관해, 플라즈마의 개선점 부분에서 논의하도록 하겠다.
그렇다면, 플라즈마 캐시는 위의 문제들을 어떻게 해결하려고 했을까? 이제, 플라즈마 캐시의 특징과 플라즈마 캐시를 도입했을 때 개선될 점을 알아본 후, 남아있는 문제들에 대해 이야기 해보도록 하자.
플라즈마 캐시
플라즈마 캐시가 기존 플라즈마 모델과 다른 점은 크게 다음 하나로 정의할 수 있다.
“id와 양이 적혀 있고, 분할, 병합이 불가능한 ‘플라즈마 캐시’를 플라즈마에서 사용한다.”
현금과 비교하면 이해가 쉽다. 만원짜리 지폐를 생각해보자. 지폐에는 지폐 고유의 번호가 붙어있으며, 그 양(10000원) 역시 표기되어 있다. 또한, 만원 지폐는 5천원 지폐 두 장과 ‘교환’은 가능하나, ‘분할’은 불가능하다. 역으로, 5천원 지폐 두 장을 포개어 접어도 만원 지폐로 ‘병합’되지 않는다.
위 특징으로부터 ‘플라즈마 캐시’가 플라즈마 체인 위에서 어떻게 존재하는지 살펴보자.
1. 플라즈마 캐시의 생성
고유한 id와 양을 가지는 ‘플라즈마 캐시’의 생성은, deposit에서 이루어진다. 과정을 살펴보자.
- A가 P-chain으로 1ETH를 deposit한다.
- A의 1ETH는 플라즈마 체인에 lock 된다.
- 루트 체인에서 새로운 id를 생성하고 그 id와 가치(1ETH)가 매핑된다.
- 체인 내에서는 그 id와 1ETH의 가치를 가지는 플라즈마 캐시가 생성되어 A가 이 소유권을 가지고 있다.
위 과정으로부터 플라즈마 체인내에서 사용될 수 있는 ‘플라즈마 캐시’가 생성되며, 이는 대체 불가능(non-fungible)한 특성을 지닌다.
2. 플라즈마 캐시의 머클트리
플라즈마 체인의 블록은 이제 다른 방식으로 거래들을 저장한다. 기존의 모델에서는, 비트코인의 utxo 모델과 같이 거래들을 머클화 시켜 저장했다. 또한, utxo 모델이기에 이 거래 값이 곧 새로운 token이 되었다. 플라즈마 캐시를 도입했을 때, 블록에 담겨 머클화 되는 정보는 거래가 아닌 아래 그림과 같이 ‘거래에 사용된 토큰’과 새로운 주인이다.
즉, 토큰의 상태 변화를 머클 트리에 담는다고 할 수 있다. 당연하게도, 누군가 조작을 위해 Address, 혹은 Id를 바꿀 경우 Root Hash역시 변화하여 담긴 정보가 다름을 쉽게 파악 할 수 있다. 또한, utxo 모델과 다르게, transaction과 상관없이 토큰의 양과 id는 불변이기에, 새로운 utxo도 이전과 같은 id를 가지고 있다. 이 점은, 개선점에서 중요하게 다루어질 것이다.
3. 토큰의 소비
플라즈마 캐시를 소비하기 위해서는 다음 두 가지 정보가 필요하다.
- 해당 id의 토큰이 소비된 이전 모든 거래 기록
- 해당 id의 토큰이 소비되지 않은 이전 모든 블록에 대해, 각 블록의 머클 트리에 해당 id의 토큰이 포함되지 않았음을 보여주는 증명
수신자는 위의 정보들을 검증 한 후, 문제가 없다면 사용할 것이다.
지금까지 플라즈마 체인 위 플라즈마 캐시의 생성, 저장, 거래 과정에서 기존 모델과 다른 특징을 살펴보았다. 플라즈마 체인위 토큰의 LifeCycle 중 마지막 과정인 Exit process는 다음 주제 ‘플라즈마 캐시의 개선점’에서 같이 다루도록 하겠다.
플라즈마 캐시의 개선점
플라즈마 캐시는 기존 플라즈마 모델의 개선 버전이다. 즉, 이전 모델의 문제를 해결하기 위해 나온 것으로 그에 따른 플라즈마 캐시만의 장점 또한 존재한다. 지금부터 플라즈마 캐시가 어떻게 기존 플라즈마 모델을 개선했는지 살펴보자.
1. 모든 토큰과 간단한 호환성
기존 모델에서는 ERC721 토큰을 플라즈마 체인 내에서 사용하려면 복잡했다. 왜냐하면 플라즈마 체인에서 활용되는 토큰인 ERC20에는 id가 없지만, ERC721에는 id가 있기 때문이다. 반면, 플라즈마 캐시는 기본적으로 ERC20보다 ERC721에 더 가깝다. 이와 더불어, 플라즈마 캐시는 ‘양’에 대한 정보를 포함하고 있어 ERC20과의 호환이 가능하다. 즉, Root Chain에서 통용되는 토큰을 간단하게 플라즈마 체인 내로 예치할 수 있다는 것이다.
2. 거래 과정의 축소
앞서, 기존 플라즈마 모델은 거래가 복잡하다고 이야기한 바가 있다. 기존 모델에서 2번의 확인 + 최종 confirm 과정이 필요한 이유는 다음과 같은 공격 상황이 발생할 수 있기 때문이다.
- A가 A -> B tx 생성 (현재 100번째 블록)
- Operator가 101, 102, 103의 invalid 블록을 생성
- 그 후, A -> B tx를 104블록에 올려서 루트까지 commit
이 상황에서
- A가 withdraw를 시도하려해도 A -> B tx가 104번째 블록에 있어 불가능(누군가 challenge를 걸 수 있다.)
- B가 withdraw를 시도하려해도 앞선 101,102,103블록의 priority가 높기 때문에 불가능.
최종적인 사인 없이 첫번째 tx 사인만으로 해당 거래가 유효하다고 한다면, 위와 같이 operator가 공격했을 때 꼼짝 없이 당하게 된다.
그렇다면 Plasma Cash에서는 어떨까? 이용자들은 더 이상 두 번의 사인 과정을 거치지 않아도 된다. 플라즈마 캐시의 경우, priority의 개념이 존재하지 않는다. exit process에서 해당 체인의 앞에서부터 priority대로 인출을 하는 것이 아니라, 각 token의 거래 기록을 보고 유효하다면 인출이 된다. 즉, A->B, B->C의 거래가 각각 500번째, 504번째 블록에 있었다고 할 때, 500번째 블록과 504번째 블록 사이에 있는 ‘다른’ 블록들은 고려 상황이 아니다. 왜냐하면, 그 블록들의 거래들은 해당 token의 거래 기록과는 상관이 없기 때문이다. 위와 같은 attack 상황에선, B는 B가 현재 가지고 있는 토큰의 거래 기록만 유효함을 보여주면 101, 102, 103 블록과 상관 없이 인출이 가능하다. A의 경우 B에게 무사히 전달이 되었기 때문에 인출이 불가능하며, 이는 A에게 전혀 손해가 아니다.
정리하자면, 기존 플라즈마 모델은 이전 블록에 따라 현재 블록의 valid함이 좌우 되기에 해당 블록과 valid함을 확인했다는 2-phase sign이 필요하다. 반면, 플라즈마 캐시의 경우 개별 token의 거래 기록만이 valid함을 좌우하기에 처음 거래 생성 시 들어가는 사인만 있으면 문제없이 거래 될 수 있다.
3. 효과적인 Exit Challenging
기본적으로 token C에대한 exit을 요청하기 위해선, C의 소유권 이전에 관한 상위 두 개의 거래 내역을 제시하면 된다. 플라즈마 캐시가 도입된 플라즈마 체인에서 부정한 exit process와 그 challenging은 다음과 같이 분류 할 수 있다.
1) 사용된 token의 출금
3->4의 tx이 컨펌됐으나 블록 3에 대해 exit을 요청하는 경우이다. Challenger는 4의 내용을 통해 challenging 할 수 있다.
2) 이중 지불 후 출금
1->2->3의 전송 과정이 valid하나, 공격자가 2->4 블록으로의 double spending을 한 후, 블록4에 대해 exit을 요청하는 경우이다. Challenger는 3의 내용으로 challenging을 한다. 이 토큰은 블록 4 전에 생겼으며 그 정보가 블록 4의 부모 체인으로 보내졌다. 따라서 exit process는 취소된다.
3) 부정한 기록을 통한 출금
1->2의 블록까지 valid하고 공격자가 2->3->4->5 블록을 만들어 4->5를 제출해, 5에 대한 exit을 요청 하는 경우이다. Challenger는 블록 2까지 valid함을 증명한 뒤, 공격자에게 다음 블록을 요청한다. 공격자가 블록 2->3이 valid함을 증명하지 못하면 exit process는 취소된다. 만일, 공격자가 invalid한 블록을 withhold하여 공개하지 않았더라도, 위의 challenging 방식은 유효하다.
중요한 점은 id의 도입으로 인해, 기존 모델에서는 불가능했던 challenging이 가능해졌다는 것이다. 앞선 문제점에서 언급 되었 듯, 기존 모델에서 operator가 부정한 token을 만들어 인출을 시도했을 경우, 참여자들은 순차적인 exit을 통해 빠져나가는 방법을 택할 수 밖에 없었다. 그러나, id가 도입되면 같은 상황에서 operator가 인출 대상 token의 모든 거래기록을 보유하고 있어야 한다. 이 기록은 deposit까지 이어지는데, 앞 상황의 경우 deposit이 존재할 수 없다. 따라서 challenge를 걸면 공격자가 유효성 증명이 불가능하기에 참여자들은 exit이 아닌 방법으로 해당 부정 인출을 취소시킬 수 있다.
4. 관찰 비용 절감
사실 상, 플라즈마 캐시의 핵심이라 할 수 있는 개선점이다. Deposit 후 생긴 모든 토큰은 Rootchain에 매핑되어 기록되어있다. 또한, 그 토큰들의 id는 불변이다. 마지막으로 위에서 서술한 거래에서 전달되는 정보를 살펴보면,
“해당 id의 토큰이 소비된 이전 모든 거래 기록”
이 포함되어 있다. 이를 바탕으로 해당 토큰 보유자는 새로이 생성되는 블록 중 자신이 보유한 토큰의 id만 확인하면 된다. 즉, P-chain이든 부모 체인이든 자신의 토큰과 관련된 블록들만 선택적으로 저장, 관찰하면 자신의 자산이 안전함을 알 수 있다. 그 저장 기록들 역시, 거래 성사시에 이전 소유자에게서 받기 때문에 검증만 된다면, 이전 기록에서 하나하나 찾을 필요가 없다.
다시 말해, 모든 데이터를 소유하고 있어야하는 기존 모델과 달리, 플라즈마 캐시는 ‘관찰’ 기능이 분할되어있다.
5. 공격자의 공격 부담 증가
기존 모델에서 출금하기 위해서는, 한 번의 출금과정만 거치면 됐다. 그러나, 플라즈마 캐시의 경우, 루트 체인에 모든 토큰이 각각 기록되어 있다. 따라서 출금을 요청하기 위해서는 출금하고자 하는 모든 토큰에 대해 따로 따로 출금 신청을 해야한다. 즉, 기존에는 한 번만 거짓말을 하면 됐지만, 플라즈마 캐시의 도입을 통해 토큰 개수 n번의 거짓말을 해야한다. 이는 공격자의 공격 부담을 증가시킨다.
위와 같은 장점들만 보면 확실히, 플라즈마 캐시는 기존 플라즈마 모델을 획기적으로 개선시킬 것이다. 그러나, 조금만 생각을 해보면 이 모델의 도입으로 인해 생기는 새로운 문제점, 혹은 여전히 해결되지 않은 기존 모델의 문제점이 보일 것이다. 이제 아래에서 그 문제들에 대해 논의해보자.
Open Problems
1. 효율적인 거래의 한계
지폐에 비교해보자, A는 만원 한 장을 들고 있고, B에게서 5천원어치의 물건을 구입하려 한다. B가 거슬러 줄 5천원이 없을 경우, 5천원 두 장을 보유하고 있는 C를 통해 A는 물건을 구입해야 한다. 물론, 네트워크 상에서는 실제보다 C를 찾는 것은 쉬울 것이다. 그러나, 이 역시 불편한 거래 과정이 한 단계 추가 되는 것이며, C는 이 거래에 대해 수수료도 요구 할 수 있다.
2. non-existence proof (미포함 증명)의 구현
앞서, 거래에서 다음 정보가 포함된다고 언급한 바 있다.
“해당 id의 토큰이 소비되지 않은 이전 모든 블록에 대해, 각 블록의 머클 트리에 해당 id의 토큰이 포함되지 않았음을 보여주는 증명”
우려되는 점은 두 가지이다.
- 증명의 크기
- 제시된 증명이 유효한지 확인하는 비용
예를 들어, 220만개의 블록이 생성되었고, 그 동안 token A가 총 10번 거래되었다고 하자. 그렇다면 다음 번 거래 시, 2,199,990개 블록에 대해 해당 token이 거래되지 않았음을 모두 증명해야 한다. 이 증명 제시 방법을 효율적으로 짜지 못하면, 굉장히 불편하며 무거운 작업이 될 것이다. Vitalik이 제시한 아이디어 따르면, zkSTARK 혹은, Bloom Filter를 도입할 경우 위 경우에 대해 증명 데이터 크기가 1600bytes 정도로 줄 것이라고 한다.
3. 복잡한 exit 신청
종료를 위해 신청자는 거래를 할때와 마찬가지로
- 해당 id의 토큰이 소비된 이전 거래 기록이 유효함을 보여주는 증명
- 해당 id의 토큰이 소비되지 않은 이전 모든 블록에 대해, 각 블록 머클트리에 해당 id의 토큰이 포함되지 않았음을 보여주는 증명
위 두 가지를 제출한다. 거래에서 수신자가 위 증명들을 검증했듯이, exit을 신청하면 플라즈마 컨트랙트에서 그 작업을 수행해야 한다. 자칫하다 상당히 무겁고 비싼 작업이 될 수 있다. 이 과정을 최적화 하는 방법이 필요하다.
4. 수수료
분할이 안 되는 플라즈마 캐시 시스템에서 수수료는 굉장히 큰 걸림돌이다. 수수료 지급에 관해서는 다음과 같은 논의가 있다.
- 플라즈마 체인 내에서 사용될 수 있는 수수료용 토큰을 만든다.
- 플라즈마 캐시의 id에 소수점을 넣어 사실 상 ‘분할’한다. 이 논의는 위 1번에도 해당하는 논의이다. 예를 들어 id=12345, amount = 1ether인 token이 있다고 하자. 이 토큰에 소수점을 도입하면 사실 id=12345.0000이 된다. 이후, 거래가 일어날 시, (12345.0000, 1 ether) 토큰은 (12345.0001, 0.9 ether)와 (12345.0002, 0.1 ether) 토큰으로 분할되는 것이다.
=> 문제1 : (수수료)>(토큰의 가치)가 될 때까지 분할되면 그 토큰은 사실상 사용되지 못한다.
=> 문제2 : 분할로 인해 감시해야하는 토큰의 개수가 점점 늘어날 것이다. - 플라즈마 캐시 내에 수수료 항목을 담는다. 즉 토큰은 (id, amount, total_fee) 값을 가진다. id=12345, amount=1 ether인 토큰이 있다고 하면, 이 토큰의 초기 total_fee=0이다. 이 토큰의 소지자가 거래를 하고 나면, (12345, 1 ether, 0) => (12345, 1 ether, 2000 gas)가 될 것이다. 이 토큰은 total_fee가 amount보다 커지기 전까지 사용될 것이고 exit process 시, 토큰의 가치는 amount-fee가 될 것이다.
확실한 것은 수수료를 신경쓰게 되면 구현과 작동이 매우 복잡해질 가능성이 있다. 이더리움 측에서 어떻게 이 문제를 풀어나갈지 궁금할 따름이다.
5. Block Withholding
이 문제는 operator에 의해 거래 데이터가 언제 공개 되는지 결정되는 문제이다. 아래 상황을 살펴보자.
Operator는 3번째 거래를 숨긴다. 그러면 참여자는 3번째를 못보고 2 -> 4의 거래를 만들게 된다. 그 직후,
operator가 숨긴 거래를 퍼뜨린다. 이 순간, 2 -> 4 거래는 이중 지불이 되어버린다. 이와 같은 문제에 대해 복구 메커니즘의 구현이 필요하다.
맺으며
지금까지 3편에 걸쳐 이더리움 재단에서 진행하는 ‘Plasma’ 프로젝트에 대해 살펴보았다. 다소 복잡해 보이지만, 하나 하나의 프로세스를 만들기 위해 수 많은 고민이 녹아있음을 엿볼 수 있었다. 이더리움의 확장성이 한계를 드러낸 지금 시점에서, Plasma 프로젝트의 완성은 필수다. 물론, 아직 풀리지 않은 문제들이 있고 구현까지 시간이 필요해 보인다. 완성만 된다면, 이더리움의 확장성은 상당히 커질 것이다.
Reference
Ethresearch
Plasma cash simple spec
Karl Floersch — Ethereum scaling : Plasma & shading
Ethereum Community Conference — Vitalik Buterin
플라즈마 백서