Solidity Fundamentals — CryptoZombies Lesson One and Two.

Connor Wiseman
Bitfwd
Published in
14 min readMay 2, 2018

What is Solidity?

The following series of articles are a write up on the LOOM network, solidity coding tutorials CryptoZombies. The tutorials cover all the fundamental aspects of building a gamified decentralised application (D-App) that can be deployed to the Ethereum network, and played by everyone with a ether address on all corners of the globe :)

Solidity is a relatively new programming language so there are not a lot of tutorials to help beginners learn how to code- decentralised style. The aim of these articles is to take you through the CryptoZombie tutorials step by step while providing knowledge of how all the code fits together and gels into one big unstoppable open source, smart contract.

Before we get started, I would like to give a quick introduction to Ethereum and smart contracts so everything is up to speed.

What is Ethereum?

Ethereum is a decentralised programmable blockchain protocol. The protocol achieves decentralisation by allowing the users of the network to sync a full copy of the blockchain onto their machine. Once the machine has synced a full copy of the blockchain it is then considered a node by the network.

https://blockgeeks.com/guides/ethereum/

What are Smart Contracts?

Programs(smart contracts) on Ethereum can be written in languages such as vyper, mutan, LLL, and serpant. However their own language Solidity is the most commonly used language that most smart contracts are written in.

Solidity is a contract-oriented, high-level language for implementing smart contracts. It was influenced by C++, Python and JavaScript and is designed to target the Ethereum Virtual Machine (EVM).

Smart contracts are pieces of code that are deployed to the Ethereum blockchain where they live forever and will always execute without hesitation. They are able to be used for many real world applications that support many different industries such as finance, ecommerce, real estate, supply-chain, medical, education and many more.

Note: These lesson recaps are creating for the intention of either learning CryptoZombies / Solidity or revising the fundamentals. Enjoy the apocalypse and please provide any feedback :) Also before you start the chapters in this article the numbers do not match the LOOM tutorials, chapter 1 in the article is always chapter 2 on the website.

Let’s get started — CryptoZombies Lesson 1 🚀

Chapters 1,2,3 and 4 — Contracts, variables and maths.

The first thing you need write when creating a smart contract is the compiler version. This should and will always be at the top on any smart contract in Ethereum. pragma solidity ^0.4.19tells the Ethereum Virtual Machine (EVM) what version of the compiler that the contract is to be used on. You can use a old compiler version such as 0.4.10with a contract that is written when the compiler version is above 0.4.10, you just have to put ^ before the the version. This will let the compiler know that the contract can be compiled with any version above ^0.4.10; .Once the pragma solidity compiler version is specified you can then start to create your smart contract. A contract name and state variables are the next thing to be coded into the contract. The contract name is self-explanatary and should always almost refer to the logic of the contract you are writing.

contract.example
contract.exercise

State variables are used through out the whole state of the contract and are also permanently stored in contract storage which means they are saved to the blockchain.

The state variables we want to give our zombies our a dna Lengthof 16 digits. And a dnaModulus of 10 to the power of 16. Both variables are uintswhich means that they are value types of only positive numbers.

http://solidity.readthedocs.io/en/v0.4.21/types.html

state variable.example
state variable.exercise

Chapters 5 and 6 — Structs && Arrays.

Once you have done the first few chapters of lesson one, you will come to chapter 5 struct. Structs allow you to code complex data types that hold multiple values. In this particular smart contract we are dealing with zombies and we will want our zombies to have names, dna etc. So for this we will use a struct. Everytime we create a new zombie we will refer to the Zombiestruct so that the zombie will have the nessacary values that it needs to be accepted as genuine in the DAPP. When we have defined the values for a zombie we will want to create a place for each zombie to be stored in the contract this will be an array[]. Array’s allow for storage of a collection of things in our case, these things are Zombies. Arrays are able to have an infinate size or a fixed size, a array with unlimited storage is called a dynamic array and a fixed size array is called a fixed array. (see syntax below for how both types are defined in a contract).

uint[10] -- This is how a "fixed" sized array would be written into a contract. A fixed sized array only allows for a certain number of objects to be stored into the array hense the name "fixed".uint[] -- this is how a dynamic array is written, dynamic arrays can hold a infinite number of objects, meaning they can just keep growing with no capacity limit.
struct.example
array.example

Chapter 7 — Function declarations.

When all this is done we can then start to add functions to our smart contract. A function declaration has a few parts to it 1: the name of the function, 2: parameters that need to be invovled with the function, 3: accessibility of the function (i.e public, private, internal, external) 4: The function may return a value or be modified so that only a certain person can use the function(more on this is later parts of the series). The first function we want to create in our zombie code is a createZombie function that will take 2 parameters. In the tutorial you will be asked to leave the body of the function empty for now, we will explain the body in the next paragraph. P.s don’t forget functions always need brackets {} for the body of the function to go in too.

function.example
function.excercise

Chapter 8 — Working with structs and arrays.

Now we can start to use the struct and array we coded in the first couple of chapters to build out the body of our function. The first line of the function should push a new zombie into the zombies array while taking both the parameters _name, _dna with it to be stored against the zombie that will created when the function is called.

array.example
array.exercise

Chapter 9 Public/Private functions.

You will then be asked to make the createZombie function private so that the function is only callable from within another function in our contract. By default functions are public which means that they can be called by anyone or any contract globally on the Ethereum network. And this is not good for our game as anyone would be able to create a zombie even if they are not playing the game.

private function.example
private function.exercise

Chapter 10 — More on functions.

In this chapter will be asked to create a another function _generateRandomDna and pass it one parameter _str (notice that function parameters always use a underscore this is so they are noticeably different from globally declared parameters such as state variables). This function will also be marked as view as it will view some of our contracts variables but not modify them. Also the function will return a uint so once you have defined it as view you should then put the return statement (NOTE: that returns on a function are always put after the parameters and the type of useability of the function).

function.exercise

Chapter 11 — Kecca256 && typecasting.

In the body of the _generateRandomDna function we will start to make use of some of Ethereum’s hashing functionality with keccak256 which is a version of a SHA3 hashing. It will give you a 256bit hash which will be used as the zombies DNA. You will have to store the hash of keccak256 in a uint variable called rand while also passing the parameter _str. Don’t forget the function has a return statement so the last line of the function will return rand divided by dnaModulus.

typecasting.example (hash’s are derived from the “string” inputs)
typecasting.exercise

Chapter 12 — Putting it all together.

If you’re wondering how this all fits together with functions being private and only viewing data from the smart contract, dont worry your about to experience the magic of solidity first hand. Chapter 12 will have you create a function createRandomZombie:) which is public and will only take one parameter _name . In the first line of the function you will need to create a uint variable called randDna and pass it the _generateRandomDna function with _name as a parameter. Then the next line should call the _createZombie function and use the parameters _name, randDna . This will allow for you to specify a name for your zombie while getting the 256bit hash produced by the kecca256 implementation on _generateRandomDna function for the zombie’s dna. Once you have completed chapter 12 theres just one more important peice of code which is missing and is one of the main properties that a blockchain offers to it’s users. #TIMESTAMPING.

Chapter 13 — Events.

Events are a very important part of solidity as they can listen for when things are happening within the code and, when a event is called, it is logged on the blockchain with a timestamp and own tx hash. Once a event is called in any smart contract in Ethereum it will be saved to the blockchain where it is immutable and can not be change’d or alterd in way that will invalidate the event. This allows for major transparency in what is happening within smart contracts and what time the action was carried out.

You will be asked to define a event at the top of your smart contract, and pass it in three parameters zombieId, _name, _dna. These parameters will also be logged on the blockchain when the event is called. For the event to be functional we will have to also change a little bit of the code in the _createZombie function (line 18) where we pushed the new zombie into the array. You will have to store zombies.push in a uint id, once you have created the new variable you can then fire the NewZombie event in the line below. So that whenever the _createZombie function is called it will also create a new event on the blockchain that a zombie was created.

event.example
event.exercise
event.exercise

Conclusion:

Now you hopefully you have succesfully completed lesson of the cryptoZombies tutorials and have the basic knowledge of how to code a simple smart contract that allows you to create a value and concatenate variables to that value. You have also learned a simple way of creating and auditing a trail of values being created through the form of an event.

Please read on for lesson 2 and lets start getting our zombies to feed on other life forms.

Here is the code for the Lesson 1

https://github.com/bitfwdcommunity/CryptoZombies-Tutorials

CryptoZombies Lesson 2

Awesome… Now that you have gone through Lesson 1, we will be moving onto more cool fundamentals of Solidity. In Lesson 2, we will be learning how to allow our zombies to start ‘feeding’ on other lifeforms.

#LetZombiesBeZombies.🧟‍

This means that we will be creating a zombieFeeding contract to write the conditions that allow our zombies to feed and grow.

Let’s get started!

Chapter 1: Mappings and addresses

Addresses

As we know, we all have our own bank accounts. They have a certain sets of numbers which are exclusive identifies to us. That is what an ‘address’ is.

The Ethereum blockchain is made up of accounts, which you can think of like bank accounts. An account has a balance of Ether (the currency used on the Ethereum blockchain), and you can send and receive Ether payments to other accounts, just like your bank account can wire transfer money to other bank accounts.

Each account has an address, which you can think of like a bank account number. It's a unique identifier that points to that account, and it looks like this: 0x78079fd6d84e05AaB7BBb8990B656a9Dd1D681B1

Overall it is an address for a specific user or smart contract. You will be interacting with addresses (also know as public keys) to send and receive ether, and even interact with smart contracts.

Mapping

Once again, structs are data structure that lists all the variables under one block. Arrays are the collection of objects that are stored away systematically.

Mapping is another way to store data in Solidity and are similar to structs and arrays.

mapping.example

Try the exercise provided.

mapping.exercise

Here you would have created a mapping structure of keeping track of the address that owns the zombie(zombieToOwner) and the other for how many zombies the owner has (ownerZombieCount).

Chapter 2: Msg. sender

Now we want to update one of our functions _createZombie by allowing it to interact with the addresses that we declared. For that we will be using msg.sender which is quite an important global variable in Solidity development. A global variable is one that is visible on the blockchain and called be called anytime throughout the code you write.

The example they provide shows you what happens with the msg.sender variable through two functions parameters.

Here the function setMyNumber stores the uint of _myNumber into the favouriteNumbber[msg.sender] variable. After this is stored, it is called in the function whatIsMyNumber and returned.

msg.sender Example

Now we will try their exercise they provided. We will be trying to update the zombieToOwner mapping with the id we defined earlier. Then increase the ownerZombieCount whilst updating the mapping data structure.

msg.sender exercise.

Chapter 3: Require

Now with our createRandomZombie function, we want to ensure that an unlimited army of zombies are not called. So what we want to do is put a parameter or boundary using require .

Require statements allow you to check if a value is of a certain amount, stored in a data structure or the function is being called by the correct address.

With the below example, the function ‘requires’ the string to be “Vitalik” or it will exit. If the input is correctly understand as “Vitalik”, the function will return “Hi”.

require example.

Now, let’s use the require function to put a parameter of ownerZombieCount mapping to be set to 0 so we don’t have unlimited zombies.

require exercise

Chapter 4: Inheritance

Writing all this code can be tiring and you don’t want to write it under one specific contract constructor…. So what Solidity let’s you do is inherit multiple contracts within your code which means you can separate your contract code.

Below, we see BabyDoge inherit the contract Doge. It simply makes things much easier to organise and manage.

Inheritance example

Now you will attempt to inherit the ZombieFactory contract into a new ZombieFeeding contract.

Inheritance exercise

Chapter 5: Import

Import is the next step when looking at organising and having clean code. import allows you to have access to multiple files in your folder. It is very simple :) Just be careful of the syntax around the file name.

import example
import exercise

Chapter 6: Storage vs. Memory

Where I personally had some problems, maybe easier for some of you guys…

As per their explanation, storage refers to the variables stored permanently on the blockchain whereas memory refers to variables that are stored temporarily and are erased between external function calls.

Storage and Memory example

Now in the exercise, you will be setting parameters around require and then allocating storage on the Blockchain through our Zombie arrays.

Storage and memory.exercise

Chapter 7: ZombieDna

This chapter has no new learnings, but will focus on enhancing our feedAndMultiply function with further reiterations to the creation of the newDna. The below example demonstrates such instances of being able to create a newDna id.

function.example

Chapter 8: Function Visibility — Internal and External

Previously we saw that we have public and private calls for our functions. This is self-explanatory to how visible the code is to external stakeholders. However we are going to introduce two new ones internal and external.

  • Internal is the same as private, except it can be called by inherited contracts
  • External is the same as public except it can only be called outside the contract
Inheritance.example

Chapter 9 and 10 : Interacting with other contracts

In the last chapter, we learned how to use the function visibility calls (public, private, internal and external) and now we want to take that a step further and inherit and interact with the other contracts on the blockchain. This is done through an interface. As per below example. we have set up the NumberInterface to be able to interact with the functions we created in the LuckyNumber contract.

interaction.example
interaction.example
interaction.exercise

Chapter 11: Handling Multiple Returns

As our contracts and functions become more advanced, we have to be able to handle multiple returns for different variables so by following the logic below you will be able to understand how we can process these multiple return functions.

Chapter 12: If Statements

Fundamental to coding in any language is the use case of if statements to be able to assist with our logical reasoning. In the example provided you are able to check IF a certain conditional statement occurs in the function, then perform another action. It’s really really useful and cool :)

Finished !!! 🎉🎉🎉🎉

Congratulations for making it to the end of Lesson 2 where you covered some of the fundamentals of Solidity programming. We hope you are enjoying the tutorials so far. Dont forget to post your code into the online solidity compiler called remix to play with and modifiy it if you wish.

https://remix.ethereum.org/

Please don’t forget to give us a clap for CryptoZombie luck 👏👏👏👏

--

--

Connor Wiseman
Bitfwd
Writer for

Blockchain architect — interested in decentralised solutions that remove the currently centralised middlemen of many industries.