Index
- Lesson 1: CryptoZombies
- Chapter 2 Contracts
- Chapter 3: State Variables & Integers
- Chapter 4: Math Operations
- Chapter 5: Structs
- Chapter 6: Arrays
- Chapter 7: Function Declarations
- Chapter 8: Working With Structs and Arrays
- Chapter 9: Private / Public Functions
- Chapter 10: More on Functions
- Chapter 11: Keccak256 and Typecasting
- Chapter 12: Putting It Together
- Chapter 13: Events
- Chapter 14: Web3.js
- Lesson 2: Zombies Attack Their Victims
- Chapter 2: Mappings and Addresses
- Chapter 3: Msg.sender
- Chapter 4: Require
- Chapter 5: Inheritance
- Chapter 6: Import
- Chapter 7: Storage vs Memory
- Chapter 8: Zombie DNA
- Chapter 9: More on Function Visibility
- Chapter 10: What Do Zombies Eat?
- Chapter 11: Using an Interface
- Chapter 12: Handling Multiple Return Values
- Chapter 13: Bonus: Kitty Genes
- Chapter 14: Wrapping It Up
- Lesson 3: Advanced Solidity Concepts
- Chapter 2: Ownable Contracts
- Chapter 3: onlyOwner Function Modifier
- Chapter 4: Gas
- Chapter 5: Time Units
- Chapter 6: Zombie Cooldowns
- Chapter 7: Public Functions & Security
- Chapter 8: More on Function Modifiers
- Chapter 9: Zombie Modifiers
- Chapter 10: Saving Gas With 'View' Functions
- Chapter 11: Storage is Expensive
- Chapter 12: For Loops
- Chapter 13: Wrapping It Up
- Lesson 4: Zombie Battle System
- Chapter 1: Payable
- Chapter 2: Withdraws
- Chapter 3: Zombie Battles
- Chapter 4: Random Numbers
- Chapter 5: Zombie Fightin'
- Chapter 6: Refactoring Common Logic
- Chapter 7: More Refactoring
- Chapter 8: Back to Attack!
- Chapter 9: Zombie Wins and Losses
- Chapter 10: Zombie Victory 😄
- Chapter 11: Zombie Loss 😞
- Lesson 5: ERC721 & Crypto-Collectibles
- Chapter 1: Tokens on Ethereum
- Chapter 2: ERC721 Standard, Multiple Inheritance
- Chapter 3: balanceOf & ownerOf
- Chapter 4: Refactoring
- Chapter 5: ERC721: Transfer Logic
- Chapter 6: ERC721: Transfer Cont'd
- Chapter 7: ERC721: Approve
- Chapter 8: ERC721: Approve
- Chapter 9: Preventing Overflows
- Chapter 10: SafeMath Part 2
- Chapter 11: SafeMath Part 3
- Chapter 12: SafeMath Part 4
- Chapter 13: Comments
- Chapter 14: Wrapping It Up
- App Front-ends & Web3.js
- Chapter 1: Intro to Web3.js
- Chapter 2: Web3 Providers
- Chapter 3: Talking to Contracts
- Chapter 4: Calling Contract Functions
- Chapter 5: Metamask & Accounts
- Chapter 6: Displaying our Zombie Army
- Chapter 7: Sending Transactions
- Chapter 8: Calling Payable Functions
- Chapter 9: Subscribing to Events
- Chapter 10: Wrapping It Up
Chapter 12: Handling Multiple Return Values
Chapter 12: Handling Multiple Return Values
This
getKitty
function is the first example we've seen that returns multiple values. Let's look at how to handle them:function multipleReturns() internal returns(uint a, uint b, uint c) {
return (1, 2, 3);
}
function processMultipleReturns() external {
uint a;
uint b;
uint c;
// This is how you do multiple assignment:
(a, b, c) = multipleReturns();
}
// Or if we only cared about one of the values:
function getLastReturnValue() external {
uint c;
// We can just leave the other fields blank:
(,,c) = multipleReturns();
}
return (1, 2, 3);
}
function processMultipleReturns() external {
uint a;
uint b;
uint c;
// This is how you do multiple assignment:
(a, b, c) = multipleReturns();
}
// Or if we only cared about one of the values:
function getLastReturnValue() external {
uint c;
// We can just leave the other fields blank:
(,,c) = multipleReturns();
}
Put it to the test
Time to interact with the CryptoKitties contract!
Let's make a function that gets the kitty genes from the contract:
1. Make a function called
feedOnKitty
. It will take 2 uint
parameters, _zombieId
and _kittyId
, and should be a public
function.2. The function should first declare a
uint
named kittyDna
.Note: In our
KittyInterface
, genes
is a uint256
— but if you remember back to lesson 1, uint
is an alias for uint256
— they're the same thing.3. The function should then call the
kittyContract.getKitty
function with _kittyId
and store genes
in kittyDna
. Remember — getKitty
returns a ton of variables. (10 to be exact — I'm nice, I counted them for you!). But all we care about is the last one, genes
. Count your commas carefully!4. Finally, the function should call
feedAndMultiply
, and pass it both _zombieId
and kittyDna
.function feedonKitty(uint _zombieId, uint _kittyId) public {
uint kittyDna;
(,,,,,,,,,kittyDna) = kittyContract.getKitty(_kittyId);
feedAndMultiply(_zombieId, kittyDna);
}
uint kittyDna;
(,,,,,,,,,kittyDna) = kittyContract.getKitty(_kittyId);
feedAndMultiply(_zombieId, kittyDna);
}
pragma solidity ^0.4.25;
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);
}
function feedonKitty(uint _zombieId, uint _kittyId) public {
uint kittyDna;
(,,,,,,,,,kittyDna) = kittyContract.getKitty(_kittyId);
feedAndMultiply(_zombieId, kittyDna);
}
}
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);
}
function feedonKitty(uint _zombieId, uint _kittyId) public {
uint kittyDna;
(,,,,,,,,,kittyDna) = kittyContract.getKitty(_kittyId);
feedAndMultiply(_zombieId, kittyDna);
}
}