Documentation Index
Fetch the complete documentation index at: https://docs.raydium.io/llms.txt
Use this file to discover all available pages before exploring further.
이 페이지는 AI 자동 번역입니다. 모든 내용은 영문판을 기준으로 합니다.영문판 보기 →
PDA(프로그램 파생 주소)와 CPI(크로스 프로그램 호출)는 Raydium을 가능하게 하는 두 가지 기본 요소입니다. PDA를 사용하면 프로그램이 개인 키 없이 결정적인 주소를 “소유”할 수 있습니다. 이것이 풀 권한과 볼트가 작동하는 방식입니다. CPI를 사용하면 한 프로그램이 다른 프로그램을 호출할 수 있습니다. 이것이 Raydium이 SPL Token 프로그램을 통해 토큰을 스왑하는 방식이고, 통합자가 Raydium을 자신의 흐름에 구성하는 방식입니다. Raydium의 소스 코드를 읽기 전에 둘 다 이해할 가치가 있습니다.
PDA: 키 없는 주소
**프로그램 파생 주소(PDA)**는 다음과 같은 공개 키입니다.- ed25519 곡선 위에 있지 않습니다(개인 키가 존재하지 않음).
- 프로그램 ID와 시드 집합에서 결정적으로 파생됩니다.
invoke_signed를 통해 오직 파생 프로그램에서만 서명할 수 있습니다.
파생
PDA는 프로그램 ID와 시드를 해싱하여 계산되고, 결과를 곡선 밖으로 강제하는 “범프” 바이트를 찾습니다. 곡선 밖 주소를 생성하는 첫 번째 범프(일반적으로 255에서 시작하여 감소)가 정규 범프입니다.u64 값 등 무엇이든 될 수 있습니다. Raydium의 관례는 사람이 읽을 수 있는 접두사 다음에 고유 식별자입니다.
Raydium PDA 패턴
Raydium 프로그램의 일반적인 PDA:| PDA | 시드 | 프로그램 |
|---|---|---|
| AMM 권한(AMM v4) | [b"amm authority"] + 범프 | AMM v4 |
| 풀 상태(CPMM) | [b"pool", amm_config, mint_a, mint_b] | CPMM |
| 풀 볼트(CPMM) | [b"pool_vault", pool, mint] | CPMM |
| 권한(CPMM) | [b"vault_and_lp_mint_auth_seed"] | CPMM |
| 풀 상태(CLMM) | [b"pool", amm_config, mint_0, mint_1] | CLMM |
| 틱 배열(CLMM) | [b"tick_array", pool, start_tick_index] | CLMM |
| 관찰(CLMM) | [b"observation", pool] | CLMM |
| 개인 포지션(CLMM) | [b"position", position_nft_mint] | CLMM |
| 팜 상태(Farm v6) | [b"pool_farm_state", farm_id] | Farm v6 |
| 사용자 원장(Farm v6) | [b"user_ledger", farm, user] | Farm v6 |
정규 범프
원칙적으로 곡선 밖 주소를 생성하는 여러 범프가 있을 수 있지만, Raydium의 프로그램은 항상 정규 범프(255에서 감소하여 발견)를 사용합니다. 이는 PDA의 계정 데이터에 저장되므로 후속 트랜잭션은 이를 전달하고 (비용이 많이 드는) 파생 루프를 건너뛸 수 있습니다.CPI: 다른 프로그램 호출
**크로스 프로그램 호출(CPI)**을 사용하면 한 프로그램이 단일 트랜잭션 내에서 다른 프로그램의 명령을 인라인으로 호출할 수 있습니다. Raydium은 CPI를 광범위하게 사용합니다.- 스왑 명령은 SPL Token 프로그램을 호출하여 토큰을 이동합니다.
- CLMM은 Metaplex를 호출하여 포지션 NFT를 민팅합니다.
- 풀 생성은 System Program을 호출하여 계정을 할당합니다.
- Farm v6은 SPL Token을 호출하여 보상을 전송합니다.
integration-guides/cpi-integration을 참조하세요.
invoke vs invoke_signed
Solana 런타임은 두 가지 CPI 기본 요소를 제공합니다.invoke: 다른 프로그램을 호출합니다. 호출된 프로그램은 외부 트랜잭션의 서명자를 상속합니다.invoke_signed: PDA를 대신하여 다른 프로그램을 호출합니다. 런타임은 PDA의 시드를 확인하고 서명을 승인합니다.
invoke_signed는 프로그램이 개인 키를 관리하지 않고 계정에 대한 권한을 보유하도록 하는 마법입니다.
예: Raydium이 풀 볼트에서 전송하기
풀 볼트는 권한이 풀 프로그램의 PDA인 Token Account입니다. 스왑 중 토큰을 전송하려면 풀 프로그램이 해당 PDA로 서명해야 합니다.invoke_signed가 호출되는 것을 보고, vault_and_lp_mint_auth_seed + 범프가 CPMM 프로그램 ID와 함께 해싱될 때 pool_authority의 주소로 파생되는지 확인하고, 토큰 전송에 대한 권한 서명을 허용합니다. 개인 키는 관여하지 않습니다.
예: 통합자가 Raydium CPMM 호출하기
통합자 프로그램(예: 에스크로우)은 CPI를 통해 Raydium의swap_base_input을 호출할 수 있습니다.
integration-guides/cpi-integration을 참조하세요.
CPI 깊이 제한
Solana는 CPI 깊이를 4 레벨로 제한합니다. 트랜잭션의 최상위 명령은 깊이 0으로 계산되며, 각 CPI 호출은 깊이를 증가시킵니다. 실제 함의: Raydium의 자체 스왑은 이미 1-2 수준의 CPI를 사용합니다(Raydium → SPL Token). 통합자가 Raydium을 호출하면 2입니다. 해당 통합자를 다른 통합자가 호출하면 3입니다. 4 레벨이 한계입니다. 대부분의 구성은 이를 쉽게 초과하지 않지만, 깊은 중첩(애그리게이터 → 라우터 → Raydium → 훅)은 한계에 도달할 수 있습니다. 깊게 하기보다는 평평하게 설계하세요.남은 계정
Raydium 명령이 가변 개수의 계정을 필요로 할 때(예: 알 수 없는 개수의 틱 배열을 교차하는 CLMM 스왑), 추가 계정은 남은 계정으로 전달됩니다 — 고정 계정 목록에 추가되고 위치별로 해석됩니다. CPMM의SwapV2는 전송 훅 프로그램의 추가 필수 계정에 대해 남은 계정을 사용합니다. 클라이언트는 필요한 계정을 가져와 추가합니다.
PDA 함정
잘못된 시드 → 잘못된 주소
시드가 잘못된 순서, 잘못된 인코딩이거나 추가 바이트를 포함/제외하는 버그는 조용히 다른 PDA를 생성합니다. 트랜잭션은 모호하게 실패합니다(프로그램이 존재하지 않는 계정을 읽으려고 시도함). 항상 시드 파생을 알려진 골든 값에 대해 단위 테스트하세요.범프를 저장하지 않기
매 트랜잭션마다 범프를 다시 파생하면 파생 루프의 계산을 지불합니다. 정규 범프를 PDA의 데이터에 저장하고 거기서 읽으세요.정규 범프와 비정규 범프 혼동
비정규 범프(곡선 밖의 주소를 생성하는 것을 찾는 경우)는invoke_signed에서 허용되지만 Raydium의 프로그램에서는 assert_eq!(bump, canonical_bump)를 통해 거부됩니다. 누군가 비정규 범프로 PDA를 주장하려고 하면 트랜잭션이 실패합니다.
소유 프로그램이 아닐 때 PDA를 서명자로 전달하기
PDA의 파생에 있는 ID의 프로그램만이 시드와 함께invoke_signed할 수 있습니다. 시도하면 런타임이 거부합니다.
CPI 함정
remaining_accounts 전달 잊기
외부 명령이 remaining_accounts에서 전송 훅 계정을 전달하지만 Raydium으로의 CPI가 이를 전달하지 않으면 Raydium은 훅 계정을 찾을 수 없어 실패합니다. 항상 필요한 CPI에 with_remaining_accounts를 포함하세요.
쓰기 가능 플래그 불일치
외부 명령이 쓰기 가능으로 표시한 계정은 호출된 프로그램이 이를 쓰려고 할 때 CPI 호출에서도 쓰기 가능해야 합니다. 불일치 → 런타임 거부.렌트 설명하지 않기
계정을 생성하는 프로그램에 대한 CPI(예: ATA 생성)는 지불자가 렌트를 위한 충분한 SOL을 가져야 합니다. 실패한 렌트 검사는 불명확한 오류로 나타납니다.작업 예: Raydium CPMM PDA 계산
getPoolInfoFromRpc({ poolId })를 호출할 때 Raydium SDK가 내부적으로 정확히 수행하는 것입니다 — 왕복 없이 관련 PDA를 파생합니다.
포인터
solana-fundamentals/account-model— PDA가 계정 모델에 어떻게 맞는지.solana-fundamentals/programs-and-anchor— PDA 선언을 위한 Anchor의 헬퍼.integration-guides/cpi-integration— Raydium으로 CPI하는 통합 구축.sdk-api/rust-cpi— Raydium의 Rust CPI 타입.


