결제고급 결제

지출 권한

Solana의 토큰 프로그램은 위임을 지원합니다. 이는 다른 계정에 지정된 한도까지 귀하의 토큰 계정에서 토큰을 전송할 수 있는 권한을 부여하는 것입니다. 이를 통해 자금의 보관권을 포기하지 않으면서도 자동 결제, 에스크로 서비스, 제3자 결제 처리와 같은 사용 사례를 구현할 수 있습니다.

위임 작동 방식

위임자를 승인하면 특정 계정이 귀하를 대신하여 토큰을 전송할 수 있도록 권한을 부여하는 것입니다.

  • 소유자가 보관권 유지: 귀하는 여전히 토큰을 소유하며 언제든지 전송하거나 취소할 수 있습니다
  • 지출 한도 설정: 위임자는 승인된 금액까지만 전송할 수 있습니다
  • 계정당 단일 위임자: 각 토큰 계정은 하나의 활성 위임자만 가질 수 있습니다
  • 새 승인이 이전 승인 대체: 새 위임자를 승인하면 이전 위임자가 자동으로 취소됩니다

위임은 비수탁 방식입니다. 위임자는 한도까지 토큰을 지출할 수 있지만, 승인된 금액을 초과하여 계정에 접근하거나 인출할 수 없습니다. 소유자는 언제든지 취소할 수 있습니다.

비즈니스 사용 사례

사용 사례위임이 도움이 되는 방식
결제 처리업체판매자가 처리업체에 거래 정산 권한 부여
자동 급여 지급재무부가 급여 서비스에 급여 지급 승인
에스크로 서비스구매자가 조건부 출금을 위해 에스크로 대리인에게 위임
거래 플랫폼사용자가 거래소에 대신 거래 실행 승인
카드 발급사용자가 카드 발급사에 토큰 계정에서 구매 대금 청구 승인

위임자 승인

다른 계정에 귀하의 계정에서 토큰을 사용할 수 있는 권한을 부여합니다:

import { getApproveCheckedInstruction } from "@solana-program/token";
// Approve delegate to spend up to 1,000 USDC (6 decimals)
const approveInstruction = getApproveCheckedInstruction({
source: tokenAccountAddress, // Your token account
mint: usdcMintAddress, // USDC mint
delegate: delegateAddress, // Account receiving permission
owner: ownerKeypair, // You (must sign)
amount: 1_000_000_000n, // 1,000 USDC in base units
decimals: 6
});

매개변수:

  • source: 권한을 부여하는 토큰 계정
  • delegate: 사용 권한을 갖게 될 계정
  • owner: 토큰 계정의 현재 소유자(트랜잭션에 서명해야 함)
  • amount: 위임자가 전송할 수 있는 최대 토큰 수
  • decimals: 검증을 위한 토큰 소수점 자릿수(소수점 오류 방지)

데모

Approve Delegate
// Generate keypairs for sender and delegate
const sender = (await generateKeypair()).signer;
const delegate = (await generateKeypair()).signer;
console.log("Sender Address:", sender.address);
console.log("Delegate Address:", delegate.address);
// Demo Setup: Create client, mint account, token account, and fund with initial tokens
const { client, mint, senderAta } = await demoSetup(sender);
console.log("\nMint Address:", mint.address);
console.log("Sender ATA:", senderAta);
// =============================================================================
// Approve Delegate
// =============================================================================
// Create instruction to approve delegate
const approveInstruction = getApproveCheckedInstruction({
source: senderAta,
mint: mint.address,
delegate: delegate.address,
owner: sender,
amount: 1_000_000n, // 1.0 tokens with 6 decimals
decimals: 6
});
// Send approve transaction
const signature = await client.transaction.prepareAndSend({
authority: sender,
instructions: [approveInstruction]
});
console.log("\n=== Approve Delegate ===");
console.log("Transaction Signature:", signature);
// Fetch token account data to show delegate is set
const tokenData = await fetchToken(client.runtime.rpc, senderAta);
console.log("\nSender Token Account Data:", tokenData.data);
// =============================================================================
// Demo Setup Helper Function
// =============================================================================
Console
Click to execute the code.

위임자 권한 취소

현재 위임자의 모든 지출 권한을 제거합니다:

import { getRevokeInstruction } from "@solana-program/token";
const revokeInstruction = getRevokeInstruction({
source: tokenAccountAddress, // Your token account
owner: ownerKeypair // You (must sign)
});

취소는 모든 위임자 권한을 제거합니다—부분 취소는 불가능합니다. 한도를 줄여야 하는 경우, 동일한 위임자에게 더 낮은 금액으로 다시 승인하세요.

데모

Revoke Delegate
// Generate keypairs for sender and delegate
const sender = (await generateKeypair()).signer;
const delegate = (await generateKeypair()).signer;
console.log("Sender Address:", sender.address);
console.log("Delegate Address:", delegate.address);
// Demo Setup: Create client, mint account, token account, and fund with initial tokens
const { client, mint, senderAta } = await demoSetup(sender);
console.log("\nMint Address:", mint.address);
console.log("Sender ATA:", senderAta);
// =============================================================================
// Transaction 1: Approve Delegate
// =============================================================================
// Create instruction to approve delegate
const approveInstruction = getApproveCheckedInstruction({
source: senderAta,
mint: mint.address,
delegate: delegate.address,
owner: sender,
amount: 1_000_000n, // 1.0 tokens with 6 decimals
decimals: 6
});
// Send approve transaction
const approveSignature = await client.transaction.prepareAndSend({
authority: sender,
instructions: [approveInstruction]
});
console.log("\n=== Transaction 1: Approve Delegate ===");
console.log("Transaction Signature:", approveSignature);
// Fetch token account data to show delegate is set
const tokenDataAfterApprove = await fetchToken(client.runtime.rpc, senderAta);
console.log("\nSender Token Account Data:", tokenDataAfterApprove.data);
// =============================================================================
// Transaction 2: Revoke Delegate
// =============================================================================
// Create instruction to revoke delegate
const revokeInstruction = getRevokeInstruction({
source: senderAta,
owner: sender
});
// Send revoke transaction
const revokeSignature = await client.transaction.prepareAndSend({
authority: sender,
instructions: [revokeInstruction]
});
console.log("\n=== Transaction 2: Revoke Delegate ===");
console.log("Transaction Signature:", revokeSignature);
// Fetch token account data to show delegate is revoked
const tokenDataAfterRevoke = await fetchToken(client.runtime.rpc, senderAta);
console.log("\nSender Token Account Data:", tokenDataAfterRevoke.data);
// =============================================================================
// Demo Setup Helper Function
// =============================================================================
Console
Click to execute the code.

위임자로서 전송하기

위임자로 활동할 때는 표준 전송을 사용하되 소유자 대신 위임자 keypair로 서명합니다:

Transfer as Delegate
import { getTransferCheckedInstruction } from "@solana-program/token";
const transferInstruction = getTransferCheckedInstruction({
source: ownerTokenAccount, // The account you have permission to spend from
mint: usdcMintAddress,
destination: recipientTokenAccount,
authority: delegateKeypair, // You (the delegate) sign, not the owner
amount: 100_000_000n, // 100 USDC
decimals: 6
});

다음 조건이 충족되면 전송이 성공합니다:

  • 출처 계정에 충분한 잔액이 있음
  • 위임자가 트랜잭션에 서명함

각 전송은 남은 허용량을 감소시킵니다. 허용량이 0에 도달하면 위임자는 더 이상 토큰을 전송할 수 없습니다.

데모

Transfer as Delegate
// Generate keypairs for sender, delegate, and recipient
const sender = (await generateKeypair()).signer;
const delegate = (await generateKeypair()).signer;
const recipient = (await generateKeypair()).signer;
console.log("Sender Address:", sender.address);
console.log("Delegate Address:", delegate.address);
console.log("Recipient Address:", recipient.address);
// Demo Setup: Create client, mint account, token accounts, and fund with initial tokens
const { client, mint, senderAta, recipientAta } = await demoSetup(
sender,
delegate,
recipient
);
console.log("\nMint Address:", mint.address);
console.log("Sender ATA:", senderAta);
console.log("Recipient ATA:", recipientAta);
// =============================================================================
// Transaction 1: Approve Delegate
// =============================================================================
// Create instruction to approve delegate
const approveInstruction = getApproveCheckedInstruction({
source: senderAta,
mint: mint.address,
delegate: delegate.address,
owner: sender,
amount: 1_000_000n, // 1.0 tokens with 6 decimals
decimals: 6
});
// Send approve transaction
const approveSignature = await client.transaction.prepareAndSend({
authority: sender,
instructions: [approveInstruction]
});
console.log("\n=== Transaction 1: Approve Delegate ===");
console.log("Delegate Address:", delegate.address);
console.log("Transaction Signature:", approveSignature);
// =============================================================================
// Fetch Token Account Data to Demonstrate Delegate is Set
// =============================================================================
const tokenAccountData = await fetchToken(client.runtime.rpc, senderAta);
console.log("\nSender Token Account Data:", tokenAccountData.data);
// =============================================================================
// Transaction 2: Transfer Using Delegate
// =============================================================================
// Create instruction to transfer tokens using delegate
// Note: delegate is the authority here, not the owner
const transferInstruction = getTransferCheckedInstruction({
source: senderAta,
mint: mint.address,
destination: recipientAta,
authority: delegate, // Delegate signs this transaction
amount: 500_000n, // 0.5 tokens with 6 decimals
decimals: 6
});
// Send transfer transaction
// Delegate pays for the transaction and authorizes the transfer (sender not needed)
const transferSignature = await client.transaction.prepareAndSend({
authority: delegate, // Delegate pays fee and signs
instructions: [transferInstruction]
});
// =============================================================================
// Fetch Final Token Account Balances
// =============================================================================
const finalSenderToken = await fetchToken(client.runtime.rpc, senderAta);
const finalRecipientToken = await fetchToken(client.runtime.rpc, recipientAta);
console.log("\n=== Transaction 2: Transfer Using Delegate ===");
console.log("Transaction Signature:", transferSignature);
console.log("\nSender Token Account Data:", finalSenderToken.data);
console.log("\nRecipient Token Account Data:", finalRecipientToken.data);
// =============================================================================
// Demo Setup Helper Function
// =============================================================================
Console
Click to execute the code.

위임 상태 확인

토큰 계정을 조회하여 현재 위임자와 남은 허용량을 확인합니다:

import { fetchToken } from "@solana-program/token";
const tokenAccount = await fetchToken(rpc, tokenAccountAddress);
if (tokenAccount.data.delegate) {
console.log("Delegate:", tokenAccount.data.delegate);
console.log("Remaining allowance:", tokenAccount.data.delegatedAmount);
} else {
console.log("No delegate set");
}

데모

Check Delegation Status
// Demo Setup: Create client, mint, two token accounts (one with delegate, one without)
const { client, ataWithDelegate, ataWithoutDelegate } = await demoSetup();
// =============================================================================
// Fetch Token Accounts
// =============================================================================
// Fetch token account with delegate
const tokenWithDelegate = await fetchToken(client.runtime.rpc, ataWithDelegate);
console.log("Token Account with Delegate:", tokenWithDelegate);
// Fetch token account without delegate
const tokenWithoutDelegate = await fetchToken(
client.runtime.rpc,
ataWithoutDelegate
);
console.log("\nToken Account without Delegate:", tokenWithoutDelegate);
// =============================================================================
// Demo Setup Helper Function
// =============================================================================
Console
Click to execute the code.

보안 고려사항

계정 소유자의 경우:

  • 신뢰할 수 있는 위임자만 승인하세요
  • 필요한 최소한의 지출 한도를 설정하세요
  • 더 이상 필요하지 않을 때 위임을 취소하세요
  • 예상치 못한 전송이 있는지 계정을 모니터링하세요

서비스 제공자(위임자)의 경우:

  • 사용자에게 요청된 지출 한도를 명확하게 전달하세요
  • 위임자 계정에 대한 적절한 키 관리를 구현하세요
  • 한도가 소진되기 전에 재승인을 요청할 수 있도록 허용량 소비를 추적하세요

위임 vs. 보관

측면위임완전 보관
토큰 소유권사용자가 보유사용자가 보관자에게 이전
지출 통제승인된 금액으로 제한이전된 자금에 대한 전체 접근
취소소유자가 즉시 가능보관자의 협조 필요
위험 노출승인된 금액으로 제한전체 잔액
필요한 신뢰제한적높음

위임은 중간 지점을 제공합니다—승인된 금액으로 위험 노출을 제한하면서 자동 결제를 가능하게 합니다.

관련 리소스

리소스설명
위임자 승인다른 계정에 토큰 계정에서 지출할 수 있는 권한을 부여하는 방법입니다.
위임자 취소기존 위임자를 제거하고 지출 권한을 취소하는 방법입니다.
토큰 전송토큰 계정 간에 토큰을 전송하는 방법입니다.

Is this page helpful?

목차

페이지 편집

관리자

© 2026 솔라나 재단.
모든 권리 보유.
연결하기