Learning Solidity as a Javascript Developer

To read more articles like this, visit my blog

Solidity is a programming language used for writing smart contracts on the Ethereum blockchain. This can be your entry point to the blockchain world.

If you are already a front-end javascript developer, then learning Solidity will be a piece of cake.

And today I am going to feed you that cake.

Let’s learn the basic solidity syntax in the next five minutes or so…

Data Types

Javascript is a dynamically typed language. This means we can basically declare anything using let and const .

let name = "Mohammad Faisal";
let age = 34;

So, you can see that in javascript, the variables take the data type dynamically.

But in solidity, we have some basic data types.

String

We can declare a string using the string keyword.

string name = "Mohammad Faisal";

Numbers

In Solidity, the number type is represented by uint256 type.

uint256 age = 34;

Now, Solidity represents numbers as uint256 (unsigned integer of 256 bits) because the Ethereum Virtual Machine (EVM) is a 256-bit machine.

It can process 256-bit numbers and operations on them natively. Therefore, using uint256 ensures that the EVM efficiently processes the numbers being used in smart contracts.

You can use uint as a replacement to uint256 .

// The following lines are equivalent
uint age = 34;
uint256 age = 34;

There are other types, such as uint8 , uint16 , etc. They can be used to reduce gas fees. But, they will also limit the number of numbers that can be represented.

Boolean

Declaring a boolean is straightforward. Just use the bool keyword

bool isHappy = false;

Address

In Solidity, the address type is a special type used to represent Ethereum addresses. This is something new for people outside of the blockchain.

address public owner;

In this case, the owner variable is declared as a public variable of type address .

The public keyword indicates that it can be accessed from outside the contract.

address payable recipient = 0x1234567890123456789012345678901234567890;

Here the recipient variable is a valid address.

Arrays

Declaring arrays is also super simple. Just add a suffix to the expected type array with [] .

To declare arrays of different types

uint[] numberArray =[1,2,3];
string[] stringArray = ["person 1" , "person 2"];

Now, arrays can have a fixed size,

uint[5] public myArray; // declares a fixed-size array with 5 elements
myArray[0] = 1; // assigns the value 1 to the first element of the array

Or it can have a dynamic size, Just like javascript.

uint[] public myDynamicArray; // declares a dynamic-size array
myDynamicArray.push(2); // adds the value 2 to the end of the array
myDynamicArray.push(3); // adds the value 3 to the end of the array

We even have the same properties and methods as javascript arrays like length , push() etc.

Declaring a multi-dimensional array is also very similar.

uint[3][2] public myMultiArray; // declares a 2-dimensional fixed-size array
myMultiArray[0][0] = 1; // assigns the value 1 to the first element of the first sub-array
myMultiArray[1][1] = 2; // assigns the value 2 to the second element of the second sub-array

Structs

Structs are like objects in javascript. We can declare a Person object like the following.

struct Person {
    string name;
    uint age;
    bool hasDriverLicense;
    }

We can create a struct and assign values to it in the same way as Javascript.

    // declares a variable of type Person
    Person public myPerson; 

    myPerson.name = "Alice"; 
    myPerson.age = 30; 
    myPerson.hasDriverLicense = true;

We can do it in a declarative way as well

Person memory p = Person("Bob", 25, false);

Pretty awesome right?

Mappings

Mappings are the same thing as Dictionary in other languages. The way we declare a mapping is

mapping (uint => string) public myMap;

Notice that we are declaring the types of the dictionary inside the () of the declaration.

The above code means,

The key of the dictionary will be a uint

And the value must be a string

So, now we can assign values like the following,

myMap[34] = "Name";

To delete a key from the mapings ,

delete myMap[34];

Now you may wonder why we have so much more flexibility in javascript. We can assign anything to anything.

Well, that’s actually a good thing and a bad thing. The strict nature of solidity makes the applications secure. This is a major priority for solidity language and Ethereum blockchain.

Loops

You can copy-paste a looping code from javascript, and it will pretty much work exactly the same in solidity.

To loop through an array of values and calculate the sum,

uint[] values = [1 , 2 ];

uint sum = 0;

for(uint i=0; i < names.length; i++){
  sum+= values[i];
 }

So you can see that the code looping syntax is exactly the same in both languages.

Functions

Declaring functions in Solidity is different than what we do in Javascript.

Following is a simple example. This function takes two numbers and returns the sum of them.

function add(uint a, uint b) public pure returns (uint) {
    return a + b;
}

Here is the breakdown

funciton — We declare that it’s a function. Same as javascript

add — The name of the function. Can be anything

(uint a, uint b) — Two input parameters to the function. There can be any number of them.

public -> The visibility of the function. The function can be accessed from anywhere.

pure -> This keyword means that we are not modifying anything.

returns (uint)-> We specify that we will return a value of type uint .

So now we are getting outside of our comfort zone. Let’s learn some new concepts in solidity.

Visibility Modifiers

We declared our function as public . But what does that mean?

A function can be called from many places. For example, inside the contract or outside the contract. The same goes for variables as well.

This visibility modifier controls and limits the visibility of a function or a variable.

Here are the available types.

1.public : Anyone can call it. The current or any other contract.

2.external : The function can only be called by other contracts.

3.internal : The function can only be called the current contract and any derived contracts.

4.private : Similar to internal The function can only be called the current contract, not by the derived contract.

What are function types?

Now one new thing we can see here is the keyword pure . There are mainly two types of functions in solidity.

1. pure function

This function modifier indicates that the function does not read or modify the contract's state.

It is used for functions that perform mathematical computations or other operations that do not require access to the contract's storage.

function add(uint a, uint b) public pure returns (uint) {
    return a + b;
}

In the above example, we are not reading or modifying anything. Just returning the sum of the function inputs.

2. View function

This function modifier indicates that the function does not modify the contract's state but may read data from the contract's storage.

It is used for functions that need to read data from the contract's state but do not modify it.

function getBalance(address account) public view returns (uint) {
    return balances[account];
}

Here we are reading from the balances array and accessing the value of the account balance. So it’s a view function.

3. Payable function

A payable function can receive either as part of a transaction. It allows the contract to receive payments and interact with external accounts.

Here’s an example of a payable function:

function buyTokens() public payable {
    // code to buy tokens
}

4. Construct a function

A constructor is a special function declared with the constructor keyword and is only executed once at the deployment of a contract.

    contract MyContract {
        uint myVar;

        constructor(uint initialVal) {
            myVar = initialVal;
        }
    }

Note that a contract can only have one constructor function, and the constructor function has the same name as the contract.

Modifiers

Modifiers are the like middlewares in javascript.

If you need to run the same logic over and over again before executing every function, then modifiers can help you with that.

Here is how you create one of the most common modifiers.

    modifier onlyOwner() {
        // Requires that the calling address is the owner of the contract.
        require(msg.sender == owner, "Not the owner");
        _;
    }

The above code checks if the caller of the function is the owner.

The msg is a global variable which can be accessed from anywhere. So don’t get confuesed

We can attach our modifier to a function

    // We attach our modifier onlyOwner 
    function doSomething(uint256 _number) public onlyOwner {
        // This assignment is only performed if the modifier passes

        // .. rest of the funciton code
    }

So now, when you call the doSomething function, first, the code inside the onlyOwner modifier will be run.

If the code passes, then the code of doSomething will execute.

This can reduce the amount of repeatable code in your application.

So. That was it. I hope you know Solidity's basics and are ready to write your first smart contract!

Have a wonderful day!

You can reach me via LinkedIn