Skip to content

Commit

Permalink
Merge pull request #35 from FuelLabs/bitzoic-src7-example
Browse files Browse the repository at this point in the history
Add SRC-7 Basic Examples
  • Loading branch information
bitzoic authored Nov 8, 2023
2 parents 07b8565 + ad7826f commit 3deceb3
Show file tree
Hide file tree
Showing 5 changed files with 253 additions and 0 deletions.
2 changes: 2 additions & 0 deletions examples/Forc.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ members = [
"src_3/multi_asset",
"src_5/initialized_example",
"src_5/uninitialized_example",
"src_7/single_asset",
"src_7/multi_asset",
"src_20/single_asset",
"src_20/multi_asset",
]
9 changes: 9 additions & 0 deletions examples/src_7/multi_asset/Forc.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[project]
authors = ["Fuel Labs <contact@fuel.sh>"]
entry = "multi_asset.sw"
license = "Apache-2.0"
name = "multi_src7_asset"

[dependencies]
src_20 = { path = "../../../standards/src_20" }
src_7 = { path = "../../../standards/src_7" }
122 changes: 122 additions & 0 deletions examples/src_7/multi_asset/src/multi_asset.sw
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
contract;

use src_7::{Metadata, SRC7};
use src_20::SRC20;

use std::{call_frames::contract_id, hash::Hash, storage::storage_string::*, string::String};

// In this example, all assets minted from this contract have the same decimals, name, and symbol
configurable {
/// The decimals of every asset minted by this contract.
DECIMALS: u8 = 0u8,
/// The name of every asset minted by this contract.
NAME: str[7] = __to_str_array("MyAsset"),
/// The symbol of every asset minted by this contract.
SYMBOL: str[5] = __to_str_array("MYAST"),
/// The metadata for the "social:x" key.
SOCIAL_X: str[12] = __to_str_array("fuel_network"),
/// The metadata for the "site:forum" key.
SITE_FORUM: str[27] = __to_str_array("https://forum.fuel.network/"),
}

storage {
/// The total number of distinguishable assets this contract has minted.
total_assets: u64 = 0,
/// The total supply of a particular asset.
total_supply: StorageMap<AssetId, u64> = StorageMap {},
/// The metadata for the "image:svg" key.
svg_images: StorageMap<AssetId, StorageString> = StorageMap {},
/// The metadata for the "attr:health" key.
health_attributes: StorageMap<AssetId, u64> = StorageMap {},
}

impl SRC7 for Contract {
/// Returns metadata for the corresponding `asset` and `key`.
///
/// # Arguments
///
/// * `asset`: [AssetId] - The asset of which to query the metadata.
/// * `key`: [String] - The key to the specific metadata.
///
/// # Returns
///
/// * [Option<Metadata>] - `Some` metadata that corresponds to the `key` or `None`.
///
/// # Examples
///
/// ```sway
/// use src_7::{SRC7, Metadata};
/// use std::string::String;
///
/// fn foo(contract_id: ContractId, asset: AssetId) {
/// let contract_abi = abi(SRC7, contract_id);
/// let key = String::from_ascii_str("social:x");
/// let data = contract_abi.metadata(asset, key);
/// assert(data.unwrap() == Metadata::String(String::from_ascii_str("fuel_network")));
/// }
/// ```
#[storage(read)]
fn metadata(asset: AssetId, key: String) -> Option<Metadata> {
if key == String::from_ascii_str("social:x") {
Some(Metadata::String(String::from_ascii_str(from_str_array(SOCIAL_X))))
} else if key == String::from_ascii_str("site:forum") {
Some(Metadata::String(String::from_ascii_str(from_str_array(SITE_FORUM))))
} else if key == String::from_ascii_str("image:svg") {
let svg_image = storage.svg_images.get(asset).read_slice();

match svg_image {
Some(svg) => Some(Metadata::String(svg)),
None => None,
}
} else if key == String::from_ascii_str("attr:health") {
let health_attribute = storage.health_attributes.get(asset).try_read();

match health_attribute {
Some(health) => Some(Metadata::Int(health)),
None => None,
}
} else {
None
}
}
}

// SRC7 extends SRC20, so this must be included
impl SRC20 for Contract {
#[storage(read)]
fn total_assets() -> u64 {
storage.total_assets.read()
}

#[storage(read)]
fn total_supply(asset: AssetId) -> Option<u64> {
storage.total_supply.get(asset).try_read()
}

#[storage(read)]
fn name(asset: AssetId) -> Option<String> {
if asset == AssetId::default(contract_id()) {
Some(String::from_ascii_str(from_str_array(NAME)))
} else {
None
}
}

#[storage(read)]
fn symbol(asset: AssetId) -> Option<String> {
if asset == AssetId::default(contract_id()) {
Some(String::from_ascii_str(from_str_array(SYMBOL)))
} else {
None
}
}

#[storage(read)]
fn decimals(asset: AssetId) -> Option<u8> {
if asset == AssetId::default(contract_id()) {
Some(DECIMALS)
} else {
None
}
}
}
9 changes: 9 additions & 0 deletions examples/src_7/single_asset/Forc.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[project]
authors = ["Fuel Labs <contact@fuel.sh>"]
entry = "single_asset.sw"
license = "Apache-2.0"
name = "single_src7_asset"

[dependencies]
src_20 = { path = "../../../standards/src_20" }
src_7 = { path = "../../../standards/src_7" }
111 changes: 111 additions & 0 deletions examples/src_7/single_asset/src/single_asset.sw
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
contract;

use src_7::{Metadata, SRC7};
use src_20::SRC20;

use std::{call_frames::contract_id, string::String};

configurable {
/// The total supply of tokens for the asset minted by this contract.
TOTAL_SUPPLY: u64 = 100_000_000,
/// The decimals of the asset minted by this contract.
DECIMALS: u8 = 9u8,
/// The name of the asset minted by this contract.
NAME: str[7] = __to_str_array("MyToken"),
/// The symbol of the asset minted by this contract.
SYMBOL: str[5] = __to_str_array("MYTKN"),
/// The metadata for the "social:x" key.
SOCIAL_X: str[12] = __to_str_array("fuel_network"),
/// The metadata for the "site:forum" key.
SITE_FORUM: str[27] = __to_str_array("https://forum.fuel.network/"),
/// The metadata for the "attr:health" key.
ATTR_HEALTH: u64 = 100,
}

impl SRC7 for Contract {
/// Returns metadata for the corresponding `asset` and `key`.
///
/// # Arguments
///
/// * `asset`: [AssetId] - The asset of which to query the metadata.
/// * `key`: [String] - The key to the specific metadata.
///
/// # Returns
///
/// * [Option<Metadata>] - `Some` metadata that corresponds to the `key` or `None`.
///
/// # Reverts
///
/// * When the AssetId provided does not match the default SubId.
///
/// # Examples
///
/// ```sway
/// use src_7::{SRC7, Metadata};
/// use std::string::String;
///
/// fn foo(contract_id: ContractId, asset: AssetId) {
/// let contract_abi = abi(SRC7, contract_id);
/// let key = String::from_ascii_str("social:x");
/// let data = contract_abi.metadata(asset, key);
/// assert(data.unwrap() == Metadata::String(String::from_ascii_str("fuel_network")));
/// }
/// ```
#[storage(read)]
fn metadata(asset: AssetId, key: String) -> Option<Metadata> {
require(asset == AssetId::default(contract_id()), "Invalid AssetId provided");

if key == String::from_ascii_str("social:x") {
Some(Metadata::String(String::from_ascii_str(from_str_array(SOCIAL_X))))
} else if key == String::from_ascii_str("site:forum") {
Some(Metadata::String(String::from_ascii_str(from_str_array(SITE_FORUM))))
} else if key == String::from_ascii_str("attr:health") {
Some(Metadata::Int(ATTR_HEALTH))
} else {
None
}
}
}

impl SRC20 for Contract {
#[storage(read)]
fn total_assets() -> u64 {
1
}

#[storage(read)]
fn total_supply(asset: AssetId) -> Option<u64> {
if asset == AssetId::default(contract_id()) {
Some(TOTAL_SUPPLY)
} else {
None
}
}

#[storage(read)]
fn name(asset: AssetId) -> Option<String> {
if asset == AssetId::default(contract_id()) {
Some(String::from_ascii_str(from_str_array(NAME)))
} else {
None
}
}

#[storage(read)]
fn symbol(asset: AssetId) -> Option<String> {
if asset == AssetId::default(contract_id()) {
Some(String::from_ascii_str(from_str_array(SYMBOL)))
} else {
None
}
}

#[storage(read)]
fn decimals(asset: AssetId) -> Option<u8> {
if asset == AssetId::default(contract_id()) {
Some(DECIMALS)
} else {
None
}
}
}

0 comments on commit 3deceb3

Please sign in to comment.