# Migrating from Solidity

{% hint style="info" %}
We encourage the Readers to first follow our [aleph-zero-smart-contracts-basics](https://docs.alephzero.org/aleph-zero/build/aleph-zero-smart-contracts-basics "mention") tutorial to get a general understanding of Ink!.
{% endhint %}

It is worth pointing out in the beginning that there are many more similarities than differences between Ink! and Solidity. Both are imperative programming languages that allow you to write contracts similarly: as a module that defines a set of methods ('messages') that return some information about the contract and/or modify the contract's state and both run in environments that utilize the concept of gas (a fee for running program instructions that prevents the contract from running indefinitely).

<figure><img src="https://1927958252-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjxGnEsASyxizmuYQHzry%2Fuploads%2FqyzEc4Epy2wD4pHg5Qxe%2FA0_SC_Infographic.jpg?alt=media&#x26;token=0e441a10-4e93-4d67-9ff2-a86c31b2f02a" alt=""><figcaption><p>Ink! vs Solidity</p></figcaption></figure>

Of course, the syntax is slightly different and Ink's type system may take some getting used to, but any Solidity developer should be able to jump right in and start developing contracts in the Aleph Zero ecosystem. Almost all of the concepts have a one-to-one correspondence between Ink! and Solidity, so converting the contracts should be a breeze. You can also try automatic translation using the [Sol2Ink](https://github.com/Supercolony-net/sol2ink) tool, which can produce satisfactory results for simpler contracts.

{% hint style="danger" %}
If you use one of the automatic translation tools, make sure to inspect the resulting code very carefully!
{% endhint %}

### Migrating a simple contract

Let's take a look at a classic 'Hello world' example of a smart contract, the Flipper: it is the most basic contract imaginable and its sole purpose is to hold a boolean value in the state and expose a message that allows callers to 'flip' it. Here is how it could look in Solidity:

```solidity
contract MyContract {
    bool private _theBool;
    event UpdatedBool(bool indexed _theBool);

    constructor(bool theBool_) {
        require(theBool_ == true, "theBool_ must start as true");

        _theBool = theBool_;
    }

    function setBool(bool newBool) public returns (bool boolChanged) {
        if _theBool == newBool {
               boolChanged = false;
        } else {
            boolChanged = true;
        }

        _theBool = newBool;
        // emit an event
        UpdatedBool(newBool);
    }
}
```

Now, the funny thing is that if you want to make this basic contract in Ink!, you only need to type one command:

```bash
cargo contract new flipper
```

`cargo contract` is a tool for managing and building Ink! smart contracts and its `new` command will scaffold a basic flipper. To build the contract you can run:

```bash
cargo contract build --release
```

And just like that, you will have the `target/release/ink/flipper.contract` file ready to be deployed.

That said, let's dive a little deeper and convert the contract manually to better understand the process.

#### File layout

Solidity keeps the storage and logic of the contract inside of the same class. In Ink! you group all of that using a module. Inside the module you:

* define your storage struct
* define the implementation of messages/methods
* define any additional structs and traits

As such, the layout of the file will look like this:&#x20;

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

use ink_lang as ink;

#[ink::contract]
mod flipper {
    #[ink(storage)]
    pub struct Flipper {
        // storage elements go here
    }

    #[ink(event)]
    pub struct SomeEvent {
        // event fields
    }
    
    // more definitions: additional structs, errors, events, trait implementations

    impl Flipper { // name needs to match the name of the storage struct
        #[ink(constructor)]
        pub fn new( /* constructor arguments */ ) -> Self {
            // constructor implementation
        }
        
        // additional messages/methods: getters, setters, etc.
    }
}
```

This layout will be pretty much constant across all of the contracts you write. Note that you almost never need to type all of the above yourself: `cargo contract new` takes care of all the scaffolding. Note the `#[ink::contract]` above module declaration: it enforces certain invariants (that we mention below) and defines some handy aliases.

#### Storage struct

Ink! defines the storage struct the Rust way: as a separate entity inside the module. The data-logic separation has a few useful implications that are beyond the scope of this tutorial: it suffices to say that this idea is battle-tested in the Rust world. To define your storage, you will write the following code:

```rust
#[ink(storage)]
pub struct Flipper {
    the_bool: bool,
}
```

The `#[ink(storage)]` macro tells the compiler that this is indeed the contract's storage. The contract needs to have exactly one such struct: don't worry, the compiler will instruct you if you forget to define it or define more than one.

Of course, you are able to define as many `struct`s as you want but only one of them can be marked with `#[ink(storage)]`.

{% hint style="info" %}
As an aside, you need to be quite conservative with putting elements in the contract's storage. Smart contracts on the Aleph Zero blockchain are exceptionally cheap but the storage fees are still something to consider during your development. For example, you may want to store your images off-chain and only store hashes on the blockchain.
{% endhint %}

#### Method implementations

Instead of putting the logic in the class/struct body, Rust (and therefore: Ink!) chooses to have a dedicated `impl` block that contains all of the methods (including the constructors).

```rust
impl Flipper { /* method definitions */ }
```

The name needs to match the name of your contract's storage struct. Inside, you can put three types of methods:

* methods marked as `#[ink(message)]` which will be what your contract's users can call;
* methods marked as `#[ink(constructor)]` which are the constructors of your contract;
* regular, unmarked methods that won't be callable as part of your contract's interface but can be used as helpers by the other methods.

#### Constructor(s)

Solidity uses a dedicated `constructor` keyword, and a contract is allowed to have only one. In contrast, Ink! allows you to define any non-zero number of constructors. Each constructor is a public method with the `#[ink(constructor)]` macro which returns an instance of the contract's storage struct:

```rust
#[ink(constructor)]
pub fn new(initial_state: bool) -> Self {
    Self {
        the_bool: initial_state,
    }
}
```

{% hint style="warning" %}
Note that while Solidity constructors work 'in-place': you assign the values to the storage elements. In Ink! you need to explicitly create and return the storage struct.

This stems from the fact that the constructor is generally a method like any other: it needs the macro but doesn't even need to have a special name. Of course, in order to make the interface understandable to your user, it's best to opt for methods called 'new', 'initialize', 'create', etc.
{% endhint %}

You can do any required initialization inside of the constructor. A common operation is initializing a mapping, if your contract has one in its storage. In that case, you will use the `Default::default()` method to initialize the mapping and then put it as one of the fields in the returned struct.

{% hint style="info" %}
Instead of using `Self`, you can just use the name of your storage struct (in our case: `Flipper`). The Rust community prefers the former for its more generic semantics.
{% endhint %}

#### Messages/methods

Here we will see some syntactic differences between Ink! and Solidity:

* in Solidity, you declare the messages as public methods on your contract class;
* Ink! puts the methods in the `impl` block but you still need to mark them as `pub`;
* in Solidity, you have two ways of returning a value from a function:
  * declare the return variable (`returns(bool someval)`) and assign to it: a concept familiar to those of us who remember the golden days of Pascal;
  * use the `return` keyword to immediately exit from a function, returning a value;
* Ink! also has two ways of returning values, arguably more functional in nature:
  * the `return` keyword;
  * implicitly returning the last expression in a function (this one being the 'purer' variant and preferred in the Rust/Ink! community);
* Ink! messages need the `#[ink(message)]` macro to be callable by your contract's users;
* Solidity relies heavily on `assert`s, `require`s and similar exception-based special functions to handle failure.
* Ink! does expose `assert!(...)` as a macro but the preferred way of handling errors is much more powerful: using the `Result` return type (more on that below).
* In Ink!, you need to explicitly state whether a function will be allowed to mutate the state of the contract. If it needs to mutate the storage elements, it needs to have `&mut self` as the first argument. Otherwise, it will have `&self` (messages in Ink! need to have `self` passed as a reference, so in either case, the ampersand will be there).

Here is a basic form of our `set_bool` message/method:

```rust
#[ink(message)]
pub fn set_bool(&mut self, new_bool: bool) -> bool {
    let bool_changed = true;

    if self.the_bool == new_bool{
        bool_changed = false;
    } else {
        bool_changed = true;
    }

    self.the_bool = new_bool;

    // implicit return
    bool_changed
}
```

{% hint style="info" %}
Note that for the implicit return to work, you must not include a semicolon on the last line.
{% endhint %}

Similarly to Solidity, you can make your methods payable: you will need to change the macro to `#[ink(message, payable)]`.

#### Events

Your contracts can emit events just like in Solidity (although when using multiple contracts you will need to use a simple workaround, as described [here](https://github.com/Cardinal-Cryptography/bulletin-board-example/blob/main/contracts/bulletin_board/lib.rs#L513)). You start by declaring your event struct and marking it with a macro (you may be starting to see a pattern here):

```rust
#[ink(event)]
pub struct UpdatedBool {
    #[ink(topic)]
    the_bool: bool,
}
```

Use the `#[ink(topic)]` macro to mark the fields of your choice indexable (this is the same as in Solidity).

To emit the event, you can use the following call:

```rust
self.env().emit_event(UpdatedBool {
    the_bool: new_bool
});
```

It creates the event struct and immediately passes it to the `emit_event` function. `self.env()` is a method that gives you access to several useful things, including the caller's address (`self.env().caller()`) and the account of the contract itself (`self.env().account_id()`). The Solidity counterparts of these calls are `msg.sender` and `address(this)`, respectively.

#### Error handling

As previously mentioned, Ink! developers do not rely on throwing exceptions or stopping the execution with `require` macros. What we do instead is use the `Result` type, which can be one of two things: `Ok(somevalue)` when the computation was successful, or `Err(someerror)` when it wasn't. It is defined roughly as:

```rust
pub enum Result<T, E> {
    Ok(val: T),
    Err(msg: E),
}
```

With `T` and `E` being generic types for the actual value and the error type, respectively. The most common usage is to define an error type like:

```rust
pub enum MyError {
    NegativeNumber,
    WrongId(id: u32),
    BadCaller(caller: Vec<u8>),
    // etc...
}
```

Then you can define your functions' return types as:

```rust
pub fn some_function(x: i32) -> Result<u32, MyError> {
    if x < 0 {
        Err(MyError::NegativeNumber)
    } else {
        Ok((x + 1) as u32)
    }
}
```

Please don't mind the contrived nature of this example: it is only there to illustrate a common pattern when dealing with errors.

Now, as a caller of this function, you can choose to do two things:

* explicitly examine the result and decide on what actions to take:

```rust
match some_function(12) {
    Ok(v) => yay(),       // the computation succeeded
    Err(e) => sad_pepe(), // there was an error
}
```

* use one of the helper methods to, for example, fail immediately if the result was not `Ok`:

```rust
some_function(-1).unwrap()
```

#### Further reading

We have only scratched the surface here but hopefully, this guide has shed some light on the process of migrating contracts from Solidity and shown that it's easier than it might seem.

For a very detailed guide, please see [this chapter of Ink's documentation](https://use.ink/ink-vs-solidity#syntax-equivalencies).
