I. Preface
Read some blockchain tutorials, papers, just found a project on the Internet, CryptoZombies.
If you want to know more about machine learning, deep learning, blockchain, computer vision and other related technologies, and want to communicate with more tycoons, please scan the QR code below to join us!
2, Require
Users can create zombies, but not unlimited, so they need to make a limitation: each user can only call once continuously. We use require to restrict that when some conditions are not met, we can throw an exception and stop running.
The following is a usage example to compare if "Vitalik" is equal to "u name". If not, throw an exception and terminate the program.
Be careful:
Solidity does not support native string comparison. We can only judge by comparing the keccak256 hash value of two strings.
function sayHiToVitalik(string memory _name) public returns (string memory) { // Compares if _name equals "Vitalik". Throws an error and exits if not true. // (Side note: Solidity doesn't have native string comparison, so we // compare their keccak256 hashes to see if the strings are equal) require(keccak256(abi.encodePacked(_name)) == keccak256(abi.encodePacked("Vitalik"))); // If it's true, proceed with the function: return "Hi!"; }
If you call functions like this
sayHiToVitalik("Vitalik")
It will return "Hi!". If the call uses other parameters, it throws an error and stops execution.
Therefore, it is necessary to verify the precondition with require before calling a function.
Three, actual combat
1, requirements
In our zombie game, we don't want users to create unlimited zombies for their army by repeatedly calling createRandomZombie - this will make the game very boring. We used require to make sure that this function is only executed the first time each user calls it to create the initial zombie.
Place the require statement before the createRandomZombie. Make the function first check that the value of ownerZombieCount [msg.sender] is 0, otherwise an error will be thrown.
Be careful:
In Solidity, the order in which keywords are placed is not important
1. Although the two positions of parameters are equivalent. However, due to the inflexibility of our answer checker, it can only identify one of them as the correct answer
2. So here, let's make an agreement to put ownerZombieCount [msg.sender] first
2, code
pragma solidity >=0.5.0 <0.6.0; contract ZombieFactory { event NewZombie(uint zombieId, string name, uint dna); uint dnaDigits = 16; uint dnaModulus = 10 ** dnaDigits; struct Zombie { string name; uint dna; } Zombie[] public zombies; mapping (uint => address) public zombieToOwner; mapping (address => uint) ownerZombieCount; function _createZombie(string memory _name, uint _dna) private { uint id = zombies.push(Zombie(_name, _dna)) - 1; zombieToOwner[id] = msg.sender; ownerZombieCount[msg.sender]++; emit NewZombie(id, _name, _dna); } function _generateRandomDna(string memory _str) private view returns (uint) { uint rand = uint(keccak256(abi.encodePacked(_str))); return rand % dnaModulus; } function createRandomZombie(string memory _name) public { // start here require(ownerZombieCount[msg.sender] == 0); uint randDna = _generateRandomDna(_name); _createZombie(_name, randDna); } }