[크립토 좀비] 1일차 시작

재호·2022년 7월 7일
0

크립토 좀비

목록 보기
1/3

블록체인의 스마트 컨트랙트 공부를 위해 크립토좀비를 시작했다.(22.07.07)

챕터 1부터 아주 쉽고 간편하게 가이드하며 알려준다. 프로그래밍 언어나 문법을 전혀 모른다면 살짝은 이해가 안되는 부분들이 있을 수 있겠다라고 생각했다.

레슨 1

크립토 좀비는 좀비라는 소재로 이더리움과 솔리디티에 대해 알려준다. 첫번째 레슨에서는 좀비 군대를 위한 좀비 공장 기능을 만드는 단계이다.

제일 먼저 기본 컨트랙트를 생성하고 기본적인 변수와 구조체를 생성한다.
contract ZombieFactory {

    uint dnaDigits = 16;
    uint dnaModulus = 10 ** dnaDigits;

    struct Zombie {
        string name;
        uint dna;
    }
    
    Zombie[] public zombies;
}
그리고 기본적인 함수 생성과 호출에 대해서도 알려준다.
	function _createZombie(string _name, uint _dna) private {
        zombies.push(Zombie(_name, _dna));
        // 여기서 이벤트 실행
    }

    function _generateRandomDna(string _str) private view returns (uint) {
        uint rand = uint(keccak256(_str));
        return rand % dnaModulus;
    }

    function createRandomZombie(string _name) public {
        uint randDna = _generateRandomDna(_name);
        _createZombie(_name, randDna);
    }

솔리디티에서 함수의 파라미터에는 _를 사용한다고 한다. 이는 전역 변수와 구별하기 위함이고 의무는 아니지만 관례라고 한다. 또한 publicprivate로 설정할 수 있는데 private로 함수를 설정할 시에는 함수명에도 _를 사용해야 한다.

레슨 1의 마지막 챕터는 이벤트 기능이다.
	event NewZombie(uint zombieId, string name, uint dna); //이벤트 선언
    
	function _createZombie(string _name, uint _dna) private {
        uint id = zombies.push(Zombie(_name, _dna)) - 1;
        NewZombie(id, _name, _dna); //이벤트 실행
    }

레슨 2

레슨 2에서는 좀비에게 먹이를 주는 것과 먹이를 먹어서 좀비가 변하는 기능을 구현한다.

먼저 매핑과 주소이다.
	mapping (uint => address) public zombieToOwner;
    mapping (address => uint) ownerZombieCount;

주소는 특정 계정을 가리키는 교유 식별자이며 매핑은 구조화된 데이터를 저장하는 한가지 방법이다. 매핑은 key-value 구조로 이루어져 있다.

Msg.sender는 현재 함수를 호출한 사람(혹은 스마트컨트랙트)의 주소를 가리키는 전역 변수이다.
	function _createZombie(string _name, uint _dna) private {
        uint id = zombies.push(Zombie(_name, _dna)) - 1;
        zombieToOwner[id] = msg.sender;
        ownerZombieCount[msg.sender]++;
        NewZombie(id, _name, _dna);
    }

새로운 좀비의 id에 대해 msg.sender가 저장되도록 하고 msg.sender에 대해 좀비 카운트를 증가 시킨다.

require는 특정 조건이 참이 아닐 때 함수가 에러 메시지를 출력하고 실행을 멈추게 한다.

이를 통해 함수 실행 전 여러 조건을 확인하는 기능에 유용하다.

	function createRandomZombie(string _name) public {
        require(ownerZombieCount[msg.sender] == 0);
        uint randDna = _generateRandomDna(_name);
        _createZombie(_name, randDna);
    }

좀비를 무제한 생성하지 못하도록 제한하기 위해 require로 좀비 카운트를 비교한다.

상속을 통해 컨트랙트를 보다 효율적으로 컨트롤할 수 있다.
import "./zombiefactory.sol";

contract ZombieFeeding is ZombieFactory {

}

같은 파일안에서도 상속할 수 있지만 파일을 나누어 상속받는 것도 코드가 깔끔해지고 관리가 용이해진다. 파일을 나눌 때에는 import로 상속받을 파일을 불러와야 한다.

함수에는 public과 private 말고도 external과 internal이라는 함수 접근자가 있다.

internal은 함수가 정의된 컨트랙트를 상속하는 컨트랙트에서도 접근이 가능하고, external은 함수가 컨트랙트 바깥에서만 호출될 수 있고 컨트랙트 내의 다른 함수에 의해 호출될 수 없도록 한다. 본 프로그램에서는 internal을 적용하여야 한다.

	function _createZombie(string _name, uint _dna) private {
        uint id = zombies.push(Zombie(_name, _dna)) - 1;
        zombieToOwner[id] = msg.sender;
        ownerZombieCount[msg.sender]++;
        NewZombie(id, _name, _dna);
    }
다른 컨트랙트와 상호작용을 하기 위해서는 Interface를 사용해야 한다.

인터페이스로 상호작용 하고자 하는 컨트랙트와 추상메서드를 정의해야 한다.

contract KittyInterface {
  function getKitty(uint256 _id) external view returns (
    bool isGestating,
    bool isReady,
    uint256 cooldownIndex,
    uint256 nextActionAt,
    uint256 siringWithId,
    uint256 birthTime,
    uint256 matronId,
    uint256 sireId,
    uint256 generation,
    uint256 genes
  );
}

솔리디티는 자바나 파이썬과는 다르게 리턴값을 여러개줄 수 있다.

function multipleReturns() internal returns(uint a, uint b, uint c) {
  return (1, 2, 3);
}

function processMultipleReturns() external {
  uint a;
  uint b;
  uint c;
  // 다음과 같이 다수 값을 할당한다:
  (a, b, c) = multipleReturns();
}

// 혹은 단 하나의 값에만 관심이 있을 경우: 
function getLastReturnValue() external {
  uint c;
  // 다른 필드는 빈칸으로 놓기만 하면 된다: 
  (,,c) = multipleReturns();
}

리턴 값이 여러개일 때에는 위와 같이 사용할 수 있다.

profile
Java, Spring, SpringMVC, JPA, MyBatis

0개의 댓글