Solidity for beginners

Xourse is now Blocksize find our most recent articles at: https://www.blocksize.com/blog

For most developers, learning how to use a new platform, language or framework will be a familiar task repeated dozens of times during their career. In total, more novel is to learn to develop a completely different paradigm. The decentralized network, the blockchain, and its more well-known application ‘bitcoin’ are not well known even among the technological community and the subtleties of how this technology is fundamentally different from what we have used before, it is certainly something new for all kinds of public

With this in mind, we will review the basics of solidity with some examples that will help us better understand this language

Solidity is a high-level language oriented to contracts. Its syntax is similar to that of JavaScript and is specifically focused on the Etehreum Virtual Machine (EVM). Solidity is typed in a static way and accepts, among other things, inheritances, libraries and complex types defined by the user.

We will start with a very simple structure where we will give a brief explanation of how to create a contract, pass a data through a function and receive them

pragma solidity^0.4.0;
contract SimpleStorage {
  uint storedData;
  function set(uint x) {
     storedData= x;
  }
  function get() constant returns (uint) {
   return storedData;
  }
}

The first line simply says that the source code has been written in version 0.4.0 of Solidity or in another fully compatible superior. This is to ensure that the contract is not going to behave differently with a newer version of the compiler. The reserved word pragma is called that way because, in general, the “pragmas” are instructions for the compiler that indicate how it should operate with the source code

A contract for Solidity is a collection of code (its functions) and data (its state) that lives in a specific address on the Ethereum blockchain. In the case of Ethereum, this is always the owner contract. And in this case, the set and get functions can be used to modify or query the value of the variable.

It simply allows anyone to store a number accessible to everyone without a (feasible) way to prevent the possibility of publishing this number. Of course, anyone could simply make a set call again with a different value and overwrite the initial number, but this number would always remain stored in the history of the blockchain. Later, we will see how to impose access restrictions so that only you can change the number.

Smart contracts

Contracts in Solidity are similar to the classes of object-oriented languages. Any contract can contain declarations of the type variables of state, functions, modifiers of function, events, structs and enums, although it is designed around the syntax of ECMAScript so that it is familiar to the existing web developers; unlike ECMAScript it has static typing and varied return types. In comparison with other EVM orientation languages of the time such as Serpent and Mutan, Solidity contained a number of important differences. Complex member variables were supported for contracts that include mappings and arbitrary-hierarchical structures. Contracts admit inheritance, including multiple inheritance, some examples will be detailed below for better understanding

pragma solidity^0.4.0;
contract SimpleStorage {
 uint storedData; // State variable
 // ...
 Function var(uint _storeData) constant returns(uint){
   storeData = _x // where _x is a local variable
 }
}

In this simple example we see two variables with the same name are declared unlike “_” this means that the variables are not state variables and can not be accessed from any part of the contract. There are other types of variables that you can access from any part of the contract. These are:

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)

Solidity is a static typing language, which means that each type of variable (state and local) has to be specified at compile time. Solidity provides several elementary types that can be combined to create more complex types. In addition, the types can interact with each other in expressions containing operators. For a quick reference list of operators, see Operator preference order.

Booleans

bool: The possible values are constants true and false.

Operators:

! (logicalnegation)
&& (logicalconjunction, “and”)
|| (logicaldisjunction, “or”)
== (equality)
!= (inequality)

Integers

int / uint: Signed and unsigned integers of various sizes. Keywords uint8 to uint256 in steps of 8 (unsigned of 8 up to 256 bits) and int8 to int256. uint and int are aliases for uint256 and int256, respectively.

Operators:

Comparisons: <=, <, ==, !=, >=, > (evaluate to bool)
Bit operators: &, |, ^ (bitwise exclusive or), ~ (bitwisenegation)
Arithmeticoperators: +, -, unary -, unary +, *, /, % (remainder), ** (exponentiation), << (leftshift), >> (rightshift)

Address

address: Holds a 20 byte value (size of anEthereumaddress). Address types also have members and serve as a base for all contracts.

String Literals

String literals are written with either double or single-quotes (“foo” or ‘bar’). They do not imply trailing zeros as in C; “foo” represents three bytes not four. As with integer literals, their type can vary, but they are implicitly convertible to bytes1, …, bytes32, if they fit, to bytes and to string.

Modifier

Modifiers are typically used in smart contracts to make sure that certain conditions are met before proceeding to executing the rest of the body of code in the method.

For example, modifier only Owner is often used to make sure that the caller of the method is the owner of the contract:

contract HelloWorldContract {
 string word = 'HelloWorld';
 address owner;
 function HelloWorldContract() {
  owner = msg.sender;
 }
 modifieronly Owner {
  if(owner != msg.sender) {
   revert();
  } else {
   _;
  }
 }
 function getWord() constant returns(string) {
  return word;
 }
 function setWord(stringnewWord) only Owner returns(string) {
  word = newWord;
  return 'You sucessfully changed the variable word';
 }
}

In the previous example you can see how to use modifier to block any entrance of data in the “setWord” function.

Input and output functions

Unlike JavaScript solidity has input and output functions these return a random number of parameters as output.

The input parameters are declared in the same way as the variables. As an exception, unused parameters may omit the name of the variable. For example, if we wanted our contract to accept a type of external calls with two integers, the code would look similar to this one:

contract Simple {
 function taker(uint _a, uint _b) {
 // do something with _a y _b.
 }
}

The output parameters can be declared with the same syntax after the reserved word returns. For example, suppose we want a function to have multiple output parameters, return (v0, v1, …, vn), it can be done in a single function. The number of components must be the same as the number of output parameters. Return two results: the sum and the product of two given values. Then, we would write a code like this:

contract Simple{
 function arithmetics(uint_a,uint_b)returns(uint o_sum,uint o_product) {
  o_sum=_a+_b;
  o_product=_a*_b;
  return(
    o_sum,
    o_product,
  );
 }
}

Control structures

Most of the control structures available in JavaScript are also in Solidity except switch and goto. This means that we have: if, else, while, do, for, break, continue, return,? :, with the usual semantics known from JavaScript.

Parentheses can not be omitted for conditionals, but the keys around the bodies of simple statements can be omitted.

Keep in mind that there is no conversion of types from non-boolean to boolean as there is in C and JavaScript, so if (1) {…} is not valid in Solidity.

Mappings

Mappings can be seen as hash tables that are virtually initialized since every possible class exists and is mapped to a value whose byte representation is all zeros: the default value of a type. Although the similarity ends here, the key data is not really stored in the mapping, only its keccak256 hash used to look up the value. Mappings are only allowed for state variables

In my experience the mapping was the most difficult when it comes to understanding solidity, so we are going to have a little more emphasis on them. In some cases when we see a mapping for the first time, many of us ask ourselves why we use them, how does it help us, to understand how it works, we will have the following example:

contract Crowdfunding {
 struct CampaignData {
  address recipient;
  uint contributed;
  uint goal;
  uint deadline;
  uint num_contributions;
  mapping(uint => Contribution) contributions;
 }
 struct Contribution {
  address contributor;
  uint amount;
 }
 uint nextCampaignId;
 mapping(uint256 => CampaignData) campaigns;
 // Start a new campaign.
 function start(address recipient, uint256 goal, uint256 deadline)                                      returns (uint id) {
  var campaign = campaigns[nextCampaignId];
  campaign.recipient = recipient;
  campaign.goal = goal;
  campaign.deadline = deadline;
  nextCampaignId ++;
  id = nextCampaignId;
 }
}

A mapping is used to structure value types, such as booleans, integers, addresses, and structs. It consists of two main parts: a _KeyType and a _ValueType; they appear in the following syntax:

mapping (_KeyType => _ValueType) mapName

the uint256 is the _KeyType and the CampaignData is the _ValueType.

Think of the _KeyType as the key you'll pass through a function to be returned a desired value, or _ValueType. By default, a mapping is initially empty, so a new _KeyType will first need to be mapped to a _ValueType.

The example contract’s start function handles 3 basic processes: (1) giving a _KeyType to a new _ValueType CampaignData struct; (2) populating the new CampaignData struct with variable values; and (3) procuring a new _KeyType nextCampaignID to be ready on deck for the next time the example contract's start function is called. This segments of the function can be dissected like so:

giving a _KeyType to a new _ValueType CampaignData struct:

var campaign = campaigns[nextCampaignId];

In this line, nextCampaignId is mapped as the _KeyType, and the new campaign struct is the _ValueType.

populating the new CampaignData struct with variable values

campaign.recipient = recipient;
campaign.goal = goal;
campaign.deadline = deadline

procuring a new _KeyType nextCampaignID for the next time the function is called:

nextCampaignId ++;

Using a mapping here is helpful because a mapping can store many _KeyTypes to _ValueTypes - in this case if there are many campaigns occurring at once they can each have their own campaignID. Each campaign having its own ID is powerful when calling for CampaignData in future functions.

Modifier payable

payable is a modifier that can be added to a function. It's impossible to have payable() as a function name as it is a reserved keyword. You may use payable only in addition to existing functions like:

function deposit() payable {};
function register(address sender) payable {};
function () payable {}

When someone transfers funds to your contract, the function with payable modifier executes automatically. Here is an example of a payable function.

contract token {
 function () payable {
 create(msg.sender);
}
function create(address _beneficiary) payable{
 uint256 amount = msg.value;
 /// your logic
 }
}