이더리움 개발 - 누구나 할 수 있는 솔리디티(Solidity) 언어 #1

    우리는 그동안 Geth를 이용하여 사설 네트워크에서 계좌 생성 및 채굴을 해보고, Mist GUI 브라우저를 이용하여 추가 계좌 생성 및 송금을 해보는 것들을 테스트 해보았습니다. 사설 네트워크에 이더리움도 있겠다 계좌도 여러개 있겠다 이제는 본격적으로 스마트 컨트랙트(Smart Contract)를 구현하기 위한 솔리디티(Solidity)를 시작해보도록 하겠습니다.


    들어가기에 앞서 우선 잠깐, 스마트 컨트랙트에 대해서 복습을 해보겠습니다. 스마트 컨트랙트는 우리가 누군가와 계약(Contract)을 하기 위해서는 중간의 신뢰하는 사람이나 기관을 넣을 필요가 없게 만드는, 탈중앙화 계약 시스템입니다. 


    즉, 내가 누군가와 계약을 한 사실을 모든 사람들에게 공표를 함으로써, 자동적으로 참여하는 노드들과 기록들이 그 증거로 남는 것이 스마트 컨트랙트입니다. 계약을 코딩으로 구현을 하여, 거짓말을 할 수 없게 되고 블록체인의 특성상 수정이 불가능하기 때문에 부인방지의 역할도 가능하게 됩니다.



    스마트 컨트랙트에 대해서 복습이 되셨나요? 혹시 이해가 가물가물 하시면, 제가 포스팅한 이더리움을 한번 읽어보시면 도움이 될 것 같습니다.



    What is Solidity?


    솔리디티는 기존에 있던 언어가 아닌 이더리움의 스마트 컨트랙트를 구현하기 위해서 만들어진 이더리움 전용 언어입니다. 솔리디티는 Python, C++, Javascript같은 널리 알려진 언어와 사용법이 유사하며, EVM(Ethereum Virtual Machine)에서 구동되어 집니다.


    이더리움은 기본적으로 무작정 솔리디티 코드를 짜는 것보다는 검증된 모범사례를 참고해서 작성되는 것을 권유하고 있습니다. 코인이 전달되는 코드이기 때문에, 잘못 짠 소스는 악의적인 해커(Hacker)들의 먹잇감이 될 수 있기 때문에 검증된 모범사례(Best Practice)의 코드가 아니라면 상당 기간의 코드리뷰(code review), 테스팅(testing), 감사(audit), 정확성증명(correctness proofs) 작업이 들어가야 할 것입니다.


    http://solidity.readthedocs.io/en/develop/index.html



    지원하는 개발 환경(IDE)


    솔리디티는 생각보다 다양한, 개발 환경을 지원합니다. 브라우저 기반의 Remix부터 범용적으로 많이 쓰이는 IDE 툴들인 IntelliJ, Visual Studio에서 Solidity Plugin을 설치하면 사용이 가능할 정도입니다. 


    이외에도 다양한 개발 환경을 지원합니다



    다양한 툴들에 대한 비교는 추후, 시간이 되면 작성을 해서 올리도록 하겠습니만, 일단 가장 많이 쓰고 있는 브라우저 기반의 개발 환경인 Remix에서 진행을 해보도록 하겠습니다.




    Remix 설치 Step by Step


    Remix를 다운로드 하여, 실행하는 Step by Step을 해보도록 하겠습니다. 

    Remix는 https://github.com/ethereum/browser-solidity/tree/gh-pages에서 다운로드 받을 수 있으며, Clone or download를 클릭 후, Download ZIP을 클릭하여 다운로드 받고, 파일을 실행하여 원하는 곳에 압축을 풀겠습니다. 


    Clone or download로, 압축 파일을 받습니다


    원하는 곳에 압축을 풉니다. 참고로 저는 c:/remix에 압축을 풀어서, 경로가 “C:\remix\browser-solidity-gh-pages”이 만들어 졌습니다.



    index.html 파일을 더블 클릭하여 실행 합니다. 빈 페이지가 뜬다면, 크롬(Chrome) 이나 웨일(Whale) 브라우저 등으로 구동을 합니다. 제 Internet Explorer는 구동이 안되는 걸 확인했습니다.



    Hello World!!

    개발자들은 처음 특정 언어를 배울때 제일 처음에 하는 코딩이 있습니다. 바로 “Hello World!”인데요. 솔리디티판 Hello World가 있습니다. 



    SimpleStorage라는 Contract를 구현하는 것이 솔리디티판 Hello World입니다. 이 예제는 값을 입력하면, 그 값을 그대로 출력하는 프로그램입니다.



    remix의 왼쪽 윗 부분을 보면 +(플러스) 모양의 아이콘이 보입니다. 해당 아이콘을 클릭하면, 윗상단에 팝업창이 뜨면서, File Name을 입력하는 공간이 나옵니다. 여기에 SimpleStorage.sol 을 입력하고, OK 버튼을 클릭합니다.



    그럼, 빈 공간이 나오는데 여기에 SimpleStorage 소스를 입력합니다. 


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    pragma solidity ^0.4.24;
     
    contract SimpleStorage {
        uint storedData;
     
        function set(uint x) public {
            storedData = x;
        }
     
        function get() public constant returns (uint) {
            return storedData;
        }
    }
    cs

    위 소스를 복사하여 사용합니다.



    소스 설명


    맨 위에 있는 pragma solidity는 해당 솔리디티를 어떤 버전으로 컴파일(Compile) 할 것이냐라는 의미입니다. 저는 0.4.24 버전으로 컴파일 한다는 것이고, 여기서 컴파일은 사람들이 식별할 수 있는 언어를 기계들이 이해할 수 있는 언어로 변환하는 것을 뜻합니다. 한마디로 저 소스를 기계들이 이해할 수 있게 기계어로 번역을 한다는 뜻입니다.


    이제 한줄씩 소스를 설명해드리도록 하겠습니다. 


    1. contract SimpleStorage { 소스 }

    우선 컨트랙트 명을 SimpleStorage로 이름을 짓겠다는 뜻입니다. 


    2. uint storedData;

    storedData라는 이름의 변수를 정수형(Integer)으로 선언한다는 의미입니다. 즉, storedData라는 곳에는 정수형밖에 들어가지 못합니다. 여기에 문자를 넣으면, 에러가 발생하게 됩니다.


    3. function set(uint x) public { 소스 }

    펑션은 하나하나 기능을 선언하는 것인데 set이라는 이름의 이 펑션은 x라는 정수형 변수만 받게 선언이 되어 있고, 해당 값을 storedData라는 변수에 세팅하게 됩니다. 즉, 해당 펑션이 선언 된 후, set(1)이라고 하면, x에 1이라는 값이 세팅이 되고, x의 값은 다시 storedData에 들어가게 되어서 결국에는 storedData에 1값이 들어가는 매우 간단한 예제입니다.


    4. function get() return uint { 소스 } 

    get 메소드는 정수형으로 리턴을 하는 펑션인데, 소스의 내용을 보면 return storedData 입니다. 즉, get()을 호출하면, storedData에 담겨져 있는 값을 그냥 출력하는 펑션입니다. 우리가 set() 펑션에 100값을 넣고, get()을 호출하면, 100이 출력이 되는 매우 간단한 컨트랙트 예제입니다.


    이제 이 소스를 컴파일 한 후, 실행을 해보도록 하겠습니다.




    소스 컴파일


    소스가 모두 입력이 되었으면, Start to compile 버튼을 클릭합니다. 소스에 오타가 나지 않았다면, 문제가 없이 컴파일이 될 것입니다.



    위 캡쳐화면처럼, SimpleStorage로 변경된 것을 볼 수 있습니다. 에러가 없다면, 위와 같이 정상적으로 SimpleStorage 부분이 뜨게 됩니다.



    소스 실행



    Compile이 완료되었으면, Run 메뉴를 선택합니다.



    Create 버튼을 클릭하면, 아래 붉은색 네모박스처럼, get과 set 펑션이 보이게 됩니다. set에 값을 넣어보도록 할텐데요 일단 우리 생각처럼 정수형만 되는지 값을 문자와 소수값을 넣어보도록 하겠습니다.



    a를 입력하고, set 버튼을 “클릭” 합니다. 그러니, 회색부분의 네모 부분처럼 에러가 발생하였습니다. Error encoding arguments 즉, 아규먼트가 잘못되었다는 것인데, 선언된 것은 숫자형인데 문자열을 전달해서 그렇습니다. 그러면, 소수값을 넣어보도록 하겠습니다.


    소수값은 예상과 다르게 정상적으로 작동이 되며, 소수점 밑은 모두 절삭해서 들어가 있습니다. 값을 출력해보고 싶으시면, get 버튼을 누르시면 됩니다. 화면처럼 "0: uint256: 2" 라는 값이 나오는 것을 확인할 수 있습니다.

    한가지 더 테스트를 해볼텐데요 uint형이 소수값을 혹시 인식하고 있는지를 테스트 해보도록 하겠습니다.


    uint storedData에 1을 넣어보고 컴파일을 해보니 이상이 없이 컴파일 되는 것을 확인 할 수 있었고, 아래는 1.5를 넣으니, 컴파일이 안되며 에러가 뜨는 것을 확인할 수 있습니다. 즉 uint에는 소수값이 들어가면 인식이 안된다는 것을 알 수 있습니다.


    참고로 테스트를 하실 때, 마이너스 정수형은 인식이 안되는 것을 확인하실 수 있을 겁니다. -1 같은 값을 넣을 경우 에러가 발생하게 되는데요. 그 이유는 uint의 형에서 u가 unsigned의 약어로 양수만 인식한다는 것을 의미합니다. 



    마이너스값을 넣고 싶으면, uint를 모두 int로 변경을 합니다.


    set에 -2를 넣었는데, get으로 -2가 출력이 되는 것을 확인할 수 있습니다. 이처럼, 변수형 선언은 신중히 고민하고 선언을 해야 나중에 스마트 컨트랙트에 문제가 없을 것입니다. 만약 선언을 잘못하여 에러가 발생할 수 있는 코드를 작성할 경우, 해커들은 취약한 부분을 노리고 어떻게든 에러를 유발하여, 작동에 이상을 가게 만들거나 토큰을 갈취할 수 있다는 점을 명심하실 바랍니다.


    다음에는 좀 더 난이도가 있는 컨트랙트 예제로 설명을 해보겠습니다. :)


    댓글

    Designed by JB FACTORY