Crypto Zombie - 2

Hong·2022년 12월 18일
0



zombiefeeding이 zombiefactory에 상속되어있는 구조다

🏭 zombiefactory.sol
  - 🍞 zombiefeeding.sol



🏭 zombiefactory.sol

pragma solidity ^0.4.19;

contract ZombieFactory {

    event NewZombie(uint zombieId, string name, uint dna);

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

    struct Zombie {
        string name;
        uint dna;
    }

    Zombie[] public zombies;

    mapping (uint => address) public zombieToOwner;
    mapping (address => uint) ownerZombieCount;

  	//Lesson 1과 달라진 점은 함수의 접근방식이 private에서 internal로 바뀌었다는 점이다
  	//아래 feeding파일을 보면 알겠지만 zombiefeeding.sol의 contract를 zombiefactory.sol에 종속시켜주기 위함이다
  	//이렇게 contract를 종속시켜 주면 상위 contract에서 작성한 함수 등을 사용할 수 있게된다
    function _createZombie(string _name, uint _dna) internal {
        uint id = zombies.push(Zombie(_name, _dna)) - 1;
        zombieToOwner[id] = msg.sender;
        ownerZombieCount[msg.sender]++;
        NewZombie(id, _name, _dna);
    }

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

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

}


Lesson 2에서는 크립토 좀비에게 먹이를 주기위해 zombiefeeding.sol를 중점적으로 작성했다.

🍞 zombiefeeding.sol

pragma solidity ^0.4.19;

//ZombieFactory contract안에 있는 _createZombie함수를 사용하기 위해 zombiefactory.sol로부터 상속을 받아왔다
import "./zombiefactory.sol"; 

//크립토 키티의 소스코드를 통해 KittyInterface라는 이름의 contract 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
  );
}

//is를 통해 ZombieFeeding이 ZombieFactory의 요소를 사용할 수 있음을 알려준다
contract ZombieFeeding is ZombieFactory {
	
  //ckAddress에 특별한 하나의 크립토 키티의 contract주소를 들고왔다.
  address ckAddress = 0x06012c8cf97BEaD5deAe237070F9587f8E7A266d;
  KittyInterface kittyContract = KittyInterface(ckAddress);
	
  //크립토 좀비에게 먹이를 주는 함수를 만들 것이다
  //_zombieId를 통해 어떤 좀비에게 먹이를 줄지 선택하고
  //_targetDna를 통해 어떤 놈을 먹이로 바칠 것인지 선택하고
  //_species를 통해 인간을 먹이로 줄지, 크립토 키티를 먹이로 줄지 선택한다
  function feedAndMultiply(uint _zombieId, uint _targetDna, string _species) public {
    //require 조건이 true가 되어야지 아래 코드가 실행된다
    //현재 호출을 수행하고 있는 msg.sender가 입력한 _zombieId의 owner인지 확인한다
    require(msg.sender == zombieToOwner[_zombieId]);
    
    Zombie storage myZombie = zombies[_zombieId];
    _targetDna = _targetDna % dnaModulus;
    uint newDna = (myZombie.dna + _targetDna) / 2; //먹이로 넣은 녀석의 dna와 내 좀비의 dna를 섞어 새로운 newDna를 만들어낸다.
    
    //if문을 통해 입력받은 먹이의 _species가 "kitty"라면(크립토 키티라면) 특별한 좀비를 만들어주기 위해 좀비의 dna끝자리를 99로 만들어준다.
    if(keccak256(_species) == keccak256("kitty")) {
      newDna = newDna - newDna % 100 + 99;
    }
    _createZombie("NoName", newDna);
  }

  //_zombieId를 통해 어느 좀비에게 먹이를 줄지 선택할 수 있다.
  //_kittyId를 통해 어느 크립토 키티를 좀비에게 먹이로 줄지 선택할 수 있다.
  function feedOnKitty(uint _zombieId, uint _kittyId) public {
    uint kittyDna;
    (,,,,,,,,,kittyDna) = kittyContract.getKitty(_kittyId);
    feedAndMultiply(_zombieId, kittyDna, "kitty");
  }

}

Solidity InterFace

Solidity Interface자식 컨트랙트를 위한 틀이다.
역할은 다른 contract와 상호작용하기 위해서 사용된다.

역시 사용하기 위한 몇 가지 규칙들이 있다.
Interface를 정의할 때는 '추상함수'로만 정의한다.

추상함수는 함수의 이름, 매개변수 인자, 출력값만 정의해두고 구체적인 함수 작동 방식은 상속받는 쪽에서 구현이 가능하게 한다.

아래는 위의 zombiefeeding.sol에도 적혀있다.
크립토 키티의 소스코드interface로 정의해서 추후에 여러 곳에서 상속받게 만든 과정이다.
크립토 키티의 "genes"(유전자, 크립토 좀비와 함치기 위해 필요함)정보를 포함해서 많은 정보들을 담고 있다.
특히한 점은, 이 함수는 많은 갯수의 값들을 return한다는 것이다 (정확히는 10개).
어떻게 이 10개의 return값들 중 원하는 값을 가져왔는지 살펴보자. (아래를 참고한다)

contract KittyInterface { //contract를 interface로 바꿔도 상관없음
  //상속받는 입장에서 사용 가능해야하기 때문에 함수접근 타입은 external또는 public으로 선언해야함.
  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
  );
}



...(skip)..



  function feedOnKitty(uint _zombieId, uint _kittyId) public {
    uint kittyDna; //우선 kittyDna변수를 선언하고
    
    //쉼표 9개(,,,,,,,,,)를 통해 내가 입력한 _kittyId 정보의 마지막 return값을 들고올 수 있다. (다르게 return값을 들고오는 방법도 존재함)
    (,,,,,,,,,kittyDna) = kittyContract.getKitty(_kittyId);
    feedAndMultiply(_zombieId, kittyDna, "kitty");
  }
profile
Notorious

0개의 댓글