title | actions | material | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Na čom sa kŕmia Zombies? |
|
|
Nadišiel čas nakŕmiť našich zombie! Ale na čom sa zombie kŕmia najradšej?
Nuž, ukázalo sa že CryptoZombies najviac zbožňujú...
CryptoKitties! 😱😱😱
(Áno, myslím to vážne 😆 )
Ay sme to mohli spraviť budeme potrebovať byť schopný čítať CryptoKitties smart kontrakt. Naimplementovať sa to dá, pretože dáta CryptoKitties su uložené verejne na blockchaine. No nie je blockchain super?
Naša hra v skutočnosti neporaní žiadnu mačičku CryptoKitty. Budeme iba čítať Cryptokitties dáta, nebudeme schopný ich zmazať alebo modifikovať 😉
Na to aby náš kontrakt mohol komunikovať s iným kontraktom na blockchain, budeme musieť najrpv definovať rozhranie (interface).
Poďme sa pozrieť na nasledujúci jednoduchý príklad. Predstavme si, že na blockchaine je nasadený takýto kontrakt:
contract LuckyNumber {
mapping(address => uint) numbers;
function setNum(uint _num) public {
numbers[msg.sender] = _num;
}
function getNum(address _myAddress) public view returns (uint) {
return numbers[_myAddress];
}
}
Toto by bol jednoduchý kontrakt na ukladanie štastné číslo. Ktokoľvek môže nastaviť svoje šťastné čislo pomocou funkcie setNum
. To potom bude asociované s jeho Ethereum adresou. Ďalej môže ktokoľvek vyhľadať štastné číslo priradené k ľubovolnej adrese.
Zvážme situáciou kedy by sme mali externý kontrakt, z ktorého by sme chceli čítať dáta z LuckyNumber
kontraktu pomocou funkcie getNum
.
Najprv by sme museli definovať rozhranie (interface ) v našom kontrakte:
contract NumberInterface {
function getNum(address _myAddress) public view returns (uint);
}
Všimni si že to vyzerá ako definícia smart kontraktu, no s pár rozdielmi. Za prvé, deklarujeme iba funkcie s ktorými chceme pracovať. V tomto prípade by to bola funkcia getNum
. Nemusíme vôbec spomínať ostatné funkcie alebo stavové premenné.
Za druhé, nemusíme definovať telá funkcií. Namiesto závoriek ({
a }
) proste ukončíme deklaráciu funkcie bodkočiarkou (;
).
Takže to vyzerá len ako základná kostra kontraktu. Kompilátor tak porozumie, že sa jedná len o rozhranie.
Tým že zahrnieme toto rozranie do kódu našej dappky, náš kontrakt bude vedieť ako vyzerajú funkcie iného kontraktu, ako ich volať, a akú odpoveď od nich má očakávať naspäť.
Ako skutočne volať funkcie cudzieho kontraktu sa pozrieme v ďalšej lekcii, zatiaľ len deklarujeme rozranie Cryptokitties kontraktu, aby sme s ním mohli začať pracovať.
Pozreli sme sa na zdrojový kód CryptoKitties za teba a našli sme funkciu s názvom getKitty
. Vracia všetky informácie o jednej mačke, včetne jej génov (a to je to, čo náš zombie potrebuje na vytvorenie nového zombie!).
Funkcia vyzerá nasledovne:
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
) {
Kitty storage kit = kitties[_id];
// if this variable is 0 then it's not gestating
isGestating = (kit.siringWithId != 0);
isReady = (kit.cooldownEndBlock <= block.number);
cooldownIndex = uint256(kit.cooldownIndex);
nextActionAt = uint256(kit.cooldownEndBlock);
siringWithId = uint256(kit.siringWithId);
birthTime = uint256(kit.birthTime);
matronId = uint256(kit.matronId);
sireId = uint256(kit.sireId);
generation = uint256(kit.generation);
genes = kit.genes;
}
Táto funkcia vyzerá trochu inak ako to, na čo sme zvyknutý. Všimni si že vracia... nie jednu, ale hneď niekoľko hodnôt. Ak prichádzaš z jazykov ako JavaScript, možno budeš prekvapený. v Solidity je možné vrátit z funkcie niekoľko hodnôt naraz.
Teraz keď už vieme, ako táto funkcia vyzerá, môžme to použiť na deklaráciu rozrania:
-
Deklaruj rozhranie s názvom
KittyInterface
. Bude vyzerať rovnako ako keď vytváraš nový kontrakt - použi kľučové slovocontract
. -
Vo vnútri rozrania deklaruj funkciu
getKitty
(bude kópiou funkcie ukázanej vyššie, no s rozdielom že zareturns
bude nasledovať bodkočiarka, namiesto{
}
závoriek).