暗号の作成(パート2)

この記事は、独自の暗号の作成に関するシリーズの2番目の(そして最後の)パートです。 最初の部分では、各Cryptocotikとは何か、ゲームを制御するのは誰か、トークンの形で猫を作る方法を学びました。 しかし、真に画期的なアプリケーションの場合、参加者が互いに最も純血な子猫を購入できるように、繁殖メカニズム、そして最も重要なのは市場取引を決定する必要があります。 画像

4. KittyBreeding:シールが完全に剥がれます



この契約には、遺伝的組み合わせの外部契約に依存する「交配」の提案を追跡するなど、猫を横断するために必要な方法が含まれています。









「外部遺伝的組み合わせ契約」( geneScience



)は、コードが開いていない別の契約に保存されます。







KittyBreeding



契約には、CEOがこの外部契約の住所を指定できる方法が含まれています。







 /// @dev Update the address of the genetic contract, can only be called by the CEO. /// @param _address An address of a GeneScience contract instance to be used from this point forward. function setGeneScienceAddress(address _address) external onlyCEO { GeneScienceInterface candidateContract = GeneScienceInterface(_address); // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 require(candidateContract.isGeneScience()); // Set the new contract address geneScience = candidateContract; }
      
      





開発者は、ゲームがあまりにも単純ではないようにこの動きに決めました-猫のDNAを決定するものを読むことができれば、サラブレッド猫の「空想」を得るためにどの猫を渡すべきかを見つけるのがはるかに簡単です。







この外部のgeneScience



コントラクトgeneScience



giveBirth()



関数で使用されgiveBirth()



すぐに彼女を知ることになります)、新しい猫のDNAを決定します。







次に、2匹の猫を横切るとどうなるかを見てみましょう。







 /// @dev Internal utility function to initiate breeding, assumes that all breeding /// requirements have been checked. function _breedWith(uint256 _matronId, uint256 _sireId) internal { // Grab a reference to the Kitties from storage. Kitty storage sire = kitties[_sireId]; Kitty storage matron = kitties[_matronId]; // Mark the matron as pregnant, keeping track of who the sire is. matron.siringWithId = uint32(_sireId); // Trigger the cooldown for both parents. _triggerCooldown(sire); _triggerCooldown(matron); // Clear siring permission for both parents. This may not be strictly necessary // but it's likely to avoid confusion! delete sireAllowedToAddress[_matronId]; delete sireAllowedToAddress[_sireId]; // Every time a kitty gets pregnant, counter is incremented. pregnantKitties++; // Emit the pregnancy event. Pregnant(kittyIndexToOwner[_matronId], _matronId, _sireId, matron.cooldownEndBlock); }
      
      





この関数は、 母親父親のアカウントをsiringWithId



し、メインの猫配列でそれらを探し、母親を参照して父親のsiringWithId



インジケーターを設定しsiringWithId



。 ( siringWithId



がゼロに等しくない場合、母親は妊娠しています)。







また、このコントラクトは、 triggerCooldown



関数を両方の親に適用します。これにより、設定された長さの間、再び交差できなくなります。







次に、 giveBirth()



関数を開いて、新しい猫を作成します。







 /// @notice Have a pregnant Kitty give birth! /// @param _matronId A Kitty ready to give birth. /// @return The Kitty ID of the new kitten. /// @dev Looks at a given Kitty and, if pregnant and if the gestation period has passed, /// combines the genes of the two parents to create a new kitten. The new Kitty is assigned /// to the current owner of the matron. Upon successful completion, both the matron and the /// new kitten will be ready to breed again. Note that anyone can call this function (if they /// are willing to pay the gas!), but the new kitten always goes to the mother's owner. function giveBirth(uint256 _matronId) external whenNotPaused returns(uint256) { // Grab a reference to the matron in storage. Kitty storage matron = kitties[_matronId]; // Check that the matron is a valid cat. require(matron.birthTime != 0); // Check that the matron is pregnant, and that its time has come! require(_isReadyToGiveBirth(matron)); // Grab a reference to the sire in storage. uint256 sireId = matron.siringWithId; Kitty storage sire = kitties[sireId]; // Determine the higher generation number of the two parents uint16 parentGen = matron.generation; if (sire.generation > matron.generation) { parentGen = sire.generation; } // Call the sooper-sekret gene mixing operation. uint256 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1); // Make the new kitten! address owner = kittyIndexToOwner[_matronId]; uint256 kittenId = _createKitty(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner); // Clear the reference to sire from the matron (REQUIRED! Having siringWithId // set is what marks a matron as being pregnant.) delete matron.siringWithId; // Every time a kitty gives birth counter is decremented. pregnantKitties--; // Send the balance fee to the person who made birth happen. msg.sender.send(autoBirthFee); // return the new kitten's ID return kittenId; }
      
      





コード展開中のコメントは、それ自体で理解できます。 そのため、最初にコードは母親が猫を産む準備ができているかどうかをチェックします。 次に、 geneScience.mixGenes()



関数を使用して子猫の遺伝子を判別し、母親の所有者を新しい猫の所有者にも設定し、すでにKittyBase



コントラクトで見た_createKitty()



関数を要求します。







geneScience.mixGenes()



関数は、コードが閉じられているため、 geneScience.mixGenes()



いることに注意してください。 したがって、子供の遺伝子がどのように決定されるかはわかりませんが、それらは母親の遺伝子、父親の遺伝子、および母親のタイムスタンプcooldownEndBlock



の機能によって影響を受けることがわかります。







5. KittyAuctions:私たちはシールを購入、販売、設置します



ここでは、猫の販売と交配のために猫をオークションに出品するためのオープンな方法があります。 オークション自体の機能は2つの別個の契約(1つは販売、もう1つはバインディング)で実行され、オークションと入札の作成はメイン契約のこのセクションで行われます。









開発者は、オークションの機能を独立した契約に分割しました。なぜなら、彼らによると、「 オークションロジックは非常に複雑で、常に小さなバグのリスクがあります。 それらが独自の契約に保存されている場合、オットセイの所有権を監視するメイン契約の運用を妨げることなく更新できます 。」







そのため、 KittyAuctions



コントラクトには関数setSaleAuctionAddress()



およびsetSiringAuctionAddress()



が含まれており、 setSaleAuctionAddress()



と同様にCEOユーザーのみが呼び出すことができます。 彼らの助けを借りて、これらの機能を実行する外部契約のアドレスを指定できます。







:「編み物」とは、猫のサービスのオークションを意味します。 あなたは一種のポン引きです。なぜなら、他のユーザーがあなたの猫をあなたの猫と交わす機会に対してあなたにエーテルを支払うからです。









これは、CryptoKitties契約自体が変更されていない場合でも、CEOがこのオークション契約のアドレスを後で変更する機会があり、これによりルールが自動的に変更されることを意味します。 繰り返しますが、開発者は定期的にバグを修正する必要があるため、これは必ずしも悪いことではありません。 この事実を考慮してください。







オークションと入札のロジックについての議論を掘り下げることはありません。さもなければ、この記事は長すぎる(そして既に非常に長い!)リスクがあります。EthFiddleWebサイトでコードを見ることができますKittyAuctions



キーワードを使用)。







6. KittyMinting:ジェネレーション0オットセイ工場



契約の最後の部分には、第0世代のシールを作成するために使用する機能が含まれています。配布できる最大5000の「プロモーションシール」を作成できます(これは新しいコミュニティにとって特に重要です)。開始価格は特別なアルゴリズムによって決定されます。 作成方法に関係なく、ジェネレーション0の5万アザラシの厳密な制限があります。その後、繁殖、繁殖、繁殖する必要があります。









このコントラクトでは、世代0のプロモキャットとキャットの数を厳密に記述します。







 uint256 public constant PROMO_CREATION_LIMIT = 5000; uint256 public constant GEN0_CREATION_LIMIT = 45000;
      
      





そして、「COO」ユーザーが世代0のプロモーション猫と猫を作成できるコードを次に示します。







 /// @dev we can create promo kittens, up to a limit. Only callable by COO /// @param _genes the encoded genes of the kitten to be created, any value is accepted /// @param _owner the future owner of the created kittens. Default to contract COO function createPromoKitty(uint256 _genes, address _owner) external onlyCOO { address kittyOwner = _owner; if (kittyOwner == address(0)) { kittyOwner = cooAddress; } require(promoCreatedCount < PROMO_CREATION_LIMIT); promoCreatedCount++; _createKitty(0, 0, 0, _genes, kittyOwner); } /// @dev Creates a new gen0 kitty with the given genes and /// creates an auction for it. function createGen0Auction(uint256 _genes) external onlyCOO { require(gen0CreatedCount < GEN0_CREATION_LIMIT); uint256 kittyId = _createKitty(0, 0, 0, _genes, address(this)); _approve(kittyId, saleAuction); saleAuction.createAuction( kittyId, _computeNextGen0Price(), 0, GEN0_AUCTION_DURATION, address(this) ); gen0CreatedCount++; }
      
      





createPromoKitty()



関数から、COOだけが好きな遺伝子を持つ新しい猫を作成し、猫を誰にでも転送できることは明らかです(合計で、5000匹の猫を作成できます)。 このような関数は、最初のテスター、友人、親relativeに使用されると思います。 ゲームを促進するために、無料のシールも配布されます。







しかし、COOは5000ものクローンをスタンプできるため、あなたの猫があなたが思うほどユニークではないかもしれないことも意味します!







createGen0Auction()



関数で、COOユーザーは新しい子猫の遺伝コードも指定します。 しかし、特定のユーザーのアドレスに送信する代わりに、ユーザーがイーサリアムに入札して子猫を購入するオークションを作成します。







7. KittyCore:メイン契約



これは、ゲームCryptoKittiesの主要な契約であり、Ethereumブロックチェーン上でコンパイルされ、リリースされます。 他の全員を結びつけるのはこの契約です。







契約の構造は一貫しているため、後者は以前に出会ったすべての契約のデータを収集し、いくつかの最終的な方法を追加します。たとえば、彼のアカウントを使用してすべての猫のデータを取得するこの関数:







 /// @notice Returns all the relevant information about a specific kitty. /// @param _id The ID of the kitty of interest. 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; }
      
      





これは、ブロックチェーンの特定の猫のすべてのデータを表示するパブリックメソッドです。 サイトにシールを表示するには、ゲームサーバーがこのコマンドを要求すると思います。







待ってください...画像データが表示されません。 猫の外観を決定するものは何ですか?



上記のコードからわかるように、猫は遺伝コードである256ビットの符号なし整数になります。







Solidity契約コードには猫の外観に関するデータはなく、256ビット整数の値を定義する説明やデータはありません。 猫の遺伝コードの解釈は、CryptoKitty Webサーバーで実行されます。







そして、これはブロックチェーン上のゲームのかなり有能なデモンストレーションですが、ブロックチェーンに完全に配置されるわけではありません。 ゲームのサイトが壊れて、誰もすべての画像をバックアップしない場合、意味のない256ビットの整数しかありません。







契約コードで、 ERC721Metadata



という契約を見つけましたが、どこでも使用されていません。 だから私は当初、開発者はすべてをブロックチェーンに保存することを計画していたが、後で気が変わった(Ethereumプラットフォームにあまりにも多くのデータを保存することはあまりにも高価ですか?)ので、ウェブサーバーに画像を保存することにしました。







まとめると



学んだこと:









サーシャ・イワノワの翻訳を手伝ってくれてありがとう!



独自のゲームを作成するためのより詳細なガイドが必要な場合は、

CryptoZombiesリソースにアクセスすることをお勧めします








All Articles