Solidity实现智能合约——宠物进食系统(二)

在上一节当中我们实现了创建宠物的功能,接下来将继续完善功能,让我们的宠物可以进食。

为了存储宠物的所有权,我们会使用到两个映射:一个记录宠物拥有者的地址,另一个记录某地址所拥有宠物的数量。

创建一个叫做 AnimalToOwner 的映射。其键是一个uint(我们将根据它的 id 存储和查找宠物),值为 address。映射属性为public。
创建一个名为 ownerAnimalCount的映射,其中键是 address,值是 uint。

 mapping (uint => address) public AnimalToOwner;mapping (address => uint) ownerAnimalCount;

修改上一节当中的 _createAnimal方法,将宠物分配给函数调用者
在得到新的宠物 id 后,更新 AnimalToOwner 映射,在 id 下面存入 msg.sender。然后,我们为这个 msg.sender 名下的 ownerAnimalCount 加 1。

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

我们不希望用户通过反复调用 createRandomAnimal 来创建无限多个宠物 ,我们可以使用了 require 来确保这个函数只有在每个用户第一次调用它的时候执行,用以创建初始宠物。在 createRandomAnimal 的前面放置 require 语句。 使得函数先检查 ownerAnimalCount[msg.sender]的值为 0 ,不然就抛出一个错误。

 function createRandomAnimal(string _name) public {//  用户只能创建一次初始宠物  require(ownerAnimalCount[msg.sender] == 0);uint randDna = _generateRandomDna(_name);_createAnimal(_name, randDna);}

接下来为了不让代码过于冗余,我们在AnimalFeeding.sol当中新建一个合约 AnimalFeeding并让它继承上一节当中的AnimalFactory合约

pragma solidity ^0.4.19;contract  AnimalFeeding is AnimalFactory {}

.将 AnimalFactory.sol 导入到我们的新文件AnimalFeeding.sol 中。

pragma solidity ^0.4.19;import "./AnimalFactory.sol";contract  AnimalFeeding is AnimalFactory{}

这时候我们就可以给宠物增加“猎食”和“繁殖”功能了!当一个宠物进食时,它自身的DNA将与食物的DNA结合在一起,形成一个新的宠物DNA。

创建一个名为feedAndGrow 的函数。 使用两个参数: _AnimalId( uint类型 )和_targetDna (也是 uint 类型)。 设置属性为 public 的。

我们不希望别人用我们的宠物去进食。 首先,我们确保对自己宠物的所有权。 通过添加一个require 语句来确保 msg.sender 只能是这个宠物的主人(类似于我们在 createRandomAnimal 函数中做过的那样)。

为了获取这个宠物的DNA,我们的函数需要声明一个名为 myAnimal 数据类型为Animal的本地变量(这是一个 storage 型的指针)。 将其值设定为在animals 数组中索引为_AnimalId所指向的值。

 function feedAndGrow(uint _AnimalId,uint _targetDna)public {// 确保当前的宠物是自己的  require(msg.sender == AnimalToOwner[_AnimalId]);//  获取这个宠物的DNAAnimal storage myAnimal = animals[_AnimalId];}

当获取食物的DNA时,我们就可以让宠物进食,让宠物DNA和食物DNA结合生成新的宠物DNA,另外我们也可以给新宠物起名。这里只是将宠物DNA和食物DNA算了平均值并把最后两位数字替换成了99,最后宠物的新名字为"No-one"。

  //  实现进食功能    宠物   食物DNA function feedAndGrow(uint _AnimalId,uint _targetDna)public {// 确保当前的宠物是自己的  require(msg.sender == AnimalToOwner[_AnimalId]);//  获取这个宠物的DNAAnimal storage myAnimal = animals[_AnimalId];_targetDna = _targetDna % dnaLength;uint newDna = (myAnimal.dna + _targetDna) / 2;newDna = newDna - newDna % 100 + 99;_createAnimal("No-one", newDna);}

上面的feedAndGrow函数需要传入的参数为宠物ID和食物DNA,宠物ID我们可以拿到,那么食物DNA我们该如何获取呢,接下来就要创建一个生成食物DNA的函数。这个函数的功能很简单,调用这个函数传入uint值,通过一个hash函数将这个uint生成一个hash值,而我们最后只会取这个hash值的后16位作为食物的DNA

 function _catchFood(uint _name) internal pure returns (uint){uint rand = uint(keccak256(_name));return rand;}

最后就是通过一个feedOnFood函数来调用上面的俩个部件来实现我们想要的功能:宠物进食可以生成新的宠物名和新的DNA(末尾俩位数字为99),而且我们初始只能创建一个宠物。

最后贴上我们的完整代码

pragma solidity ^0.4.19;
import "./AnimalFactory.sol";contract  AnimalFeeding is AnimalFactory{//  实现进食功能    宠物   食物DNA function feedAndGrow(uint _AnimalId,uint _targetDna)public {// 确保当前的宠物是自己的  require(msg.sender == AnimalToOwner[_AnimalId]);//  获取这个宠物的DNAAnimal storage myAnimal = animals[_AnimalId];_targetDna = _targetDna % dnaLength;uint newDna = (myAnimal.dna + _targetDna) / 2;newDna = newDna - newDna % 100 + 99;_createAnimal("No-one", newDna);}function _catchFood(uint _name) internal pure returns (uint){uint rand = uint(keccak256(_name));return rand;}function feedOnFood(uint _AnimalId,uint _FoodId) public{uint foodDna = _catchFood(_FoodId);feedAndGrow(_AnimalId,foodDna);}}

接下来给大家演示一下代码的功能


部署成功之后我们可以先创建我们的宠物drogon

此时我们还可以继续尝试初始创建第二个宠物cat,这时候你就会发现初始化失败,说明我们定义的初始化一个宠物的功能实现了。

接下来给我们的宠物进食。发现喂食成功,此时我们可以来查看我们的数组当中的宠物

我们的第一个初始化宠物drogon

drogon进食后进化成的第二个宠物No-one,而且我们可以发现新宠物的DNA最后俩位成功变成了99

到这里我们的功能就都实现了,大家也可以去尝试玩一玩。
下一节我们进一步对这个合约进行功能优化:链接: Solidity实现智能合约——Solidity高级理论(三)

Solidity实现智能合约——宠物进食系统(二)相关推荐

  1. solidity开发智能合约

    文章目录 1 Solidity与智能合约 2 智能合约概述 3 以太坊简介 4 以太坊交互工具 5 开发环境搭建 5.1 remix在线编译器 5.2 搭建本地网络 5.2.1 安装本地remix-i ...

  2. 【0基础】学习solidity开发智能合约-初识solidity

    本篇课程开始,我们来学习一下如何使用solidity开发智能合约,由于博主对于solidity的学习,也是自学的,所以一些不足或有纰漏之处还望指出,大家共同进步,本系列课程会分很多节课讲述,从入门到进 ...

  3. 以太坊智能合约开发(四):Solidity转账智能合约实验

    以太坊智能合约开发(四):Solidity转账智能合约实验 1 合约编写 2 在线调试 1 合约编写 编写一个分布式转账智能合约,部署合约的人为合约管理员,只有管理员可以为其他用户发放代币,其他用户之 ...

  4. EOS智能合约:system系统合约源码分析

    链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载. eosio.system 概览 笔者使用的IDE是VScode,首先来看eosio.system的源码结构.如下图所示. ...

  5. 【精】EOS智能合约:system系统合约源码分析

    系统合约在链启动阶段就会被部署,是因为系统合约赋予了EOS链资源.命名拍卖.基础数据准备.生产者信息.投票等能力.本篇文章将会从源码角度详细研究system合约. 关键字:EOS,eosio.syst ...

  6. solidity:智能合约结构介绍

    合约结构介绍 1.SPDX 版权声明 bytecode metadata 介绍 2.pragma solidity 版本限制 3.contract 关键字 4.import 导入声明 5.interf ...

  7. 【Solidity】零基础入门Solidity编写智能合约代码

    如果你有其他语言基础,可以很快入门,如果新手建议了解即可,以下是课程目录: 1.智能合约概述 2.区块链基础 3.以太坊虚拟机 4.安装Solidity编译器 5.从源代码编译 6.CMake参数 7 ...

  8. 【区块链Solidity】智能合约与Solidity介绍

    目录 智能合约 Solidity语言简介 Solidity语言特性 智能合约 智能合约的英文是Smart Contract 最早是尼克丶萨博在1995年就提出了智能合约的概念~就是将法律条文写成可执行 ...

  9. solidity bytes 智能合约开发知识浅学(五点一)bytes基本概念

    环境说明: Ide:在线remix Solidity IDE 语言:solidity solidity 版本号:0.4.20 Tip:如果一点都不懂的建议从头开始看 运行结果截图我不赘述,所有合约代码 ...

最新文章

  1. linux下screen工具使用
  2. 如何使Layouts里的页面应用站点母板页
  3. python基础教程学习笔记十二
  4. 大话设计模式Python实现-简单工厂模式
  5. python怎么写测试脚本语言_手把手带你,用Python写一个Monkey自动化测试脚本!!!...
  6. 一个简单易用的代码生成工具
  7. 计算机快捷键下档健,电脑文档快捷键
  8. smb文件共享_使用SMB文件共享作为存储替代方案
  9. 怎样调整服务器C盘空间
  10. 阿里云和域名怎么备案?
  11. mac关闭谷歌自动更新
  12. 知云文献翻译打不开_科研星火 | 基础技能——翻译篇
  13. gprmax构造多层均质土壤模型
  14. linux软件的下载
  15. mat-icon 翻转_案例研究-翻转网站以获取利润
  16. 计算机高级文秘学什么的,文秘专业主要学什么|文秘专业的职业目标是什么
  17. 喜!人民币入篮;忧!欧央行下调。【济南中金点评 www.zjzx01.com】
  18. WIN7系统忘记密码怎么办?忘记开机密码的解决方法
  19. 杭州c语言开发招聘,杭州招银网络科技
  20. 【Cocos游戏实战】功夫小子第六课之游戏主功能场景的分析和实现

热门文章

  1. Intel 中国研究院面试经历
  2. 菜鸟驿站下一站:跟美团抢社区生意
  3. 阅读笔记-进击的学霸-理念篇-学习中心论
  4. 杰理之添加外挂 flash 驱动及实现音乐播放功能【篇】
  5. web前端必学功法之一:留言板
  6. 解决Adobe Acrobat Pro DC 使用高亮文本标记,但是文字却被遮住了问题
  7. php仿qq空间,PHP实现的QQ空间g_tk加密算法
  8. 解决IMX6Q网卡AR8035不稳定问题
  9. 8.2透明度混合-关闭写入
  10. Citrix收购Unidesk:剑指应用分层软件