Skip to main content

How to implement a Slow Updates Tree

To learn more about the Slow Updates Tree, go here

On this page you will learn how to implement a slow updates tree into your contract, and an example of a token blacklisting contract that uses the slow updates tree.

How to implement a slow updates tree

  1. Copy the SlowTree.nr example and its dependencies, found here. Replace the constants with whatever you like and deploy it to your sandbox
  2. Copy the SlowMap interface for easy interaction with your deployed SlowTree. Find it here
  3. Import this interface into your contract
interface
use crate::interfaces::SlowMap;
Source code: noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr#L29-L31
  1. Store the SlowTree address in private storage as a FieldNote
constructor
#[aztec(public)]
#[aztec(initializer)]
fn constructor(admin: AztecAddress, slow_updates_contract: AztecAddress) {
Source code: noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr#L43-L47
  1. Store the SlowTree address in public storage and initialize an instance of SlowMap using this address
write_slow_update_public
storage.slow_update.initialize(slow_updates_contract);
Source code: noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr#L50-L52
  1. Now you can read and update from private functions:
get_and_update_private
let slow = SlowMap::at(storage.slow_update.read_private());
slow.update_at_private(&mut context, user.to_field(), roles);
Source code: noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr#L64-L67
  1. Or from public functions:
get_public
let slow = SlowMap::at(storage.slow_update.read_public());
Source code: noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr#L94-L96

View the reference for more information.

Exploring an example integration through a TokenBlacklist Smart Contract

The TokenBlacklist contract is a token contract that does not allow blacklisted accounts to perform mints or transfers. In this section we will go through how this is achieved through the slow updates tree.

You can find the full code for the TokenBlacklist smart contract here.

Importing SlowMap

The contract first imports the SlowMap interface:

interface
use crate::interfaces::SlowMap;
Source code: noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr#L29-L31

This interface allows the contract to interact with its attached SlowTree. It abstracts these functions so they do not have to be implemented in the TokenBlacklist contract.

Constructor and initialization

The contract's constructor takes the address of the slow updates contract:

constructor
#[aztec(public)]
#[aztec(initializer)]
fn constructor(admin: AztecAddress, slow_updates_contract: AztecAddress) {
Source code: noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr#L43-L47

This initialization sets up the connection between the TokenBlacklist contract and a previously deployed SlowTree, allowing it to use the interface to directly interact with the SlowTree.

Private transfer function utilizing the slow updates tree

In the private transfer function, the contract uses the interface to check if a user is blacklisted:

transfer_private
#[aztec(private)]
fn transfer(from: AztecAddress, to: AztecAddress, amount: Field, nonce: Field) {
let slow = SlowMap::at(storage.slow_update.read_private());
let from_roles = UserFlags::new(U128::from_integer(slow.read_at(&mut context, from.to_field())));
assert(!from_roles.is_blacklisted, "Blacklisted: Sender");
let to_roles = UserFlags::new(U128::from_integer(slow.read_at(&mut context, to.to_field())));
assert(!to_roles.is_blacklisted, "Blacklisted: Recipient");
Source code: noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr#L239-L247

Here, the contract reads the roles of the sender and recipient from the SlowTree using the read_at function in the interface. It checks if either party is blacklisted, and if so, the transaction does not go ahead.