Lab 2: First steps with solidity
================================

Goals
-----

As explained in the previous lecture, smart-contracts on Ethereum are developped 
using the Solidity programming language. 
We are going to learn the basic of this programming language by developing a
few contracts. 

Remix IDE
^^^^^^^^^
If you've already have some programming experience, you may have used an IDE.
An *Integreated Development Environment* is the main tool developers use to 
write their code. It has syntax highlighting, can detect simple code error,
can often be used to compile and run the code... 

Think of a text editor on steroid!

To develop with Solidity, we are going to use an online IDE called *Remix*.
It's online so you don't have to download anything! It can be found here: https://remix.ethereum.org

Our first contract
^^^^^^^^^^^^^^^^^^
We are going here to create our first smart contract! This contract can store informations 
related to a solar panel. OK, this is a very simple example but we need to start somewhere!

This is the code of our little contract:
    
.. code-block:: solidity

    // SPDX-License-Identifier: GPL-3.0

    pragma solidity ^0.8.0;

    //contract name is VirtualPowerPlant
    contract VirtualPowerPlant {

        //create two variables.  A string and an integer

        // A name identifying our virtual power plant
        string private name;
        // The capacity of our power plant in kWh
        uint private capacity;

        // change the name
        function setName(string memory newName) public {
            name = newName;
        }

        // return the name
        function getName () public view returns (string memory) {
            return name;
        }
        
        // change the capacity
        function setCapacity(uint newCapacity) public {
            capacity = newCapacity;
            
        }

        // return the capacity
        function getCapacity () public view returns (uint) {
            return capacity;
        }
        
    }

If you've already done some python or any programing, some aspects of this program 
may seem familiar. Others may seems new. By the end of this lab session, everything
should be crystal clear for you!

Explanations
************
This program defines a contract called **VirtualPowerPlant** that manipulate two informations:

- name, that is some text (called a *string* in programming)
- capacity, that is a positive number (here called a *uint*, meaning *unsigned integer*)

Those variables should be considered **global**. Once the contract is deployed, different calls may end up modifying those
variables but they always remain the same for **everyone**.

And defines four functions:

- setName: change the name to the one provided as a parameter
- getName: return the name stored
- setCapacity: change the capacity of the power plant to the one provided as a parameter
- getCapacity: return the capacity of our power plant

You will notice that Solidity have small particularities in their function syntax. Functions have:

* A list of parameters with their `types <https://docs.soliditylang.org/en/develop/types.html>`_
* A `visibility <https://docs.soliditylang.org/en/develop/contracts.html#function-visibility>`_ (to keep things simple we only consider those two possibilities)
    * public: this function can be call by external users and from other functions inside the contract
    * private: this function can only be called from within this contract
* A `state mutability <https://docs.soliditylang.org/en/develop/contracts.html#state-mutability>`_ definition
    * view: this function can read internal data but will not modify anything
    * pure: this function will neither read nor modify any internal data 
* A list of returned values

.. tip:: 
    
    Remember that everything between two braces is should be considered as 
    one unit. For example, everything between **contract VirtualPowerPlant {** and **}** 
    belong to the contract's definition. You shouldn't have anything after the **}**.

Getting started with Remix
**************************

In a web browser, go to https://remix.ethereum.org/ to open the online remix IDE. You should have a default workspace 
with three default contracts. Feel free to have a look and try to understand what each of those contract does. Some things
may not make sense now but we should be able to understand the most of it by the end of this course.

No need to understand the files in the *script* directory, it's only used by remix for deployment. 

.. admonition:: Task

        Create a new workspace using the default settings, and remove existing contracts (the files ending with *.sol*). 

        Create a new file for your contract (*vpp.sol*) and paste the contract.

Compiling
*********

Before we need to deploy and execute our contract, we need to compile it (transform it to machine code that can actually be 
executed). 

With Remix, compilation is managed in the "Solidity compiler" window. You need to click first on your contract files, then 
click on the compiler window and click on the **Compile vpp.sol**. 

Deployment
**********

To deploy our contract, we need to go on the "Deploy & run transactions" window. Select the **Ganache provider** as the 
deployment environment (you may need to provide the URL address where Remix can contact Ganache. This address is displayed
on top of Ganache and called **RPC server**). 

Select then your compiled contract and click on deploy. This should create a new block with a new transaction on Ganache. 
Go check it. Notice how deployment has created a new address for your contract. In Ethereum, a contract is just like 
any account, it has a balance in Ether and an address used to call and execute it. 

Calling the contract
********************

You can try to execute the contract now. If you have sucessfully deployed your contract, you should have an item in 
**Deployed contracts**. Click on it and you should have a form to call your contract's functions.

.. admonition:: Task

        Try to play with your contract to see how it modifies the **name** and **capacity** variables. 
        When executing **getCapacity** or **getName**, results are returned in the transaction execution infos on the lower part of remix. 

Notice how a call to **setCapacity** and **setName** generate and transaction and how a call to the other functions does not. 
The functions **setCapacity** and **setName** modifies the contract. It needs to be validated by the blockchain and stored 
somewhere. That's what the transaction is about. The functions **getCapacity** and **getName** are **views** functions, 
that does not modify the contract data, only read it. No need to bother the blockchain network this transactions for those 
functions. As everyone have the same vision of the network, everyone can provide the results of those functions.

Modifying the contract
^^^^^^^^^^^^^^^^^^^^^^

Play with functions and variables
*********************************

Now we are going to play with this simple contract a bit.

.. admonition:: Task

        Try to add a function **increaseCapacity** that increase the capacity by 1

.. admonition:: Task

        Try to add a new variable called **production** that will be used to keep track of the production of individual equipments, 
        identified by their name (e.g "SolarPanel1").
        You should be using the `mapping <https://docs.soliditylang.org/en/v0.8.17/types.html>`_ type. 

.. admonition:: Task

        Add a function **updateProduction** that will set the production for a given equipment and a function **productionForEquipment** 
        that returns the production recorded for a given equipment.

To play with your new contract, you will need to recompile and redeploy it. Try to do it and use your new functions.

Advanced 
^^^^^^^^

This section is optional. You have finished early, feel free to go though its content
to manipulate Solidity and smart contract design a bit more.

We are going to implement a new contract, that represent a simple auction system for a virtual power plant.

The scenario could goes as follows:

- The smart contract manage the auction system
- The energy provider start an auction system for a given amount of MW at a given price
- A list of registered clients can bid for this auction
- The smart contract keep tracks of who bidded and for how much
- To simplify the scenario, we won't set a fix date to end the auction. 
    - A function will end the auction and return the name of the client that won the auction

Try first to identify which informations you need to store in the contract and the type of each informations.
Then to list all different functions you may need. 
Finaly, implement the contract in Remix.

.. tip:: 
    
    You may use a `structure <https://docs.soliditylang.org/en/v0.8.17/structure-of-a-contract.html#struct-types>`_ to represent all informations for a given client

Feel free to modify this scenario to experiment with Solidity.
