Solidity Implements Intelligent Contracts - Pet Feeding System

Solidity Realizes Intelligent Contract - Pet Feeding System (2)

In the last section we implemented the pet creation function and will continue to improve it so that our pets can eat.

To store pet ownership, we use two mappings: one to record the addresses of pet owners and the other to record the number of pets owned by an address.

Create a map called AnimalToOwner. The key is a uint (we'll store and find pets based on its id) and the value is address. The mapping property is public.
Create a map named ownerAnimalCount with address as the key and uint as the value.

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

Modify the _in the previous section createAnimal method that assigns pets to function callers
Update the AnimalToOwner map after you get a new pet id and save msg.sender under the id. Then, we add 1 to the ownerAnimalCount under this msg.sender name.

 
    function _createAnimal(string _name,uint _dna) internal{
        uint animalId = animals.push(Animal(_name,_dna))-1;   
         //  Correspond the current address to the id at this time 
        AnimalToOwner[animalId] = msg.sender;
        //  Add one to the number of pets at this address 
        ownerAnimalCount[msg.sender]++;
        NewAnimal(animalId, _name, _dna);
    }

We don't want users to create an infinite number of pets by repeatedly calling createRandomAnimal. We can use require to ensure that this function is executed only the first time each user calls it to create an initial pet. Place the require statement in front of the createRandomAnimal. Causes the function to check for a value of 0 for ownerAnimalCount[msg.sender], or throws an error.

 function createRandomAnimal(string _name) public {
        //  Users can only create an initial pet once  
        require(ownerAnimalCount[msg.sender] == 0);
        uint randDna = _generateRandomDna(_name);
        _createAnimal(_name, randDna);
    }

Next, to keep the code redundant, we created a new contract AnimalFeeding in AnimalFeeding,sol

pragma solidity ^0.4.19;

contract  AnimalFeeding is AnimalFactory {

}

Import AnimalFactory.sol into our new file AnimalFeeding.sol.

pragma solidity ^0.4.19;

import "./AnimalFactory.sol";

contract  AnimalFeeding is AnimalFactory{

  // Start here

}

At this point we can add "hunting" and "breeding" functions to our pets! When a pet eats food, its own DNA binds to the DNA of the food to form a new pet DNA.

Create a function called feedAndGrow. Use two parameters:_ AnimalId (uint type) and _ targetDna (also uint type). Set the property to public.

We don't want people to eat with our pets. First, we ensure ownership of our pets. Make sure msg.sender can only be the owner of this pet by adding a require statement (similar to what we did in the createRandomAnimal function).

To get the pet's DNA, our function needs to declare a local variable named myAnimal with a data type of Animal (this is a storage pointer). Set its value to index in the animals array to _ The value that AnimalId points to.

 function feedAndGrow(uint _AnimalId,uint _targetDna)public {
        // Make sure your current pet is your own  
        require(msg.sender == AnimalToOwner[_AnimalId]);
        //  Get the pet's DNA
        Animal storage myAnimal = animals[_AnimalId];
    }

When we get the food's dna, we can feed our pets, let pet DNA and food DNA combine to produce new pet DNA, and we can also name new pets. Here we just averaged the pet DNA and food DNA and replaced the last two digits with 99, and the pet's new name was No-one.

  //  Pet Food DNA for Eating Function 
    function feedAndGrow(uint _AnimalId,uint _targetDna)public {
        // Make sure your current pet is your own  
        require(msg.sender == AnimalToOwner[_AnimalId]);
        //  Get the pet's DNA
        Animal storage myAnimal = animals[_AnimalId];
        
         _targetDna = _targetDna % dnaLength;
         uint newDna = (myAnimal.dna + _targetDna) / 2;
         newDna = newDna - newDna % 100 + 99;
         _createAnimal("No-one", newDna);
    }

The feed AndGrow function above requires the parameters passed in are pet ID and food DNA, which we can get, so how do we get food DNA? Next, we need to create a function to generate food DNA. The function of this function is very simple. Call this function to pass in the uint value, generate a hash value through a hash function, and we will only take the last 16 bits of this hash value as food DNA.

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

Finally, we use a feed OnFood function that calls both parts to do what we want: Pet feeding generates a new pet name and new DNA (99 digits at the end), and initially we can only create one pet.

Attach our complete code at the end

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

contract  AnimalFeeding is AnimalFactory{
    
     //  Pet Food DNA for Eating Function 
    function feedAndGrow(uint _AnimalId,uint _targetDna)public {
        // Make sure your current pet is your own  
        require(msg.sender == AnimalToOwner[_AnimalId]);
        //  Get the pet's 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);
    }
    
}

Next, I'll show you what the code does.


After successful deployment we can create our pet drogon first

At this point we can continue trying to initially create a second pet cat, and you will find that the initialization failed, indicating that the function we defined to initialize a pet has been implemented.

Next feed our pets. We can now see the pets in our array when we find that the feeding was successful

Our first initialization pet drogon

drogon has evolved into a second pet, No-one, after eating, and we can see that the last two of the new pets successfully turned into 99

Now that we're all here, you can try it out.

Tags: solidity

Posted on Fri, 05 Nov 2021 13:47:33 -0400 by crazytigger