AsetHoki Mint
Alamat mint Token-2022 kanonis yang mengidentifikasi aset ini.
Fungsi transfer dan pencatatan saldo dijalankan SPL Token-2022. Program Anchor AsetHoki hanya menjadi lapisan konfigurasi. Semakin sedikit yang ditulis sendiri, semakin sedikit yang bisa salah secara permanen.
Alamat mint Token-2022 kanonis yang mengidentifikasi aset ini.
Dompet terpisah untuk alokasi Ekosistem, pengembangan, kemitraan, vesting tim, komunitas, dan kepatuhan.
Layanan backend yang menanyakan RPC/indexer Solana lalu memulangkan status kelayakan.
Pemetaan aman antara akun Ekosistem terautentikasi dan alamat dompet Solana yang terverifikasi.
Menyimpan admin, alamat mint, treasury, suplai total, dan ambang akses Ekosistem.
Pemantauan transaksi, peringatan treasury, kesehatan RPC, status sinkronisasi dompet, dan pencatatan insiden.
Kepemilikan token berada di rantai. Otorisasi Ekosistem, kontrak pelanggan, penagihan langganan, dan aturan bisnis rinci tetap di luar rantai. Ini menekan biaya transaksi dan mencegah setiap penyesuaian kebijakan Ekosistem berubah menjadi pemutakhiran program blockchain.
Karena seluruh suplai dibuat satu kali lewat Token-2022, program akses tidak memerlukan fungsi mint imbalan yang dapat menambah suplai.
use anchor_lang::prelude::*;
declare_id!("AHoKi1111111111111111111111111111111111111");
pub const DECIMALS: u8 = 9;
pub const MAX_SUPPLY_TOKENS: u64 = 8_888_888;
#[program]
pub mod asethoki_access {
use super::*;
pub fn initialize_config(
ctx: Context<InitializeConfig>,
basic_threshold: u64,
pro_threshold: u64,
enterprise_threshold: u64,
) -> Result<()> {
require!(basic_threshold > 0, AsetHokiError::InvalidThreshold);
require!(basic_threshold < pro_threshold, AsetHokiError::InvalidThreshold);
require!(pro_threshold < enterprise_threshold, AsetHokiError::InvalidThreshold);
let cfg = &mut ctx.accounts.config;
cfg.admin = ctx.accounts.admin.key();
cfg.mint = ctx.accounts.mint;
cfg.treasury = ctx.accounts.treasury;
cfg.max_supply_tokens = MAX_SUPPLY_TOKENS;
cfg.basic_threshold = basic_threshold;
cfg.pro_threshold = pro_threshold;
cfg.enterprise_threshold = enterprise_threshold;
cfg.bump = ctx.bumps.config;
Ok(())
}
pub fn update_thresholds(
ctx: Context<UpdateThresholds>,
basic_threshold: u64,
pro_threshold: u64,
enterprise_threshold: u64,
) -> Result<()> {
require!(basic_threshold > 0, AsetHokiError::InvalidThreshold);
require!(basic_threshold < pro_threshold, AsetHokiError::InvalidThreshold);
require!(pro_threshold < enterprise_threshold, AsetHokiError::InvalidThreshold);
let cfg = &mut ctx.accounts.config;
cfg.basic_threshold = basic_threshold;
cfg.pro_threshold = pro_threshold;
cfg.enterprise_threshold = enterprise_threshold;
Ok(())
}
}
#[account]
pub struct AsetHokiConfig {
pub admin: Pubkey,
pub mint: Pubkey,
pub treasury: Pubkey,
pub max_supply_tokens: u64,
pub basic_threshold: u64,
pub pro_threshold: u64,
pub enterprise_threshold: u64,
pub bump: u8,
}
Ambang divalidasi menaik (basic < pro < enterprise) dan admin diikat lewat has_one pada UpdateThresholds — tanpa itu siapa pun yang menandatangani bisa menulis ulang kebijakan akses seluruh Ekosistem.
import { Connection, Keypair, clusterApiUrl } from "@solana/web3.js";
import {
TOKEN_2022_PROGRAM_ID, AuthorityType,
createMint, getOrCreateAssociatedTokenAccount, mintTo, setAuthority,
} from "@solana/spl-token";
const DECIMALS = 9;
const TOTAL_SUPPLY = 8_888_888n;
const mint = await createMint(
connection, payer, mintAuthority.publicKey, freezeAuthority,
DECIMALS, undefined, undefined, TOKEN_2022_PROGRAM_ID,
);
const baseUnits = TOTAL_SUPPLY * (10n ** BigInt(DECIMALS));
await mintTo(connection, payer, mint, treasuryAta.address,
mintAuthority, baseUnits, [], undefined, TOKEN_2022_PROGRAM_ID);
// Suplai dibuat tetap: cabut mint authority setelah seluruh suplai dicetak.
await setAuthority(connection, payer, mint, mintAuthority,
AuthorityType.MintTokens, null, [], undefined,
TOKEN_2022_PROGRAM_ID);
Cuplikan di atas memperlakukan 8.888.888 sebagai suplai tetap dan memakai clusterApiUrl("devnet") beserta keypair yang dihasilkan di tempat. Penerapan sungguhan memerlukan signer yang aman, pengujian, audit keamanan, serta tinjauan desain operasional dan regulasi.
Bila mint authority justru ingin dipertahankan untuk kebutuhan tertentu, desain tata kelola, batas mint, multisig, dan kontrol suplai harus dibuat berbeda — dan klaim “suplai tetap” harus dicabut dari seluruh materi.
export async function getAsetHokiAccessLevel(
connection: Connection, walletAddress: string, mintAddress: string,
) {
const owner = new PublicKey(walletAddress);
const mint = new PublicKey(mintAddress);
const accounts = await connection.getParsedTokenAccountsByOwner(owner, {
programId: TOKEN_2022_PROGRAM_ID,
});
let balance = 0;
for (const item of accounts.value) {
const info = item.account.data.parsed.info;
if (info.mint === mint.toBase58()) {
balance += Number(info.tokenAmount.uiAmount || 0);
}
}
if (balance >= 5000) return { level: "Enterprise", balance };
if (balance >= 500) return { level: "Professional", balance };
if (balance >= 100) return { level: "Basic", balance };
return { level: "Trial", balance };
}
Hasil RPC sebaiknya dikombinasikan dengan caching, percobaan ulang, pemeriksaan finalitas, pemantauan, dan masa tenggang — agar perubahan saldo tidak mendadak mengganggu operasional perusahaan pengguna. Pemadaman RPC harus jatuh ke mode terdegradasi yang terdefinisi, bukan ke penolakan akses.
Aset kripto tidak mengenal pembatalan: tidak ada chargeback, tidak ada pemulihan. Kontrol berikut diterapkan sebelum mainnet, bukan sesudah.
| Kontrol | Yang harus dipastikan |
|---|---|
| Verifikasi suplai tetap | Setelah mint 8.888.888 selesai, pastikan mint authority benar-benar sudah dicabut bila suplai tetap adalah kebijakan final. |
| Multisig treasury | Treasury besar tidak boleh dikendalikan satu private key. |
| Freeze authority | Tentukan secara eksplisit apakah dipertahankan, dipindahkan ke multisig, atau dicabut. |
| Audit penerapan | Catat alamat mint, program ID, treasury, authority, signature transaksi, dan konfigurasi ambang. |
| Keamanan dompet | Jangan menyimpan private key pengguna di basis data biasa; pakai non-kustodial, MPC, atau kustodian yang sesuai. |
| Fail-safe Ekosistem | Masa tenggang dan mekanisme cadangan bila RPC gagal atau data saldo sementara tidak tersedia. |
| Vesting | Kontrak vesting atau proses berkunci waktu untuk alokasi tim dan kontributor. |
| Audit independen | Audit smart contract oleh pihak ketiga sebelum dipakai di mainnet. |
| Batas laju imbalan | Pembatasan laju dan alur persetujuan untuk distribusi imbalan. |
| Redundansi RPC | RPC/indexer ganda beserta pemantauannya untuk verifikasi saldo. |