![見出し画像](https://assets.st-note.com/production/uploads/images/144349641/rectangle_large_type_2_40bbddab462af508e79b857257f65821.png?width=1200)
【Sui直コンバトル】1st - コントラクトとコード
コントラクト
https://suivision.xyz/package/0x0a5c57a8b67f78a9186276d06aada84029d9dd362dd56eb4d6deb41bbda4c407
コード
module onigiri::chokucon_battle_first {
// === Imports ===
use std::string::{utf8, String};
use sui::sui::{SUI};
use sui::balance::{Self, Balance};
use sui::coin::{Self, Coin};
use sui::display::{Self, Display};
use sui::package::{Self};
use sui::table::{Self, Table};
// === Errors ===
const EDirectorIsPaused: u64 = 100;
const ENotWhitelisted: u64 = 101;
const EAlreadyMinted: u64 = 102;
const EAlreadyRewarded: u64 = 103;
// === Constants ===
const MINT_SUCCESS_REWARD_SUI: u64 = 5_000_000_000; // 5 SUI
// === Structs ===
public struct CHOKUCON_BATTLE_FIRST has drop {}
public struct AdminCap has store, key {
id: UID,
}
public struct Director has key, store {
id: UID,
paused: bool,
participants: Table<address, bool>,
minted: Table<address, bool>,
rewarded: Table<address, bool>,
mint_success_reward: Balance<SUI>,
}
public struct ChallengerNFT has key, store {
id: UID,
}
public struct MasterNFT has key, store {
id: UID,
}
public struct Reward<phantom T> has key {
id: UID,
balance: Balance<T>,
}
// === Initialization ===
fun init(otw: CHOKUCON_BATTLE_FIRST, ctx: &mut TxContext) {
let challenger_keys = vector[
utf8(b"name"),
utf8(b"image_url")
];
let challenger_values = vector[
utf8(b"Chokucon Battle 1st Challenger NFT"),
utf8(b"https://yefpkulasxjrieeyvjzj.supabase.co/storage/v1/object/public/images/Chokucon_Battle_1st_Challenger_NFT.png"),
];
let master_keys = vector[
utf8(b"name"),
utf8(b"image_url")
];
let master_values = vector[
utf8(b"Chokucon Battle 1st Master NFT"),
utf8(b"https://yefpkulasxjrieeyvjzj.supabase.co/storage/v1/object/public/images/Chokucon_Battle_1st_Master_NFT.png"),
];
let publisher = package::claim(otw, ctx);
let mut challenger_display = display::new_with_fields<ChallengerNFT>(&publisher, challenger_keys, challenger_values, ctx);
display::update_version(&mut challenger_display);
let mut master_display = display::new_with_fields<MasterNFT>(&publisher, master_keys, master_values, ctx);
display::update_version(&mut master_display);
transfer::public_transfer(challenger_display, ctx.sender());
transfer::public_transfer(master_display, ctx.sender());
transfer::public_transfer(publisher, ctx.sender());
transfer::transfer(AdminCap {
id: object::new(ctx),
}, ctx.sender());
transfer::share_object(Director {
id: object::new(ctx),
paused: true,
participants: table::new<address, bool>(ctx),
minted: table::new<address, bool>(ctx),
rewarded: table::new<address, bool>(ctx),
mint_success_reward: balance::zero(),
});
}
// === Public Functions ===
entry public fun mint(director: &mut Director, ctx: &mut TxContext) {
assert!(director.paused == false, EDirectorIsPaused);
assert!(table::contains(&director.participants, ctx.sender()) == true, ENotWhitelisted);
assert!(table::contains(&director.minted, ctx.sender()) == false, EAlreadyMinted);
let reward_balance = director.mint_success_reward.split(MINT_SUCCESS_REWARD_SUI);
transfer::public_transfer(coin::from_balance(reward_balance, ctx), ctx.sender());
table::add(&mut director.minted, ctx.sender(), true);
transfer::transfer(ChallengerNFT { id: object::new(ctx) }, ctx.sender());
}
entry public fun get_reward<T>(_: &ChallengerNFT, director: &mut Director, reward: &mut Reward<T>, ctx: &mut TxContext) {
assert!(director.paused == false, EDirectorIsPaused);
assert!(table::contains(&director.participants, ctx.sender()) == true, ENotWhitelisted);
assert!(table::contains(&director.rewarded, ctx.sender()) == false, EAlreadyRewarded);
let balance = reward.balance.withdraw_all();
transfer::public_transfer(coin::from_balance(balance, ctx), ctx.sender());
table::add(&mut director.rewarded, ctx.sender(), true);
transfer::transfer(MasterNFT { id: object::new(ctx) }, ctx.sender());
}
entry public fun add_reward<T>(c: Coin<T>, ctx: &mut TxContext) {
transfer::share_object(Reward {
id: object::new(ctx),
balance: c.into_balance(),
});
}
entry public fun add_mint_success_reward(director: &mut Director, c: Coin<SUI>) {
director.mint_success_reward.join(c.into_balance());
}
// === Admin functions ===
public fun admin_pause(_: &AdminCap, director: &mut Director) {
director.paused = true;
}
public fun admin_resume(_: &AdminCap, director: &mut Director) {
director.paused = false;
}
public fun admin_add_participants(_: &AdminCap, director: &mut Director, mut participants: vector<address>) {
let mut i = participants.length();
while (i > 0) {
let p = participants.pop_back();
if (table::contains(&director.participants, p) == false) {
table::add(&mut director.participants, p, true);
};
i = i - 1;
};
}
public fun admin_update_image_url(_: &AdminCap, display: &mut Display<ChallengerNFT>, image_url: String) {
display.edit(utf8(b"image_url"), image_url);
display::update_version(display);
}
entry public fun admin_withdraw_reward<T>(_: &AdminCap, reward: &mut Reward<T>, ctx: &mut TxContext) {
let balance = reward.balance.withdraw_all();
transfer::public_transfer(coin::from_balance(balance, ctx), ctx.sender());
}
entry public fun admin_withdraw_mint_reward(_: &AdminCap, director: &mut Director, ctx: &mut TxContext) {
let balance = director.mint_success_reward.withdraw_all();
transfer::public_transfer(coin::from_balance(balance, ctx), ctx.sender());
}
}