Solidity实现智能合约——宠物进食系统(二)
在上一节当中我们实现了创建宠物的功能,接下来将继续完善功能,让我们的宠物可以进食。
为了存储宠物的所有权,我们会使用到两个映射:一个记录宠物拥有者的地址,另一个记录某地址所拥有宠物的数量。
创建一个叫做 AnimalToOwner 的映射。其键是一个uint(我们将根据它的 id 存储和查找宠物),值为 address。映射属性为public。
创建一个名为 ownerAnimalCount的映射,其中键是 address,值是 uint。
mapping (uint => address) public AnimalToOwner; mapping (address => uint) ownerAnimalCount; 12
修改上一节当中的 _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); } 123456789
我们不希望用户通过反复调用 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); } 123456
接下来为了不让代码过于冗余,我们在AnimalFeeding.sol当中新建一个合约 AnimalFeeding并让它继承上一节当中的AnimalFactory合约
pragma solidity ^0.4.19; contract AnimalFeeding is AnimalFactory { } 12345
.将 AnimalFactory.sol 导入到我们的新文件AnimalFeeding.sol 中。
pragma solidity ^0.4.19; import "./AnimalFactory.sol"; contract AnimalFeeding is AnimalFactory{ } 123456789
这时候我们就可以给宠物增加“猎食”和“繁殖”功能了!当一个宠物进食时,它自身的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]); // 获取这个宠物的DNA Animal storage myAnimal = animals[_AnimalId]; } 123456
当获取食物的DNA时,我们就可以让宠物进食,让宠物DNA和食物DNA结合生成新的宠物DNA,另外我们也可以给新宠物起名。这里只是将宠物DNA和食物DNA算了平均值并把最后两位数字替换成了99,最后宠物的新名字为"No-one"。
// 实现进食功能 宠物 食物DNA function feedAndGrow(uint _AnimalId,uint _targetDna)public { // 确保当前的宠物是自己的 require(msg.sender == AnimalToOwner[_AnimalId]); // 获取这个宠物的DNA Animal storage myAnimal = animals[_AnimalId]; _targetDna = _targetDna % dnaLength; uint newDna = (myAnimal.dna + _targetDna) / 2; newDna = newDna - newDna % 100 + 99; _createAnimal("No-one", newDna); } 123456789101112
上面的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; } 1234
最后就是通过一个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]); // 获取这个宠物的DNA Animal 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); } }
1234567891011121314151617181920212223242526272829接下来给大家演示一下代码的功能
部署成功之后我们可以先创建我们的宠物drogon
此时我们还可以继续尝试初始创建第二个宠物cat,这时候你就会发现初始化失败,说明我们定义的初始化一个宠物的功能实现了。
接下来给我们的宠物进食。发现喂食成功,此时我们可以来查看我们的数组当中的宠物
我们的第一个初始化宠物drogon
drogon进食后进化成的第二个宠物No-one,而且我们可以发现新宠物的DNA最后俩位成功变成了99
到这里我们的功能就都实现了,大家也可以去尝试玩一玩。
下一节我们进一步对这个合约进行功能优化:链接: Solidity实现智能合约——Solidity高级理论(三)
相关知识
solodity实现erc721 宠物
宠物智能仓储系统有哪些
IOT毕设|智能宠物屋研究与实现
智能宠物监控系统的发展前景,以下信息要了解!
智能宠物看护系统发展前景,以下信息要了解!
毕业论文题目:基于Java的宠物领养系统设计与实现摘要:本论文介绍了一种基于Java的宠物领养系统的设计与实现方法。该系统能够有效地管理宠物信息、提高领养效率、降低领养成本,同时提供安全、可靠的宠
宠物领养系统设计实现
基于区块链技术的宠物终身管理平台All Pet介绍
加盟智能狗窝,把握宠物市场新趋势,实现财富自由!
基于智能推荐的宠物之家网站设计与实现(开题报告+源码)
网址: Solidity实现智能合约——宠物进食系统(二) https://m.mcbbbk.com/newsview52017.html
上一篇: 【图】好物分享之宠物用品 |
下一篇: 宠物主热衷于网上购物,在线电商与 |