솔라나 문서프로그램 개발하기

IDL - 사용하기 쉬운 프로그램 인터페이스

IDL은 **인터페이스 정의 언어(Interface Definition Language)**의 약자입니다.
Solana에서 IDL은 프로그램의 인터페이스를 설명하는 JSON 파일입니다. IDL을 통해 익스플로러와 사용자는 프로그램 명령어, 계정 데이터, 프로그램 오류를 디코딩할 수 있으며, 다양한 프로그래밍 언어로 클라이언트를 생성할 수 있습니다.


IDL이 중요한 이유

  • 표준화 → 프로그램 인터페이스를 위한 공통 형식.
  • 개발자 경험 → 클라이언트 SDK를 자동으로 생성.
  • 조합성 → 다른 개발자들이 소스 코드를 읽지 않고도 프로그램과 상호작용할 수 있습니다.
  • 가독성 → 누구나 익스플로러에서 프로그램 소스 코드를 읽지 않고도 프로그램 명령어와 계정 데이터를 확인할 수 있습니다.

IDL로 할 수 있는 것들

명령어 및 계정 데이터 디코딩

모든 익스플로러는 프로그램 IDL을 사용하여 명령어와 계정 데이터를 디코딩합니다. 여기서 Anchor 0.30.1레거시 IDL 예시를 Solana Explorer UI에서 확인할 수 있습니다. 이 트랜잭션에서는 pushInDirection과 방향을 포함한 2048 게임의 디코딩된 명령어를 확인할 수 있습니다.

TypeScript 클라이언트에서 Solana JS helpers를 사용하여 명령어와 계정 데이터를 디코딩할 수 있습니다.

Anchor 이벤트 또는 계정 변경 사항 파싱

생성된 TypeScript 타입을 사용하면 프로그램의 계정 변경 사항을 쉽게 구독할 수 있습니다.

import { Connection } from "@solana/web3.js";
const connection = new Connection("https://api.devnet.solana.com");
// Fetch account once
const account = await program.account.counter.fetch(counterPda);
// Subscribe via websocket to account changes
program.account.counter.subscribe(counterPda).on("change", (account) => {
console.log("Account changed:", account);
});
// Or use decoder to decode any account or instruction data
connection.onAccountChange(counterPda, (accInfo) => {
console.log(
"Account changed:",
program.coder.accounts.decode("counterData", account.data)
);
});

예를 들어, 프로그램에서 Anchor 이벤트를 발생시키고 이를 로깅하거나, 데이터베이스에 기록하거나, 텔레그램 채팅으로 메시지를 전송하는 데 활용할 수 있습니다.

// Emit the purchase event
emit!(PurchaseMade {
buyer: *ctx.accounts.signer.key,
product_name: name,
price,
timestamp: Clock::get()?.unix_timestamp,
table_number,
receipt_id,
telegram_channel_id: ctx.accounts.receipts.telegram_channel_id.clone(),
store_name: ctx.accounts.receipts.store_name.clone(),
receipts_account: ctx.accounts.receipts.key(),
});

이를 위해 Solana JS helpers를 사용하여 이벤트를 파싱할 수 있습니다. Anchor 이벤트를 활용해 텔레그램 채팅에 메시지를 게시하는 구현 예시도 참고할 수 있습니다.

트랜잭션 디코딩

Solana JS helpers를 사용하여 클라이언트에서 트랜잭션을 디코딩할 수도 있습니다. 이를 통해 전체 트랜잭션의 타입이 지정된 객체를 얻을 수 있습니다.

나만의 클라이언트 구축

IDL을 사용하면 다양한 언어로 자신만의 클라이언트를 만들 수 있습니다. 상호작용하고 싶은 프로그램을 찾아 IDL을 다운로드한 후, 원하는 언어로 클라이언트를 생성할 수 있습니다.

TypeScript로 클라이언트를 생성하는 방법에 대한 예시를 확인하세요.

Anchor의 IDL

Anchor 프레임워크를 사용하는 경우:

  • 프로그램을 빌드할 때 IDL이 자동으로 생성됩니다.
  • target/idl/<program>.json에 저장됩니다.
  • TypeScript 타입은 target/types/<program>.ts에 생성됩니다.
  • 프로그램 주소는 IDL(idl.address)에 저장됩니다.
anchor build
cat target/idl/counter.json

IDL의 구조

다음은 최소한의 예시입니다(Anchor v0.30+ 스펙):

{
"address": "6khKp4BeJpCjBY1Eh39ybiqbfRnrn2UzWeUARjQLXYRC",
"metadata": {
"name": "counter",
"version": "0.1.0",
"spec": "0.1.0"
},
"instructions": [
{
"name": "increment",
"discriminator": [11, 18, 104, 9, 104, 174, 59, 33],
"accounts": [{ "name": "counter", "writable": true }],
"args": []
}
],
"accounts": [
{
"name": "Counter",
"discriminator": [255, 176, 4, 245, 188, 253, 124, 25]
}
],
"types": [
{
"name": "Counter",
"type": {
"kind": "struct",
"fields": [{ "name": "count", "type": "u64" }]
}
}
]
}
  • address: 온체인 프로그램 ID.
  • metadata: 프로그램/인터페이스에 대한 { name, version, spec, ... }.
  • instructions: accounts, args, discriminator를 포함한 호출 가능한 메서드.
  • accounts: 프로그램이 노출하는 계정 타입(discriminator 포함).
  • types: 명령어/계정에서 참조하는 struct/enum/타입 별칭.
  • events / errors / constants: 이벤트, 오류 코드, 상수에 대한 선택적 정의.

참고: Anchor v0.30에서 새로운 IDL 스펙이 도입되었습니다. 레거시 IDL(0.30 이전)은 최상위 레벨에 name, version 필드를 사용하고 accounts에서 isMut/isSigner를 사용했습니다. anchor idl convert를 사용하거나 Anchor v0.30+로 재빌드하여 레거시 IDL을 변환할 수 있습니다. 레거시 IDL을 새 스펙으로 즉석에서 변환해야 하는 경우 변환 코드를 사용할 수도 있습니다. 이는 예를 들어 Solana 익스플로러를 유지 관리하면서 하위 호환성을 유지하고자 할 때 유용합니다.


TypeScript 클라이언트

Anchor는 TypeScript 클라이언트도 자동으로 생성합니다. 생성된 클라이언트는 target/types 폴더에서 확인할 수 있습니다.

클라이언트(TypeScript, v0.30+)에서 다음과 같이 쉽게 프로그램 명령어를 호출하고 계정을 가져올 수 있습니다:

import { AnchorProvider, Program } from "@coral-xyz/anchor";
import idl from "./counter.json";
const provider = AnchorProvider.local();
const program = new Program(idl, provider);
await program.methods.increment().rpc();

C# 클라이언트

C# 클라이언트를 생성하려면 다음 명령어를 사용하세요:

cd program
dotnet tool install Solana.Unity.Anchor.Tool <- run once
dotnet anchorgen -i target/idl/counter.json -o target/idl/Counter.cs

Unity에서 C# 클라이언트와 상호작용하는 방법은 Solana 게임 프리셋 또는 게임 문서에서 자세히 알아볼 수 있습니다.

Python 클라이언트

Python의 경우 AnchorPy 라이브러리를 사용할 수 있습니다.

향후 Codama 렌더러를 통해 더 많은 클라이언트 생성기를 이용할 수 있게 될 예정입니다.


Anchor 없이 IDL 사용하기

모든 프로그램이 Anchor로 구축되는 것은 아닙니다.
네이티브 Solana 프로그램의 경우:

  • **Codama**라는 도구가 현재 매크로를 통해 Rust에서 IDL을 생성하거나 Anchor IDL을 변환하는 방식으로 개발 중입니다. Codama IDL을 생성하기 위한 Codama 매크로 의 진행 중인 예시가 있습니다. Codama는 Anchor/Shank IDL을 Codama IDL로 변환합니다. Anchor IDL을 얻으려면 Anchor로 생성하거나(레거시 프로젝트의 경우 anchor idl convert 사용) 하세요.
  • Codama 매크로가 완전히 준비될 때까지 Metaplex Shank를 사용하여 Shank IDL을 생성한 후 Codama IDL로 변환할 수도 있습니다.
  • IDL을 직접 작성할 수도 있지만(Anchor 또는 Codama 형식) 신뢰성이 높지 않습니다. Cursor와 같은 AI 도구가 IDL 작성을 도와줄 수 있지만, 항상 프로그램 소스 코드로 IDL을 검증해야 하며, Anchor, Codama 또는 Metaplex Shank를 사용하는 것이 더 나은 방법입니다.

온체인에 IDL 저장하기

IDL을 온체인에 업로드하는 방법은 두 가지가 있습니다. 가장 많이 사용되는 표준 방식은 Anchor IDL 계정입니다. Anchor가 IDL을 온체인에 업로드할 수 있도록 하는 방식은 프로그램에 추가 명령어를 더하여 온체인에서 IDL을 업로드하고 업데이트할 수 있게 합니다. 이로 인해 프로그램 크기가 다소 늘어나며, 이것이 program metadata program이 만들어진 이유입니다. program metadata program에서는 모든 프로그램 IDL과 이름, 연락처, 아이콘과 같은 security.txt 정보가 program metadata program의 PDA에 저장됩니다.

Anchor IDL 계정

Anchor는 프로그램의 PDA에 IDL을 온체인으로 저장합니다.

  • IDL은 Anchor IDL 계정에 온체인으로 업로드할 수 있습니다.
  • 이를 통해 익스플로러, 지갑, SDK가 Solana에서 직접 IDL을 가져올 수 있습니다.

최초 업로드 시 (IDL 계정 초기화):

anchor idl init <PROGRAM_ID> -f target/idl/counter.json --provider.cluster devnet

업그레이드 시 (권한자에 의한 이후 업데이트):

anchor idl upgrade <PROGRAM_ID> -f target/idl/counter.json --provider.cluster devnet

유용한 관련 명령어:

anchor idl fetch -o idl.json <PROGRAM_ID>
anchor idl authority <PROGRAM_ID>
anchor idl set-authority -p <PROGRAM_ID> -n <NEW_AUTHORITY>
anchor idl erase-authority -p <PROGRAM_ID>

기본적으로 Anchor IDL 계정 생성은 권한 제한이 없습니다. 따라서 가능한 한 빨리 IDL을 업로드한 후 권한자를 설정하세요.

Anchor IDL 계정에 대한 자세한 내용은 Anchor 문서에서 확인할 수 있습니다.

Program Metadata Program (PMP)

program metadata program은 프로그램 IDL과 이름, 연락처, 아이콘과 같은 security.txt 정보를 온체인에 저장할 수 있게 해주는 프로그램입니다. 향후 IDL을 온체인에 저장하는 표준 방식이 될 가능성이 높습니다.

npx @solana-program/program-metadata write idl <program-id> ./idl.json

program metadata program에 대한 자세한 내용은 program metadata program 문서에서 확인할 수 있습니다.

참고: 이 글이 마지막으로 업데이트된 시점 기준으로 PMP는 아직 모든 익스플로러에서 지원되지 않습니다.


모범 사례

프로그램 배포의 모범 사례는 Squads와 같은 멀티시그를 사용하고, 이 프로세스를 최대한 간편하게 만들기 위해 Solana GitHub Actions 워크플로우를 활용하는 것입니다.

이를 통해 프로그램이 자동으로 업그레이드되고, IDL이 업로드되며, 빌드가 검증되고, 멀티시그에서 서명하고 프로그램을 배포할 트랜잭션이 제안됩니다.

  1. IDL을 최신 상태로 유지 → 프로그램을 변경할 때마다 항상 IDL을 업데이트하세요.
  2. IDL을 온체인에 업로드 → 투명성과 도구 지원을 위해.
  3. 커스텀 오류 문서화 → 클라이언트의 UX를 개선합니다.
  4. 빌드 검증 → IDL이 배포된 프로그램과 일치하는지 확인하세요.

IDL 버전 관리

현재 Anchor에서는 한 번에 온체인에 하나의 IDL 버전만 보유할 수 있습니다. 즉, 프로그램을 변경하려면 새 버전의 IDL을 업로드해야 하며, 가급적 프로그램 업그레이드와 동시에 진행해야 합니다. 클라이언트가 아직 업데이트되지 않은 경우 문제가 발생할 수 있으며, 이것이 program metadata program이 작성된 이유 중 하나입니다. PMP를 사용하면 프로그램에 대해 다양한 시드를 가질 수 있고 이를 통해 버전 관리가 가능합니다. 이 설계는 아직 완전히 확정되지 않았으며 논의 중입니다.


추가 자료


이것이 Solana IDL의 기본입니다. IDL은 온체인 프로그램과 오프체인 클라이언트를 연결하는 다리 역할을 하며, 오늘날 볼 수 있는 풍부한 도구와 SDK 생태계를 가능하게 합니다.

Is this page helpful?