Is Fe the next smart contract language?

Is Fe the next smart contract language?

When I started coding smart contracts I was always wondering if there could be a better way of writing them where you could avoid C++-like code structuring. When it comes to solidity you can write basic contracts pretty easily. Let's write a basic HelloWorld contract and see how that looks before we jump into what the hell is Fe.

Here is a basic hello world solidity contract:

// SPDX-License-Identifier: MIT

pragma solidity ^0.7.0;

// Defines a contract named `HelloWorld`.
contract HelloWorld {
   string public message;
   constructor(string memory initMessage) {
      message = initMessage;
   }
   function update(string memory newMessage) public {
      message = newMessage;
   }
   function viewMessage() public view returns(string memory) {
      return message;
   }
}

If you want to deploy this contract you can do it here with a click: Remix HelloWorld

Pretty simple right. I won't go into the depths here since there are a lot of tutorials explaining the same. Although, I want to go through the structure. People who like Python over other languages know how frustrating it is to add a missing semicolon or a brace that you forgot while you were writing the code. To make this simple and easy with a more python-rust-inspired interface, people at Ethereum have developed Fe.

Fe is a new compiler that is written on rust and the name indicating the element Iron in the periodic table depicts the durability. Also, rust forms on iron so (good work Fe team).

Without wasting time let's look into Fe. Let's translate the HelloWorld contract into Fe.

To compile the Fe code first we will need to grab the compiler binary. Let's get that from the repository releases here: Fe Release. You can find the binaries in the assets below with the release. I am using 0.10.0 alpha and that is the latest while writing this article.

Once you have that let's now type the contract. It's time to get rusty.

Here is the code in Fe. You can see how easy, simple and concise it is now than earlier. Let's go through the lines here.

# The `contract` keyword defines a new contract type
contract HelloWorld:
    message: String<100>
    pub fn __init__(self, _message: String<100>):
        self.message = _message
    pub fn update(self, newMessage: String<100>):
        self.message = newMessage
    pub fn getMessage(self) -> String<100>:
        return self.message.to_mem()

Github gist here: Helloworld.fe

  1. The contract keyword is a type in Fe and it specifies the type of object we are creating here. We are initializing a contract module using the keyword contract.
  2. message: String<100> is actually a declaration here to declare a global variable message as a String type with a maximum size restriction of 100 characters. We type the variable name followed by a colon specifying the type of variable.
  3. The init method basically the constructor here as we see in python. We use the same notation style variable: type as the parameter. Notice the python style self keyword that goes into each method.
  4. The function getMessage actually returns a String. To achieve this we use the arrow keyword as you can notice above.

Let's focus on the to_mem() section of the code. This is important to make the referenced type value to be copied into memory to be returned by the contract to the caller. This is analogous to string memory declaration in solidity. This moves the value from storage to memory.

We are down to 8 lines of code with hassle-free compilation. Now that we have the code, let's compile it.

I am using a mac, so fe_mac is the name of the binary I will be using to compile this fe file. Here we go:

$ ./fe_mac helloworld.fe

This generates a folder called output. The output folder will contain the binary and the abi file. Let's take a look at the abi file it generates:

[
  {
    "name": "update",
    "type": "function",
    "inputs": [
      {
        "name": "newMessage",
        "type": "string"
      }
    ],
    "outputs": []
  },
  {
    "name": "getMessage",
    "type": "function",
    "inputs": [],
    "outputs": [
      {
        "name": "",
        "type": "string"
      }
    ]
  },
  {
    "name": "",
    "type": "constructor",
    "inputs": [
      {
        "name": "_message",
        "type": "string"
      }
    ],
    "outputs": []
  }
]

Here is our abi for the remix solidity code:

[
    {
        "inputs": [
            {
                "internalType": "string",
                "name": "initMessage",
                "type": "string"
            }
        ],
        "stateMutability": "nonpayable",
        "type": "constructor"
    },
    {
        "inputs": [],
        "name": "message",
        "outputs": [
            {
                "internalType": "string",
                "name": "",
                "type": "string"
            }
        ],
        "stateMutability": "view",
        "type": "function"
    },
    {
        "inputs": [
            {
                "internalType": "string",
                "name": "newMessage",
                "type": "string"
            }
        ],
        "name": "update",
        "outputs": [],
        "stateMutability": "nonpayable",
        "type": "function"
    },
    {
        "inputs": [],
        "name": "viewMessage",
        "outputs": [
            {
                "internalType": "string",
                "name": "",
                "type": "string"
            }
        ],
        "stateMutability": "view",
        "type": "function"
    }
]

In the upcoming posts, let's take a closer look into how do we deploy these Fe contracts on Ethereum.

If you are interested in cryptocurrency and looking into using historical data for ML or any other projects take a look at the API I developed here:

If you are interested in the project you can hit me up in the comments. Link to the CryptoViz API Project: github.com/adityak74/cryptoviz