Default host: aarch64-apple-darwin
fuelup home: /Users/mdragibhussain/.fuelup
installed toolchains
beta-2-aarch64-apple-darwin
beta-3-aarch64-apple-darwin (default)
latest-aarch64-apple-darwin
latest-2023-01-18-aarch64-apple-darwin
active toolchain
beta-3-aarch64-apple-darwin (default)
forc : 0.37.3
- forc-client
- forc-deploy : 0.37.3
- forc-run : 0.37.3
- forc-doc : 0.37.3
- forc-explore : 0.28.1
- forc-fmt : 0.37.3
- forc-index : 0.18.4
- forc-lsp : 0.37.3
- forc-tx : 0.37.3
- forc-wallet : 0.2.2
fuel-core : 0.17.11
fuel-indexer : 0.18.4
fuels versions
forc : 0.39
data_structures.sw
library data_structures;
pub enum State {
Initialized: (),
Uninitialized: (),
}
impl core::ops::Eq for State {
fn eq(self, other: Self) → bool {
match (self, other) {
(State::Initialized, State::Initialized) => true,
(State::Uninitialized, State::Uninitialized) => true,
_ => false,
}
}
}
pub struct TokenMetadata {
// This is left as an example. Support for dynamic length string is needed here
name: str[7],
}
impl TokenMetadata {
pub fn new() → Self {
Self {
name: “Example”,
}
}
}
errors.sw
library errors;
pub enum InitError {
CannotReinitialize: (),
NotInitialized: (),
}
// TODO: can rename back to AccessError once Name collision on types of different contracts · Issue #791 · FuelLabs/fuels-rs · GitHub is fixed
pub enum ValidityError {
MaxTokensMinted: (),
NoContractAdmin: (),
SenderNotAdmin: (),
}
interface.sw
library interface;
dep data_structures;
use data_structures::TokenMetadata;
abi Auxiliary {
/// Sets the inital state and unlocks the functionality for the rest of the contract.
///
/// This function can only be called once.
///
/// # Arguments
///
/// * new_admin
- The administrator to be set for this contract.
/// * new_max_supply
- The maximum supply of tokens that may ever be minted.
///
/// # Reverts
///
/// * When the contract has already been initalized
#[storage(read, write)]
fn constructor(new_admin: Option, new_max_supply: Option);
/// Returns the metadata for a specific token.
///
/// # Arguments
///
/// * `token_id` - The id of the token which the metadata should be returned.
#[storage(read)]
fn token_metadata(token_id: u64) -> Option<TokenMetadata>;
}
main.sw
contract;
dep data_structures;
dep errors;
dep interface;
use data_structures::{State, TokenMetadata};
use errors::{InitError, ValidityError};
use interface::Auxiliary;
use std::auth::msg_sender;
use nft::{
administrator::{
admin,
Administrator,
set_admin,
},
approve,
approved,
balance_of,
burnable::{
burn,
Burn,
},
is_approved_for_all,
mint,
NFT,
owner_of,
set_approval_for_all,
supply::{
max_supply,
set_max_supply,
Supply,
},
token_metadata::{
set_token_metadata,
token_metadata,
},
tokens_minted,
transfer,
};
storage {
state: State = State::Uninitialized,
}
impl Administrator for Contract {
#[storage(read)]
fn admin() → Option {
admin()
}
#[storage(read, write)]
fn set_admin(new_admin: Option<Identity>) {
require(admin().is_some(), ValidityError::NoContractAdmin);
set_admin(new_admin);
}
}
impl Burn for Contract {
#[storage(read, write)]
fn burn(token_id: u64) {
set_token_metadata(Option::None::(), token_id);
burn(token_id);
}
}
impl Auxiliary for Contract {
#[storage(read, write)]
fn constructor(new_admin: Option, new_max_supply: Option) {
require(storage.state == State::Uninitialized, InitError::CannotReinitialize);
storage.state = State::Initialized;
set_admin(new_admin);
set_max_supply(new_max_supply);
}
#[storage(read)]
fn token_metadata(token_id: u64) -> Option<TokenMetadata> {
token_metadata(token_id)
}
}
impl NFT for Contract {
#[storage(read, write)]
fn approve(approved_identity: Option, token_id: u64) {
approve(approved_identity, token_id);
}
#[storage(read)]
fn approved(token_id: u64) -> Option<Identity> {
approved(token_id)
}
#[storage(read)]
fn balance_of(owner: Identity) -> u64 {
balance_of(owner)
}
#[storage(read)]
fn is_approved_for_all(operator: Identity, owner: Identity) -> bool {
is_approved_for_all(operator, owner)
}
#[storage(read, write)]
fn mint(amount: u64, to: Identity) {
require(storage.state == State::Initialized, InitError::NotInitialized);
require(admin().is_none() || (msg_sender().unwrap() == admin().unwrap()), ValidityError::SenderNotAdmin);
require(max_supply().is_none() || (tokens_minted() + amount <= max_supply().unwrap()), ValidityError::MaxTokensMinted);
mint(amount, to);
let mut token_index = tokens_minted() - amount;
while token_index < tokens_minted() {
set_token_metadata(Option::Some(TokenMetadata::new()), token_index);
token_index += 1;
}
}
#[storage(read)]
fn owner_of(token_id: u64) -> Option<Identity> {
owner_of(token_id)
}
#[storage(write)]
fn set_approval_for_all(approval: bool, operator: Identity) {
set_approval_for_all(approval, operator);
}
#[storage(read)]
fn tokens_minted() -> u64 {
tokens_minted()
}
#[storage(read, write)]
fn transfer(to: Identity, token_id: u64) {
transfer(to, token_id);
}
}
impl Supply for Contract {
#[storage(read)]
fn max_supply() → Option {
max_supply()
}
#[storage(read, write)]
fn set_max_supply(supply: Option<u64>) {
require(storage.state == State::Uninitialized, InitError::CannotReinitialize);
set_max_supply(supply)
}
}
All 4 files are present in the src directory and the main.sw file is importing these dependencies but on compilation (forc build) I’m getting the following error:
Compiling contract nft-contract0 (/Users/mdragibhussain/Documents/BlockchainProjects/fuel-project/fresh-start/nft-contract/nft-contract0)
error
→ /Users/mdragibhussain/Documents/BlockchainProjects/fuel-project/fresh-start/nft-contract/nft-contract0/src/main.sw:3:1
|
1 |
2 |
3 | dep data_structures;
| ^^^ Expected an item.
4 | dep errors;
5 | dep interface;
|
Aborting due to 1 error.
Error: Failed to compile nft-contract0