1 of 48

Plasma MVP(7f80bc9)

Smart Contract Audit

정순형(철학자)

kevin.j@onther.io

<외부자료 활용 시 출처 명시 부탁드립니다.>

2 of 48

발표영상

2

3 of 48

아이디어의 단초를 제공해준

4000D와 팀원들에게

감사의 말을 전합니다.

3

4 of 48

발표 방향과 순서

정답을 알려주기보다는 적절한 의문을 던지고 함께 호흡하는 방식

왜냐하면 저도 여러분처럼 그냥 블록체인을 좋아하는 한 명의 미완성된 연구자이기 때문

  • 계산 복잡도 이론과 EVM - 분석을 위한 툴과 접근 방식
  • 플라즈마MVP에 대한 간략한 소개
  • 플라즈마 컨트렉트의 구성 요소에 복잡도 이론적 접근

4

5 of 48

몇 가지 질문

  • 알고리즘과 자료구조를 수강하신분?
    • 계산복잡도 이론?
  • 이더리움 황서를 읽어 보신분?
    • EVM의 스토리지, 스택과 메모리?
    • 0x60 옵코드는?
  • 플라즈마?
    • 플라즈마 백서?
    • 플라즈마 소개글?(디사이퍼 연재 글)
    • 플라즈마 MVP 코드?
    • 플라즈마 MVP의 커미터?

5

6 of 48

What is Audit?

  • 코드상 보안 상의 헛점을 짚어주는일
    • 목적에 맞는 기능 수행
    • 취약점과 공격벡터

  • 효율적으로 코드가 수행할 수 있도록 개선/검토 하는 일
    • 같은 결과를 내지만 적은 가스(gas)를 소모
    • 단일 컨트랙트가 전체 네트워크에 주는 영향력을 최소화

6

7 of 48

What is Audit?

  • 코드상 보안 상의 헛점을 짚어주는일
    • 목적에 맞는 기능 수행
    • 취약점과 공격벡터

  • 효율적으로 코드가 수행할 수 있도록 개선/검토 하는 일
    • 같은 결과를 내지만 적은 가스(gas)를 소모
    • 단일 컨트랙트가 전체 네트워크에 주는 영향력을 최소화

7

8 of 48

복잡도 이론과 스마트 컨트렉트

8

9 of 48

알고리즘 교과서에서 가르치는 계산복잡도이론

  • 시간 복잡도(Time Complexity) : 연산 횟수 * 각 연산별 시간
  • 공간 복잡도(Space Complexity) : 총 공간 요구 = 고정 공간 요구 + 가변 공간 요구( S(P)=c+SP(n)S(P)=c+SP(n))
  • 시-공간 트레이드오프(Time-Space Complexity)
    • 시간복잡도와 공간복잡도는 반비례
    • 과연 EVM도 그럴까?

9

10 of 48

미니미 토큰의 잔액 조회의 시간복잡도는?

  • 왼쪽 함수는 transfer, generateToken할때마다 호출됨
  • 잔액 상태 변수를 특이하게 정의함

mapping(address => Checkpoint[]) balances;

10

11 of 48

미니미 토큰의 잔액 조회의 시간복잡도는?

  • Binary Search
  • O(log(n))
  • 어카운트 숫자, 토큰별 어카운트 숫자
  • 반복문 한번 가스소모량(t) 0.1M gas(가정)
  • n이 0.1M이라고 가정
  • 최대 가스 소모량은 t*O(log(n))
  • 100000 * log(100000) = 0.5M
  • 블록가스리밋보다 적으므로 가능하다

11

12 of 48

미니미 토큰의 잔액 조회의 공간복잡도는?

  • 왼쪽 함수는 transfer, generateToken할때마다 호출됨
  • 잔액 상태 변수를 특이하게 정의함

mapping(address => Checkpoint[]) balances;

12

13 of 48

EIP 150이후의 가스비 정리

https://docs.google.com/spreadsheets/d/1n6mRqkBz3iWcOlRem_mO09GtSKEKrAsfO7Frgx18pNU/edit#gid=0

  • 고정 공간을 변경하는 데 소요되는 가스는?

13

14 of 48

이더리움 블록체인에서 비용이란 무엇일까?

정답 : GAS

→ 그렇다면 시간비용은? → 각 연산당 비용 (GAS)

→ 그렇다면 공간비용은? → SSTORE, MSTORE, MLOAD, MSTORE, PUSH, POP.. (GAS)

14

15 of 48

이더리움 블록체인에서 비용이란 무엇일까?

정답 : GAS

→ 그렇다면 시간비용은? → 각 연산당 비용 (GAS)

→ 그렇다면 공간비용은? → SSTORE, MSTORE, MLOAD, MSTORE, PUSH, POP.. (GAS)

시간비용과 공간비용이 같다??

15

16 of 48

이더리움 블록체인에서 비용이란 무엇일까?

정답 : GAS

→ 그렇다면 시간비용은? → 각 연산당 비용 (GAS)

→ 그렇다면 공간비용은? → SSTORE, MSTORE, MLOAD, MSTORE, PUSH, POP.. (GAS)

시간비용과 공간비용이 같다??

그렇다면 공간비용도 고려해서 코딩해야 한다??

16

17 of 48

두 함수의 공간복잡도는?

17

18 of 48

이더리움 블록체인에서 비용이란 무엇일까?

정답 : GAS

→ 그렇다면 시간비용은? → 각 연산당 비용 (GAS)

→ 그렇다면 공간비용은? →SSTORE, MSTORE, MLOAD, MSTORE, PUSH, POP.. (GAS)

시간비용과 공간비용이 같다??

그렇다면 공간비용도 고려해서 코딩해야 한다??

아니다. 공간 점유 비용이 상대적으로 싸다, 다만 상태변수(스토지리) 제외!

18

19 of 48

EIP 150이후의 가스비 정리 : SSTORE

https://docs.google.com/spreadsheets/d/1n6mRqkBz3iWcOlRem_mO09GtSKEKrAsfO7Frgx18pNU/edit#gid=0

  • 고정 공간을 변경하는 데 소요되는 가스는?

19

20 of 48

이더리움 블록체인에서 비용이란 무엇일까?

정답 : GAS

→ 그렇다면 시간비용은? → 각 연산당 비용 (GAS)

→ 그렇다면 공간비용은? → SSTORE, MSTORE.. (GAS)

SSTORE를 쓰는 공간

→ 공간비용을 고려해야 한다.

20

21 of 48

이더리움 블록체인에서 비용이란 무엇일까?

정답 : GAS

→ 그렇다면 시간비용은? → 각 연산당 비용 (GAS)

→ 그렇다면 공간비용은? → SSTORE, MSTORE.. (GAS)

시간비용과 공간비용의 부담이 같다

21

  • 시-공간 트레이드오프(Time-Space Complexity)는 틀렸다.

SSTORE + 시간비용

= 시공간비용

22 of 48

복잡도는 어디까지 허용될까?

22

폰노이만 머신의 일반적인 복잡도 허용

23 of 48

이더리움 스마트 컨트렉트의 복잡도 허용

23

폰노이만 머신의 일반적인 복잡도 허용

EVM의 복잡도 허용

24 of 48

플라즈마(Plasma)

24

25 of 48

플라즈마(Plasma)

  • 계층형 블록체인
  • 부모체인은 자식체인의 상위 법원이 된다

  • Merklize State Commitment
  • Single Source of Value
  • Rule with Exit
  • Map Reduce Computation

25

26 of 48

Brief Introduction to Plasma MVP

26

child_chain.py

ganache

client.py

루트체인

차일드체인

명령을 날림

루트체인 상태 변경

차일드체인 상태 변경

blocks = {1,2, .. }

마이닝 된 블록

RootChain.sol

Account0

Account1

Account2

current_block:

마이닝 메모리 풀

27 of 48

디사이퍼에서 쓴 다음 글은 매우 도움됩니다!

27

28 of 48

Plasma MVP의 루트체인의 컨트렉트 구성

28

RootChain.sol

library_SafeMath.sol

library_Merkle.sol

library_PlasmaRLP.sol

library_Math.sol

library_Validate.sol

PriorityQueue.sol

29 of 48

Plasma MVP의 루트체인의 컨트렉트 구성

29

RootChain.sol

library_SafeMath.sol

library_Merkle.sol

library_PlasmaRLP.sol

library_Math.sol

library_Validate.sol

PriorityQueue.sol

30 of 48

RootChain.sol의 주요 함수 구성

  1. submitblock() : 자식체인의 머클루트 정보를 부모체인에 올리는 함수
  2. deposit() : 루트체인에 eth를 묻고 자식체인에 peth를 받기 위한 함수
  3. startDepositExit() → addExitToQueue() : deposit()으로 들어온 eth를 exit대기열에 올리는 함수
  4. startExit() → addExitToQueue() : 자식체인의 특정 utxo의 peth를 exit대기열에 올리는 함수
  5. challengeExit() : exits들을 challenge하는 함수
  6. finalizeExit() : 대기열에 쌓인 exits들을 메인체인에서 풀어서 보내주는 함수

30

31 of 48

RootChain.sol의 주요 함수 구성

  • submitblock() : 자식체인의 머클루트 정보를 부모체인에 올리는 함수
  • deposit() : 루트체인에 eth를 묻고 자식체인에 peth를 받기 위한 함수
  • startDepositExit() → addExitToQueue() : deposit()으로 들어온 eth를 exit대기열에 올리는 함수
  • startExit() → addExitToQueue() : 자식체인의 특정 utxo의 peth를 exit대기열에 올리는 함수
  • challengeExit() : exits들을 challenge하는 함수
  • finalizeExit() : 대기열에 쌓인 exits들을 메인체인에서 풀어서 보내주는 함수

31

파란색 : 현재 구현되어 있는 부분

32 of 48

exit(출금) 과정 : 전체 요약

32

사용자의 요청(startDepositExit 함수, startExit 함수)에 의해

대기열에 여러 exit들(출금요청)이 쌓여있고,

[exit1, exit2, exit3 … ]

각각의 exit정보들에 대한 priority에 대한 정보들은 PriorityQueue.sol을 통해 관리된다.

(챌린지를 거친) finalizeExit함수는 대기열에 쌓인 exit들을 우선순위를 고려하여 하나씩 꺼내 이더를 보내준다.

33 of 48

exit(출금) 과정 : 사용자 요청(startDepositExit)

33

큐에 저장

34 of 48

exit(출금) 과정 : 사용자 요청(addExitToQueue)

34

우선순위 큐에 <삽입>

35 of 48

exit(출금) 과정 : Finalize

35

3.우선순위 큐에서 <삭제>

1. 우선순위 큐에서 다음 엑싯을 찾고(다음 페이지)

2.이더 보내고

36 of 48

exit(출금) 과정 : getNextExit

36

우선순위 큐에서 최소값이 다음 엑싯 값이 된다

37 of 48

개별 컨트렉 소개2 : PriorityQueue.sol

37

38 of 48

38

39 of 48

엑싯 요청 vs Finalize 시-공간 비용 비교

39

엑싯 요청

Finalize

ExitQueue.Insert() - 상태변수 변경,

percUp(currentSize) - 상태변수 길이(n)만큼 변경

exits[utxoPos] - 상태변수 변경

쌓여있는 exit수를 n이라고 하면

transfer(), - 21,000가스

ExitQueue.delMin(), - 상태변수 변경(2번)

ExitQueue.percDown(), - 상태변수 변경

delete exits[utxoPos].owner; - 상태변수 변경

5000번의 exit 요청이 있었다는 가정(n=5000)

연산당 시공간비용(t)은 약 5000gas

1000번째 exit의 시공간비용은?

t*O(log_2(5000))

→ 5000*12

→ 60000gas + @

5000개를 한꺼번에 exit할 경우(n=5000)

t = 60,000gas

t*O(log_2(n))

→ 60,000*O(log_2(5000))

→ 60000 * 12

→ 0.72M gas

40 of 48

엑싯 요청 vs Finalize 시-공간 비용 비교

40

엑싯 요청

Finalize

ExitQueue.Insert() - 상태변수 변경,

percUp(currentSize) - 상태변수 길이(n)만큼 변경

exits[utxoPos] - 상태변수 변경

쌓여있는 exit수를 n이라고 하면

transfer(), - 21,000가스

ExitQueue.delMin(), - 상태변수 변경(2번)

ExitQueue.percDown(), - 상태변수 변경

delete exits[utxoPos].owner; - 상태변수 변경

5000번의 exit 요청이 있었다는 가정(n=5000)

연산당 시공간비용(t)은 약 5000gas

5000번째 exit의 시공간비용은?

t*O(log_2(5000))

→ 5000*12

60000 gas + @

5000개를 한꺼번에 exit할 경우(n=5000)

t = 60,000gas

t*O(log_2(n))

→ 60,000*O(log_2(5000))

→ 60000 * 12

0.72 M gas

매우 훌륭함

41 of 48

출금요청과 출금 실행

41

출금요청 시공간복잡도

→ t*O(log_2(n))

...

n번 출금요청

...

출금실행 시공간 복잡도 → t*O(log_2(n))

n개 출금

42 of 48

추가 연구 : Merkle과 PlasmaRLP의 시공간복잡도

42

RootChain.sol

library_SafeMath.sol

library_Merkle.sol

library_PlasmaRLP.sol

library_Math.sol

library_Validate.sol

PriorityQueue.sol

43 of 48

추가연구 : challenge의 경우

require(merkleHash.checkMembership(txindex, root, proof));

43

44 of 48

추가 연구 : 플라즈마 캐시

  • 구현 아직 없음

44

45 of 48

마무리

45

46 of 48

실제 실무에서 겪은일..

  • 요구사항 : ERC20 토큰을 발행/전송하는데 발행일 기준 각각 유효일이 있고, 전송할때 유효일이 지나면 잔액이 0으로 떨어졌으면 좋겠어요..!!

4000D : “@kevin 토큰 생성시 정해지는 유효 기간 은, 특정 토큰 수량마다 다른거죠? 만약 그렇다면, 특정 토큰의 (토큰 수량, 유효 기간) 의 tuple 을 배열로 저장해야할거에요. 그런 배열을 `tupleRecords` 라고 부르면, `transfer()` 할 떄, 유효하지 않은 토큰 수량을 계산 / 반영해야하는데, 이 때의 계산복잡도 *(`tupleRecords`의 각 원소를 읽고, 유효 기간이 지난 토큰 수량의 총 합을 계산)* 는 최대 `tupleRecords`의 길이 `n` 에 비례해서 `O(n)` 이 될거에요. 이더리움에서 `O(n)` 의 복잡도를 가지는 함수를 구현하는것은 불가능해요. `O(n)`만큼 반복문을 수행하면 언젠가 out of gas 가 발생할거니까요.”

kevin : 어차피 프라이빗 체인에 올리니 상관 없잖아?

4000D : !!

46

47 of 48

Questions?

47

48 of 48

Thanks

48