实验1 Solidity基础
实验流程
- 新建文件AnimalIncubators.sol
- 建立一个基础合约 AnimalIncubators,并指定Solidity编译器版本
- 创建宠物结构体与所用常量,及公共数组
animals[]
- 依据描述完成
_createAnimal、_generateRandomDna、createRandomAnimal
三个函数
实验代码
pragma solidity >=0.4.12 <0.6.0;
contract Animallncubators { uint dnaDigits = 16; uint dnaLength = 10**16; struct Animal { uint dna; string name; } Animal[] public animals; event NewAnimal(uint AnimalId, string name, uint dna); function _createAnimal(string _name, uint _dna) private { animals.push(Animal(_dna, _name)); uint _animalId = animals.length - 1; NewAnimal(_animalId, _name, _dna); } function _generateRandomDna(string _str) private view returns (uint){ uint rand = uint(keccak256(_str)); return rand % dnaLength; } function createRandomAnimal(string _name) public { uint randDna = _generateRandomDna(_name); _createAnimal(_name, randDna); } }
|
实验效果
如图部署合约后创建三个分别叫Drogon、Rheagal、Viserion的宠物
![image-20221013143629630](https://cdn.jsdelivr.net/gh/Skye-rs/CDN/image/loading.gif)
![image-20221013143729922](https://cdn.jsdelivr.net/gh/Skye-rs/CDN/image/loading.gif)
![image-20221013143805379](https://cdn.jsdelivr.net/gh/Skye-rs/CDN/image/loading.gif)
实验二 Solidity进阶——宠物成长系统
实验流程
- 创建两个映射
AnimalToOwner、ownerAnimalCount
记录宠物拥有者的地址和某地址所拥有宠物的数量。
- 修改
_createAnimal
函数来使用映射,得到新宠物后更新映射
- 修改
createRandomAnimal
函数,使得每个用户只能调用该函数一次
- 完成
AnimalFeeding
合约,增加进食和成长功能: 当一个宠物进食后,它自身的DNA将与食物的DNA结合在一起,形成一个新的宠物DNA
实验代码
AnimalIncubators2.sol
pragma solidity >=0.4.12 <0.6.0;
contract Animallncubators { uint dnaDigits = 16; uint dnaLength = 10**16; struct Animal { uint dna; string name; } Animal[] public animals; event NewAnimal(uint AnimalId, string name, uint dna); mapping(uint=>address) AnimalToOwner; mapping(address=>uint) ownerAnimalCount; function _createAnimal(string _name, uint _dna) internal { animals.push(Animal(_dna, _name)); uint _animalId = animals.length - 1; AnimalToOwner[_animalId]=msg.sender; ownerAnimalCount[msg.sender]+=1; NewAnimal(_animalId, _name, _dna); } function _generateRandomDna(string _str) private view returns (uint){ uint rand = uint(keccak256(_str)); return rand % dnaLength; } function createRandomAnimal(string _name) public { require(ownerAnimalCount[msg.sender]==0); uint randDna = _generateRandomDna(_name); _createAnimal(_name, randDna); } }
|
AnimalFeeding.sol
pragma solidity >=0.4.12 <0.6.0; import "./AnimalIncubators2.sol";
contract AnimalFeeding is Animallncubators{ function feedAndGrow(uint _AnimalId,uint _targetDna) internal { require (keccak256(AnimalToOwner[_AnimalId])==keccak256(msg.sender)); Animal storage myAnimal=animals[_AnimalId]; uint _tDna=_targetDna%dnaDigits; uint _newDna=uint((myAnimal.dna+_tDna)/2); _newDna=(_newDna/100)*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); } }
|
实验效果
首先生成一个宠物
![image-20221013152312911](https://cdn.jsdelivr.net/gh/Skye-rs/CDN/image/loading.gif)
在同一地址下生成第二只宠物报错
![image-20221013152412427](https://cdn.jsdelivr.net/gh/Skye-rs/CDN/image/loading.gif)
在其他地址下生成另外两只宠物![image-20221013194828520](https://cdn.jsdelivr.net/gh/Skye-rs/CDN/image/loading.gif)
给Drogon喂食,产生了No-one
![image-20221013153529625](https://cdn.jsdelivr.net/gh/Skye-rs/CDN/image/loading.gif)
实验三 Solidity高阶理论
实验流程
- 创建
ownable.sol
,并在createRandomAnimal
函数中添加onlyOwner
- 更新宠物结构的属性,新添
level readyTime
- 修改
feedAndGrow
函数实现冷却效果
- 完成
changeName changeDna getAnimalsByOwner
函数
实验代码
AnimalIncubators3.sol
pragma solidity >=0.4.12 <0.6.0; import "./ownable.sol";
contract Animallncubators is Ownable { uint dnaDigits = 16; uint dnaLength = 10**16; struct Animal { uint dna; string name; uint32 level; uint32 readyTime; } uint32 cooldownTime = 60; Animal[] public animals; event NewAnimal(uint AnimalId, string name, uint dna); mapping(uint=>address) AnimalToOwner; mapping(address=>uint) ownerAnimalCount; function _createAnimal(string _name, uint _dna) internal { animals.push(Animal(_dna, _name,0,uint32(now))); uint _animalId = animals.length - 1; AnimalToOwner[_animalId]=msg.sender; ownerAnimalCount[msg.sender]+=1; NewAnimal(_animalId, _name, _dna); } function _generateRandomDna(string _str) private view returns (uint){ uint rand = uint(keccak256(_str)); return rand % dnaLength; } function createRandomAnimal(string _name) public { require(ownerAnimalCount[msg.sender]==0); uint randDna = _generateRandomDna(_name); _createAnimal(_name, randDna); } }
|
AnimalFeeding.sol
pragma solidity >=0.4.12 <0.6.0; import "./AnimalIncubators3.sol";
contract AnimalFeeding is Animallncubators{ function feedAndGrow(uint _AnimalId,uint _targetDna) internal { require (keccak256(AnimalToOwner[_AnimalId])==keccak256(msg.sender)); Animal storage myAnimal=animals[_AnimalId]; require(now>=myAnimal.readyTime); uint _tDna=_targetDna%dnaDigits; uint _newDna=uint((myAnimal.dna+_tDna)/2); _newDna=(_newDna/100)*100+99; _createAnimal("No-one",_newDna); myAnimal.readyTime=uint32(now)+cooldownTime; } 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); } }
|
AnimalHelper.sol
pragma solidity >=0.4.12 <0.6.0; import "./AnimalFeeding.sol";
contract AnimalHelper is AnimalFeeding{ modifier aboveLevel (uint _level,uint _AnimalId){ require(animals[_AnimalId].level>=_level); _; } function changeName(uint _AnimalId,string _newName) external aboveLevel(2,_AnimalId){ require(keccak256(msg.sender)==keccak256(AnimalToOwner[_AnimalId])); animals[_AnimalId].name=_newName; } function changeDna(uint _AnimalId,uint _newDna) external aboveLevel(20,_AnimalId){ require(keccak256(msg.sender)==keccak256(AnimalToOwner[_AnimalId])); animals[_AnimalId].dna=_newDna; } function getAnimalsByOwner(address _owner)external view returns(uint[]){ uint [] memory result=new uint[](ownerAnimalCount[_owner]); uint count=0; for(uint i=0;i<animals.length;i++){ if(keccak256(AnimalToOwner[i])==keccak256(_owner)){ result[count]=i; count+=1; } } return result; } }
|
实验效果
onlyOwner
![image-20221013155425795](https://cdn.jsdelivr.net/gh/Skye-rs/CDN/image/loading.gif)
新建一个小动物喂食
![image-20221013161950806](https://cdn.jsdelivr.net/gh/Skye-rs/CDN/image/loading.gif)
再喂一次冷却还没到,报错
![image-20221013162023288](https://cdn.jsdelivr.net/gh/Skye-rs/CDN/image/loading.gif)
再给1号喂
![image-20221013162057057](https://cdn.jsdelivr.net/gh/Skye-rs/CDN/image/loading.gif)
![image-20221013162057249](https://cdn.jsdelivr.net/gh/Skye-rs/CDN/image/loading.gif)
这时候总共有0,1,2三只
![image-20221013162135266](https://cdn.jsdelivr.net/gh/Skye-rs/CDN/image/loading.gif)
看一下getAnimalsByOwner
函数效果
![image-20221013162210136](https://cdn.jsdelivr.net/gh/Skye-rs/CDN/image/loading.gif)
Author:
紫炁
License:
Copyright (c) 2019 CC-BY-NC-4.0 LICENSE
Slogan:
Do you believe in DESTINY?