이 예제는 온체인 메타데이터, 일시 중지 가능한 전송, 영구 대리자, 그리고 동결된 상태로 시작하는 token accounts가 포함된 Token-2022 mint를 생성합니다. Kit, 레거시 TypeScript 또는 Rust를 선택한 다음, 격리된 테스트 네트워크에서 실행하세요:
import { createClient, generateKeyPairSigner, lamports } from "@solana/kit";import { rpcAirdrop, solanaRpc } from "@solana/kit-plugin-rpc";import { airdropPayer, payer as kitPayer } from "@solana/kit-plugin-signer";import { getCreateAccountInstruction } from "@solana-program/system";import {AccountState,TOKEN_2022_PROGRAM_ADDRESS,extension,fetchMint,getInitializeMintInstruction,getMintSize,getPostInitializeInstructionsForMintExtensions,getPreInitializeInstructionsForMintExtensions,} from "@solana-program/token-2022";const payer = await generateKeyPairSigner();const mint = await generateKeyPairSigner();const client = await createClient().use(kitPayer(payer)).use(solanaRpc({rpcUrl: "http://localhost:8899",rpcSubscriptionsUrl: "ws://localhost:8900",}),).use(rpcAirdrop()).use(airdropPayer(lamports(1_000_000_000n)));// A compliance-ready Token-2022 mint: onchain metadata, pausable transfers,// a permanent delegate that can move or burn any balance, and token accounts// that start frozen until the issuer thaws them.const extensions = [extension("MetadataPointer", {authority: payer.address,metadataAddress: mint.address,}),extension("TokenMetadata", {updateAuthority: payer.address,mint: mint.address,name: "Example Stablecoin",symbol: "EXUSD",uri: "https://example.com/exusd.json",additionalMetadata: new Map<string, string>(),}),extension("PausableConfig", { authority: payer.address, paused: false }),extension("PermanentDelegate", { delegate: payer.address }),extension("DefaultAccountState", { state: AccountState.Frozen }),];// Token metadata is written after the mint is initialized, so allocate the// account without it but fund rent for the full size.const spaceWithoutMetadata = BigInt(getMintSize(extensions.filter(({ __kind }) => __kind !== "TokenMetadata")),);const spaceWithMetadata = BigInt(getMintSize(extensions));const rent = await client.rpc.getMinimumBalanceForRentExemption(spaceWithMetadata).send();const instructions = [getCreateAccountInstruction({payer,newAccount: mint,lamports: rent,space: spaceWithoutMetadata,programAddress: TOKEN_2022_PROGRAM_ADDRESS,}),...getPreInitializeInstructionsForMintExtensions(mint.address, extensions),getInitializeMintInstruction({mint: mint.address,decimals: 6,mintAuthority: payer.address,freezeAuthority: payer.address,}),...getPostInitializeInstructionsForMintExtensions(mint.address,payer,extensions,),];const { context } = await client.sendTransaction(instructions);console.log("Transaction Signature:", context.signature);// Verify the mint and its extensionsconst mintAccount = await fetchMint(client.rpc, mint.address);const enabledExtensions =mintAccount.data.extensions.__option === "Some"? mintAccount.data.extensions.value.map(({ __kind }) => __kind): [];console.log("Mint Address:", mintAccount.address);console.log("Decimals:", mintAccount.data.decimals);console.log("Extensions:", enabledExtensions.join(", "));
Console
Click to execute the code.
트랜잭션 서명, mint 주소, 활성화된 확장 기능 목록이 표시됩니다.
devnet을 대상으로 지정하기
RPC URL을 devnet용으로 교체하고 faucet에서 payer에 자금을 공급하세요:
solanaRpc({rpcUrl: "https://api.devnet.solana.com",rpcSubscriptionsUrl: "wss://api.devnet.solana.com"});
그 외에는 모두 동일합니다. mainnet에서 동일한 구성을 사용하기 전에, 해당 자산의 권한 관리, 컴플라이언스 운영, 모니터링을 계획하세요.
다음 단계
- Solana의 자산 - mint accounts, token accounts 및 권한
- Token Extensions - 자산에 필요한 제어 기능만 선택하세요
- 토큰 ACL - 허용 목록과 차단 목록 적용
- Delivery versus payment - 자산과 그 결제를 원자적으로 정산
Is this page helpful?