Learn Sui development with practical examples, from basic smart contracts to complex DeFi protocols. All examples are production-ready and thoroughly tested.
module my_coin::my_coin {
use sui::coin::{Self, Coin, TreasuryCap};
use sui::url::{Self, Url};
/// The type identifier of coin. The coin will have a type
/// tag of kind: `Coin<package_object::mycoin::MYCOIN>`
/// Make sure that the name of the type matches the module's name.
struct MYCOIN has drop {}
/// Module initializer is called once on module publish. A treasury
/// cap is sent to the publisher, who then controls minting and burning
fun init(witness: MYCOIN, ctx: &mut TxContext) {
let (treasury, metadata) = coin::create_currency<MYCOIN>(
witness,
9,
b"MYCOIN",
b"My Coin",
b"My custom coin on Sui",
option::some<Url>(url::new_unsafe_from_bytes(b"https://example.com/icon.png")),
ctx
);
transfer::public_freeze_object(metadata);
transfer::public_transfer(treasury, tx_context::sender(ctx));
}
public entry fun mint(
treasury_cap: &mut TreasuryCap<MYCOIN>,
amount: u64,
recipient: address,
ctx: &mut TxContext,
) {
coin::mint_and_transfer(treasury_cap, amount, recipient, ctx);
}
public entry fun burn(treasury_cap: &mut TreasuryCap<MYCOIN>, coin: Coin<MYCOIN>) {
coin::burn(treasury_cap, coin);
}
}module nft_collection::collection {
use sui::object::{Self, UID};
use sui::transfer;
use sui::tx_context::{Self, TxContext};
use sui::url::{Self, Url};
use std::string::{Self, String};
use sui::event;
/// The NFT structure
struct NFT has key, store {
id: UID,
name: String,
description: String,
image_url: Url,
creator: address,
edition: u64,
}
/// Collection information
struct Collection has key {
id: UID,
name: String,
description: String,
creator: address,
total_supply: u64,
max_supply: u64,
}
/// Event emitted when an NFT is minted
struct NFTMinted has copy, drop {
nft_id: address,
creator: address,
recipient: address,
edition: u64,
}
/// Create a new collection
public entry fun create_collection(
name: vector<u8>,
description: vector<u8>,
max_supply: u64,
ctx: &mut TxContext
) {
let collection = Collection {
id: object::new(ctx),
name: string::utf8(name),
description: string::utf8(description),
creator: tx_context::sender(ctx),
total_supply: 0,
max_supply,
};
transfer::share_object(collection);
}
/// Mint a new NFT
public entry fun mint_nft(
collection: &mut Collection,
name: vector<u8>,
description: vector<u8>,
image_url: vector<u8>,
recipient: address,
ctx: &mut TxContext
) {
assert!(collection.total_supply < collection.max_supply, 0);
assert!(tx_context::sender(ctx) == collection.creator, 1);
collection.total_supply = collection.total_supply + 1;
let nft = NFT {
id: object::new(ctx),
name: string::utf8(name),
description: string::utf8(description),
image_url: url::new_unsafe_from_bytes(image_url),
creator: collection.creator,
edition: collection.total_supply,
};
let nft_id = object::id_address(&nft);
event::emit(NFTMinted {
nft_id,
creator: collection.creator,
recipient,
edition: collection.total_supply,
});
transfer::public_transfer(nft, recipient);
}
}