lukeleeai
Published in

lukeleeai

CryptoZombies (1)— Solidity Basics

Solidity Basics

Define a function

A function looks like this:

function name(string memory _var1, uint _var2)
function name() public pure returns (uint)
function _name() private view

pure means we don’t access any states in the contract. view means we don’t update the state but only view it.

It’s a convention to put _ before private functions or function arguments.

You also have to specify which type you return. Note that you shouldn’t forget memory or other data area (storage, calldata) where the type is stored when defining a parameter for reference types. The reference types include string, struct, and array. Updating their value in the function changes the original value where as updating value types only change their copies.

Address

In Ethereum, there are accounts and each of them has its unique address. The function in a smart contract is never executed until someone calls it. We can use msg.sender to get that person’s address.

Mapping

You can create a map in Solidity.

contract Bank {
mapping (uint => address) public moneyToOwner;
mapping (address => uint) ownerToBalance;
function updateBalance(uint update) public {
ownerToBalance[msg.sender] += update;
}
}

Pretty straightforward.

Require

There’s a keyword equivalent to assert in Python.

function _generateRandomDna(string memory _name) private pure returns (uint) {
uint rand = uint(keccak256(abi.encodePacked(_name));
return rand % dnaModulus;
function createZombie(string memory _name) public {
require(ownerZombieCount[msg.sender] == 0); // LINE 1
uint randDna = _generateRandomDna(_name);
_createZombie(_name, randDna);
}

Look at the LINE 1 where it uses require. It raises an error if the logic statement doesn’t meet the condition. This way, we can ensure the code runs only when the condition we want is met.

Inheritance

Inheritance is pretty straightforward and you can do it just to make codes cleaner.

contract Animal {}
contract Cat is Animal {}

Data Area — Memory vs Storage vs

Internal vs External

  • public: any other functions can call it
  • private: only the functions inside the same contract can call it
  • external: only the functions outside the contract can call it
  • internal: only the functions inside the same contract and its inheritors can call it

Interface

We can use a code deployed on Ethereum by using an interface if we know its address on the network.

Let’s say that there is a contract like this:

contract LuckyNumber {   
mapping(address => uint) numbers;

function setNum(uint _num) public {
numbers[msg.sender] = _num;
}
function getNum(address _myAddress) public view returns (uint) {
return numbers[_myAddress];
}
}

In our code, we should declare an interface that can interact with the contract above. By doing so, we let our contract know what functions we used and how they look like.

contract NumberInterface {
function getNum(address _myAddress) public view returns (uint)
}

You just copy-paste the function you’d like to use.

To actually use the interface,

contract MyContract {
address NumberAddress = 0x3bsuijs3f2... # address of the contract on Ethereum
NumberInterface numberInterface = NumberInterface(NumberAddress);function doSomething() {
uint number = numberInterface.getNum(msg.sender);
}
}

Multiple return values

A function in Solidity has an interesting property: it can return multiple values.

function getUserInfo(string memory _userId) public view returns (
string memory username,
uint age
)
// to unpack multiple return values:
function unpackValues() {
uint age;
(, age) = getUserInfo(msg.sender); // alternatively, you can put a variable before , to store the value.}

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store