관리 메뉴

개발이야기

[마스터링 이더리움] Mastering Ethereum - Vyper 본문

블록체인 /마스터링 이더리움

[마스터링 이더리움] Mastering Ethereum - Vyper

안성주지몬 2018. 12. 19. 12:08

Smart Contracts and Vyper

Vyper는 더 나은 감사가능성을 제공하려고 분투하는 EVM을 위한 실험적이고 컨트랙트 지향 언어이며 개발자들이 지능적인 코드를 생성하는 데 쉽게 한다. 사실, Vyper의 원리 중 하나는 개발자가 오해의 소지가 있는 코드를 작성하는 것을 가상적으로 불가능하게 만드는 것이다.


Vulnerabilities and Vyper

최근 연구는 약 백만 개의 배포된 이더리움 스마트 컨트랙트를 분석하였고 이러한 많은 컨트랙트들이 심각한 취약성을 가지고 있다는 것을 발견했다.  그들의 분석에서, 연구자들은 취약성을 추적하는 세 가지 기본적인 카테고리로 윤곽을 보여줬다.


- Suicidal contracts(자살 컨트랙트)

: 스마트 컨트랙트는 임의의 주소에 의해 kill될 수 있다.

- Greedy contracts(탐욕 컨트랙트)

: 스마트 컨트랙트는 이더를 풀 수 없는 상태에 도달할 수 있다.

- Prodigal contracts(낭비 컨트랙트)

: 스마트 컨트랙트는 이더를 임의의 주소로 풀 수 있게 만들어질 수 있다.


취약성들은 코드를 통해 스마트 컨트랙트로 소개되어진다. 이러한 취약성과 다른 취약성들이 의도적으로 소개되지 않았다고 강하게 주장할 수 있지만, 그것과 상관없이 바람직하지 못한 스마트 컨트랙트 코드는 이더리움 사용자를 위한 자금의 예상치 못한 결과를 낳을 수 있고, 이는 이상적이지 못하다. Vyper는 안전한 코드를 쉽게 작성하기 위해 설계되었거나 우연하게 오해가 있거나 취약한 코드를 작성하게 까다롭게 만들도록 설계되어 있다.


Comparison to Solidity

Vyper가 불안전한 코드 작성을 어렵게 만들려고 시도한 방법 중 하나는 의도적으로 Solidity의 몇 가지 특징을 생략한 것이다. Vyper에서 배포하려고 고려하는 스마트 컨트랙트에서 Vyper에서 어떤 특징을 가지고 있지 않고 왜 그런지를 이해하는 것이 중요하다. 그러므로, 이러한 특징들을 살펴보고 왜 그들이 생략했는지에 대한 정의를 제공할 것이다.


Modifiers

이전 장에서 봤듯이, Solidity에서는 modifier를 사용하여 함수를 작성할 수 있다. 예를 들어, 다음과 같은 함수 changeOwner는 실행의 한 부분인 onlyBy라는 modifier에서 코드를 실행할 것이다.

function changeOwner(address _newOwner)
   public
   onlyBy(owner)
{
   owner = _newOwner;
}

이 modifiers는 소유권 사이의 관계에서 규칙을 강요한다. 당신이 봤듯이, 이러한 특이한 modifiers는 changeOwner 함수를 대신하여 미리 확인하는 수행을 하는 메커니즘으로 수행한다.

modifier onlyBy(address _account)
{
   require(msg.sender == _account);
   _;
}

그러나 modifiers은 여기서 보듯이 확인 수행만 하지는 않다. 사실, modifiers로써, 그들은 함수 호출 상황에서 스마트 컨트랙트의 환경을 많이 바꿀 수 있다. 간단히 말해서, modifiers는 만연하다.

다른 Solidity 스타일 예제를 보자

enum Stages {
   SafeStage
   DangerStage,
   FinalStage
}

uint public creationTime = now;
Stages public stage = Stages.SafeStage;

function nextStage() internal {
   stage = Stages(uint(stage) + 1);
}

modifier stageTimeConfirmation() {
   if (stage == Stages.SafeStage &&
               now >= creationTime + 10 days)
       nextStage();
   _;
}

function a()
   public
   stageTimeConfirmation
   // More code goes here
{
}

한 면에서, 개발자들은 그들의 코드를 호출하는 다른 코드를 항상 확인해야 한다. 하지만, 확실한 상황에서 개발자들은 코드의 한 줄을 간과할 수 있다. 이는 정신적으로 함수 호출 계층과 스마트 컨트랙트 변수의 상태를 메모리로 커밋하는 것을 놓치는 동안 개발자들 큰 파일에서 돌아다닐 경향이 있다.


앞에서의 예제를 더욱 더 깊게 한 번 보자. 한 개발자가 a라고 불리는 public 함수를 작성하였다고 상상해보자. 개발자는 이 컨트랙트가 새롭고 다른 사람에 의해 작성된 modifier를 활용한다. 즉시, stageTimeComfirmation modifier가 호출 함수와 연관된 컨트랙트의 나이와 상관없이 몇 개의 확인을 수행하는지 보여준다. 개발자가 인지하지 못하는 것은 modifier가 다른 함수 nextStage를 또한 호출하는 것이다. 이러한 간단한 검증 시나리오에서, public 함수 a를 호출하는 것은 스마트 컨트랙트의 stage 변수를 SafeStage에서 DangerStage로 이동시키는 결과를 낳는다.


Vyper는 modifiers와 다같이 작업한다. Vyper로부터의 추천은 다음과 같다: 만약 modifiers로 오직 가정만 수행한다면, 단순한게 인라인 체크를 사용하고 함수의 한 부분으로서 가정한다; 만약 스마트 컨트랙트 상태와 그 밖의 등등을 modify한다면 이러한 변화들을 함수의 부분으로 명백하게 다시 만들 것이다. 감사가능성과 읽기 쉽게 함으로써, 독자들은 정신적으로 함수 주변에 있는 modifiers를 “포장”할 필요가 없다.


Class inheritance





Comments