Solidity for Beginners : Writing your first Smart Contract
Tags: web3, blockchain, webdev, beginners
Published: 2022-11-14 05:55:00

So if you have been following this series, you already got the Solidity basics down.

It's time for you to become a Solidity Developer. 
Writing your first Smart Contract and earning tons of dollars!
<img src="https://media.giphy.com/media/KE7JUK6cRsn56PPyBA/giphy.gif" alt="penguin printing dollars"/>

Just kidding, it will take some time from here too.
But first,

## What is a Smart Contract?
🚨_Spoiler Alert_ : They are not really Smart, and they are *literally* not Contracts.

Smart contracts are basically programs written in a programming language and stored on a Computer Node(Blocks) that execute automatically(hence the word Smart).

But wait, don't all programs execute automatically? Yes, they do.

## How do we write a Smart Contract?
There are steps for doing anything. So we'll follow a simple set of steps.

## Step 1 : Building Trust
Blockchain is essentially a set of interactions, each costing a fees(cryptocurrency).
Do you give your money to anyone? (PS : If you do, I would love to have a cup of coffee from you 😉 ).
<img src="https://media.giphy.com/media/HgwCgxQ37MTN5dexFu/giphy.gif" alt="talking dollar bill"/>
No, you need to trust that person first. Also, you'll have to prevent people from copying your code and using it to deceive others.
 
Well, that's why need to include a license specifier at the top. 
You can use any open source licensing like : `MIT, Apache, GNU, etc` or `UNLICENSED` if you want to prevent people from copying your code.

Also, you need to specify the version of Solidity you are using.
For this we use the `pragma` directive.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
```

## Step 2 : Building blocks
Now that we have the trust, we start writing our Contract.
Today, we will try to build a Smart Contract that helps us book a Hotel Room.
```solidity
contract HotelRoom {
//code goes here
}
```

Let's see what does a Hotel Room have?
- **Occupancy** : A hotel room should either be Vacant or Occupied. So we will use an `enum` to check if the room is occupied or empty. 
- **Cost** : You cannot rent a room to someone without charging them some money right? Here, we will take 2 Ether for each room.
- **Owner** : Where will all the money💸 go? To you - that is the account that is hosting this contract.

So, now the contract will look like this : 
```solidity
contract HotelRoom {
    enum Status {
        Vacant, 
        Occupied
    }

    address payable public owner;
    Status public currentStatus;

    constructor(){
        owner = payable(msg.sender);
        currentStatus = Status.Vacant;
    }
}
```

We see there is a constructor function. If you are familiar to programming you know that constructors are used for initializing data.

Similarly, we are assigning the owner as the account address that is hosting the smart contract.

> Note : `msg` is a global variable that is like the `this` variable in other languages. It has various properties that refer to the calling object. Constructors in smart contracts are 🚨ONLY🚨 called during deployment. So, `msg.sender` is the account hosting the smart contract.

## Step 3 : Adding functionality
Now that we are ready with the basic setup, we will dive into the actual functionalities. 

There is only 1 thing to do : Book the hotel. 🌟
But the process is not simple.

Remember, we can book the room only if 2 conditions are met 👇: 
- Room is empty
- The person sends enough Ether to book the room.

We will check these conditions using modifiers. 
> Modifiers are conditions that are checked before running a function. 

Let's create our 2 modifiers for the above conditions.

```solidity
   //check if room is empty
    modifier onlyWhileVacant(){
        require(currentStatus == Status.Vacant, "Room Already Booked");
        _;
    }

    //check if ethers sent are enough
    modifier costs(uint _amount){
        require(msg.value >= _amount, "Not Enough Ether");
        _;
    }
```

`require` is a special function that checks if the first argument is true and returns the second(optional) argument if false.

But there are useless without a function to book the room, right?
<img src="https://media.giphy.com/media/W4WTSqR9SNdoCmqJou/giphy.gif" alt="mr. bean with eye roll"/>

The function is also simple : 
```solidity
   function book() payable public onlyWhileVacant costs(2 ether){

        currentStatus = Status.Occupied;

        (bool sent, bytes memory data) = owner.call{value : msg.value}("");
        require(true);

        emit Occupy(msg.sender, msg.value);
    }
```

You can see the modifiers being called in the first line itself.
But wait there is something new : `payable` and `emit`.

✅Payable is a keyword that specifies that a function or an address accepts payments.
Here, that will be 2 ethers.

But, what is emit.

## Step 4 : Finishing touches
We are almost there. Just a last thing. 
Yes, the room is booked. But, the smart contract knows it. 
What about the blockchain?

Well, for that we have events.

> An Event is a member of a smart contract that applications can subscribe and listen to. These are logged and stored into the blockchain for as long as the blockchain exists.

So, for a room to be booked, we need to make a log for that. This makes it a public record that the room was booked by the account for those many ethers.📝

The event would be : 
```solidity
event Occupy(address _occupant, uint _value);
```
And this event is emitted by the booking function.

There, you have created your first contract. 
<img src="https://media.giphy.com/media/QTAVEex4ANH1pcdg16/giphy.gif" alt="steve carrell clapping"/>
Head over to the Remix IDE and test it out.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;


contract HotelRoom{
    enum Status {
        Vacant, 
        Occupied
    }

    address payable public owner;
    Status public currentStatus;

    constructor(){
        owner = payable(msg.sender);
        currentStatus = Status.Vacant;
    }

    event Occupy(address _occupant, uint _value);

    modifier onlyWhileVacant(){
        require(currentStatus == Status.Vacant, "Room Already Booked");
        _;
    }

    modifier costs(uint _amount){
        require(msg.value >= _amount, "Not Enough Ether");
        _;
    }

    function book() payable public onlyWhileVacant costs(2 ether){

        currentStatus = Status.Occupied;

        (bool sent, bytes memory data) = owner.call{value : msg.value}("");
        require(true);

        emit Occupy(msg.sender, msg.value);
    }
}
```

Do comment and let me know if you want a series on a Web3 project development using React and Solidity. See you in the next one.👋

Till then follow me on 🍕🍕 [Twitter](https://twitter.com/thevinitguptaa) and [Github](https://github.com/thevinitgupta)