IoT SmartContract in Solidity

이 포스팅은 스마트컨트랙트 코드에 이용되는 솔리디티 사용법을 익히기 위해 도움이 되는 자료다. 스마트 컨트랙트 예제를 통해 스마트컨트랙트의 흐름과 솔리디티 문법을 공부하고자 포스팅을 작성했다.

이번에 다루는 포스팅 주제는 IoT기계를 스마트 컨트랙트로 제어하는 예제이다. 이 기본예제를 활용하여 향후, 도어락을 비롯한 셰어링 서비스에 사용 할 수 있다.

Diagram

  1. 오너가 SmartController를 생성
  2. IoT 사용자는 payToController 함수로 이더를 송금
  3. IoT Device가 송금을 확인 후, 서비스 시작
  4. 이용시간이 종료되면 상태를 변경하고 서비스 이용을 종료
  5. 오너는 송금된 이더를 인출
pragma solidity ^0.4.11; //컴파일러 버전 지정

contract SmartController {
    // Controller가 사용할 구조체
    struct Controller {
    address add; // client의 주소
    uint endTime; // 이용 종료 시간
    bool status; // true일 때만 사용가능
    }

    address public owner; // 오너의 주소 (EOA)
    address public iot; // IoT Device의 주소 (EOA)

    mapping (uint => Controller) public controllers; // Controller 구조체를 담을 매핑
    uint public numPaid; //결제 횟수 카운터 변수

    /// 오너의 권한 체크
    modifier onlyOwner() {
      require(msg.sender == owner);
      _;
    }
    /// IoT 장치 권한 체크
    modifier onlyIoT() {
      require(msg.sender == iot);
      _;
    }
    ///생성자, IoT장치의 주소를 매개변수로 받음
    function SmartController(address _iot) public {  // 접근지정자 꼭!
      // owner의 값에 이 계약을 생성한 계정 주소 대입
      owner = msg.sender;
      iot = _iot;
      numPaid = 0;
    }
    //이더 지불 시, 호출되는 함수
    function payToController() public payable {
      require(msg.value == 1000000000000000000); //1ETH가 아니면 종료
      //Controller 생성
      Controller storage c = controllers[numPaid++]; //storage로  생성
      c.add = msg.sender;
      c.endTime = now + 60; // 이용시간 1분, now - 해당 컨트랙트가 실행된 블록의 타임스템프
      c.status = true;
    }
    /// 상태(staus)를 변경하는 함수, 이용 종료 시각에 호출
    // controllers의 키 값이 매개변수가 됨
    function updateStatus(uint _index) public onlyIoT {
      //인덱스 값에 해당하는 Controller 구조체가 없으면 종료
      require(controllers[_index].add != 0);

      //이용 종료 시간이 되지 않았으면 종료
      require(now > controllers[_index].endTime);

      controllers[_index].status = false; //상태변경
    }
    // 지불된 이더를 인출하는 함수
    function withdrawFunds() public onlyOwner {
        require (owner.send(address(this).balance));
    }
    // 계약을 소멸시키는 함수
    function kill() public onlyOwner {
      selfdestruct(owner);
    }
}

코드 리뷰 및 TIP (솔리디티 문법)

11 ~ 12 line, 이더리움에는 2가지의 주소타입이 있다. 컨트랙트를 설계할 때 어떤 타입의 주소일지 고민해보며 코드를 작성하자!

14 ~ 15 line, 맵핑을 통해 컨트랙트에 저장할 “상태변수”를 선언한다.

28 ~ 33 line, 생성자는 스마트 계약을 새로 만들 때 실행된다. 생성자 이름은 반드시 계약 이름과 같아야 한다. 또한 최근 솔리디티에서는 접근지정자를 정해줘야 컴파일이 되므로 꼭 작성하자! 생성자의 인자는 새롭게 생성되는 IoT장치의 CA가 매개변수로 들어가는데 위 다이어그램을 보면서 컨트랙트의 구조에 대하여 고민해보면 왜 그런지 알 수 있을 것이다!

35 ~ 42 line, payable 함수 : 이더를 주고 받기 위한 솔리디티에서의 기능이다. ‘payable’키워드를 넣어줘야 송금이 가능하다. **어떠한 인자도 필요하지 않다! Controller 구조체에 담길 정보를 storage 키워드를 선언하여 작성한다. **상태 변수의 정보는 memory영역이 아닌 storage영역에 저장된다!

솔리디티 문법 내, 변수의 Data Location의 위치가 궁금하다면 아래 링크 참조
https://solidity-kr.readthedocs.io/ko/latest/types.html?highlight=data%20location

45 ~ 53 line, 교재에서는 if문을 사용하여 예외를 발생시키는 키워드로 예외가 발생하면 진행하던 처리를 롤백했다. 그러나, 솔리디티가 버전업 된후, 현재 미스트에서는 if문을 사용하면 컴파일이 되지 않는다. 그렇기 때문에 require를 사용하여 조건식을 작성한다. **예외가 발생해도 가스는 소비한다.

55 ~ 57 line, 상위버전 “address(this).balance” instead of “this.balance”

59 ~ 61 line, 계약을 소멸시키기 위해 인자로 주소를 지정한다. 계약이 끝나면, 컨트랙트가 갖고 있던 이더가 인자로 지정된 주소로 송금한다. 이후, 코드는 해당 상태에서 지워진다. (이 것에 관한 도큐먼트는 아래 링크내 하단참고)
https://solidity-kr.readthedocs.io/ko/latest/units-and-global-variables.html?highlight=selfdestruct

Function Modifier

반복적으로 사용되는 조건을 정의하기 위해서 사용된다. modifier를 구현하여 함수에 적용하면 ‘modifier의 이름’으로 지정 modifier에게만 권한이 주어진다. require에는 처리를 이어가기 위한 필요한 조건식을 작성한다. 조건이 맞지 않으면 throw가 일어난다.

contract Purchase {
    address public seller;

    modifier onlySeller() { // Modifier
        require(msg.sender == seller);
        _; //마지막에 반드시 붙여야 한다.
    }

    function abort() public onlySeller { // Modifier usage
        // ...
    }
}

https://solidity-kr.readthedocs.io/ko/latest/structure-of-a-contract.html?highlight=modifier#structure-function-modifiers
자세한 사용방법이 궁금하다면, 위 도큐먼트에서 확인 할 수 있다.

솔리디티 예약어

msg.sender : 함수를 호출한 계정의 주소에 접근한다.

mag.value : 이더를 송금하는 형태로 함수를 호출한 경우, 송금액(wei단위)에 접근한다.

this : 현재 계약의 주소에 접근한다.

balance : address의 잔액에 접근한다.

다음 포스팅에서는 위에서 작성한 SmartController.sol을 직접 배포하여 동작 하는 것을 확인해 보겠다.


참고 문헌으로 아래의 도서를 활용했다. 위 코드는 본 책을 읽고 일부 소스코드를 수정하여 재작성한 코드이다. (솔리디티 문법이 워낙 빠르게 변하다 보니 책을 집필할 시기의 문법으로 미스트에 배포를 시도하면 실패한다. 이 포스팅에서 작성한 코드로 실습해보기 바란다.) 그동안 블록체인을 어떻게 공부해야 할지 몰라서 시행착오를 겪으며, 블록체인을 4개월 가량 공부했는데 아래 책 한권이면 1달 안에 가능 할 것 같다. 입문자에게는 좋은 책이다.

구글북스 미리보기 링크 : https://www.google.co.kr/search?hl=ko&tbo=p&tbm=bks&q=isbn:9791162249581

Coin Marketplace

STEEM 0.19
TRX 0.15
JST 0.030
BTC 65663.89
ETH 2670.06
USDT 1.00
SBD 2.91