이 부분은 두번쨰 과정이다.
일단 전에 글과 비교하여 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;
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);
}
}
일단 mapping값이 추가가 되었다.
이를 통해서 생성된 좀비의 주인이지를 확인이 가능하다.
key-value
로 구성된 객체라고 생각하면 된다.일단 흐름에 따라서 먼저 작동을 하게되는 createRandomZombie
를 살펴보자
createRandomZombie
require구문이 참일떄 아래 코드가 작동을 하고 거짓이면 아래 코드가 작동하지 않는다.
이후 마찬가지로 좀비 생성을 하는 함수를 호출한다.
_createZombie
이러한 작업을 하는 이유는 사용자 한명당 하나의 좀비만 생성하기 위함이다.
우리가 만든 좀비는 다른 것을 양분으로 삼는다.
그 부분에 대해서 다루는 것이다.
pragma solidity ^0.4.19;
import "./zombiefactory.sol";
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
);
}
contract ZombieFeeding is ZombieFactory {
address ckAddress = 0x06012c8cf97BEaD5deAe237070F9587f8E7A266d;
KittyInterface kittyContract = KittyInterface(ckAddress);
function feedAndMultiply(uint _zombieId, uint _targetDna, string _species) public {
require(msg.sender == zombieToOwner[_zombieId]);
Zombie storage myZombie = zombies[_zombieId];
_targetDna = _targetDna % dnaModulus;
uint newDna = (myZombie.dna + _targetDna) / 2;
if (keccak256(_species) == keccak256("kitty")) {
newDna = newDna - newDna % 100 + 99;
}
_createZombie("NoName", newDna);
}
function feedOnKitty(uint _zombieId, uint _kittyId) public {
uint kittyDna;
(,,,,,,,,,kittyDna) = kittyContract.getKitty(_kittyId);
feedAndMultiply(_zombieId, kittyDna, "kitty");
}
}
일단 기본적으로 같은 폴더내에 있다는 가정하에 import
구문을 활용한 것이다.
KittyInterface
단순히 인터페이스 이며 값이 들어오면 해당값에 맞게 데이터가 반환이 된다.
그후 기본 셋팅된 주소를 크립토키티 인터페이스로 변환해주고 해당 반환값을 가져온다.
kittyContract
가 가지고 있게 될 것이다.
feedOnKitty
genes데이터는 getkitty
의 반환값중 맨 마지막에 있다.
그 값을 포함하여 feedAndMultiply
에 들어온 인자랑 같이 보내준다.
feedAndMultiply
zombieToOwner을 사용 가능한 이유는 앞서 import했기 때문이다.
그후 myZombie라는 Zombie의 구조체 형식을 따르는 변수를 만들어 주고 zombies라는 배열에서 Id값에 맞는 데이터를 찾아온다.
그후 들어온 키티 데이터와 내가 가지고 있는 좀비 데이터를 합쳐준다.
if문은 없어도 된다.
if문을 사용하여 처리해 주는 이유는 솔팅과 같이 특별한 값을 추가해 주기 위함이다.
그후 새로운 좀비를 만들어 준다.
기존의 좀비를 갱신하는 것이 아니다. 데이터를 합친 완전한 새로운 좀비를 만드는 것이다.