Access Control

Smart contracts require the ability to restrict access to and identify certain users or contracts. Unlike account-based blockchains, transactions in UTXO-based blockchains (i.e. Fuel) do not necessarily have a unique transaction sender. Additional logic is needed to handle this difference, and is provided by the standard library.


To deliver an experience akin to the EVM's access control, the std library provides a msg_sender function, which identifies a unique caller based upon the call and/or transaction input data.


use std::{
    chain::auth::{AuthError, msg_sender},

abi MyOwnedContract {
    fn receive(field_1: u64) -> bool;

const OWNER: b256 = 0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c;

impl MyOwnedContract for Contract {
    fn receive(field_1: u64) -> bool {
        let sender: Result<Identity, AuthError> = msg_sender();
        if let Identity::Address(addr) = sender.unwrap() {
            assert(addr.into() == OWNER);
        } else {


The msg_sender function works as follows:

  • If the caller is a contract, then Result::Ok(Sender) is returned with the ContractId sender variant.
  • If the caller is external (i.e. from a script), then all coin input owners in the transaction are checked. If all owners are the same, then Result::Ok(Sender) is returned with the Address sender variant.
  • If the caller is external and coin input owners are different, then the caller cannot be determined and a Result::Err(AuthError) is returned.