Contracts
Last updated
Last updated
Bako ID is a series of Smart Contracts on Fuel that enables the registration and management of @bakoid
handles. Handles on Bako ID are registered in a structure that allows both accounts and contracts to have their own identity. After registration, the handle owner has full control over it, allowing them to manage all information and resolutions associated with the handle.
Bako ID is built on two main contracts: the Registry and the Manager. The Registry serves as the entry point for registering new handles, working alongside the Manager to validate ownership during interactions with the handle and to lock primary resolvers.
The Registry is responsible for implementing the methods that allow direct interaction with handles, as well as serving as the entry point for the logic behind handle registration. The main Registry implements the following ABI:
Responsible for registering a new handle, the method reverts when:
The Asset ID ≠ ETH - Reverts with RegistryContractError::IncorrectAssetId
The handle has already been minted - Reverts with RegistryContractError::AlreadyMinted
The handle contains invalid characters (valid: A-Z, a-z, 0-9, _) - Reverts with NameValidationError
The Asset ID amount ≠ the handle price - Reverts with RegistryContractError::InvalidAmount
If not reverted, the method interacts with the Token to mint the NFT and registers the record in the Manager.
Method responsible for adding new metadata to the handle, which directly interacts with the Token contract implementing SRC-7 to store the data.
Only the handle owner has permission to execute the method. If called by another account, the method will revert with RegistryContractError::NotOwner
.
Both methods are responsible for modifying the handle's addresses. They interact directly with the Manager contract, which updates the handle's structure while ensuring that the resolver address is correctly locked.
As with the Set Metadata method, only the owner has permission to execute these methods. Otherwise, the method reverts with RegistryContractError::NotOwner
.
This contract, together with the Registry, forms the core of Bako ID. It is responsible for storing new handles, managing a handle's addresses, and locking resolver addresses.
To ensure security, methods are implemented to manage the Admin, which in the context of Bako ID refers to the Registry contract. Only the contract owner has permission to manage the administrator addresses.
For this contract, which is responsible for storing and managing the handles, a storage structure has been designed to work with handle data in a secure and efficient manner.
The association between the handle and its data is managed through a hash calculated from the name: handle_hash = sha256(handle)
.
The storage is divided into three parts. The first part is records_data
, a Map where the key represents the handle_hash
, and the value is a structure of RecordData
:
The records_name
is a Map where the key is the handle_hash
, and the value is a String representing the name:
records_resolver
is responsible for locking primary resolvers. It represents a Map where the key is of type Identity
and the value is the handle_hash
.
A value can only be inserted if it is available, ensuring that primary resolvers are not overwritten.
Responsible for inserting the data of a new handle into Bako ID, this method reverts when:
The msg_sender
is not an admin or owner of the Manager: reverts with ManagerError::OnlyOwner
The handle has already been minted: reverts with ManagerError::RecordAlreadyExists
After the validation process, if no reverts occur, the handle is inserted into the storage.
This method alters the resolver address in the handle's record and ensures the lockup between the address and handle. The execution is reverted when:
The msg_sender
is not an admin or owner of the Manager: reverts with ManagerError::OnlyOwner
The handle has not been minted: reverts with ManagerError::RecordNotFound
The resolver address is locked: reverts with ManagerError::ResolverAlreadyInUse
If no reverts occur, the method:
Alters the resolver in storage.records_data
Removes the lockup of the old resolver address
Locks the new resolver address in storage.records_resolver
This contract follows the Fuel standards by implementing the Native Asset ABIs to represent an NFT, along with the Admin and Ownership library.
The method mint(recipient: Identity, sub_id: Option<SubId>, amount: u64)
of the contract ensures that only one token exists per handle. It is reverted when:
The msg_sender
is not an admin: AdminError::NotAdmin
The sub_id
is not an Option::Some
: MintError::CannotMintMoreThanOneNFTWithSubId
The amount
is greater than 1: MintError::CannotMintMoreThanOneNFTWithSubId
The total supply for the AssetId is already filled: MintError::NFTAlreadyMinted
The Resolver contract provides methods for on-chain resolution of handle addresses and names, such as resolving the address of a name and the name of an address.
It implements two ABIs:
AddressResolver
, responsible for resolving the handle's address.
NameResolver
, responsible for resolving the name of an address.
All methods interact with the Manager using the getter methods defined in the ManagerInfo
ABI.
fn addr(name: String) -> Option<Identity>
`The method for searching a resolver address through the handle returns an Option::Some
if found, and an Option::None
if not found.
fn name(addr: Identity) -> Option<
String>`The method for searching a name through the resolver returns an Option::Some
if found, and an Option::None
if not found.
The NFT is uniquely represented by a single handle. To ensure the token is unique, its is calculated based on the contract and its Sub ID, representing the handle's name:
The primary functionality of the Token in the protocol is to store the handle's metadata, enabling interaction with both on-chain and off-chain information. For the keys, the standard defined in is followed, along with additional default keys defined in the .