3


🔥 zombiefactory.sol

pragma solidity ^0.4.19;

import "./ownable.sol";

contract ZombieFactory is Ownable {

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

    uint dnaDigits = 16;
    uint dnaModulus = 10 ** dnaDigits;
    uint cooldownTime = 1 days;

    struct Zombie {
      string name;
      uint dna;
      uint32 level;
      uint32 readyTime;
    }

    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, uint32(now + cooldownTime))) - 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);
    }

}

🔨 その他の内容


まず付加機能の変数を発表した.
  • level , readyTime
  • cooldownTimeという地域変数を発表し、日付を付与した.
    これらの追加変数はゾンビが攻撃できる時間を意味する.
  • 後に話します.
  • 🔨 新知


    基本的に、uint 256またはuint 32またはメモリは同じです.
  • 、ソリッドステートメモリ容量256のため
  • ただし、structに書き込まれる値は異なります.
  • structにuint 32を書き込むと、256のメモリサイズではなく32のメモリサイズがあります.
  • は自動圧縮であるため、
  • ソリディティにも時間があります.
    現在のような場合、1970年1月1日から現在に戻る秒数.
    solidity time言語には、秒、分、時間、日、週、年が含まれます.
    明かりがあって、すべて秒計算です.
  • 1 min=60秒、1時間=60*60秒
  • また、nowはデフォルトでuint 256を返すため、構造体に応じてuint 32に設定されます.
    now+cooldownTimeを適用することで、1日で攻撃を実現できます.

    🔥 ownable.sol

    contract Ownable {
      address public owner;
    
      event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    
    
      function Ownable() public {
        owner = msg.sender;
      }
    
    
      modifier onlyOwner() {
        require(msg.sender == owner);
        _;
      }
      
      function transferOwnership(address newOwner) public onlyOwner {
        require(newOwner != address(0));
        OwnershipTransferred(owner, newOwner);
        owner = newOwner;
      }
    
    }
    これは授権のための競争です.
  • 難解なコードがないように見えるので、スキップしましょう.
  • 🔥 zombiefeeding.sol

    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 {
    
      KittyInterface kittyContract;
    
      function setKittyContractAddress(address _address) external onlyOwner {
        kittyContract = KittyInterface(_address);
      }
    
      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");
      }
    
    }

    🔨 その他の内容


    まずゾンビに餌をやるというデータを別途もらって使います.
  • は、定数値として指定されている場合、そのアドレスのすべてのコンテンツに依存する必要があるためです.
  • この場合の欠点は、データのアドレス値が変更されたり、エラーが発生したりした場合に使用できないことです.
    したがって、まずsetKittyContractAddress関数により値を取得する.
    したがって、他の悪意のあるユーザが奇妙なデータを提供する可能性があるため、onlyOwnerが使用される.
  • この関数は外部の値を受け入れなければならないので、externalが追加されました.
  • 🔥 zombiehelper.sol

    pragma solidity ^0.4.19;
    
    import "./zombiefeeding.sol";
    
    contract ZombieHelper is ZombieFeeding {
    
      modifier aboveLevel(uint _level, uint _zombieId) {
        require(zombies[_zombieId].level >= _level);
        _;
      }
    
      function changeName(uint _zombieId, string _newName) external aboveLevel(2, _zombieId) {
        require(msg.sender == zombieToOwner[_zombieId]);
        zombies[_zombieId].name = _newName;
      }
    
      function changeDna(uint _zombieId, uint _newDna) external aboveLevel(20, _zombieId) {
        require(msg.sender == zombieToOwner[_zombieId]);
        zombies[_zombieId].dna = _newDna;
      }
    
      function getZombiesByOwner(address _owner) external view returns(uint[]) {
        uint[] memory result = new uint[](ownerZombieCount[_owner]);
        uint counter = 0;
        for(let i=0; i<zombies.length; i++){
          if(zombieToOwner[i] == _owner){
            result[counter] = i;
            counter++
          }
        }
        return result;
      }
    
    }
    
    今日はほとんどこの中で仕事をしながら勉強します.
    ゾンビ能力を記述するコードです.
    基本的には、あるレベルに達したときにのみ関数を起動できるので、条件を付けます.
  • aboveLevel
  • あるレベルに達すると、関数は実行可能であり、ユーザーが実行しなければならないことを特徴としています.
    その後、関数の機能に応じて、新しいDNAの名前を変更したり設定したりすることができます.getZombiesByOwnerユーザが持つゾンビ返却関数.
    グローバルと呼ばれる配列を使用すると、メモリ消費が深刻になります.
  • メモリの消費量が深刻で、これは大量のガス代が必要であることを意味します.
  • レイアウトには他のユーザーのゾンビも含まれているため、特定のゾンビを移動すると空間が空白になり、すべてのレイアウトを移動する必要があります.
  • ゾンビの値のみを取得し、別の配列から削除しない場合は、すべての配列を迂回する必要があります.
  • したがって、関数内に配列を個別に作成します.
    これは低効率なプロセスですが、メモリの面では効率的な作業です.

    🔨 詳細

    storage演算はメモリ上で非常に高価です.storage演算はブロックチェーン生態系に永久的に記録されるため、生態系を変更する必要があり、これはコストを増加させる.
    したがって、非効率であっても、storageと比較して、呼び出すたびにmomoryで再作成することが望ましい.
  • は、ある配列で単純にコンテンツを検索するのではなく、コンテンツを変数に格納する

    🔥 に感銘を与える


    この文章は個人的にも集中していないので、専門性がずいぶん下がったようです...
  • 実はBigshotこの金融関連の映画はとても面白いです...その部分について考えましたが、集中できなかったようです.
  • 次のレッスンも徐々に集中していきます.
    もう一度書き直して復習する