博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【CryptoZombies - 1 Solidity 教程】016 函数多返回值&奖励实战
阅读量:4074 次
发布时间:2019-05-25

本文共 5076 字,大约阅读时间需要 16 分钟。

一、前言

看了一些区块链的教程,论文,在网上刚刚找到了一个项目实战,CryptoZombies。

如果你想了解更多有关于机器学习、深度学习、区块链、计算机视觉等相关技术的内容,想与更多大佬一起沟通,那就扫描下方二维码加入我们吧!

二、 函数多返回值

1、讲解

之前我们看到,我们使用了一个返回多个值的函数。

function getKitty(uint256 _id) external view returns (    bool isGestating,    bool isReady,    uint256 cooldownIndex,    uint256 nextActionAt,    uint256 siringWithId,    uint256 birthTime,    uint256 matronId,    uint256 sireId,    uint256 generation,    uint256 genes) {    Kitty storage kit = kitties[_id];     // if this variable is 0 then it's not gestating    isGestating = (kit.siringWithId != 0);    isReady = (kit.cooldownEndBlock <= block.number);    cooldownIndex = uint256(kit.cooldownIndex);    nextActionAt = uint256(kit.cooldownEndBlock);    siringWithId = uint256(kit.siringWithId);    birthTime = uint256(kit.birthTime);    matronId = uint256(kit.matronId);    sireId = uint256(kit.sireId);    generation = uint256(kit.generation);    genes = kit.genes;}

很多用户python的同学对这种方式是比较习惯的,比如,我们写一个函数,我们有一个函数,并给出其参数和自变量的值:

a = 2b = 4c = 6x1 = 1x2 = 1y = a * x1 + b * x2 + c

我们定义一个函数,用于修改参数:

def changePara(new_a,new_b,new_c):    return new_a,new_b,new_ca,b,c = changePara(1,2,3)

这种方式就是多返回值。

接下来我们通过一个简单的例子来讲解一下在以太坊中的多返回值。

首先,我们可以定义一个具有多返回值的函数:

function multipleReturns() internal returns(uint a, uint b, uint c) {  return (1, 2, 3);}

当我们定义完这样一个函数,我们就可以在下面调用,进行多个参数同时赋值:

function processMultipleReturns() external {  uint a;  uint b;  uint c;  // 这样来做批量赋值:  (a, b, c) = multipleReturns();}

如果我们只想对一个参数进行赋值,我们对其他的参数留空即可:

// 如果我们只想返回其中一个变量:function getLastReturnValue() external {  uint c;  // 可以对其他字段留空:  (,,c) = multipleReturns();}

 

2、实战

1.要求

我们来定义一个函数,从 kitty 合约中获取它的基因:

1.创建一个名为 feedOnKitty 的函数。它需要2个 uint 类型的参数,_zombieId 和_kittyId ,这是一个 public 类型的函数。

2.函数首先要声明一个名为 kittyDna 的 uint

3.这个函数接下来调用 kittyContract.getKitty函数, 传入 _kittyId ,将返回的 genes 存储在 kittyDna 中。记住 —— getKitty 会返回一大堆变量。 (确切地说10个 - 我已经为你数过了,不错吧!)。但是我们只关心最后一个-- genes。数逗号的时候小心点哦!

4.最后,函数调用了 feedAndMultiply ,并传入了 _zombieId 和 kittyDna 两个参数。

 

2.代码

pragma solidity >=0.5.0 <0.6.0;import "./zombiefactory.sol";contract KittyInterface {  function getKitty(uint256 _id) external view returns (    bool isGestating,    bool isReady,    uint256 cooldownIndex,    uint256 nextActionAt,    uint256 siringWithId,    uint256 birthTime,    uint256 matronId,    uint256 sireId,    uint256 generation,    uint256 genes  );}contract ZombieFeeding is ZombieFactory {  address ckAddress = 0x06012c8cf97BEaD5deAe237070F9587f8E7A266d;  KittyInterface kittyContract = KittyInterface(ckAddress);  function feedAndMultiply(uint _zombieId, uint _targetDna) public {    require(msg.sender == zombieToOwner[_zombieId]);    Zombie storage myZombie = zombies[_zombieId];    _targetDna = _targetDna % dnaModulus;    uint newDna = (myZombie.dna + _targetDna) / 2;    _createZombie("NoName", newDna);  }  // define function here  function feedOnKitty(uint _zombieId,uint _kittyId) public {    uint kittyDna;    (,,,,,,,,,kittyDna) = kittyContract.getKitty(_kittyId);    feedAndMultiply(_zombieId,kittyDna);  }}

三、 奖励:Kitty基因实战

1、说明

我们完成了函数多返回值的学习,也就完成了基本的功能逻辑主体了,接下来我们为其添加一个奖励功能。

首先我们需要给kitty制造的僵尸添加一些特征,用以说明他们是小猫僵尸。我们在第一节课讲到DNA中的前12位用于指定僵尸外观,我们使用后两位来处理特殊特征。

我们常说猫有9条命,所以将最后两位设为99,在这里我们要使用判断语句,这与在JavaScript中差不多。示例如下:

function eatBLT(string sandwich) public {  // 看清楚了,当我们比较字符串的时候,需要比较他们的 keccak256 哈希码  if (keccak256(sandwich) == keccak256("BLT")) {    eat();  }}

 

2、实战

1.要求

在僵尸代码中实现小猫的基因。:

1.首先,修改下 feedAndMultiply 函数的定义,给它传入第三个参数:一条名为 _species 的字符串(存储为memory)。

2.接下来,在我们计算出新的僵尸的DNA之后,添加一个 if 语句来比较 _species 和字符串 "kitty" 的 keccak256 哈希值。

注意:我们不能直接把字符串传递给keccak256。相反,我们将在左侧传递abi.encodePacked(_species)作为参数,在右侧传递abi.encodePacked(“kitty”)作为参数

3.在 if 语句中,我们用 99 替换了新僵尸DNA的最后两位数字。可以这么做:

newDna = newDna - newDna % 100 + 99;

4.最后,我们修改了 feedOnKitty 中的函数调用。当它调用 feedAndMultiply 时,增加 “kitty” 作为最后一个参数。

 

2.代码

pragma solidity >=0.5.0 <0.6.0;import "./zombiefactory.sol";contract KittyInterface {  function getKitty(uint256 _id) external view returns (    bool isGestating,    bool isReady,    uint256 cooldownIndex,    uint256 nextActionAt,    uint256 siringWithId,    uint256 birthTime,    uint256 matronId,    uint256 sireId,    uint256 generation,    uint256 genes  );}contract ZombieFeeding is ZombieFactory {  address ckAddress = 0x06012c8cf97BEaD5deAe237070F9587f8E7A266d;  KittyInterface kittyContract = KittyInterface(ckAddress);  // Modify function definition here:  function feedAndMultiply(uint _zombieId, uint _targetDna, string memory _species) public {    require(msg.sender == zombieToOwner[_zombieId]);    Zombie storage myZombie = zombies[_zombieId];    _targetDna = _targetDna % dnaModulus;    uint newDna = (myZombie.dna + _targetDna) / 2;    // Add an if statement here    if(keccak256(abi.encodePacked(_species)) == keccak256(abi.encodePacked("kitty"))) {      newDna = newDna - newDna % 100 + 99;    }    _createZombie("NoName", newDna);  }  function feedOnKitty(uint _zombieId, uint _kittyId) public {    uint kittyDna;    (,,,,,,,,,kittyDna) = kittyContract.getKitty(_kittyId);    // And modify function call here:    feedAndMultiply(_zombieId, kittyDna, "kitty");  }}

 

转载地址:http://qzyni.baihongyu.com/

你可能感兴趣的文章
大数据学习:Spark RDD操作入门
查看>>
大数据框架:Spark 生态实时流计算
查看>>
大数据入门:Hive和Hbase区别对比
查看>>
大数据入门:ZooKeeper工作原理
查看>>
大数据入门:Zookeeper结构体系
查看>>
大数据入门:Spark RDD基础概念
查看>>
大数据入门:SparkCore开发调优原则
查看>>
大数据入门:Java和Scala编程对比
查看>>
大数据入门:Scala函数式编程
查看>>
【数据结构周周练】002顺序表与链表
查看>>
C++报错:C4700:使用了非初始化的局部变量
查看>>
【数据结构周周练】003顺序栈与链栈
查看>>
C++类、结构体、函数、变量等命名规则详解
查看>>
C++ goto语句详解
查看>>
【数据结构周周练】008 二叉树的链式创建及测试
查看>>
《软件体系结构》 第九章 软件体系结构评估
查看>>
《软件体系结构》 第十章 软件产品线体系结构
查看>>
《软件过程管理》 第六章 软件过程的项目管理
查看>>
《软件过程管理》 第九章 软件过程的评估和改进
查看>>
分治法 动态规划法 贪心法 回溯法 小结
查看>>