Plasma 총정리 : 이더리움 확장성 솔루션

조상연
14 min readSep 1, 2018
“person's hand beside plasma ball” by Josh Riemer on Unsplash

TL;DR

플라즈마는 이더리움의 오프 체인 솔루션으로 여러 종류의 플라즈마가 제안되고 있다. 기초적인 모델로 UTXO를 적용한 MVP를 만들었으나 참여자가 모두 플라즈마 블록과 메인 블록을 계속 확인해야한다는 단점으로 인해 Plasma Cash가 나왔다. Cash라는 말에 걸맞게 마치 지폐처럼 각 Peth마다 고유번호가 있어 합칠 수도 나눌 수도 없다. 이를 해결하기 위해 Plasma Debit, 즉 플라즈마 체크카드가 나왔다. 또한 Plasma Cash도 블록수가 늘어남에 따라 거래 증명을 위한 머클루트 용량이 선형적으로 증가하기에 이를 체크포인트 개념으로 해결하려는 것이 Plasma XT이다. 최근엔 단순한 UTXO거래에 불과한 Plasma에 스마트 컨트랙트를 올릴려는 시도인 Plasma EVM이 한국의 온더에 의해 제안되었다.

1. Plasma가 뭐지?

이더리움의 오프체인 솔루션으로 확장성 문제를 해결하기 위해 제시되었습니다. 이건 모두가 아는 사실이지만 정확히 어떻게 이루어져 있는지 알기가 쉽지 않았습니다. 자료도 찾아보고 코드도 보며 내린 결론은 아직 미완의 솔루션이기 때문에 정확히 A-Z를 정의내리기 힘들다는 점이었습니다. 그렇기에 플라즈마는 이렇다보다는 플라즈마가 가지고 있는 질문들을 파악해보는 것이 더 의미가 있을 것 같습니다.

기본적으로 플라즈마는 기존 이더리움의 루트 체인에 기반하여 차일드 체인(플라즈마 체인)을 확장시키는 아이디어에서 출발합니다. 위 그림에서처럼 Root chain에 여러 플라즈마 체인이 생길 수 있고, 각 플라즈마 체인은 루트 체인에 플라즈마 컨트랙트를 생성해야합니다.

이 플라즈마 컨트랙트는 플라즈마 체인으로 가치를 이동(Deposit)시키고 추후에 다시 이더로 가치를 반환(Exit)해주는 역할을 합니다. 그리고 그 과정에서 옳지 못한 Exit의 경우 Challenge를 받아 해당 Exit를 거절할 수 있습니다. 여기서 가치인 ETH는 오직 Root chain에서 생성되며 이를 Plasma Contract 맡기고 생성된 PETH(Plasm Eth)는 오직 해당 Plasma Chain 내에서 사용할 수 있습니다. 이 체인의 참여자가 아니더라도 PETH를 받을 수 있고 Exit도 가능합니다.

플라즈마 체인 내부에선 Plasma Operator에 의해 블록이 생성되며 블록의 거래내역의 루트 해시 값을 메인 체인에 담아 신뢰를 보장합니다. 이 모든 과정을 참여자가 지켜보고 루트 체인에 담긴 것까지 확인한 이후에 컨펌 메시지를 보내야 거래한 PETH를 사용할 수 있게 됩니다. 언뜻 보기엔 체인을 하나 더 만들고 그 체인의 각 블록 해시 값을 루트체인에 담아 신뢰를 보장하고 플라즈마 체인에서 더 빠르고 편하게 거래할 수 있는 행복한 세상 같지만 여러 문제점이 도사리고 있습니다.

2. Plasma의 핵심 질문

  1. 내 거래가 플라즈마 체인에 잘 담기는가?
  2. 내 거래가 루트 체인에도 잘 담기는가?
  3. 내가 받은 UTXO가 혹시 이미 써버린건 아닐까?
  4. Operator가 비잔틴은 아닐까?
  5. 다른 참여자가 비잔틴은 아닐까?

플라즈마에선 악의적인 행위자를 방지하기 위해서 여러 장치를 해두었습니다. 이것을 잘 이해하기 위해 Plasma가 기본적으로 가지는 핵심적인 질문을 제 나름대로 정리해보았습니다. 각각의 질문들을 해결하기 위한 방법은 많지만 가장 근본이 되는 것은 참여자가 루트 체인과 플라즈마 체인을 감시한다는 것으로 자신의 거래가 잘 담기는지 확인하고 다른 참여자나 Operator의 비잔틴 행위도 감시하여 Challenge라는 행위를 통해 방지해야 합니다. 이에 대한 내용은 Karl의 Ethereum Plasma MVP Overview 영상을 통해 더 확실히 아실 수 있습니다.

위 영상의 핵심은 PoA(Proof of Authority)으로 강력해질 수 있는 Operator의 권한을 어떻게 효과적으로 제한하는가 입니다. 만약 Operator가 자신에게 9999 PETH를 보내는 트랜잭션을 블록에 담아 생성하고 이를 Exit하려 한다면 이를 참여자들이 보고 바로 Exit로 대응합니다. 이럴 경우 플라즈마 컨트랙트는 가장 먼저 생성된 UTXO부터 처리하여 Operator가 가장 나중에 생성해버린 UTXO는 출금하려해도 컨트랙트에 남은 ETH가 없어 줄 수 없는 상황을 만들어 버립니다.

하지만 이런 방식은 참여자들이 모든 블록을 보고 저장해야 하는 부담감을 가지고 있습니다. 근본적인 해결책 또한 되지 못합니다. 그래서 이에 대한 해결책으로 Plasma Cash: Plasma with much less per-user data checking 가 2018년 3월 제안되었습니다.

3. Plasma Cash

Plasma Cash의 아이디어는 말 그대로 Cash, 지폐를 떠올리시면 쉽습니다. 5만원권에 모두 일련번호가 있고 다 제각각이듯 Peth에도 고유한 넘버링을 붙입니다. 이 고유한 넘버링은 컨트랙트에서 발행하는 것으로 금액, 보낸 사람의 주소, Deposit 횟수를 합쳐 Keccak256를 통해 나온 해시값의 uint256한 값을 사용합니다.

uint uid = uint256(keccak256(currency, msg.sender, depositCount));

이렇게 되면 내가 3번째로 보낸 1 ETH권, 앨리스가 보낸 6번째 7 ETH권이 나오게 되고, 절대 중복되지 않습니다. (혹시라도 그렇게 돌린 Kecaak256값이 같을 확률은 정말 낮습니다.) 그리고 천원권 4개 합친다고 4천원권이 합쳐지지 않고, 5천원권을 3천원 / 2천원권으로 쪼갤 수 없듯이 이렇게 나온 Plasma Cash는 합칠 수도 쪼갤 수도 없습니다.

Sparse Merkle tree image from: https://doi.org/10.1007/978-3-319-47560-8_13

그래서 고유의 아이디가 왜 중요할까요? Sparse Merkle Tree(SMT)와 함께 알아봅시다. Sparse는 듬성듬성하다는 의미로 머클트리의 군데군데가 비어있는 걸 뜻합니다. 즉 트랜잭션들로 촘촘하게 머클 트리를 만드는게 아닌, 일단 깊이 n을 설정하고 그렇게 생기는 2**n 만큼의 잎사귀(리프)에 값을 저장한다는 의미입니다. 위 사진처럼 a1에만 값이 존재하고 나머지는 비어있는 것이죠. 깊이가 256만큼 이라면 2**256개의 리프가 생기고 keccak256을 통해 나오는 값에 맞게 해당 자리를 미리 비워두는 게 가능합니다. 주소는 있지만 땅은 비어있는 셈입니다.

이를 통해 해당 주소에 트랜잭션이 발생한 기록을 확인하면 UTXO가 정말 Unspent되었다는 걸 확인할 수 있습니다. 예를 들어 앨리스가 컨트랙트에 3 ETH를 맡기며 UTXO의 유니크한 id를 받았다면, 그것을 위한 SMT 속 자리가 이미 마련되어 있습니다. 유니크하기에 다른 UTXO가 차지할 염려도 없습니다. 앨리스가 나중에 이 UTXO를 사용할 때는 정말 사용하지 않았다는 증명을 위해 이전 모든 블록 들의 SMT속에서 해당 자리가 비어있음을 보여주는 머클루트를 보내야합니다. 대신 용량은 해당 유니크한 id만 보면 되기에 기존 Plasma보다 훨씬 적습니다.

또한 이 id는 나만이 쓸 수 있는 유니크한 UTXO이기에 위에서 설명드린 Operator의 비잔틴 행위도 방지할 수 있습니다. Plasma MVP에서 그런 문제가 발생한 근본적 이유는 내가 가진 PETH와 남들이 가진 PETH가 같았기에 Operator가 마음대로 생성해도 똑같은 PETH가 되지만, 유니크하게 바꿔버린다면 그런 행동 자체를 방지할 수 있기 때문입니다.

//plasma_cash/utils/merkle/sparse_merkle_tree.pyclass SparseMerkleTree(object):    def __init__(self, depth=257, leaves={}):
self.depth = depth
if len(leaves) > 2**(depth-1):
raise self.TreeSizeExceededException(
'tree with depth {} could not have {} leaves'.format(depth, len(leaves))
)
# Sort the transaction dict by index.
self.leaves = OrderedDict(sorted(leaves.items(), key=lambda t: t[0]))
self.default_nodes = self.create_default_nodes(self.depth)
if leaves:
self.tree = self.create_tree(self.leaves, self.depth, self.default_nodes)
self.root = self.tree[-1][0]
else:
self.tree = []
self.root = self.default_nodes[self.depth - 1]

출처: https://github.com/omisego/plasma-cash/blob/master/plasma_cash/utils/merkle/sparse_merkle_tree.py

4. Plasma Debit

기존 Plasma MVP의 문제를 멋지게 해결한 Plasma Cash지만 심각한 문제가 있습니다. 바로 Cash를 나누거나 병합할 수 없어 실제 사용하기엔 매우 힘들다는 점입니다. 5 Peth 1장만 있다면 3 Peth를 보내고 싶어도 보낼 수 없게 되는 어처구니 없는 상황이 발생합니다. 이를 해결하기 위해 제안된 것이 바로 Plasma Debit 입니다. Debit은 체크카드처럼 돈을 맡기고 해당 한도 내에서만 돈을 사용할 수 있게 하는 것이 핵심입니다. 이를 위해서 독특한 구조가 필요하게되는데 바로 Balance 내에 bonded와 withdrawable라는 2가지 value가 필요합니다. 플라즈마 체인에 묶인 금액(bonded) v와 루트체인으로 인출 가능한 금액(withdrawable) a로 처음 네트워크에 가입하면 이 둘의 값이 같습니다.

struct Balance {  uint256 bonded;
uint256 withdrawable;
}mapping (address => Balance) public balances;

withdrawable(a)이 bonded(v)를 초과할 수 없으므로 처음 가입한 직후엔 다른 참여자로 부터 peth를 받을 수 없습니다. 만약 2peth를 받고 싶다면 아래 중 하나의 경우로 가능해집니다

1. v-a가 2 peth이상으로 빈공간이 있는 참여자에게 2peth를 전송해 공간을 마련하다.
2. operator에게 요청하여 v를 늘려 유동성을 확보한다.

이때 v를 늘리기 위해 참여자는 root-chain 컨트랙트에 2 eth를 deposit 해야하고 확인 후에 operator는 v를 2만큼 늘려줍니다. 돈 자체를 더 주는게 아닌 지갑의 크기를 키워주는 것입니다. 여기서 operator는 모든 참여자의 v와 a값을 합산하여 유동성과 통화발행량을 측정할 수 있습니다.

이러한 구조를 위해 머클트리 안에 각 계좌별로 리프노드를 만들고 그 안에 bonded와 withdrawable을 넣어 해당 계좌의 트랜잭션 내역을 간단한 머클루트로 확인할 수 있게 합니다. 하지만 현재까지 Plasma Debit은 구현체가 없으며 loom network에서 plasma cash 기반으로 실험적으로 테스트 중입니다.

5. Plasma XT

Plasma Cash의 또다른 문제로 각 토큰(Peth)가 과거 모든 블록에 대한 머클루트를 가져야하므로 블록수가 늘어남에 따라 거래 증명을 위한 용량이 선형적으로 증가할 수 밖에 없다는 점이었습니다. 그러므로 장래에는 거래를 위해 GB단위 용량이 필요할 수 있습니다. 이것은 일반적인 PC 환경에선 큰 문제가 아닐 수 있지만 모바일 같은 소형기기에선 치명적이기에 해결이 필요합니다. 이를 체크포인트 개념으로 특정 체크포인트 이전에 대해선 확인을 하지 않아도 되게 하는 Plasma XT가 제안되었습니다. 하지만 아직까지 별다른 진전은 없어보입니다. 혹시 더 아시는 분은 댓글로 알려주시면 감사하겠습니다 :)

6. Onther의 Plasma EVM

최근의 한국의 이더리움 R&D 기업 Onther에 의해 제안된 Plasma EVM이 있습니다. Plasma EVM은 플라즈마에 EVM을 올리기 힘들다는 기존 생각 에 전면으로 대치하고 있습니다. 리서치 페이지에 개제된 내용에 따르면 2가지블록 종류를 가지게 되는데 첫 번째는 Root chain과의 작용(enter, exit)에 관한 요청들을 담는 requestBlock이고, 두 번째는 일반적인 이더 전송과 Message call(사실상 enter와 exit 제외한 나머지)을 담는 nonrequestBlock입니다. 이렇게 함으로써 Enter와 Exit 과정에서 생기는 취약한 점을 분리하고 EVM이 안전하게 돌아갈 수 있도록 하는 것 같습니다. 좀 더 자세한 이야기는 9월 8일에 열리는 제20회 서울 이더리움 밋업에서 들으실 수 있습니다. 박주형 온더 CTO께서 직접 Plasma EVM에 대한 설명을 해주실 예정입니다.

7. Conculsion

위에서 언급한 Plasma외에도 Truebit 과의 결합을 꾀한 플라즈마 등 다른 제안도 정말 많이 존재합니다. 그만큼 개선이 많이 필요한 솔루션이며 샤딩과 더불어 이더리움의 Layer-2 솔루션의 희망이기도 합니다. 비탈릭도 결국 Layer-2 솔루션이 더 많은 비중을 차지할 것이고 더 많은 시도가 필요하다고 역설한 바 있습니다. 처음 스터디를 진행할 때는 어려움도 많았고 도대체 어떤 걸 하려는 건지 알기 힘들었으나 차차 이해를 하고 나니 아직 한참 남았구나라는 생각이 들었습니다. 플라즈마 제안 하나 하나마다 의문이 떠나지 않았고, 이러면 어떻게 될까? 저러면 어떻게 되지? 라는 질문의 연속이었습니다. 하지만 Plasma가 처음 제안된지 이제 겨우 1년이란 점을 생각해보면 그 사이에 정말 많은 발전을 했다고 봅니다. 계속 관심을 가지고 볼만한 솔루션이고 특히 Plasma evm의 발전이 기대됩니다. 긴 글 봐주셔서 감사합니다.

Reference

  1. https://medium.com/crypto-economics/what-is-plasma-plasma-cash-6fbbef784a
  2. https://blog.ujomusic.com/a-plasma-cash-primer-27dcfd1d5ddc
  3. https://www.youtube.com/watch?v=jTc_2tyT_lY
  4. https://ethresear.ch/t/plasma-debit-arbitrary-denomination-payments-in-plasma-cash/2198
  5. https://ethresear.ch/t/plasma-xt-plasma-cash-with-much-less-per-user-data-checking/1926
  6. https://medium.com/@eolszewski/plasma-debit-simplified-dd8aa233e602
  7. https://ethresear.ch/t/plasma-evm-state-enforceable-construction/3025

--

--