Solidity实现智能合约——宠物进食系统(二)
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实现智能合约——宠物进食系统(二)相关推荐
- solidity开发智能合约
文章目录 1 Solidity与智能合约 2 智能合约概述 3 以太坊简介 4 以太坊交互工具 5 开发环境搭建 5.1 remix在线编译器 5.2 搭建本地网络 5.2.1 安装本地remix-i ...
- 【0基础】学习solidity开发智能合约-初识solidity
本篇课程开始,我们来学习一下如何使用solidity开发智能合约,由于博主对于solidity的学习,也是自学的,所以一些不足或有纰漏之处还望指出,大家共同进步,本系列课程会分很多节课讲述,从入门到进 ...
- 以太坊智能合约开发(四):Solidity转账智能合约实验
以太坊智能合约开发(四):Solidity转账智能合约实验 1 合约编写 2 在线调试 1 合约编写 编写一个分布式转账智能合约,部署合约的人为合约管理员,只有管理员可以为其他用户发放代币,其他用户之 ...
- EOS智能合约:system系统合约源码分析
链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载. eosio.system 概览 笔者使用的IDE是VScode,首先来看eosio.system的源码结构.如下图所示. ...
- 【精】EOS智能合约:system系统合约源码分析
系统合约在链启动阶段就会被部署,是因为系统合约赋予了EOS链资源.命名拍卖.基础数据准备.生产者信息.投票等能力.本篇文章将会从源码角度详细研究system合约. 关键字:EOS,eosio.syst ...
- solidity:智能合约结构介绍
合约结构介绍 1.SPDX 版权声明 bytecode metadata 介绍 2.pragma solidity 版本限制 3.contract 关键字 4.import 导入声明 5.interf ...
- 【Solidity】零基础入门Solidity编写智能合约代码
如果你有其他语言基础,可以很快入门,如果新手建议了解即可,以下是课程目录: 1.智能合约概述 2.区块链基础 3.以太坊虚拟机 4.安装Solidity编译器 5.从源代码编译 6.CMake参数 7 ...
- 【区块链Solidity】智能合约与Solidity介绍
目录 智能合约 Solidity语言简介 Solidity语言特性 智能合约 智能合约的英文是Smart Contract 最早是尼克丶萨博在1995年就提出了智能合约的概念~就是将法律条文写成可执行 ...
- solidity bytes 智能合约开发知识浅学(五点一)bytes基本概念
环境说明: Ide:在线remix Solidity IDE 语言:solidity solidity 版本号:0.4.20 Tip:如果一点都不懂的建议从头开始看 运行结果截图我不赘述,所有合约代码 ...
最新文章
- linux下screen工具使用
- 如何使Layouts里的页面应用站点母板页
- python基础教程学习笔记十二
- 大话设计模式Python实现-简单工厂模式
- python怎么写测试脚本语言_手把手带你,用Python写一个Monkey自动化测试脚本!!!...
- 一个简单易用的代码生成工具
- 计算机快捷键下档健,电脑文档快捷键
- smb文件共享_使用SMB文件共享作为存储替代方案
- 怎样调整服务器C盘空间
- 阿里云和域名怎么备案?
- mac关闭谷歌自动更新
- 知云文献翻译打不开_科研星火 | 基础技能——翻译篇
- gprmax构造多层均质土壤模型
- linux软件的下载
- mat-icon 翻转_案例研究-翻转网站以获取利润
- 计算机高级文秘学什么的,文秘专业主要学什么|文秘专业的职业目标是什么
- 喜!人民币入篮;忧!欧央行下调。【济南中金点评 www.zjzx01.com】
- WIN7系统忘记密码怎么办?忘记开机密码的解决方法
- 杭州c语言开发招聘,杭州招银网络科技
- 【Cocos游戏实战】功夫小子第六课之游戏主功能场景的分析和实现