Fe or Solidity, which is better?
Published: 2023-11-29 20:45:49

---
title: Fe or Solidity, which is better?
published: true
description: 
tags: 
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vzvv9iu5s1bc2tq7wjup.png
# Use a ratio of 100:42 for best results.
# published_at: 2023-11-08 20:29 +0000
---

Language diversity is just as crucial as client diversity, it can help making a smart contract chain more secure and resilient to bugs at compiler level. Also it can help sparking fresh ideas born from a brand-new codebase. Fe is a new EVM language, like Solidity and Vyper. However, Fe brings new opinions in term of readability, decidability and gas estimations.

In this guide we'll launch an ERC20 using Fe. Just keep in mind that whilst Fe is ready to be used on production, the dev tooling still needs to do a lot of catch-up compared to the other EVM languages. This guide is for both the early adopters and the curious.

{% youtube zKxmtbVNscg %}

## Before we start

For this tutorial you will need [Metamask](https://metamask.io/) or other wallet of your choice, with Scroll Sepolia funds that you can get from a [Sepolia faucet](https://sepoliafaucet.com/) and then bridge them to L2 using the [Scroll Sepolia bridge](https://scroll.io/bridge). Alternatively, you can use a [Scroll Sepolia Faucet](https://docs.scroll.io/en/user-guide/faucet/) to get funds directly on L2.

On this guide we'll deploy on Scroll Sepolia, I'll explain the exact changes that are needed to deploy on any other EVM chain.

## 1. Installation

On Linux:

```bash
wget https://github.com/ethereum/fe/releases/download/v0.26.0/fe_amd64
mv fe_amd64 fe
chmod +x fe
```

On Mac:

```bash
wget https://github.com/ethereum/fe/releases/download/v0.26.0/fe_mac
mv fe_mac fe
chmod +x fe
```

You will also need to install foundry in either Linux or Mac (needed for contract deployment)

```bash
curl -L https://foundry.paradigm.xyz | bash
# now, reload your env vars, just close and reopen your terminal
foundryup
```

For more information check the official [Fe](https://fe-lang.org/) and [foundry](https://book.getfoundry.sh/getting-started/installation) installation guide.

## 2. Create an ERC20 contract

Create the following file named `erc20_token.fe`:

`erc20_token.fe`

```rust
struct Approval {
    #indexed
    pub owner: address
    #indexed
    pub spender: address
    pub value: u256
}

struct Transfer {
    #indexed
    pub from: address
    #indexed
    pub to: address
    pub value: u256
}

contract ERC20 {
    _balances: Map<address, u256>
    _allowances: Map<address, Map<address, u256>>
    _total_supply: u256
    _name: String<100>
    _symbol: String<100>
    _decimals: u8

    pub fn __init__(mut self, mut ctx: Context) {
        self._name = "My Fe Token"
        self._symbol = "MFeT"
        self._decimals = u8(18)
        self._mint(ctx, account: ctx.msg_sender(), value: 1000_000_000_000_000_000_000_000)
    }

    pub fn name(self) -> String<100> {
        return self._name.to_mem()
    }

    pub fn symbol(self) -> String<100> {
        return self._symbol.to_mem()
    }

    pub fn decimals(self) -> u8 {
        return self._decimals
    }

    pub fn totalSupply(self) -> u256 {
        return self._total_supply
    }

    pub fn balanceOf(self, _ account: address) -> u256 {
        return self._balances[account]
    }

    pub fn transfer(mut self, mut ctx: Context, recipient: address, value: u256) -> bool {
        self._transfer(ctx, sender: ctx.msg_sender(), recipient, value)
        return true
    }

    pub fn allowance(self, owner: address, spender: address) -> u256 {
        return self._allowances[owner][spender]
    }

    pub fn approve(mut self, mut ctx: Context, spender: address, value: u256) -> bool {
        self._approve(ctx, owner: ctx.msg_sender(), spender, value)
        return true
    }

    pub fn transferFrom(mut self, mut ctx: Context, sender: address, recipient: address, value: u256) -> bool {
        assert self._allowances[sender][ctx.msg_sender()] >= value
        self._transfer(ctx, sender, recipient, value)
        self._approve(ctx, owner: sender, spender: ctx.msg_sender(), value: self._allowances[sender][ctx.msg_sender()] - value)
        return true
    }

    pub fn increaseAllowance(mut self, mut ctx: Context, spender: address, addedValue: u256) -> bool {
        self._approve(ctx, owner: ctx.msg_sender(), spender, value: self._allowances[ctx.msg_sender()][spender] + addedValue)
        return true
    }

    pub fn decreaseAllowance(mut self, mut ctx: Context, spender: address, subtractedValue: u256) -> bool {
        self._approve(ctx, owner: ctx.msg_sender(), spender, value: self._allowances[ctx.msg_sender()][spender] - subtractedValue)
        return true
    }

    fn _transfer(mut self, mut ctx: Context, sender: address, recipient: address, value: u256) {
        assert sender != 0
        assert recipient != 0
        _before_token_transfer(from: sender, to: recipient, value)
        self._balances[sender] = self._balances[sender] - value
        self._balances[recipient] = self._balances[recipient] + value
        ctx.emit(Transfer(from: sender, to: recipient, value))
    }

    fn _mint(mut self, mut ctx: Context, account: address, value: u256) {
        assert account != address(0)
        _before_token_transfer(from: address(0), to: account, value)
        self._total_supply = self._total_supply + value
        self._balances[account] = self._balances[account] + value
        ctx.emit(Transfer(from: address(0), to: account, value))
    }

    fn _burn(mut self, mut ctx: Context, account: address, value: u256) {
        assert account != address(0)
        _before_token_transfer(from: account, to: address(0), value)
        self._balances[account] = self._balances[account] - value
        self._total_supply = self._total_supply - value
        ctx.emit(Transfer(from: account, to: address(0), value))
    }

    fn _approve(mut self, mut ctx: Context, owner: address, spender: address, value: u256) {
        assert owner != address(0)
        assert spender != address(0)
        self._allowances[owner][spender] = value
        ctx.emit(Approval(owner, spender, value))
    }

    fn _setup_decimals(mut self, _ decimals_: u8) {
        self._decimals = decimals_
    }

    fn _before_token_transfer(from: address, to: address, _ value: u256) {}
}
```

For more demos, check [this repo](https://github.com/ethereum/fe/tree/master/crates/test-files/fixtures/demos).

## 3. Compile the contract

Generate the ABI and bytecode by running the following:

```bash
./fe build erc20_token.fe
```

For more information check the [Fe docs](https://fe-lang.org/docs/index.html).

## 4. Deployment

You can deploy now on Scroll Sepolia by putting your private key on `YOURPRIVATEKEY` and running the following command. Just make sure it has Scroll Sepolia Testnet funds.

If you are deploying on a chain other than Scroll Sepolia, change the rpc url from `https://sepolia-rpc.scroll.io/` to an RPC url from your chain of choice.

```bash
cast send --legacy --rpc-url https://sepolia-rpc.scroll.io/ --private-key YOURPRIVATEKEY --create $(cat output/ERC20/ERC20.bin)
```

The token should now be on your account fully ERC20 compatible. The transaction and token address should be displayed on the console, or you can find it on [Scroll Sepolia Etherscan](https://sepolia.scrollscan.dev/) or on the scan of the chain you deployed to.

Fe recommends using Anvil from foundry to deploy and interact with contracts, for more information check the [foundry docs](https://book.getfoundry.sh/reference/cast/cast-send).

## Conclusion

It is still too early to decide which one I will use more in the future, as Fe is in a very early stage and is likely to undergo changes. However, I really like the idea of a new language with fresh ideas learned from Solidity's lessons. I doubt Solidity will cease to be the dominant language for many years, but I hope that new error analysis tools and gas calculators will lead to significant adoption of Fe and enable it to build a community. Personally, I will keep an eye on new developments and will be testing it in future projects!

Which one do like better? Do you still prefer Solidity or do you want to give Fe a try?

**Thanks for watching this guide!**

Follow Filosofía Código on dev.to and in [Youtube]( https://www.youtube.com/channel/UCbF5CFuXv2vTkcGfepWV2nA) for everything related to Blockchain development.