Confidential Transfer 확장으로 mint를 생성하는 방법
Confidential Transfer 확장은 mint account에 추가 상태를 더해 프라이빗 토큰 전송을 가능하게 합니다. 이 섹션에서는 이 확장이 활성화된 토큰 mint를 생성하는 방법을 설명합니다.
다음 다이어그램은 Confidential Transfer 확장으로 mint를 생성하는 데 필요한 단계를 보여줍니다:
Confidential Transfer Mint 상태
이 확장은 mint account에 ConfidentialTransferMint 상태를 추가합니다:
#[repr(C)]#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]pub struct ConfidentialTransferMint {/// Authority to modify the `ConfidentialTransferMint` configuration and to/// approve new accounts (if `auto_approve_new_accounts` is true)////// The legacy Token Multisig account is not supported as the authoritypub authority: OptionalNonZeroPubkey,/// Indicate if newly configured accounts must be approved by the/// `authority` before they may be used by the user.////// * If `true`, no approval is required and new accounts may be used/// immediately/// * If `false`, the authority must approve newly configured accounts (see/// `ConfidentialTransferInstruction::ConfigureAccount`)pub auto_approve_new_accounts: PodBool,/// Authority to decode any transfer amount in a confidential transfer.pub auditor_elgamal_pubkey: OptionalNonZeroElGamalPubkey,}
*rsConfidentialTransferMint*에는 세 가지 구성 필드가 있습니다:
-
authority: mint의 기밀 전송 설정을 변경하고, 자동 승인이 비활성화된 경우 새로운 기밀 계정을 승인할 권한을 가진 계정입니다.
-
auto_approve_new_accounts: true로 설정하면 사용자가 기밀 전송이 기본적으로 활성화된 token account를 생성할 수 있습니다. false로 설정하면 authority가 각 새 token account를 기밀 전송에 사용하기 전에 승인해야 합니다.
-
auditor_elgamal_pubkey: 기밀 트랜잭션에서 전송 금액을 복호화할 수 있는 선택적 감사자로, 일반 대중으로부터 프라이버시를 유지하면서 규정 준수 메커니즘을 제공합니다.
필수 명령어
Confidential Transfer가 활성화된 mint를 생성하려면 단일 트랜잭션에서 세 가지 명령어가 필요합니다:
-
Mint Account 생성: System Program의
CreateAccount명령어를 호출하여 mint account를 생성합니다. -
Confidential Transfer 확장 초기화: Token Extensions Program의 ConfidentialTransferInstruction::InitializeMint 명령어를 호출하여 mint의
ConfidentialTransferMint상태를 구성합니다. -
Mint 초기화: Token Extensions Program의
Instruction::InitializeMint명령어를 호출하여 표준 mint 상태를 초기화합니다.
이러한 명령어를 직접 작성할 수도 있지만, spl_token_client 크레이트는 아래
예제에서 보여주듯이 단일 함수 호출로 세 가지 명령어를 모두 포함한 트랜잭션을
빌드하고 전송하는 create_mint 메서드를 제공합니다.
예제 코드
다음 코드는 Confidential Transfer 확장을 사용하여 민트를 생성하는 방법을 보여줍니다.
Confidential Transfer는 메인넷과 데브넷에서 활성화된 ZK ElGamal Proof 프로그램에
의존합니다. 기본 solana-test-validator는 이를 활성화하지 않지만,
Surfpool과 같은 메인넷 포킹 로컬 validator는
활성화합니다. 자금이 충전된 페이어를 사용하여 해당 환경 중 하나(코드는 데브넷을
사용)에서 예제를 실행하고, 플레이스홀더 민트 및 계정 주소를 본인의 것으로
교체하세요.
Rust
fn main() -> Result<()> {let rpc_client = RpcClient::new_with_commitment(String::from("https://api.devnet.solana.com"),CommitmentConfig::confirmed(),);let payer = load_keypair()?;let mint = Keypair::new();let decimals: u8 = 2;// Allocate space for a mint that carries the ConfidentialTransferMint// extension, then fund it for rent exemption.let space =ExtensionType::try_calculate_account_len::<Mint>(&[ExtensionType::ConfidentialTransferMint])?;let rent = rpc_client.get_minimum_balance_for_rent_exemption(space)?;// The auditor ElGamal key lets the issuer decrypt transfer amounts for// compliance. Persist this key. Pass `None` to create a mint with no auditor.let auditor = ElGamalKeypair::new_rand();let auditor_pubkey: PodElGamalPubkey = (*auditor.pubkey()).into();let create_account_ix = system_instruction::create_account(&payer.pubkey(),&mint.pubkey(),rent,space as u64,&spl_token_2022::id(),);// The confidential-transfer extension must be initialized before the base// mint and cannot be added later.let init_confidential_ix = initialize_confidential_transfer_mint(&spl_token_2022::id(),&mint.pubkey(),Some(payer.pubkey()), // authority that can update confidential settingstrue, // auto-approve new accountsSome(auditor_pubkey),)?;let init_mint_ix = initialize_mint_base(&spl_token_2022::id(),&mint.pubkey(),&payer.pubkey(), // mint authorityNone, // freeze authoritydecimals,)?;let blockhash = rpc_client.get_latest_blockhash()?;let transaction = Transaction::new_signed_with_payer(&[create_account_ix, init_confidential_ix, init_mint_ix],Some(&payer.pubkey()),&[&payer, &mint],blockhash,);let signature = rpc_client.send_and_confirm_transaction(&transaction)?;println!("Created confidential mint {}: {signature}", mint.pubkey());Ok(())}fn load_keypair() -> Result<Keypair> {let keypair_path = dirs::home_dir().context("could not find home directory")?.join(".config/solana/id.json");let bytes: Vec<u8> = serde_json::from_reader(std::fs::File::open(keypair_path)?)?;let mut secret = [0u8; 32];secret.copy_from_slice(&bytes[0..32]);Ok(Keypair::new_from_array(secret))}
Typescript
const client = await createClient().use(signerFromFile(join(homedir(), ".config/solana/id.json"))).use(solanaRpc({rpcUrl: "https://api.devnet.solana.com"}));const payer = client.payer;const mint = await generateKeyPairSigner();// The auditor ElGamal key lets the issuer decrypt transfer amounts for// compliance. Persist it; omit `auditorElgamalPubkey` to create a mint with no// auditor.const auditor = await deriveElGamalKeypairForOwnerMint({signer: payer,owner: payer.address,mint: mint.address});const plan = getCreateMintInstructionPlan({payer,newMint: mint,decimals: 2,mintAuthority: payer,extensions: [{__kind: "ConfidentialTransferMint",authority: some(payer.address),autoApproveNewAccounts: true,auditorElgamalPubkey: some(auditor.elgamalPubkey)}]});const result = await client.sendTransaction(plan);console.log(`Created confidential mint ${mint.address}: ${result.context.signature}`);
Is this page helpful?