Permissioned Tokens met Token ACL (sRFC37)

Token ACL (Access Control List) is een Solana-programma dat compliante, permissioned tokens mogelijk maakt zonder de gebruikerservaring te compromitteren. Het implementeert sRFC37, waarmee bedrijven tokens kunnen maken met allow/block list-functionaliteit terwijl de naadloze UX behouden blijft die gebruikers verwachten.

Het Probleem

Bedrijven hebben compliante tokens nodig die kunnen:

  1. KYC/AML-vereisten afdwingen
  2. Gesanctioneerde adressen blokkeren
  3. Tokenoverdrachten beperken tot goedgekeurde partijen

De traditionele aanpak maakt gebruik van de DefaultAccountState-extensie van Token-2022 om accounts in een bevroren toestand aan te maken, waarbij handmatige tussenkomst vereist is om elk account te ontdooien:

┌─────────────────────────────────────────────────────┐
│ TRADITIONAL FROZEN TOKENS │
├─────────────────────────────────────────────────────┤
│ │
│ 1. User creates token account │
│ └─> Account is FROZEN ❄️ │
│ │
│ 2. User contacts issuer support │
│ └─> "Please whitelist my wallet" │
│ │
│ 3. Issuer manually verifies KYC │
│ └─> Delays, friction, poor UX │
│ │
│ 4. Issuer thaws account │
│ └─> Finally can receive tokens │
│ │
│ ❌ Bad UX - users wait hours/days │
│ │
└─────────────────────────────────────────────────────┘

Dit zorgt voor aanzienlijke wrijving en teniet doet de belofte van directe, permissionless blockchain-transacties.

De Oplossing

Token ACL maakt permissionless ontdooien mogelijk - gebruikers kunnen hun eigen accounts automatisch ontdooien als ze voldoen aan de criteria die zijn gedefinieerd door een Gate Program:

┌─────────────────────────────────────────────────────┐
│ TOKEN ACL FLOW │
├─────────────────────────────────────────────────────┤
│ │
│ 1. User creates token account │
│ └─> Account is FROZEN ❄️ │
│ │
│ 2. User calls permissionless thaw │
│ └─> Token ACL checks Gate Program │
│ │
│ 3. Gate Program validates user │
│ ├─> On allow list? ✅ THAW │
│ ├─> On block list? ❌ STAY FROZEN │
│ └─> AllowAllEoas mode? ✅ THAW │
│ │
│ 4. Account thawed instantly! │
│ └─> User can receive tokens immediately │
│ │
│ ✅ Great UX - instant, self-service │
│ │
└─────────────────────────────────────────────────────┘

Educatieve Referentie-implementatie

Deze handleiding bevat een volledige werkende implementatie die u lokaal kunt uitvoeren. De broncode biedt referentie-implementaties voor verkenning en educatieve doeleinden.

De code van de ACL-programma's is beschikbaar in de token-acl repository en het ABL Gate Program is beschikbaar in de abl-gate-program repository.

Belangrijk: Het ABL (Allow Block List) Gate Program dat in deze handleiding wordt gebruikt, is een referentie-implementatie. Hoewel het geauditeerd en productieklaar is, zijn uitgevers vrij om aangepaste Gate Programs te maken die beter passen bij hun specifieke compliancebehoeften. U bent alleen gebonden aan de Token ACL-specificatie (sRFC37), niet aan dit specifieke Gate Program-ontwerp.

Gebruik deze code NIET rechtstreeks in productie zonder:

  • Uitgebreide beveiligingsaudits
  • Adequate sleutelbeheeroplossingen
  • Beoordeling van naleving van regelgeving
  • Juridisch advies

Waarom Token ACL?

AspectTraditioneel BevrorenToken ACL
AccountactiveringHandmatig (minuten/dagen)Direct (zelfservice)
GebruikerservaringSlechtNaadloos
CompliancebeheerVolledigVolledig
SanctieblokkeringHandmatigAutomatisch via Gate Program
Integratie-inspanningHoogLaag (SDK beschikbaar)
ComposabiliteitBeperktVolledig (werkt met DeFi)

Token ACL vs Transfer Hooks

Zowel Token ACL als Transfer Hooks zijn Token-2022-oplossingen voor het toevoegen van aangepaste logica aan tokens, maar ze dienen verschillende doeleinden en hebben verschillende afwegingen:

AspectToken ACLTransfer Hooks
Wanneer Logica Wordt UitgevoerdAlleen bij bevriezen/ontdooienBij elke overdracht
OverdrachtsoverheadGeen - overdrachten zijn standaardExtra CU's + accounts bij elke overdracht
AccountafhankelijkhedenAlleen tijdens accountactiveringVereist bij elke overdrachtstransactie
DeFi-composabiliteitVolledig - protocollen werken normaalBeperkt - veel protocollen blokkeren
Beste VoorKYC/AML, sancties, allow/block listsRoyalty's, aangepaste overdrachtsvalidatie
Complexiteit voor GebruikersLaag - eenmalige ontdooioperatieHoger - elke overdracht vereist extra gegevens

Wanneer Token ACL te Gebruiken

Kies Token ACL wanneer u wilt beheren wie uw token kan bezitten:

  • KYC/AML-compliance - verificeer houders voordat ze tokens kunnen ontvangen
  • Sanctiescreening - blokkeer specifieke adressen
  • Beperkingen voor geaccrediteerde investeerders - beperk tokenhouders tot geverifieerde partijen
  • PDA-blokkering - voorkom dat slimme contracten tokens bezitten

Wanneer Transfer Hooks te Gebruiken

Kies Transfer Hooks wanneer u wilt beheren hoe tokens bewegen:

  • NFT-royalty's - bereken kosten bij elke overdracht
  • Overdrachtsrestricties - beperk overdrachtsbedragen of -frequentie
  • Aangepaste overdrachtslogica - voer code uit bij elke beweging
  • Onchain-analyses - volg alle tokenbewegingen

Aanvullende Oplossingen

Token ACL en Transfer Hooks kunnen samen worden gebruikt. U kunt bijvoorbeeld Token ACL gebruiken om te beheren wie uw token kan bezitten (compliance) en Transfer Hooks gebruiken voor royaltyhandhaving bij elke overdracht.

Architectuuroverzicht

Token ACL bestaat uit drie hoofdcomponenten:

  1. Token ACL Program: Het kernprogramma dat het beheer van bevriezingsbevoegdheden en permissionless operaties beheert
  2. Gate Program: Aangepaste logica die bepaalt wie kan ontdooien/bevriezen (bijv. ABL Gate Program voor allow/block lists)
  3. MintConfig: Per-mint configuratie die instellingen opslaat en bevriezingsbevoegdheid delegeert
┌─────────────────────────────────────────────────────────────────┐
│ TOKEN ACL ARCHITECTURE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ delegates ┌─────────────────┐ │
│ │ Token Mint │ ──────────────────→ │ MintConfig │ │
│ │ (Token-22) │ freeze authority │ (Token ACL) │ │
│ └──────────────┘ └────────┬────────┘ │
│ │ │
│ │ calls │
│ ▼ │
│ ┌──────────────┐ validates ┌─────────────────┐ │
│ │ User │ ◄─────────────────── │ Gate Program │ │
│ │ (wallet) │ │ (ABL/Custom) │ │
│ └──────────────┘ └─────────────────┘ │
│ │ │
│ ┌────────┴────────┐ │
│ │ │ │
│ ┌────▼────┐ ┌─────▼───┐ │
│ │ Allow │ │ Block │ │
│ │ Lists │ │ Lists │ │
│ └─────────┘ └─────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘

Kernconcepten

  1. Delegatie van Bevriezingsbevoegdheid: Wanneer u een Token ACL-configuratie aanmaakt, wordt de bevriezingsbevoegdheid van de mint overgedragen aan de MintConfig PDA. Dit stelt Token ACL in staat om bevriezen/ontdooien te beheren.

  2. Gate Programs: Externe programma's die de allow/block-logica implementeren. Het ABL (Allow Block List) Gate Program is een referentie-implementatie - uitgevers kunnen aangepaste Gate Programs bouwen met andere logica (bijv. onchain KYC-verificatie, op orakels gebaseerde sanctiecontroles, of integratie met identiteits- protocollen).

  3. Permissionless Operaties: Gebruikers kunnen hun eigen accounts ontdooien zonder tussenkomst van de uitgever, zolang het Gate Program goedkeuring geeft.

  4. TokenMetadata-integratie: Door een token_acl-veld toe te voegen aan de metadata van uw mint wordt automatische detectie door wallets en SDK's zoals @solana/token-helpers mogelijk gemaakt.

Automatische Detectie met TokenMetadata

Wanneer u een token_acl-veld toevoegt aan de TokenMetadata-extensie van uw mint, verwijzend naar het Gate Program-adres, kunnen SDK's zoals @solana/token-helpers automatisch Token ACL-mints detecteren en ontdooiinstructies opnemen bij het aanmaken van token accounts.

ABL Gate Program-modi

ABL is een Referentie-implementatie

Het hier getoonde ABL Gate Program is een referentie-implementatie die veelvoorkomende allow/block list-gebruiksgevallen dekt. U bent echter niet gebonden aan dit ontwerp. De Token ACL-specificatie (sRFC37) definieert alleen de interface tussen Token ACL en Gate Programs - u kunt aangepaste Gate Programs maken met:

  • Integratie met onchain identiteits-/KYC-protocollen
  • Op orakels gebaseerde realtime sanctiescreening
  • Multi-sig goedkeuringsworkflows
  • Op tijd gebaseerde of voorwaardelijke toegangsregels
  • Elke andere aangepaste compliancelogica

De enige vereiste is het implementeren van de Gate Program-interface zoals gedefinieerd in sRFC37.

Het ABL (Allow Block List) Gate Program ondersteunt verschillende modi:

ModusBeschrijvingGebruiksscenario
AllowAllEoasAlle gewone wallets (niet-PDA's) kunnen ontdooienOpen tokens met PDA-blokkering
AllowAlleen wallets op de allow list kunnen ontdooienKYC-vereiste tokens
BlockAlle wallets BEHALVE die op de block list kunnen ontdooienNaleving van sancties
ComposietCombineer allow + block listsVolledige compliance-instelling

Prioriteit van Block List

Bij gebruik van composietlijsten heeft de block list altijd prioriteit. Een wallet die zowel op de allow list ALS op de block list staat, kan NIET ontdooien.

Programma-adressen

Voor het gemak zijn de programma's al gedeployed op devnet. U kunt de volgende adressen gebruiken. De mainnet-release volgt na de audits.

ProgrammaAdres
Token ACLTACLkU6CiCdkQN2MjoyDkVg2yAH9zkxiHDsiztQ52TP
ABL Gate ProgramGATEzzqxhJnsWF6vHRsgtixxSB8PaQdcqGEVTEHWiULz

Vereisten

Om de voorbeelden lokaal uit te voeren, zorg ervoor dat u de programma's kloont naar uw lokale validator:

  1. Solana CLI

    (Voor lokaal uitvoeren gebruik 2.x, NIET 3.x - er is een bekend probleem met Token-2022-metadata op dit moment, waardoor de stap van het toevoegen van aanvullende metadata mislukt)

    solana --version
  2. Node.js 18+ en pnpm

  3. Lokale validator met vereiste programma's:

    solana-test-validator \
    --clone TACLkU6CiCdkQN2MjoyDkVg2yAH9zkxiHDsiztQ52TP \
    --clone GEC5tu9eaZQrNS7ohERwZRqyvLvV8k2iVZqqt6VuwvJu \
    --clone GATEzzqxhJnsWF6vHRsgtixxSB8PaQdcqGEVTEHWiULz \
    --clone D2GUvBwbnkFu3R5s1rz5dcBJ81UsqY3nvHbLdeJLtSx5 \
    --url devnet \
    --reset

Volledige Implementatie

Stap 1: Installeer Afhankelijkheden

pnpm add @solana/kit @solana-program/token-2022 @solana-program/system \
@solana-program/compute-budget @token-acl/sdk @token-acl/abl-sdk \
@solana/spl-token-metadata @solana/web3.js ws

Stap 2: Maak een Token aan met Token ACL

Hier is een volledig voorbeeld dat een compliant token aanmaakt met Token ACL:

import {
createSolanaRpc,
createSolanaRpcSubscriptions,
sendAndConfirmTransactionFactory,
getSignatureFromTransaction,
generateKeyPairSigner,
pipe,
createTransactionMessage,
setTransactionMessageFeePayer,
setTransactionMessageLifetimeUsingBlockhash,
appendTransactionMessageInstructions,
signTransactionMessageWithSigners,
lamports
} from "@solana/kit";
import { getCreateAccountInstruction } from "@solana-program/system";
import { getSetComputeUnitLimitInstruction } from "@solana-program/compute-budget";
import {
TOKEN_2022_PROGRAM_ADDRESS,
getInitializeMintInstruction,
getInitializeTokenMetadataInstruction,
getUpdateTokenMetadataFieldInstruction,
tokenMetadataField,
AccountState,
getMintSize,
getPreInitializeInstructionsForMintExtensions,
extension
} from "@solana-program/token-2022";
import { pack } from "@solana/spl-token-metadata";
import { PublicKey } from "@solana/web3.js";
// Token ACL SDK
import {
getCreateConfigInstruction,
findMintConfigPda,
getTogglePermissionlessInstructionsInstruction,
findThawExtraMetasAccountPda
} from "@token-acl/sdk";
// ABL Gate Program SDK
import {
getCreateListInstruction,
getSetupExtraMetasInstruction,
getAddWalletInstruction,
findListConfigPda,
findWalletEntryPda,
ABL_PROGRAM_ADDRESS,
Mode
} from "@token-acl/abl-sdk";
// TLV sizes for Token-2022 extensions
const TYPE_SIZE = 2;
const LENGTH_SIZE = 2;
async function createTokenACLMint() {
// Setup RPC
const rpc = createSolanaRpc("http://localhost:8899");
const rpcSubscriptions = createSolanaRpcSubscriptions("ws://localhost:8900");
const sendAndConfirm = sendAndConfirmTransactionFactory({
rpc,
rpcSubscriptions
});
// Load your payer keypair
const payer = await loadKeypair("~/.config/solana/id.json");
// Generate mint keypair
const mint = await generateKeyPairSigner();
console.log(`🪙 Mint: ${mint.address}`);
// TokenMetadata config - includes 'token_acl' for auto-detection
const TOKEN_NAME = "Compliant Token";
const TOKEN_SYMBOL = "COMP";
const TOKEN_URI = "";
const TOKEN_ACL_KEY = "token_acl";
// Define extensions
const defaultAccountStateExtension = extension("DefaultAccountState", {
state: AccountState.Frozen
});
const metadataPointerExtension = extension("MetadataPointer", {
authority: payer.address,
metadataAddress: mint.address
});
const extensions = [defaultAccountStateExtension, metadataPointerExtension];
// Calculate mint size
const baseMintSize = getMintSize(extensions);
const metadataForSizing = {
mint: new PublicKey(mint.address),
name: TOKEN_NAME,
symbol: TOKEN_SYMBOL,
uri: TOKEN_URI,
additionalMetadata: [[TOKEN_ACL_KEY, ABL_PROGRAM_ADDRESS]] as [
string,
string
][]
};
const metadataLen = pack(metadataForSizing).length;
const totalSpace = baseMintSize + metadataLen + TYPE_SIZE + LENGTH_SIZE;
// Get rent
const mintRent = await rpc
.getMinimumBalanceForRentExemption(BigInt(totalSpace))
.send();
// Get extension pre-initialization instructions
const extensionInstructions = getPreInitializeInstructionsForMintExtensions(
mint.address,
extensions
);
// Build transaction
const { value: blockhash } = await rpc.getLatestBlockhash().send();
const createMintTx = pipe(
createTransactionMessage({ version: 0 }),
(tx) => setTransactionMessageFeePayer(payer.address, tx),
(tx) => setTransactionMessageLifetimeUsingBlockhash(blockhash, tx),
(tx) =>
appendTransactionMessageInstructions(
[
getSetComputeUnitLimitInstruction({ units: 400_000 }),
getCreateAccountInstruction({
payer,
newAccount: mint,
lamports: lamports(mintRent),
space: baseMintSize,
programAddress: TOKEN_2022_PROGRAM_ADDRESS
}),
...extensionInstructions,
getInitializeMintInstruction({
mint: mint.address,
decimals: 6,
mintAuthority: payer.address,
freezeAuthority: payer.address
}),
getInitializeTokenMetadataInstruction({
metadata: mint.address,
updateAuthority: payer.address,
mint: mint.address,
mintAuthority: payer,
name: TOKEN_NAME,
symbol: TOKEN_SYMBOL,
uri: TOKEN_URI
}),
getUpdateTokenMetadataFieldInstruction({
metadata: mint.address,
updateAuthority: payer,
field: tokenMetadataField("Key", [TOKEN_ACL_KEY]),
value: ABL_PROGRAM_ADDRESS
})
],
tx
)
);
// Sign and send
const signedTx = await signTransactionMessageWithSigners(createMintTx);
await sendAndConfirm(signedTx, { commitment: "confirmed" });
console.log("✅ Mint created with TokenMetadata");
return mint.address;
}

Stap 3: Maak Token ACL-configuratie aan

Maak na het aanmaken van de mint de Token ACL-configuratie aan:

async function createTokenACLConfig(
mintAddress: Address,
payer: TransactionSigner
) {
const [mintConfigPda] = await findMintConfigPda({ mint: mintAddress });
console.log(`📋 MintConfig PDA: ${mintConfigPda}`);
const createConfigIx = getCreateConfigInstruction({
payer: payer.address,
authority: payer,
mint: mintAddress,
mintConfig: mintConfigPda,
gatingProgram: ABL_PROGRAM_ADDRESS
});
const { value: blockhash } = await rpc.getLatestBlockhash().send();
const tx = pipe(
createTransactionMessage({ version: 0 }),
(tx) => setTransactionMessageFeePayer(payer.address, tx),
(tx) => setTransactionMessageLifetimeUsingBlockhash(blockhash, tx),
(tx) => appendTransactionMessageInstructions([createConfigIx], tx)
);
const signedTx = await signTransactionMessageWithSigners(tx);
await sendAndConfirm(signedTx, { commitment: "confirmed" });
console.log("✅ Token ACL config created");
console.log(" Freeze authority transferred to MintConfig PDA");
return mintConfigPda;
}

Stap 4: ABL Gate Program instellen

Maak een ABL-lijst aan en stel extra meta's in:

// AllowAllEoas - All regular wallets can thaw automatically
async function setupAllowAllEoas(
mintAddress: Address,
mintConfigPda: Address,
payer: TransactionSigner
) {
const listSeed = mintAddress; // Use mint as seed
const [listConfigPda] = await findListConfigPda({
authority: payer.address,
seed: listSeed
});
const createListIx = getCreateListInstruction({
authority: payer,
listConfig: listConfigPda,
mode: Mode.AllowAllEoas, // All EOAs can thaw
seed: listSeed
});
const [thawExtraMetasPda] = await findThawExtraMetasAccountPda(
{ mint: mintAddress },
{ programAddress: ABL_PROGRAM_ADDRESS }
);
const setupMetasIx = getSetupExtraMetasInstruction({
authority: payer,
tokenAclMintConfig: mintConfigPda,
mint: mintAddress,
extraMetas: thawExtraMetasPda,
lists: [listConfigPda]
});
// Send transaction with both instructions...
console.log("✅ ABL list created with AllowAllEoas mode");
}

Stap 5: Schakel Permissionless Ontdooien in

Stel gebruikers in staat hun eigen accounts te ontdooien:

async function enablePermissionlessThaw(
mintConfigPda: Address,
authority: TransactionSigner
) {
const toggleIx = getTogglePermissionlessInstructionsInstruction({
authority,
mintConfig: mintConfigPda,
thawEnabled: true,
freezeEnabled: false // Optional: enable permissionless freeze too
});
// Send transaction...
console.log("✅ Permissionless thaw enabled");
}

Stap 6: Gebruiker Ontdooit Zijn Account

Gebruikers kunnen nu hun eigen accounts ontdooien via de SDK:

import {
createThawPermissionlessIdempotentInstructionWithExtraMetas,
TOKEN_ACL_PROGRAM_ADDRESS
} from "@token-acl/sdk";
import { fetchEncodedAccount } from "@solana/kit";
async function userThawsAccount(
mintAddress: Address,
userAta: Address,
userAddress: Address,
payer: TransactionSigner
) {
// Account retriever function for the SDK
const accountRetriever = async (addr: Address) => {
return await fetchEncodedAccount(rpc, addr);
};
// The SDK handles all the complexity of fetching extra metas
const thawIx =
await createThawPermissionlessIdempotentInstructionWithExtraMetas(
payer, // authority (signer)
userAta, // token account to thaw
mintAddress, // mint
userAddress, // token account owner
TOKEN_ACL_PROGRAM_ADDRESS, // Token ACL program
accountRetriever // account fetcher
);
// Send transaction signed by payer...
console.log("✅ Account thawed permissionlessly!");
}

@solana/token-helpers gebruiken voor Automatisch Ontdooien

De @solana/token-helpers-SDK kan automatisch Token ACL-mints detecteren en ontdooiinstructies opnemen:

import { createAndConfirmAssociatedTokenAccount } from "@solana/token-helpers";
// This automatically includes thaw instruction if mint has 'token_acl' metadata
const { signature, associatedTokenAddress } =
await createAndConfirmAssociatedTokenAccount(
rpc,
rpcSubscriptions,
payer,
user.address,
mintAddress,
true // idempotent
);
console.log(`✅ Account created AND thawed automatically!`);
console.log(` ATA: ${associatedTokenAddress}`);

TokenMetadata-vereiste

Voor automatische detectie door @solana/token-helpers moet uw mint het volgende hebben:

  1. De TokenMetadata-extensie geïnitialiseerd
  2. Een additionalMetadata-veld met sleutel token_acl en waarde ingesteld op het Gate Program-adres

Composiet Allow + Block Lists

Voor maximale compliancecontrole, combineer allow- en block lists:

async function setupCompositeLists(
mintAddress: Address,
mintConfigPda: Address,
payer: TransactionSigner
) {
// Create ALLOW list
const allowListSeed = /* unique seed for allow list */;
const [allowListPda] = await findListConfigPda({
authority: payer.address,
seed: allowListSeed,
});
const createAllowListIx = getCreateListInstruction({
authority: payer,
listConfig: allowListPda,
mode: Mode.Allow,
seed: allowListSeed,
});
// Create BLOCK list
const blockListSeed = /* unique seed for block list */;
const [blockListPda] = await findListConfigPda({
authority: payer.address,
seed: blockListSeed,
});
const createBlockListIx = getCreateListInstruction({
authority: payer,
listConfig: blockListPda,
mode: Mode.Block,
seed: blockListSeed,
});
// Setup extra metas with BOTH lists
const [thawExtraMetasPda] = await findThawExtraMetasAccountPda(
{ mint: mintAddress },
{ programAddress: ABL_PROGRAM_ADDRESS }
);
const setupMetasIx = getSetupExtraMetasInstruction({
authority: payer,
tokenAclMintConfig: mintConfigPda,
mint: mintAddress,
extraMetas: thawExtraMetasPda,
lists: [allowListPda, blockListPda], // Both lists!
});
// Send transaction...
console.log("✅ Composite lists created");
console.log(" - Allow list: Only whitelisted users can thaw");
console.log(" - Block list: Blocked users can NEVER thaw");
}

Gedrag van Composietlijsten

┌─────────────────────────────────────────────────────┐
│ COMPOSITE LIST LOGIC │
├─────────────────────────────────────────────────────┤
│ │
│ User tries to thaw: │
│ │
│ 1. Check BLOCK list first │
│ └─> On block list? ❌ DENY (always) │
│ │
│ 2. Check ALLOW list │
│ └─> On allow list? ✅ ALLOW │
│ └─> Not on allow list? ❌ DENY │
│ │
│ Key insight: Block list ALWAYS wins! │
│ │
└─────────────────────────────────────────────────────┘

Gebruiksscenario's

1. Effectentokens (KYC Vereist)

Gebruik een Allow list om ervoor te zorgen dat alleen KYC-geverifieerde investeerders tokens kunnen bezitten:

// Create allow list
const createListIx = getCreateListInstruction({
authority: issuer,
listConfig: allowListPda,
mode: Mode.Allow,
seed: mintAddress
});
// After KYC verification, add investor
await addToAllowList(allowListPda, kycVerifiedInvestor, issuer);

2. Naleving van Sancties

Gebruik een Block list om te voorkomen dat gesanctioneerde adressen tokens ontvangen:

// Create block list
const createListIx = getCreateListInstruction({
authority: complianceOfficer,
listConfig: blockListPda,
mode: Mode.Block,
seed: mintAddress
});
// Block sanctioned address
await addToBlockList(blockListPda, sanctionedAddress, complianceOfficer);

3. Open Token met PDA-bescherming

Gebruik AllowAllEoas om alle gewone wallets toe te staan terwijl PDA's (slimme contracten) worden geblokkeerd:

const createListIx = getCreateListInstruction({
authority: payer,
listConfig: listConfigPda,
mode: Mode.AllowAllEoas, // Regular wallets OK, PDAs blocked
seed: mintAddress
});

4. Volledige Enterprise Compliance

Combineer Allow list + Block list voor volledige controle:

  • Allow list: KYC-geverifieerde investeerders
  • Block list: Gesanctioneerde adressen, vertrokken medewerkers, enz.

Productieoverwegingen

Voordat u naar productie deployt:

  1. Beveiligingsaudits: Laat uw implementatie en eventuele aangepaste Gate Programs professioneel auditeren

  2. Sleutelbeheer: Gebruik adequate bewaaroplossingen voor bevoegdheidssleutels. Overweeg multi-sig voor gevoelige operaties

  3. Naleving van regelgeving: Raadpleeg juridische experts over effectenregelgeving, KYC/AML-vereisten en sanctienaleving

  4. Lijstbeheer: Bouw robuuste systemen voor het beheren van allow/block lists, inclusief:

    • Geautomatiseerde sanctiescreeningintegratie
    • KYC-providerintegratie
    • Auditlogboekregistratie
  5. Monitoring: Implementeer monitoring voor:

    • Mislukte ontdooipogingen (mogelijke complianceproblemen)
    • Lijstwijzigingen
    • Gebruik van bevoegdheidssleutels
  6. Noodherstel: Plan voor sleutelrotatie, lijstherstel en noodbevriesprocedures

Solana CLI-versie

Token ACL met TokenMetadata vereist Solana CLI 2.x. Er is een bekend probleem met CLI 3.x dat de automatische uitbreiding van TokenMetadata verstoort. Controleer altijd uw CLI-versie voordat u deployt.

Opdrachtregelinterface (CLI)

Zowel Token ACL als het ABL Gate Program bieden CLI's voor het beheren van configuraties en lijsten zonder code te schrijven. Dit is handig voor operationele teams.

Token ACL CLI

De Token ACL CLI beheert mintconfiguraties en bevriezen/ontdooioperaties.

Installatie

# Install from crates.io
cargo install token-acl-cli
# Verify installation
token-acl --version

Token ACL-opdrachten

OpdrachtBeschrijving
create-configMaakt een nieuwe mintconfiguratie aan (draagt bevriezingsbevoegdheid over)
delete-configVerwijdert een mintconfiguratie
set-authorityStelt de bevoegdheid van een mintconfiguratie in
set-gating-programStelt het gating-programma in voor een mint-configuratie
set-instructionsToestemmingsloos ontdooien/bevriezen in- of uitschakelen
thawOntdooit een token account (autoriteit vereist)
freezeBevriest een token account (autoriteit vereist)
thaw-permissionlessOntdooit een token account zonder toestemming
freeze-permissionlessBevriest een token account zonder toestemming
create-ata-and-thaw-permissionlessMaakt een ATA aan en ontdooit in één opdracht

Een Token ACL-configuratie aanmaken

# Create a mint config (delegates freeze authority to Token ACL)
token-acl create-config <MINT_ADDRESS> \
--gating-program GATEzzqxhJnsWF6vHRsgtixxSB8PaQdcqGEVTEHWiULz

Toestemmingsloos ontdooien inschakelen

# Enable permissionless thaw only (recommended for most use cases)
# - Users can self-service unfreeze after passing gate checks
# - Only authority can freeze accounts (security best practice)
token-acl set-instructions --enable-thaw --disable-freeze <MINT_ADDRESS>
# Enable both permissionless thaw AND freeze
# Use case: Allow anyone to freeze blocked users, or users to self-freeze
token-acl set-instructions --enable-thaw --enable-freeze <MINT_ADDRESS>
# Disable all permissionless operations (authority-only mode)
token-acl set-instructions --disable-thaw --disable-freeze <MINT_ADDRESS>

Ontdooi-/bevriesoperaties

# Thaw an account permissionlessly (user self-service)
token-acl thaw-permissionless <MINT_ADDRESS> <TOKEN_ACCOUNT_ADDRESS>
# Thaw using authority (issuer operation)
token-acl thaw <MINT_ADDRESS> <TOKEN_ACCOUNT_ADDRESS>
# Freeze using authority (compliance enforcement)
token-acl freeze <MINT_ADDRESS> <TOKEN_ACCOUNT_ADDRESS>

ATA aanmaken en ontdooien in één opdracht

# Creates associated token account and thaws it automatically
token-acl create-ata-and-thaw-permissionless --mint <MINT_ADDRESS> --owner <WALLET_ADDRESS>

ABL Gate CLI (allow-block-list)

De ABL Gate CLI beheert toestaan/blokkeer-lijsten en portemonnee-invoeren.

Installatie

# Install from crates.io
cargo install token-acl-gate-cli
# Verify installation (binary is named 'allow-block-list')
allow-block-list --version

ABL Gate-opdrachten

OpdrachtBeschrijving
create-listMaakt een nieuwe toestaan/blokkeer-lijst aan
delete-listVerwijdert een lijst
add-walletVoegt een portemonnee toe aan een lijst
remove-walletVerwijdert een portemonnee uit een lijst
apply-lists-to-mintConfigureert welke lijsten van toepassing zijn op een mint

Een lijst aanmaken

# Create an ALLOW list (only whitelisted wallets can thaw)
allow-block-list create-list --mode allow
# Create a BLOCK list (blocked wallets cannot thaw)
allow-block-list create-list --mode block
# Create an ALLOW-ALL-EOAs list (all regular wallets can thaw)
allow-block-list create-list --mode allow-all-eoas

De opdracht geeft het list_config PDA-adres en de seed terug — sla deze op!

Portemonnees op lijsten beheren

# Add wallet to a list (works for both allow and block lists)
allow-block-list add-wallet <LIST_ADDRESS> <WALLET_ADDRESS>
# Remove wallet from a list
allow-block-list remove-wallet <LIST_ADDRESS> <WALLET_ADDRESS>

Lijsten toepassen op een mint

# Apply a single list to a mint
allow-block-list apply-lists-to-mint <MINT_ADDRESS> <LIST_ADDRESS>
# Apply multiple lists (e.g., allow + block for composite compliance)
allow-block-list apply-lists-to-mint <MINT_ADDRESS> <ALLOW_LIST> <BLOCK_LIST>

Globale CLI-opties

Beide CLI's ondersteunen deze opties:

OptieBeschrijving
-u, --url <URL>RPC-URL (standaard: uit Solana-configuratie)
-k, --payer <KEYPAIR>Betalers keypair-bestand of hardware-portemonnee
-C, --config <PATH>Pad naar Solana-configuratiebestand
-v, --verboseExtra informatie weergeven

Volledig CLI-workflowvoorbeeld

Hier is een volledige workflow met alle CLI's om een compliant token helemaal vanaf nul in te stellen:

# ============================================================================
# STEP 1: Configure Solana CLI
# ============================================================================
solana config set --url localhost
# ============================================================================
# STEP 2: Create Token22 Mint with Metadata + DefaultAccountState Extensions
# ============================================================================
# Create the mint with:
# - Token-2022 program
# - Freeze authority enabled
# - Default account state = frozen (all new accounts start frozen)
# - Metadata extension with token_acl field for auto-detection
spl-token create-token \
--program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb \
--enable-freeze \
--default-account-state frozen \
--enable-metadata
# Output:
# Creating token 7KzLwpXMzKa8JiqYr2ookFjxLx1xMF4xM4YhVqPJpump
# Address: 7KzLwpXMzKa8JiqYr2ookFjxLx1xMF4xM4YhVqPJpump
# Save the mint address for use in subsequent commands
MINT=7KzLwpXMzKa8JiqYr2ookFjxLx1xMF4xM4YhVqPJpump
# Initialize the token metadata
spl-token initialize-metadata $MINT "Compliant Token" "COMP" "https://example.com/metadata.json"
# Add the token_acl field for wallet auto-detection
# This tells wallets/SDKs which gate program to use for thaw
spl-token update-metadata $MINT token_acl GATEzzqxhJnsWF6vHRsgtixxSB8PaQdcqGEVTEHWiULz
# Verify the token was created correctly
spl-token display $MINT
# ============================================================================
# STEP 3: Create Token ACL Config
# ============================================================================
# This transfers freeze authority from your wallet to the Token ACL MintConfig PDA
token-acl create-config $MINT \
--gating-program GATEzzqxhJnsWF6vHRsgtixxSB8PaQdcqGEVTEHWiULz
# Output:
# ✅ Config created for mint 7KzLwpXMzKa8JiqYr2ookFjxLx1xMF4xM4YhVqPJpump
# MintConfig PDA: 9xYzAbCdEfGhIjKlMnOpQrStUvWxYz123456789abc
# ============================================================================
# STEP 4: Create ABL Lists
# ============================================================================
# Create a block list for sanctions compliance
allow-block-list create-list --mode block
# Output:
# list_config: 5HnJkLmNoPqRsTuVwXyZ987654321defghijk
# seed: 3AbCdEfGhIjKlMnOpQrStUvWxYz123456789
# Save the block list address
BLOCK_LIST=5HnJkLmNoPqRsTuVwXyZ987654321defghijk
# ============================================================================
# STEP 5: Apply Lists to Mint
# ============================================================================
# Configure the block list to be used for this mint's permissionless operations
allow-block-list apply-lists-to-mint $MINT $BLOCK_LIST
# ============================================================================
# STEP 6: Enable Permissionless Thaw
# ============================================================================
# Allow users to thaw their own accounts (if not on block list)
# --enable-thaw: Users can self-service unfreeze after passing gate checks
# --disable-freeze: Only authority can freeze
token-acl set-instructions --enable-thaw --disable-freeze $MINT
# ============================================================================
# STEP 7: Manage Block List (Compliance Operations)
# ============================================================================
# To fully block a user, you need TWO steps:
# 1. Add to block list (prevents future thawing)
# 2. Freeze their token account (stops current usage)
# Step 7a: Add wallet to block list
# Replace with actual wallet address to block (must be valid base58 pubkey)
allow-block-list add-wallet $BLOCK_LIST <WALLET_TO_BLOCK>
# Step 7b: Freeze their existing token account (if they have one)
# This requires the token account address, not the wallet address
# spl-token address --verbose --token $MINT to get the token account address
# token-acl freeze <TOKEN_ACCOUNT_ADDRESS>
# Note: Adding to block list alone only prevents them from THAWING.
# If their account is already thawed, they can still use it until you freeze it!
# Later, if sanctions are lifted:
# 1. Remove from block list
# allow-block-list remove-wallet $BLOCK_LIST <WALLET_ADDRESS>
# 2. User can then thaw their account again
# ============================================================================
# STEP 8: User Creates Account and Thaws
# ============================================================================
# A user can now create their token account and thaw it in one command
# Use your own wallet or generate one: solana-keygen new --no-outfile
USER_WALLET=$(solana address) # Uses your configured wallet
token-acl create-ata-and-thaw-permissionless --mint $MINT --owner $USER_WALLET
# Output:
# ✅ Created ATA: 8AbCdEfGhIjKlMnOpQrStUvWxYz123456789xyz
# ✅ Thawed successfully!
# ============================================================================
# STEP 9: Mint Tokens to User
# ============================================================================
# Now the issuer can mint tokens to the user's thawed account
spl-token mint $MINT 1000 --recipient-owner $USER_WALLET
# Verify balance
spl-token balance $MINT

Token-metadata voor automatische detectie

Het toevoegen van het metadataveld token_acl is cruciaal voor wallet-integratie. Wanneer wallets zoals Phantom of SDK's zoals @solana/token-helpers dit veld zien, voegen ze automatisch ontdooiinstructies toe bij het aanmaken van token accounts.

spl-token update-metadata $MINT token_acl GATEzzqxhJnsWF6vHRsgtixxSB8PaQdcqGEVTEHWiULz

Volgende stappen

  1. Probeer de workshop: Kloon de token-acl repository en voer de demovoorbeelden uit. Lees de implementatie van de ACL en het ABL Gate-programma.

  2. Aangepaste Gate-programma's bouwen: Het ABL Gate-programma is slechts een referentie- implementatie. Bouw uw eigen Gate-programma om te integreren met uw bestaande complianceinfrastructuur, identiteitsproviders, of implementeer aangepaste logica die aansluit bij uw specifieke vereisten

  3. Integreren met DeFi: Token ACL-tokens zijn volledig samenstelbaar met DeFi- protocollen

  4. Lees de specificatie: Bekijk sRFC37 voor de volledige technische specificatie en neem deel aan de sRFC37-discussie

Conclusie

Token ACL (sRFC37) biedt een krachtige oplossing voor ondernemingen die behoefte hebben aan compliance-conforme, permissioned tokens zonder concessies te doen aan de gebruikerservaring die blockchain waardevol maakt. Belangrijkste voordelen:

  • Directe activering: Gebruikers kunnen hun accounts zelf ontdooien
  • Volledige compliancecontrole: Toestaan-lijsten, blokkeer-lijsten of aangepaste logica
  • Flexibele Gate-programma's: Gebruik de referentie-ABL-implementatie of bouw aangepaste Gate-programma's die integreren met uw complianceinfrastructuur
  • Naadloze integratie: SDK's verwerken de complexiteit automatisch
  • Samenstelbaar: Werkt met bestaande DeFi-protocollen
  • Geauditeerd: Productieklare programma's gedeployed op mainnet

De combinatie van de DefaultAccountState-extensie van Token-2022 met de toestemmingsloze operaties van Token ACL creëert een nieuw paradigma voor conforme token-uitgifte op Solana.

Is this page helpful?

© 2026 Solana Foundation. Alle rechten voorbehouden.