solidity智能合约

Solidity 是以太坊官方支持的用于编写智能合约的语言,在语法上参考了 JavaScript 和 Java 等语言,语法和概念上基本类似。

本次实验参考了

进行了一个简单的实验和学习,cryptozombies是一款使用了区块链技术开发的DAPP,其主要是一个建立自己的僵尸军团进行拓展和升级的游戏。本次实验我参考教程,完成简单的实现。

游戏的主要文件结构如下:

各个文件作用的介绍:

  1. Zombiefactory.sol本智能合约主要包含僵尸的基本结构、创建僵尸、创建随机僵尸、生成随机僵尸的方法。
  2. Zombiefeeding.sol 本智能合约主要包含僵尸的互食以及产生新的僵尸
  3. Zombieattack.sol 本智能合约实现了两个僵尸在战斗的时候的一些过程和逻辑
  4. Zombiehelper.sol本智能合约实现了设置僵尸的升级花费,以及修改僵尸的一些信息时需要的必要条件
  5. Zombieownership.sol本智能合约实现了僵尸的所有者转换以及收益,
  6. Erc721.sol 代币交易相关的接口
  7. Ownable.sol 控制执行的权限问题
  8. Safemath.sol 为溢出问题提供解决方案
  9. Index.html一个简单的web3和智能合约交互的界面

下面是每个和约具体的代码实现:

Zombiefactory.sol代码实现:

在本合约中

pragma solidity >=0.5.0 <0.6.0;

pragma 表示 Solidity 的版本号,这个合约的版本需要在 0.5.0 和 0.6.0 之间。

import "./ownable.sol";

import "./safemath.sol";

使用 import 语句引入其他 Solidity 文件,其中包括 Ownable 合约和 SafeMath 合约。Ownable 合约定义了一个基本的权限控制系统,而 SafeMath 合约提供了数学计算函数,用于防止整数溢出等问题。

定义一个名为 ZombieFactory 的合约,它继承了 Ownable 合约,以便使用权限控制系统。使用了 SafeMath 的库函数,用于在数学计算时避免整数溢出等问题。 定义一个事件,用于当新的僵尸被创建时进行记录和通知。

定义了一些常量,包括 DNA 位数,DNA 取模数和冷却时间。

定义一个名为 Zombie 的结构体,用于表示一个僵尸的属性。

Zombie[] public zombies:定义了一个动态数组,用于存储所有的僵尸。

mapping (uint => address) public zombieToOwner;

mapping (address => uint) ownerZombieCount;

定义两个映射,用于存储僵尸所有者和每个所有者拥有的僵尸数量。

定义一个名为 _createZombie 的内部函数,用于创建一个新的僵尸。这个函数将一个新的僵尸添加到 zombies 数组中,并将它的所有者设置为当前消息的发送者,同时增加这个所有者拥有的僵尸数量。最后,该函数会触发 NewZombie 事件,以通知外部世界有一个新的僵尸被创建。

定义一个名为_generateRandomDna的私有函数,用于随机生成一个dna序列。

定义名为createRandomZombie的函数,通过随机生成的dna序列创建新的僵尸。

Zombiefeeding.sol的代码如下:

本智能合约包含一个名为 ZombieFeeding 的合约,该合约继承自之前已经定义的 ZombieFactory 合约

定义了一个名为KittyInterface的接口,用于与外部合约进行交互。在这个接口中,有一个函数 getKitty,用于返回与kitty相关的信息,用于在设置特殊类别的僵尸时获取各个属性。

声明了一个名为 onlyOwnerOf 的修饰符,该修饰符要求调用者必须是指定 _zombieId 所属的僵尸的所有者,否则函数将抛出异常。

setKittyContractAddress函数用于将 kittyContract 变量设置为指定地址 _address 所对应的 KittyInterface 类型的合约实例。由于该函数使用了 onlyOwner 修饰符,因此只有合约所有者才能调用该函数。

_triggerCooldown函数用于在喂养僵尸之后,将僵尸的冷却时间重置为 cooldownTime。它接受一个名为 _zombie 的存储类型的参数,该僵尸的冷却时间将被修改。

_isReady函数用于检查僵尸是否已经完成冷却,它接受一个名为 _zombie 的存储类型的参数,并返回一个布尔值。

feedAndMultiply 函数接收Zombie ID、目标 DNA 和种类字符串作为参数。首先,它检查给定 Zombie 是否已经准备好进行交配(即其 readyTime 是否已过)。然后它从给定的目标 DNA 中提取出 DNA 模数,并将其与给定 Zombie 的 DNA 相加取平均数以生成新的 DNA。如果给定的种类字符串等于 "kitty",则将新的 DNA 设为除以 100 的余数加上 99。最后,使用 _createZombie 函数创建一个名为 "NoName" 的新 Zombie,并将其 DNA 设为新生成的 DNA,然后调用 _triggerCooldown 函数将给定 Zombie 的 readyTime 设为当前时间加上 cooldownTime。

feedOnKitty 函数接收Zombie ID 和猫的 ID 作为参数,调用 KittyContract 的 getKitty 函数以获取猫的 DNA,然后调用 feedAndMultiply 函数以将给定 Zombie 的 DNA 和猫的 DNA 相加取平均数以生成新的 DNA,并创建一个新的 Zombie。这个函数可以公开访问,因此任何人都可以使用它来喂养他们的 Zombie。

Zombieattack.sol 的代码如下:

本智能合约实现了一个名为zombieattack的智能合约,用于处理和zombie之间相互攻击的过程。

合约导入了ZombieHelper合约,这意味着它具有ZombieHelper合约中定义的所有函数和变量。

randNonce是用于生成随机数的种子。

attackVictoryProbability是攻击胜利的概率,初始化为70%。

randMod是一个内部函数,用于生成一个随机数,并将其限制在给定的范围内。该函数将当前时间、调用者地址和randNonce值连接在一起,通过keccak256哈希算法计算出一个哈希值,并将其转换为一个数字。最后,取这个数字对给定的参数进行取模,返回一个介于0和(_modulus - 1)之间的数字。

attack的函数首先获取攻击方和被攻击方的僵尸的信息,使用randMod函数生成一个随机数,如果随机数小于或等于attackVictoryProbability,则攻击方获胜。在这种情况下,攻击方的胜利次数和等级都会增加,被攻击方的失败次数会增加,并调用feedAndMultiply函数,以将攻击方的DNA和被攻击方的DNA混合在一起,创建一个新的僵尸。如果攻击方输了,那么它的失败次数会增加,被攻击方的胜利次数会增加,并调用_triggerCooldown函数,以重新启动僵尸的冷却计时器。

Zombiehelper.sol代码如下:

本智能合约实现了设置僵尸的升级花费,以及修改僵尸的一些信息时需要的必要条件。

定义一个名为aboveLevel的修饰器,修饰器要求被修饰的函数的第二个参数(_zombieId)所对应的僵尸的等级大于等于第一个参数(_level),否则会抛出异常并停止函数执行。

withdraw的函数,修饰为只能由合约拥有者调用,并从当前合约地址向合约所有者发送所有的余额。

setLevelUpFee的函数,修饰为只能由合约拥有者调用,并用传入的参数设置levelUpFee的值。

levelUp函数只能由外部调用,并且调用者必须支付一个等于levelUpFee的以太币,否则会抛出异常并停止函数执行。如果满足条件,则增加指定僵尸的等级。

changeName函数只能由外部调用,并要求满足以下条件:指定的僵尸的等级大于等于2,调用者必须是该僵尸的所有者。如果满足条件,则将指定僵尸的名称更改为新的名称。

changeDna函数只能由外部调用,并要求满足以下条件:指定的僵尸的等级大于等于20,调用者必须是该僵尸的所有者。如果满足条件,则将指定僵尸的DNA更改为新的DNA。

getZombiesByOwner的函数它只能由外部调用,并返回指定所有者所拥有的所有僵尸的ID。它首先创建了一个动态数组result,其长度等于指定所有者所拥有的僵尸数量,然后循环遍历所有的僵尸,如果某个僵尸的所有者是指定的所有者,则将该僵尸的ID添加到result中,最终返回result数组。

Zombieownership.sol的代码如下:

本智能合约实现名为ZombieOwnership的智能合约,它是从从ZombieAttack和ERC721继承而来的。它实现了ERC721标准中定义的接口,用于管理和交易Zombie。

balanceOf(address _owner)函数返回指定地址所有拥有的令牌数量。

ownerOf(uint256 _tokenId)函数返回拥有指定令牌的地址。

_transfer(address _from, address _to, uint256 _tokenId)执行令牌的所有权转移。

transferFrom(address _from, address _to, uint256 _tokenId):用于授权地址将指定的令牌转移到另一个地址。

approve(address _approved, uint256 _tokenId):用于授权地址对指定的令牌进行管理。

Erc721.sol 代码:

本合约定义了RC721,erc721是Ethereum上的一种代币标准,它定义了一种可互换的非同质代币(NFT)协议,允许用户拥有并交易不同的代币,每个代币都是独一无二的。

该合约定义了以下四个函数:

balanceOf(address _owner)函数返回指定地址所拥有的代币数量。

ownerOf(uint256 _tokenId)函数返回指定代币ID的所有者地址。

transferFrom(address _from, address _to, uint256 _tokenId)函数从一个地址向另一个地址转移指定代币ID的所有权。

approve(address _approved, uint256 _tokenId)函数将代币ID的所有权授权给另一个地址,以便该地址可以转移代币。

Ownable.sol 代码如下:

本智能合约包含一个名为 Ownable 的智能合约,Ownable 智能合约提供了一种方便的方式,用于控制谁可以执行合约中的敏感操作,例如修改合约的状态或者提取合约中的资产。通常情况下,只有合约的所有者才有权限执行这些操作,而其他用户只能执行只读操作。通过继承 Ownable 智能合约,其他合约可以获得类似的权限控制功能,从而确保合约中的操作都得到了适当的授权和认证。

私有变量 _owner:表示合约的所有者地址。

OwnershipTransferred 事件:用于在所有者发生变化时触发通知。

构造函数将合约的创建者设置为所有者,并触发 OwnershipTransferred 事件,通知合约已经被创建。

公共函数 owner(),用于获取合约的所有者地址。

修饰符 onlyOwner(),用于限制只有合约的所有者才能调用某些函数。

公共函数 isOwner(),用于判断当前调用者是否是合约的所有者。

公共函数 renounceOwnership(),只有合约的所有者可以调用该函数,用于放弃合约的所有权,触发 OwnershipTransferred 事件,并将 _owner 设为 address(0)。

公共函数 transferOwnership(address newOwner),只有合约的所有者可以调用该函数,用于将合约的所有权转移给新的所有者,并调用 _transferOwnership() 实现转移。

内部函数 _transferOwnership(address newOwner),用于将合约的所有权转移给新的所有者,同时触发 OwnershipTransferred 事件,并更新 _owner 变量的值。在转移所有权前,需要确保新的所有者地址不为 0。

Safemath.sol 代码如下:

本智能合约结合assert和相关的判读,对于uint类型的数据的溢出安全问题提供了解决方案。

猜你喜欢

转载自blog.csdn.net/qq_53633989/article/details/130514201