Solidity Language for Ethereum

Carlos Gonzalez Juarez
7 min readAug 19, 2017

--

In this guide, we are going to talk about this language for developing Ethereum smart-contracts. We are not going to go deep through the Ethereum platform in here since it goes out of the scope.

Here you have some of the key characteristics of the new language.

  • High level language
  • Similar to Javascript
  • ”Classes” are called contracts in ethereum world
  • It may have functions
  • It may have events

Just as a remember you can test the contract in the Browser. And deploy them in mist the official wallet.

Contracts

Inside a solidity file, you can have as many contracts as you need, just write them down of each other as you can see now.

contract SimpleDapp {   
}
contract SimpleDappNew {

}

Also, we have constructors as any other language and it will be called once the contract is deployed. To create one, just call a function with the same name as the contract. You can add variables to the constructor and everything, don’t be shy!

In solidity, it is possible to interact from one contract to another, to do so, we have to possibilities:

  1. Call another instance of other contract
  2. Create a new instance of a contract

You can see both examples in the following code:

contract SomeOtherSimpleDapp{
//This will be a reference form the other instance of the class
SimpleDapp simpleDapp;

//This will be a NEW instance of the contract
SimpleDapp newInstanceOfSimpleDapp;

function SomeOtherSimpleDapp(address whereIsMyOtherContract){
simpleDapp = SimpleDapp(whereIsMyOtherContract);
newInstanceOfSimpleDapp = new SimpleDapp();
}

function getSimpleDappSomeVar() constant returns (uint) {
return simpleDapp.getSomeVar();
}

function getNewInstanceOfSimpleDappSomeVar() constant returns (uint) {
return newInstanceOfSimpleDapp.getSomeVar();
}
}

As you may see, we are using functions up there, this takes us to the next point: functions.

Functions

Primarily we have two basic kind of functions in solidity, the constant ones and the ones who modify the chain. The first ones allows us to check for data without having to pay with our gas, to do so, we just have to have to add the constant word to the function as we will see now.

//This is not a constant function, so we will pay for it.
function setSomeVar(uint myVar){
someVar = myVar;
}

//This is a constant function.
function getSomeVar() constant returns (uint){
return someVar;
}

As we can see, you have to add the type of the variable you are returning, not as Javascript does. Off course, you can call functions inside other functions, but if any of them is not constant, you will have to pay for it. Here is an example:

contract Child{
uint8 public age = 1;

function birthDay() { <-- gas used: 26933
age = age + 1;
}

function nextYearIllBe() constant returns (uint8){ <-- gas used: 0
return age + 1;
}


function newBirthDay() { <-- gas used 26991
age = nextYearIllBe();
}
}

Control structures

The control structures don’t differ too much from Javascript and the normal ones works exactly the same way. Just in case you want more information you can read the doc here: Control Structures

Inheritance

The inheritance in Solidity works very similar as how Python uses it as its documentation says. When a contract inherits from multiple contracts, only a single contract is created on the blockchain, and the code from all the base contracts is copied into the created contract.

contract owned {
function owned() { owner = msg.sender; }
address owner;
}


// Use "is" to derive from another contract. Derived
// contracts can access all non-private members including
// internal functions and state variables. These cannot be
// accessed externally via `this`, though.
contract mortal is owned {
function kill() {
if (msg.sender == owner) selfdestruct(owner);
}
}

Multiple inheritance is also possible, just write coma-separated the contracts that will be the father. If one contract inherited more than one time from different contracts (like using owned and mortal as fathers), only one object will be instantiated for both.

Beyond than this, we can implement as well interfaces really easily. Any contract with a function without body will be considered as an interface by the compiler. You can override a function just writing it again in the child contract.

If a constructor takes an argument, it needs to be provided in the header:

contract PriceFeed is owned, mortal, named("GoldFeed") {}

Libraries

Libraries are similar to contracts, but their purpose is that they are deployed only once at a specific address and their code is reused in the contracts. It can only access state variables of the calling contract if they are explicitly supplied. Libraries are far more complex and I won’t explain them in an initial post, but be sure to check out the official documentation official documentation if you need more information.

Types

This section will be easy even when you come from Javascript. Solidity changes the way to create variables in order to have safe declaration of them. The list of basic types is the next:

  • bool
  • uint
  • uint8 up to uint256
  • bytes
  • bytes32
  • string

The bad news is that Fixed Point Numbers are not fully implemented yet, as the wiki says: “Fixed point numbers are not fully supported by Solidity yet. They can be declared, but cannot be assigned to or from.

There are also other different types, and very useful in Solidity, one of them is the address which is a byte var with a length of 20. Also, this address have to members:

  • Balance: Shows the amount of money that address has.
  • Send(): Allows us to send money to that direction. You need to pass an integer inside the function, so it knows how much it should send. You always must to be sure to check the value that send() returns, because it can return False and the operation won’t happen. This may happen because it runs out of gas for example.

Enums are quite easy to work with and allows us to create vars that have to specific values. Internally, they work as integers, so it won’t consume too much work for the program. Also, because of this reason, when you write a function that returns an enum, it will be converted to an uint and it return you the number. The good part is that you don’t have to bother about it, since the enums are integers internally and will work perfectly. Here is an example:

enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill }
ActionChoices choice;
ActionChoices constant defaultChoice = ActionChoices.GoStraight;

Data Location

You may have thought that we finished the types very fast and that is true, but is just because we need to explain some other things before going to complex data.

Every complex type, i.e. arrays and structs, has an additional annotation, the “data location”, about whether it is stored in memory or in storage.

We will use in memory variables when we return something from a function and storage variables when we create a normal variable in the program.

To quickly understand the difference, basically we can say that when we use storage and memories variables together in an assignment, it will create a copy of the memory var and will assign to the storage variable. But when we assign an storage variable to an another storage variable, we are not creating another copy, we just send the reference of it.

By default, the assignation is done by the compiler, but we can change the type of data location manually in case we want to. So in case we want to return the reference of a variable in a function we can:

function g(uint[] storage storageArray) internal {}

Arrays

Arrays can have a compile-time fixed size or they can be dynamic. For storage arrays, the element type can be arbitrary (i.e. also other arrays, mappings or structs). For memory arrays, it cannot be a mapping and has to be an ABI type if it is an argument of a publicly-visible function.

Creating arrays with variable length in memory can be done using the new keyword and it is not possible to resize memory arrays.

//In memory arrays
uint[] memory a = new uint[](7);
bytes memory b = new bytes(len);
//In storage array
uint[] x;

Arrays have two members:

  • length: It can change the size of the array.
  • push: To append elements to the end of the array, and will return the new length of the it.

Structs

These types work exactly as in other languages and help us to define new types for our contracts. To define one:

struct Campaign {
address beneficiary;
uint fundingGoal;
uint numFunders;
uint amount;
}

Global variables

When we talk about ethers, sometimes is a big unit to send or to work with, because of that, solidity provides us other units as Wei or Szabo. You can use this link to check them out: Ether unit converter.

So you can use those units in your contracts to make the works easier for you.

Further than that, you can use also other time constants as years, week, minute, seconds…

Also some other functions as:

block.blockhash(uint blockNumber) returns (bytes32): hash of the given block — only works for 256 most recent blocks excluding current

block.coinbase (address): current block miner’s address

block.difficulty (uint): current block difficulty

block.gaslimit (uint): current block gaslimit

block.number (uint): current block number

block.timestamp (uint): current block timestamp as seconds since unix epoch

msg.data (bytes): complete calldata

msg.gas (uint): remaining gas

msg.sender (address): sender of the message (current call)

msg.sig (bytes4): first four bytes of the calldata (i.e. function identifier)

msg.value (uint): number of wei sent with the message

now (uint): current block timestamp (alias for block.timestamp)

tx.gasprice (uint): gas price of the transaction

tx.origin (address): sender of the transaction (full call chain)

From all of those, the one I use the most is probably msg.

Another useful thing is the mathematical functions. The most important functions are:

sha256(...) returns (bytes32)
sha3(...) returns (bytes32)

The last function I want to talk about is:

selfdestruct(address recipient)

Which allows us to destroy the current contract and return the funds to its owner.

This is the end of the first solidity guide where you have learned a lot about it, but you should program in it in order to learn it. In next lessons we will check out some examples.

--

--