Learn Solidity Programming By Examples - Part 1

Learn Solidity Programming By Examples - Part 1

A Programming Language To Write EVM (Ethereum Virtual Machine) Smart Contracts

Learn Solidity Programming By Examples - Part 1

Hello World! Today we are going to be learning about solidity, a programming language to write our ethereum smart contracts. You’ll learn Solidity’s main language constructs in a more structured way and develop a progressively deeper understanding of the language. This is the first part in this series.

What can Solidity do?

Smart contracts power the Ethereum ecosystem and have enabled many great projects since 2015. The use cases include:

  • Non Fungible Tokens
  • Prediction Markets & Real Estate collateral
  • Decentralized Finance: Stablecoins, Lending, Derivatives, and much more.

    EVM Contract Languages


Before diving into Solidity, let’s take a little step back and explore briefly some alternative EVM languages. Solidity isn’t the only EVM high-level language for writing contracts. Although it’s the most popular option among Ethereum developers, mainly because it’s frequently upgraded, well maintained, and recommended in the official Ethereum documentation, other alternatives exist, namely LLL, Serpent, and Viper. Let’s see what these languages look like and when it would make sense to use them instead of Solidity.

LLL

LLL, whose acronym stands for lovely little language, is a Lisp-like language (which LLL also stands for) that provides low-level functions close to the EVM opcodes and simple control structures (such as for, if, and so on). These functions allow you to write low-level contract code without having to resort to handwriting EVM assembly. If you’ve ever seen Lisp code or you’re familiar with Clojure, you’ll recognize the distinctive prefix notation and heavy parentheses used in the following LLL listing:

(seq 1
 (def 'value 0x00) 2
 (def 'dummy 0xbc23ecab) 3
 (returnlll 4
 (function dummy 5
 (seq
 (mstore value(calldataload 0)) 6
 (return value 32))))) 7
  • 1 Instructs the LLL compiler to evaluate expressions below this line in order
  • 2 Declares a variable named value at memory location 0x00
  • 3 Declares a function called dummy at memory location 0xbc23ecab
  • 4 Defines a macro in the LLL compiler to return the code below it
  • 5 Starts defining the function ‘dummy’
  • 6 Reads the location 0 of the data passed in when calling the function (call data) and stores it in a variable named value
  • 7 Returns 32 bytes from the variable value

This is roughly equivalent to the following Solidity code:

contract Dummy {
 function dummy(bytes32 _value) returns (bytes32) {
 return _value;
 } 
}

Strictly speaking, these two pieces of code aren’t entirely equivalent because the LLL code doesn’t check the function signature or prevent Ether transfer, among other things.

LLL was the first EVM language that the Ethereum core team provided because, given the similarity between how the stack-based Lisp language and the EVM work, it allowed them to deliver it more quickly than any other language. Currently, the main benefit of using LLL would be to get a more compact bytecode, which might be cheaper to run.

After the first public release of the platform, the focus shifted to higher-level languages that would provide a simpler syntax to contract developers. Serpent was the first to be developed.

Serpent and Viper

Serpent is a Python-like language that was popular for a few months after its release. It was praised for its minimalistic philosophy and for offering the efficiency of a low-level language through simple syntax.

If you’re familiar with Python, these are the main limitations you’ll find in Serpent:

  • It doesn’t provide list comprehensions (elegant syntax to create lists from existing sequences and lists) and complex data structures.

  • It doesn’t support first-class functions, therefore limiting your ability to use a functional programming style.

Here is an example of a Serpent code:

def init():
     self.storage[msg.sender] = 10000
def balance_query(address):
     return(self.storage[address])
def transfer(to, amount):
     if self.storage[msg.sender] >= amount:
         self.storage[msg.sender] -= amount
         self.storage[to] += amount

Even if you don’t know Python, you should be able to understand this code. The only variable you might be confused about is self.storage. This is a dictionary containing the contract state. It holds the equivalent of all the state variables in Solidity.

Serpent’s popularity began to fade when the focus shifted to Solidity, which programmers started to maintain more regularly. A new experimental Python-like language, called Viper, is currently being researched and is publicly available on GitHub. Its aim is to provide a more extended type set than that offered by Serpent and easier bound and overflow checking on arithmetic operations and arrays. It will also allow you to write first-class functions, although with some limitations, and therefore write more functional code. The main benefit of using Viper is to get more compact and safer bytecode than you’d get from compiling Solidity.

Now that you have a better understanding of EVM languages, let’s move back to Solidity. Enough of illustration. Now if you are new to solidity programming, we will be using the online solidity development editor to write our smart contracts.

What is remix? Remix IDE allows developing, deploying and administering smart contracts for Ethereum like blockchains. It can also be used as a learning platform. Visit Remix - Ethereum IDE

image.png Remix IDE

Creating New Workspace

Before we start writing our smart contracts using remix, we need to create a workspace so we can keep track and also manage our smart contracts in an organized manner.

In the workspaces, click on the + icon to create a new workspace, in my case i have names it as workspace_part1.

image.png Creating Workspace

Creating New SOl File

After creating our workspace, the next thing we will have to do is to create our solidity file. Follow the steps below:

  • Click on the contract folder
  • Click on Create New FIle
  • Type a new name for your file e.g (partone.sol).
  • Click Ok to create the file.

Always remember to add .sol extension whenever you are creating a new solidity file. Also make sure your contract file name begins with a capital letter.

Paste in the code below in your newly created solidity file. In my case _Partone.sol

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0; 

/**
 * @Learning solidity be examples
 * @Ernest Obot
 */
contract Partone {


}

Let me explain what is going on in the code above:

// SPDX-License-Identifier: GPL-3.0

The first line tells you that the source code is licensed under the GPL version 3.0. Machine-readable license specifiers are important in a setting where publishing the source code is the default.

pragma solidity >=0.7.0 <0.9.0;

The next line specifies that the source code is written for Solidity version 0.7.0, or a newer version of the language up to, but not including version 0.9.0. This is to ensure that the contract is not compilable with a new (breaking) compiler version, where it could behave differently.

/**
 * @Learning solidity be examples
 * @Ernest Obot
 */
contract Partone {

}

A contract in the sense of Solidity is a collection of code (its functions) and data (its state) that resides at a specific address on the Ethereum blockchain. So we name our contract Partone. Each contract can contain declarations of State Variables, Functions, Function Modifiers, Events, Errors, Struct Types and Enum Types. Furthermore, contracts can inherit from other contracts.

Solidity Primitive Data Types

A primitive data type variable is stored on the EVM stack, which allocates a single memory space to hold its value. When a value type variable is assigned to another variable or passed to a function as a parameter, its value is copied into a new and separate instance of the variable. Consequently, any change in the value of the assigned variable doesn’t affect the value of the original variable. Primitive data type variable includes the following:

  • Boolean
  • Integer Types (int or uint)
  • Byte
  • Address

Boolean

Variables declared as bool can have either a true or false value; for example

bool isComplete = false;

Logical expressions must resolve to true or false, so trying to use integer values of 0 and 1 for false and true, as in JavaScript, C, or C++, isn’t allowed in Solidity.

Integer Types

You can declare integer variables either as int (signed) or uint (unsigned). You also can specify an exact size, ranging from 8 to 256 bits, in multiples of 8. For example, int32 means signed 32-bit integer, and uint128 means unsigned 128-bit integer. If you don’t specify a size, it’s set to 256 bits.

Assignments between variables of different integer types is possible only if it’s meaningful, which generally means the type of the receiving variable is less restrictive or is larger. If that’s the case, an implicit conversion happens. The contract shown here, which you can enter into the Remix editor, shows some examples of valid and invalid assignments leading to implicit conversions when successful:

contract Partone {
    int256 bigNumber = 150000000000;

    int32 mediumNegativeNumber = -450000;

    uint16 smallPositiveNumber = 15678;

     int16 newSmallNumber = bigNumber; 1

     uint64 newMediumPositiveNumber = mediumNegativeNumber; 2
     uint32 public newMediumNumber = smallPositiveNumber; 3
     int256 public newBigNumber = mediumNegativeNumber; 4
 }
  • 1 Compile error because newSmallNumber is too small to contain bigNumber
  • 2 Compiler error because uint64 can only hold positive numbers
  • 3 smallPositiveNumber is implicitly converted from uint16 to uint32; newMediumNumber =15,678
  • 4 mediumNegativeNumber is implicitly converted from int32 to int256; newBigNumber =-450,000

To compile this code, remove the two lines that are causing errors, such as

TypeError: type int256 isn’t implicitly convertible to expected type int16

When an implicit conversion isn’t allowed, it’s still possible to perform explicit conversions. In such cases, it’s your responsibility to make sure the conversion is meaningful to your logic. To see an example of explicit conversions in action, add the following two lines to the IntConversions contract:

  int16 public newSmallNumber = int16(bigNumber); 1
  uint64 public newMediumPositiveNumber = uint64(mediumNegativeNumber); 2
  • 1 The explicit conversion and assignment are successful, but newSmallNumber = 23,552.
  • 2 The explicit conversion and assignment are successful, but newMediumPositiveNumber = 18,446,744,073,709,101,616.

Bytes

You can declare byte arrays of a fixed size with a size ranging from 1 to 32—for example, bytes8 or bytes12. By itself, byte is an array of a single byte and is equivalent to bytes1.

contract Partone {
      byte8 public newbyt = 5;
}

If no size is specified, bytes declares a dynamic size byte array, which is a reference type.

Address

The address type comes in two flavours, which are largely identical:

  • address: Holds a 20 byte value (size of an Ethereum address).
  • address payable: Same as address, but with the additional members transfer and send.

The idea behind this distinction is that address payable is an address you can send Ether to, while a plain address cannot be sent Ether.

Address objects, are generally declared using a literal containing up to 40 hexadecimal digits prefixed by 0x, hold 20 bytes; for example:

contract Partone {
      address ownerAddress = 0x10abb5EfEcdC09581f8b7cb95791FE2936790b4E;
}

Mostly used for storing ethereum or custom token addresses.

Conclusion

This brings us to the end of our Part 1 in learning solidity programming. In the next next part we will dive more into the world of solidity and write smart contract from simple to rubust. Please consider to like this content if you find it super useful. If you need any help please let me know in the comment section.

Thank you guys!

Would you like to buy me a coffee, You can do it here .

Visit my blog and subscribe to my newsletter to get posts right to your mailbox. Megtrix Publications

My Website