이더리움에서 게임을 만든다? 크립토 좀비(3. 고급 솔리디티 개념)

민식킴·2021년 3월 2일
0

크립토 좀비

목록 보기
4/9
사족

7일차.
2월 28일(일), EOM과의 회의를 통해 방향을 바로잡았다. 그저 주어진대로 크립토좀비를 하고있었다. 이대로도 괜찮지만 뭔가 2%부족하달까? 어쨌든 나는 아직 배경지식이 부족했고 솔리디티를 배우고 있음에도 이를 잘 활용할 생각 없이 그저 하고있있다. 그래서 블록체인 관련 강의를 같이 병행하면서 해보기로 했다. 인프런 한양대X그라운드 강의
실제로 7일차, 강의와 언어학습의 병행은 내가 무엇을 하고있는지 알수 있게 해주었다.

CH.1: 컨트랙트의 불변성

컨트랙트를 배포하고 나면, 컨트랙트는 변하지 않는다(Immutable). 만약 컨트랙트 코드에 결점이 있다면, 그것을 이후에 고칠 수 있는 방법이 전혀 없고 사용자들에게 결점을 보완한 다른 스마트 컨트랙트 주소를 쓰라고 해야한다. 이 불변성은 그만큼 블록체인의 보안이 완벽하다는 것을 반증한다.
나는 이전에 크립토키티의 주소를 그대로 붙혀썼었다. 그런데 크립토 키티의 컨트렉트에 버그가 있다면? 다른 주소를 써야 한다면? 이를 위해 수정할 수 있는 함수를 추가해야 한다.(수정 못한다면서요??) 그래, 컨트랙트는 수정할 순 없으나 주소가 바뀌는 것은 입력값이다. 주소는 얼마든지 수정할수 있단것이다.
지금 상황에선 키티주소를 빼고 external로 _address주소를 받아 실행시키게 하였다.

CH.2 소유 가능한 컨트랙트

하지만 external로 받은 함수는 외부에서도 마음대로 관여할 수 있다.(그러니까 공격자가 주소를 임의로 바꾸고 업데이트할 수도 있단 소리다.)
이를 방지하기 위해 소유권을 확인 해주는 컨트랙트가 OpenZeppelin 솔리디티 라이브러리에서 가져온 Ownable이다.

import "./ownable.sol"; // 라이브러리 추가하듯 import하는것 잊지말자
contract ZombieFactory is Ownable { // 이렇게 상속한다면 나 이외에는 관여할 수 없다!
 //ZombieFeeding is ZombieFactory
 //ZombieFactory is Ownable
}

그리고 아래는 원나블의 컨트랙트를 그대로 따왔다.

/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable {
  address public owner;
  event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

  /**
   * @dev The Ownable constructor sets the original `owner` of the contract to the sender
   * account.
   */
  function Ownable() public {
    owner = msg.sender;
  }

  /**
   * @dev Throws if called by any account other than the owner.
   */
  modifier onlyOwner() {
    require(msg.sender == owner);
    _;  // 여기를 유심히 보자
  }

  /**
   * @dev Allows the current owner to transfer control of the contract to a newOwner.
   * @param newOwner The address to transfer ownership to.
   */
  function transferOwnership(address newOwner) public onlyOwner {
    require(newOwner != address(0));
    OwnershipTransferred(owner, newOwner);
    owner = newOwner;
  }
}

자세한건 아래에...

CH.3 onlyOwner 함수 제어자

 function likeABoss() external onlyOwner {
    LaughManiacally("Muahahahaha");
  }

만일 이런 코드가 있다면 onlyOwner의 코드가 먼저 실행된다. 그리고 onlyOwner의 _; 부분을 likeABoss 함수로 되돌아가 해당 코드를 실행하게 된다!

CH.4 가스(Gas)

가스는 블록체인을 사용하는데 필요한 수수료라고 생각하면 된다. 따라서 코딩을 최적화 하는것이 가스비 절약(?)에 유리하다. 특히 구조체.
가스는 왜 필요한가, 나는 그저 수수료정도로만 생각했지만 꽤 합리적인 이유가 또 있었다.
만약 누군가가 무한 반복문을 써서 네트워크를 방해하거나, 자원 소모가 큰 연산을 써서 네트워크 자원을 모두 사용하지 못하도록 한다면?
그렇다 가스가 있다면 이런 사람은 가스폭탄은 맞게 될것이다. 말그대로 가스비 폭탄.

CH.5 시간 단위 & CH.6 좀비 재사용 대기 시간

이제 좀비에 레벨과 쿨타임을 설정할 것이다. 그럴려면 시간을 알아야 겠지.

솔리디티는 시간을 다룰 수 있는 단위계를 기본적으로 제공하네.
now 변수를 쓰면 현재의 유닉스 타임스탬프(1970년 1월 1일부터 지금까지의 초 단위 합) 값을 얻을 수 있네. 내가 이 글을 쓸 때 유닉스 타임의 값은 1515527488이군.

참고: 유닉스 타임은 전통적으로 32비트 숫자로 저장되네. 이는 유닉스 타임스탬프 값이 32비트로 표시가 되지 않을 만큼 커졌을 때 많은 구형 시스템에 문제가 발생할 "Year 2038" 문제를 일으킬 것이네. 그러니 만약 우리 DApp이 지금부터 20년 이상 운영되길 원한다면, 우리는 64비트 숫자를 써야 할 것이네. 하지만 우리 유저들은 그동안 더 많은 가스를 소모해야 하겠지. 설계를 보고 결정을 해야 하네!

솔리디티는 또한 seconds, minutes, hours, days, weeks, years 같은 시간 단위 또한 포함하고 있다. 하지만 윤달과 같이 시간이 오래 지나면 실제 시간과 맞지않을 수 있으므로 업데이트를 해주어야 한다.

ps

오 레벨과 쿨타임이라니, 게임적인 요소가 들어가니 반갑다.
가스비 또한 새로웠다.

profile
우리의 꿈, 우리의 희망

0개의 댓글