Contracts

Syntax
Contract :
   contract IDENTIFIER {
  ContractMember*
  _}

ContractMember:
   Visibility?
   (
         ContractField
      | Function
      | Struct
      | Enum
   )

Visibility :
   pub?

ContractField :
   IDENTIFIER : Type

A contract is a piece of executable code stored at an address on the blockchain. See Appendix A. in the Yellow Paper for more info. Contracts can be written in high level languages, like Fe, and then compiled to EVM bytecode for deployment to the blockchain.

Once the code is deployed to the blockchain, the contract's functions can be invoked by sending a transaction to the contract address (or a call, for functions that do not modify blockchain data).

In Fe, contracts are defined in files with .fe extensions and compiled using fe build.

A contract is denoted using the contract keyword. A contract definition adds a new contract type to the module. This contract type may be used for calling existing contracts with the same interface or initializing new contracts with the create methods.

An example of a contract:

struct Signed {
    pub book_msg: String<100>
}

contract GuestBook {
    messages: Map<address, String<100>>

    pub fn sign(mut self, mut ctx: Context, book_msg: String<100>) {
        self.messages[ctx.msg_sender()] = book_msg
        ctx.emit(Signed(book_msg: book_msg))
    }

    pub fn get_msg(self, addr: address) -> String<100> {
        return self.messages[addr].to_mem()
    }
}

Multiple contracts can be compiled from a single .fe contract file.

pragma

An optional pragma statement can be placed at the beginning of a contract. They are used to enable developers to express that certain code is meant to be compiled with a specific compiler version such that non-matching compiler versions will reject it.

Read more on pragma

State variables

State variables are permanently stored in the contract storage on the blockchain. State variables must be declared inside the contract body but outside the scope of any individual contract function.

pub contract Example {
    some_number: u256
    _some_string: String<100>
}

Contract functions

Functions are executable blocks of code. Contract functions are defined inside the body of a contract, but functions defined at module scope (outside of any contract) can be called from within a contract as well.

Individual functions can be called internally or externally depending upon their visibility (either private or public).

Functions can modify either (or neither) the contract instance or the blockchain. This can be inferred from the function signature by the presence of combinations of mut, self and Context. If a function modifies the contract instance it requires mut self as its first argument. If a function modifies the blockchain it requires Context as an argument.

Read more on functions.

The __init__() function

The __init__ function is a special contract function that can only be called at contract deployment time. It is mostly used to set initial values to state variables upon deployment. In other contexts, __init__() is commonly referred to as the constructor function.

pub contract Example {

    _some_number: u256
    _some_string: String<100>

    pub fn __init__(mut self, number: u256, string: String<100>)  {
        self._some_number=number;
        self._some_string=string;
    }
}

It is not possible to call __init__ at runtime.

Structs

Structs might also exist inside a contract file. These are declared outside of the contract body and are used to define a group of variables that can be used for some specific purpose inside the contract. In Fe structs are also used to represent an Event or an Error.

Read more on structs.