[Dev] Ethereum 개발 - #2. Smart Contract를 이용한 dApp 개발

in #ethereum6 years ago (edited)

이전 글에서는 이더리움을 설치하고 테스트넷을 통해 Ether의 발행부터 송금까지 다루어봤습니다. 여기서는 이더리움의 확장 기능인 Contract를 사용해 브라우저에서 동작하는 간단한 카운터 프로그램을 만들어 보겠습니다.

이더리움 스마트 컨트랙트


  • 에이전트 방식으로 동작하는 Contract 프로그램을 블록체인에 배치할 수 있고 다양하게 동작하도록 프로그램밍할 수 있음
  • 계정과 동일한 주소를 가지며 이 주소에 트랜잭션을 발행하여 동작을 수행함
  • Contract는 geth 내부의 EVM(Ethereum Virtual Machine) 환경에서 동작
  • EVM은 자바의 가상 머신(JVM: Java Virtual Machine)처럼 운영체제에 종속되지 않고 코드를 구동할 수 있음
  • Contract 코드는 블록체인에 저장돼 네트워크를 통해 각 노드에 전파되므로 개별적으로 배포할 필요가 없으며, 이러한 특징을 통해 이더리움은 분산 응용프로그램 기술을 실현함
  • Contract 프로그램은 Solidity라는 이더리움 공유의 언어를 사용(Serpent, LLL 등 여러 언어가 존재하지만 Solidity가 가장 활발함)

스마트 컨트랙트에 대해 잘 설명된 자료가 있어 링크해 드립니다.

개발 도구 준비


Contract 개발을 위해서는 브라우저 기반의 IDE인 Remix을 준비합니다.
스크린샷 2018-04-13 오후 4.24.56.png
브라우저 기반 Solidity IDE인 Remix 실행 화면

이 밖에도 다양한 개발 도구들이 있지만 Remix가 가장 활발하게 업데이트되고 있습니다.

Remix 기동

Remix는 브라우저 기반의 온라인 모드설치 파일을 다운받아서 로컬환경에서 실행할 수 있는 2가지 모드를 제공합니다. 여기서는 크롬이나 파이어폭스 등의 브라우저를 통한 온라인 모드를 사용을 하겠습니다.

처음 실행하면 기본으로 Ballot라는 Contract가 보입니다. 이 코드를 삭제한 뒤, 새 Contract를 입력하면 됩니다.
스크린샷 2018-04-13 오후 5.22.21.png
사파리 브라우저에서 Remix를 실행한 화면

Contract 작성


카운터를 1씩 증가시키는 간단한 Contract 코드입니다.

// 계정 관리용 Contract
contract CounterMaster {
    // 계정 목록
    // Contract는 주소를 지정해 호출해야하기 때문에 주소 및 카운터 Contract를 지원하는 맵 정보
    mapping (address => Counter) private counters;
    // 주소를 관리하는 배열
    address[] private addressList;

    // 카운터 Contract를 배열과 맵에 추가
    function addCounter(bytes32 name) {
        // 카운터 Contract를 작성
        Counter c = new Counter(name);

        // 배열에 주소를 추가
        addressList.push(address(c));
        // 매핑에 주소와 카운터 Contract 등록
        counters[address(c)] = c;
    }

    // 카운터 Contract 주소 목록 가져 오기
    function getCounterAddressList() constant returns
    (address[] counterAddressList) {
        counterAddressList = addressList;
    }
}

// 카운터 Contract
contract Counter {
    // 카운터 항목 이름
    bytes32 counterName;
    // 카운트 수
    uint32 numberOfCounter;

    // 생성자(신규 작성시에 카운터 항목 이름 설정)
    function Counter(bytes32 name) {
        counterName = name;
    }

    // 카운트 업
    function countUp() {
        numberOfCounter++;
    }

    // 카운터 항목 이름 검색
    function getCounterName() constant returns (bytes32 name) {
        return counterName;
    }

    //카운트 수 가져오기
    function getNumberOfCounter() constant returns (uint32 number) {
        return numberOfCounter;
    }
}

스크린샷 2018-04-16 오후 11.32.00.png
화면에 표시된 Contract 소스 코드

Contract 배포


작성한 Contract를 배포합니다. JSON-RPC 서버 기동 옵션을 추가하고 geth를 기동합니다.

geth --networkid "123" --rpc --rpcaddr "172.16.234.28" --rpcport 8545 --rpccorsdomain "*" --rpcapi "net,eth,web3,personal" --datadir "eth_testdata" --testnet console

스크린샷 2018-04-16 오후 11.35.54.png

기동 후 miner.start() 명령으로 채굴을 시작합니다.

이제, Contract 코드를 기동한 로컬 블록체인에 배포해 보겠습니다.

  1. 화면 우측의 Run 메뉴를 클릭하고 Environment에서 Web3 Provider 옵션을 선택합니다.스크린샷 2018-04-16 오후 11.00.47.png

  2. Web3 Provider Endpoint 입력란에 geth 기동시 지정한 IP를 입력합니다.(port은 8545 default 사용)
    스크린샷 2018-04-16 오후 11.05.27.png
    여기서 아래와 같은 Web3 Provider에 연결할 수 없다는 메세지가 표시될 경우, Remix를 https가 아닌 http로 재접속 후 진행하면 정상적으로 연결이 됩니다.
    스크린샷 2018-04-16 오후 11.49.25.png

  3. CounterMaster 계약의 create 버튼을 누릅니다.
    스크린샷 2018-04-16 오후 11.32.00.png
    Remix 화면 하단의 콘솔창에 CounterMaster Contract가 생성됐다는 트랜잭션이 표시됩니다.
    스크린샷 2018-04-16 오후 11.57.39.png

테스트 데이터 입력


테스트 데이터 입력전에 getCounterAddressList() 함수를 호출해 보면 데이터를 없는 것을 확인할 수 있습니다.
스크린샷 2018-04-17 오전 12.03.20.png

CounterMaster의 addCounter() 함수를 호출해 3개의 테스트 데이터를 입력해 보겠습니다.
스크린샷 2018-04-17 오전 12.02.53.png
스크린샷 2018-04-17 오전 12.05.56.png

스크린샷 2018-04-17 오전 12.06.42.png
스크린샷 2018-04-17 오전 12.05.56.png

스크린샷 2018-04-17 오전 12.06.58.png
스크린샷 2018-04-17 오전 12.06.09.png

위에서 3개의 테스트 데이터를 입력하고 getCounterAddressList()를 호출하면 아래와 같이 데이터가 입력된 것을 확인할 수 있습니다.
스크린샷 2018-04-17 오전 12.07.08.png
스크린샷 2018-04-17 오전 12.06.26.png

Coin Marketplace

STEEM 0.20
TRX 0.14
JST 0.029
BTC 67494.12
ETH 3222.64
USDT 1.00
SBD 2.65