千家信息网

Solidity Zombies怎么使用

发表于:2025-02-03 作者:千家信息网编辑
千家信息网最后更新 2025年02月03日,本篇内容主要讲解"Solidity Zombies怎么使用",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Solidity Zombies怎么使用"吧!Zo
千家信息网最后更新 2025年02月03日Solidity Zombies怎么使用

本篇内容主要讲解"Solidity Zombies怎么使用",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"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 合约。 事件 是合约和区块链通讯的一种机制。你的前端应用"监听"某些事件,并做出反应。如:

var abi = // abi是由编译器生成的  var ZombieFactoryContract = web3.eth.contract(abi)  var contractAddress = /// 发布之后在以太坊上生成的合约地址  var ZombieFactory = ZombieFactoryContract.at(contractAddress)   // ZombieFactory能访问公共的函数以及事件// 监听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 中,有一些全局变量可以被所有函数调用。 其中一个就是 msg.sender,它指的是当前调用者(或智能合约)的 address。
Solidity 使用自己的本地时间单位。 变量 now 将返回当前的unix时间戳(自1970年1月1日以来经过的秒数)。我写这句话时 unix 时间是 1515527488。

注意:Unix时间传统用一个32位的整数进行存储。这会导致"2038年"问题,当这个32位的unix时间戳不够用,产生溢出,使用这个时间的遗留系统就麻烦了。所以,如果我们想让我们的 DApp 跑够20年,我们可以使用64位整数表示时间,但为此我们的用户又得支付更多的 gas。真是个两难的设计啊!

Solidity 还包含秒(seconds),分钟(minutes),小时(hours),天(days),周(weeks) 和 年(years) 等时间单位。它们都会转换成对应的秒数放入 uint 中。所以 1分钟 就是 60,1小时是 3600(60秒×60分钟),1天是86400(24小时×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 是一种可以查看向合约发送了多少以太的方法,另外 ether 是一个內建单元。
这里发生的事是,一些人会从 web3.js 调用这个函数 (从DApp的前端), 像这样 :

// 假设 `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);    }  }}

到此,相信大家对"Solidity Zombies怎么使用"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

0