您当前的位置: 首页 > 

柠檬味小发糕

暂无认证

  • 3浏览

    0关注

    84博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Solidity实现智能合约——Solidity高级理论(三)

柠檬味小发糕 发布时间:2021-11-12 22:29:13 ,浏览量:3

Solidity实现智能合约——Solidity高级理论(三)

在上一节当中我们实现了一个可以初始化创建宠物,并让它进食生成一个新宠物的功能,接下来我们继续对这个系统功能进行完善。

在这一节当中我们将会完成以下的功能:为宠物添加俩个新属性等级和冷却时间,不知道大家有没有发现上一节宠物可以不限制的进食,在这一节当中我们来给它们做一个进食时间的限制,此外我们可以花费gas让我们的宠物升级,对于达到一定等级的宠物我们可以增加一些新权限:对自己宠物进行更改名字或者是更改DNA。 话不多说,我们直接开始吧。

Ownable 合约:

1,合约创建,构造函数先行,将其 owner 设置为msg.sender(其部署者)

2,为它加上一个修饰符 onlyOwner,它会限制陌生人的访问,将访问某些函数的权限锁定在 owner 上。

3,允许将合约所有权转让给他人。

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

}

首先,我们新建一个 ownable.sol文件,将上面的代码复制到这个文件当中,然后修改 AnimalFactory 合约, 让它继承自 Ownable,记得要将 ownable.sol导入 AnimalFactory.sol文件当中。

回到AnimalFactory.sol,为 Animal 结构体 添加两个属性:level(uint32)和readyTime(uint32)。因为希望同类型数据打成一个包,所以把它们放在结构体的末尾。

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

声明一个名为 cooldownTime 的uint,并将其设置为30 seconds,我们给 Animal 结构体中添加 level 和 readyTime 两个参数,所以现在创建一个新的 Animal 结构体时,需要修改 _createAnimal(),在其中把新旧参数都初始化一下。

修改 animals.push那一行, 添加2个参数:1(表示当前的 level )和uint32(now + cooldownTime)(现在+冷却时间,表示下次允许攻击的时间 readyTime)。

注意:必须使用 uint32(…) 进行强制类型转换,因为now返回类型 uint256。所以我们需要明确将它转换成一个uint32 类型的变量。

uint dnaDigits = 16;   //宠物DNA位数
uint dnaLength = 10**dnaDigits;
uint cooldownTime = 30 seconds;
 function _createAnimal(string _name,uint _dna) internal{
        uint animalId = animals.push(Animal(_name,_dna,1,uint32(now + cooldownTime)))-1; 
         //  将当前地址对应此时的id 
        AnimalToOwner[animalId] = msg.sender;
        //  这个地址下的宠物数量加一 
        ownerAnimalCount[msg.sender]++;
        NewAnimal(animalId, _name, _dna);
    }

接下来我们回到AnimalFeeding.sol文件当中 先定义一个 _triggerCooldown 函数。它要求一个参数, _Animal,表示一某个宠物的存储指针。这个函数可见性设置为 internal。

在函数中,把 _Animal.readyTime设置为 uint32(now + cooldownTime)。

接下来,创建一个名为 _isReady 的函数。这个函数的参数也是名为 _Animal 的Animal storage。这个功能只具有 internal 可见性,并返回一个 bool 值。

函数计算返回(_Animal.readyTime = _level); _; } // 当宠物等级达到2级时就可以自己改名 function changeName(uint _AnimalId, string _newName) external aboveLevel(2,_AnimalId){ require(msg.sender == AnimalToOwner[_AnimalId]); animals[_AnimalId].name = _newName; } // 当宠物等级达到4级时就可以自己改DNA function changeDna(uint _AnimalId, uint _newDna) external aboveLevel(4,_AnimalId) { require(msg.sender == AnimalToOwner[_AnimalId]); animals[_AnimalId].dna = _newDna; } function getAnimalsByOwner(address _owner) external view returns(uint[]) { uint[] memory result = new uint[](ownerAnimalCount[_owner]); uint counter = 0; for (uint i = 0; i < animals.length; i++) { if (AnimalToOwner[i] == _owner) { result[counter] = i; counter++; } } return result; } }

AnimalFeeding.sol的完整代码

pragma solidity ^0.4.19;
import "./AnimalIncubators.sol";

contract AnimalFeeding is AnimalFactory{
   
   // 重新计算冷却时间 
    function _triggerCooldown(Animal storage _Animal) internal {
      _Animal.readyTime = uint32(now + cooldownTime);
   }
   
   // 是否到了宠物的冷却时间 
   function _isReady(Animal storage _Animal) internal view returns (bool) {
     return (_Animal.readyTime  address) public AnimalToOwner;
    mapping (address => uint) ownerAnimalCount;
    
    
    //  孵化宠物函数 
    // function hatchAnimal(string name,uint dna) public{
    //     animals.push(Animal(name,dna));
        
    // }
    
    event NewAnimal(uint AnimalId,string name,uint dna);
    
    function _createAnimal(string _name,uint _dna) internal{
        uint animalId = animals.push(Animal(_name,_dna,1,uint32(now + cooldownTime)))-1; 
         //  animals.push(Animal(_name,_dna));
         
         //  将当前地址对应此时的id 
        AnimalToOwner[animalId] = msg.sender;
        //  这个地址下的宠物数量加一 
        ownerAnimalCount[msg.sender]++;
        NewAnimal(animalId, _name, _dna);
    }
    
    function _generateRandomDna(string _str) private view returns(uint){
        uint rand = uint(keccak256(_str));
        return rand % dnaLength;
    }
    
    function createRandomAnimal(string _name) public {
        //  用户只能创建一次初始宠物  
        require(ownerAnimalCount[msg.sender] == 0);
        uint randDna = _generateRandomDna(_name);
        _createAnimal(_name, randDna);
    }
}

下一章我会给大家继续完善这个系统的功能,实现一个宠物战斗的功能 链接: Solidity实现智能合约——宠物战斗(四). 最后给大家介绍一下学习solidity一个非常好玩的网站,我做的这三个合约也是从中学习而来,希望能帮助到大家: 编游戏的同时学习以太坊 DApp 开发.

关注
打赏
1640351950
查看更多评论
立即登录/注册

微信扫码登录

0.0360s