溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Solidity Zombies怎么使用

發(fā)布時(shí)間:2021-12-07 15:54:05 來源:億速云 閱讀:224 作者:iii 欄目:互聯(lián)網(wǎng)科技

本篇內(nèi)容主要講解“Solidity Zombies怎么使用”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Solidity Zombies怎么使用”吧!

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);
    }

}

Ownable是來自 OpenZeppelin Solidity 庫的 Ownable 合約。 事件 是合約和區(qū)塊鏈通訊的一種機(jī)制。你的前端應(yīng)用“監(jiān)聽”某些事件,并做出反應(yīng)。如:

var abi = // abi是由編譯器生成的  
var ZombieFactoryContract = web3.eth.contract(abi)  
var contractAddress = /// 發(fā)布之后在以太坊上生成的合約地址  
var ZombieFactory = ZombieFactoryContract.at(contractAddress)   
// ZombieFactory能訪問公共的函數(shù)以及事件

// 監(jiān)聽NewZombie事件, 并且更新UI  
var event = ZombieFactory.NewZombie(function(error, result) {  
  if (error) return
  generateZombie(result.zombieId, result.name, result.dna)
})

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;

  modifier ownerOf(uint _zombieId) {
    require(msg.sender == zombieToOwner[_zombieId]);
    _;
  }

  function setKittyContractAddress(address _address) external onlyOwner {
    kittyContract = KittyInterface(_address);
  }

  function _triggerCooldown(Zombie storage _zombie) internal {
    _zombie.readyTime = uint32(now + cooldownTime);
  }

  function _isReady(Zombie storage _zombie) internal view returns (bool) {
      return (_zombie.readyTime <= now);
  }

  function feedAndMultiply(uint _zombieId, uint _targetDna, string _species) internal ownerOf(_zombieId) {
    Zombie storage myZombie = zombies[_zombieId];
    require(_isReady(myZombie));
    _targetDna = _targetDna % dnaModulus;
    uint newDna = (myZombie.dna + _targetDna) / 2;
    if (keccak256(_species) == keccak256("kitty")) {
      newDna = newDna - newDna % 100 + 99;
    }
    _createZombie("NoName", newDna);
    _triggerCooldown(myZombie);
  }

  function feedOnKitty(uint _zombieId, uint _kittyId) public {
    uint kittyDna;
    (,,,,,,,,,kittyDna) = kittyContract.getKitty(_kittyId);
    feedAndMultiply(_zombieId, kittyDna, "kitty");
  }
}

在 Solidity 中,有一些全局變量可以被所有函數(shù)調(diào)用。 其中一個(gè)就是 msg.sender,它指的是當(dāng)前調(diào)用者(或智能合約)的 address。
Solidity 使用自己的本地時(shí)間單位。 變量 now 將返回當(dāng)前的unix時(shí)間戳(自1970年1月1日以來經(jīng)過的秒數(shù))。我寫這句話時(shí) unix 時(shí)間是 1515527488。

注意:Unix時(shí)間傳統(tǒng)用一個(gè)32位的整數(shù)進(jìn)行存儲(chǔ)。這會(huì)導(dǎo)致“2038年”問題,當(dāng)這個(gè)32位的unix時(shí)間戳不夠用,產(chǎn)生溢出,使用這個(gè)時(shí)間的遺留系統(tǒng)就麻煩了。所以,如果我們想讓我們的 DApp 跑夠20年,我們可以使用64位整數(shù)表示時(shí)間,但為此我們的用戶又得支付更多的 gas。真是個(gè)兩難的設(shè)計(jì)??!

Solidity 還包含秒(seconds),分鐘(minutes),小時(shí)(hours),天(days),周(weeks) 和 年(years) 等時(shí)間單位。它們都會(huì)轉(zhuǎn)換成對(duì)應(yīng)的秒數(shù)放入 uint 中。所以 1分鐘 就是 60,1小時(shí)是 3600(60秒×60分鐘),1天是86400(24小時(shí)×60分鐘×60秒),以此類推。

ZombieHelper.sol

pragma solidity ^0.4.19;

import "./zombiefeeding.sol";

contract ZombieHelper is ZombieFeeding {

  uint levelUpFee = 0.001 ether;

  modifier aboveLevel(uint _level, uint _zombieId) {
    require(zombies[_zombieId].level >= _level);
    _;
  }

  function withdraw() external onlyOwner {
    owner.transfer(this.balance);
  }

  function setLevelUpFee(uint _fee) external onlyOwner {
    levelUpFee = _fee;
  }

  function levelUp(uint _zombieId) external payable {
    require(msg.value == levelUpFee);
    zombies[_zombieId].level++;
  }

  function changeName(uint _zombieId, string _newName) external aboveLevel(2, _zombieId) ownerOf(_zombieId) {
    zombies[_zombieId].name = _newName;
  }

  function changeDna(uint _zombieId, uint _newDna) external aboveLevel(20, _zombieId) ownerOf(_zombieId) {
    zombies[_zombieId].dna = _newDna;
  }

  function getZombiesByOwner(address _owner) external view returns(uint[]) {
    uint[] memory result = new uint[](ownerZombieCount[_owner]);
    uint counter = 0;
    for (uint i = 0; i < zombies.length; i++) {
      if (zombieToOwner[i] == _owner) {
        result[counter] = i;
        counter++;
      }
    }
    return result;
  }

}

msg.value 是一種可以查看向合約發(fā)送了多少以太的方法,另外 ether 是一個(gè)內(nèi)建單元。
這里發(fā)生的事是,一些人會(huì)從 web3.js 調(diào)用這個(gè)函數(shù) (從DApp的前端), 像這樣 :

// 假設(shè) `OnlineStore` 在以太坊上指向你的合約:    
OnlineStore.buySomething().send(from: web3.eth.defaultAccount, value: web3.utils.toWei(0.001))

ZombieBattle.sol

pragma solidity ^0.4.19;
import "./zombiehelper.sol";
contract ZombieBattle is ZombieHelper {
  uint randNonce = 0;
  uint attackVictoryProbability = 70;

  function randMod(uint _modulus) internal returns(uint) {
    randNonce++;
    return uint(keccak256(now, msg.sender, randNonce)) % _modulus;
  }

  function attack(uint _zombieId, uint _targetId) external ownerOf(_zombieId) {
    Zombie storage myZombie = zombies[_zombieId];
    Zombie storage enemyZombie = zombies[_targetId];
    uint rand = randMod(100);
    if (rand <= attackVictoryProbability) {
      myZombie.winCount++;
      myZombie.level++;
      enemyZombie.lossCount++;
      feedAndMultiply(_zombieId, enemyZombie.dna, "zombie");
    } else {
      myZombie.lossCount++;
      enemyZombie.winCount++;
      _triggerCooldown(myZombie);
    }
  }
}

到此,相信大家對(duì)“Solidity Zombies怎么使用”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI