🌴Sway from Solidity: Program Types
Table of contents
Sway is the smart contract language for FuelVM. In this article, I listed major differences between Sway programs and Solidity programs. I hope this article helps people with a Solidity background to get started with sway quickly and easily.
Solidity only has two types of programs, Contract and Library. Sway also has two additional program types besides Contract and Library - Predicate and Script.
The major differences are outlined below:
Contract
Sway contract must define or import an ABI declaration and implement all the methods defined in the ABI implementation.
No contract inheritance.
Sway contract cannot create new contracts from a contract.
In solidity, you can create new contracts using
create
orcreate2
from a contract.However, you can check if a deployed contract matches the code by checking the bytecode root. (example)
All the storage variables must be defined in
Storage{}
.Apart from variables defined in
Storage{}
, variables are immutable by default.To make them mutable, you need to mark the variable with
mut
.let mut amount = 7u8;
There is no constructor in Sway contract
- You need to define a function to initialize the contract
No auto-generated getter for storage variables.
- You need to define getter functions yourself.
There are no external, public or internal functions in Sway.
All functions defined in ABI must be implemented
All the implemented functions are visible to the public
Functions defined outside of the ABI implementation are not accessible to the public. It works like internal/private functions in Solidity.
Functions are pure by default in sway
If you want to define whether a function can read/write storage, use
storage
attribute#[storage(read)] fn get_amount() -> u64 { ... } #[storage(read, write)] fn increment_amount(increment: u64) -> u64 { ... }
From
0.33.0
, methods without thepayable
attribute cannot accept coins.#[storage(write), payable] fn deposit() -> u64 { ... } #[payable] fn receive() -> u64 { ... }
No fallback/receive function
Asset/Token work as native assets in Fuel
In the sway token contract, you can define how the tokens can be minted or burnt. As it works as a native asset, you cannot limit the token transfer in the token contract.
In sway, you can only get the asset balance of a
ContractID
. You cannot get the asset balance of anAddress
There are two types of
Identity
:Address
andContractId
In solidity, it's not easy to tell if an account is an EOA or a contract.
In Sway, an account is either an
Address
(EOA) or aContractId
(contract). If you are not sure what type of address you will interact with, you can just useIdentity
.// https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/identity.sw pub enum Identity { Address: Address, ContractId: ContractId, }
Detecting Reentrancy (stack is transparent)
In FuelVm, each tx will be allocated with a fixed-size memory space.
calls to external contracts are pushed to the memory space as a call frame. they can only modify the state of the call frame they belong to.
Inside this context, you are aware of everything that happens here (know what call frames are pushed to the memory space before you)By checking if the contract is called in previous call frames, you can know if the contract is reentered or not
Reentrancy library
Before
0.35.0
, it's understd::reentrancy::
.As of
0.35.0
, it's moved to sway_libs.
There can only be one contract per project.
In FuelVM, SafeMath check is enforced at the VM level
Safemath checks in Solidity are done at the bytecode level only. Overflow can still happen if you cast a big number into a smaller type.
You can also turn off/on the check by using this library.
Library
Similar to libraries in Solidity, you can define some common behaviours such as utils functions, structs and ABI in the library.
It has no persistent storage.
Storage{}
cannot be used.
Predicate
Predicate contains a main function that returns a boolean value.
Predicate can not be deployed on-chain. It appears as an address on-chain, which is derived from the hash of its bytecode.
It's stateless and independent of on-chain status. But it can access data in the tx.
It has no persistent storage (
Storage{}
cannot be used).
Users can send coins to the predicate address.
The coins in the predicate address can only be unlocked by making the predicate main function return true.
Script
Similar to predicates, it cannot be deployed on-chain either.
It is state-aware. It can access on-chain status and call other contracts.
It has no persistent storage.
Storage{}
cannot be used.
It contains one
main()
function with no return value.
References
Follow me on twitter for more about smart contract development and security
Subscribe to my newsletter
Read articles from zt directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by