# Lesson 1 - Getting started with ink!

### 1. Setup

This section demonstrates how to install the different tools to be able to develop on Aleph Zero.

To develop on Aleph Zero, you will need openssl installed. If it is not already installed, onpenssl can be installed with the following command:

+++ MacOS

```
brew install openssl
```

+++ Ubuntu

```
sudo apt-get install libssl-dev
```

+++ Protobuf is also needed and can be installed with the following command:

+++ MacOS

```
brew install protobuf
```

+++ Ubuntu

```
sudo apt update
sudo apt install protobuf-compiler
```

+++

You will need to first install [Rust](https://www.rust-lang.org/tools/install) which means that you will need to have curl installed as well. Do not install curl with snap, use apt instead:

+++ MacOS

```
brew install curl  
```

+++ Ubuntu

```
sudo apt install curl  
```

+++ After installing curl, Rust can be installed with the following two commands.

```
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env 
```

The minimum version of rust that needs to be installed is 1.66.

\==- ink! version 3 installation Following the Rust installation, toolchains need to be installed. This can be done thanks to the following commands

```
rustup toolchain install nightly
rustup component add rust-src --toolchain nightly
rustup target add wasm32-unknown-unknown --toolchain nightly
```

Then, binaryen is needed and can be installed with the following command

+++ MacOS

```
brew install binaryen
```

+++ Ubuntu

```
sudo apt install binaryen
```

+++

Finally, the cargo package manager is required to develop on Aleph Zero and can be installed with one of the following commands

```
cargo install --git https://github.com/paritytech/cargo-contract.git --rev 4f831bc2e4b8f3fa5a6a4d1b3fa673e99807af8f
```

\==- To install ink! v4, you just need to execute this command.

```
cargo install --force --locked cargo-contract
```

If you already started a project with ink! v3 please follow thise guidelines in order to migrate to ink! v4: [Migration](https://use.ink/faq/migrating-from-ink-3-to-4/)

* Course\_01:&#x20;

{% embed url="<https://www.youtube.com/watch?v=_-pBWORpgJs&list=PLRhOOnbF7IGK0wR4LIFhl9GtnPH6XoLR>\_" %}

### 2. Create and write your smart contract

The second section consists of writing a smart contract which plays the role of a computer which can perform addition and subtraction only. The smart contract will have the following element:

* a global variable;
* an addition function that will take a value as input to be added to the global variable;
* a subtraction function that will take a value as input to be subtracted to the global variable.

The source code is avalaible ate the bottom of this page.

The command used to create the smart contract is the following.

```
cargo contract new computer 
```

The command above will create a folder `computer` with the following files:

* Cargor.tolm: Rust Dependencies and ink! Configuration;
* lib.rs: source code of your smart contract;
* .gitingore.
* Course\_02:&#x20;

{% embed url="<https://www.youtube.com/watch?v=f4ISsW2ayTA&list=PLRhOOnbF7IGK0wR4LIFhl9GtnPH6XoLR_&index=3>" %}

### 3. Test & compile

In this this section, we will demonstrate how to test and compile your smart contract. First, we need to go in you project folder, this means for this example, we need to executed the command

```
cd computer
```

Then, the command to perform the tests on the contract is the following.

```
cargo test
```

After testing the smart contract, the compilation can be performed thanks to the following command ==- ink! v3 With ink! v3, we need the nightly toolchain, therefore, the following command needs to be executed:

```
cargo +nightly contract build
```

\==-

```
cargo contract build
```

* Course\_03:&#x20;

{% embed url="<https://www.youtube.com/watch?v=dhLhZkpQ4as&list=PLRhOOnbF7IGK0wR4LIFhl9GtnPH6XoLR_&index=4>" %}

### 4. Deploy on the Aleph Zero Testnet

In this section, we will demonstrate how to deploy your contract on Aleph Zero testnet and how to interact with it. The video first demonstrates how to deploy and interact with a smart contract with a user interface. Then we will demonstrate a way to deploy and interact with your smart contract using the command line.

To deploy your smart contract you can first execute these two commands.

The first one to store your seed

```
export SEED="replace with your twelve words seed"
```

and the second one to store the URL of Aleph Zero testnet.

```
export URL="wss://ws.test.azero.dev"
```

Then you need to be in the folder of your project. In our case, we need to be inside the folder `computer`.

Then, this command will deploy the smart contract on Aleph Zero testnet

```
cargo contract instantiate --suri "$SEED" --url "$URL" --constructor new --args 100 -x
```

The command above will generate an address for your contract and this will generate

```
export CONTRACT="replace with address "
```

Then to interact, the following command can be used

```
cargo contract call --suri "$SEED" --url "$URL" --contract "$CONTRACT" --message add --args 101 -x
```

Note about the flag `-x`: This will execute your command on Aleph Zero testnet. Executing the command presented above without this flag will present you the expected command.

* Course\_04:

{% embed url="<https://www.youtube.com/watch?v=TiihJ_Ax14U&list=PLRhOOnbF7IGK0wR4LIFhl9GtnPH6XoLR_&index=5>" %}

### 5. Deploy Locally

The last section demonstrate how to use substrate locally. First, we need to install the substrate you can download the binaries at the link [binaries](https://github.com/paritytech/substrate-contracts-node/releases) or build it locally from the git repository [gitparitycheck](https://github.com/paritytech/substrate-contracts-node#note)

After downloading the binary, please open a terminal in the folder `substrate-contracts-node-linux` on linux or `substrate-contracts-node-mac` if you are using Mac and execute the following command:

```
./substrate-contracts-node
```

If you want have more information about substrate please visit [substrate.io](https://substrate.io/).

* Course\_05:

{% embed url="<https://www.youtube.com/watch?v=MlvyufjX6x4&list=PLRhOOnbF7IGK0wR4LIFhl9GtnPH6XoLR_&index=5>" %}

### Sample Code

```rust
#![cfg_attr(not(feature = "std"), no_std)]

#[ink::contract]
mod computer {

    /// Defines the storage of your contract.
    /// Add new fields to the below struct in order
    /// to add new static storage fields to your contract.
    #[ink(storage)]
    pub struct Computer {
        /// Stores a single `i32` value on the storage.
        value: i32,
    }

    impl Computer {
        /// Constructor that initializes the `i32` value to the given `init_value`.
        #[ink(constructor)]
        pub fn new(init_value: i32) -> Self {
            Self { value: init_value }
        }

        /// Constructor that initializes the `i32` value to `0`.
        ///
        /// Constructors can delegate to other constructors.
        #[ink(constructor)]
        pub fn default() -> Self {
            Self::new(Default::default())
        }

        /// A message that can be called on instantiated contracts.
        /// This one add the input 'by' to the stored `value`
        #[ink(message)]
        pub fn add(&mut self, by: i32) {
            self.value += by;
        }

        /// A message that can be called on instantiated contracts.
        /// This one substact the input 'by' to the stored `value`
        #[ink(message)]
        pub fn sub(&mut self, by: i32) {
            self.value -= by;
        }

        /// Simply returns the current value of our `i32`.
        #[ink(message)]
        pub fn get(&self) -> i32 {
            self.value
        }
    }

    /// Unit tests in Rust are normally defined within such a `#[cfg(test)]`
    /// module and test functions are marked with a `#[test]` attribute.
    /// The below code is technically just normal Rust code.
    #[cfg(test)]
    mod tests {
        /// Imports all the definitions from the outer scope so we can use them here.
        use super::*;

        /// We test if the default constructor does its job.
        #[ink::test]
        fn default_works() {
            let computer = Computer::default();
            assert_eq!(computer.get(), 0);
        }

        /// We test a simple use case of our contract.
        #[ink::test]
        fn it_works() {
            let mut computer = Computer::new(100);
            assert_eq!(computer.get(), 100);
            computer.add(100);
            assert_eq!(computer.get(), 200);
            computer.sub(199);
            assert_eq!(computer.get(),1);
        }
    }
}

```

* [lib.rs](https://gitlab.kudelski.com/emea-blockchain/aleph-zero/-/blob/main/Course_Basics_AZ0/Code/counter/lib.rs)
