Jito DontFront를 활용한 MEV 보호
MEV(Maximal Extractable Value)란 블록 내 트랜잭션을 재정렬하거나 포함 또는 제외함으로써 포착할 수 있는 가치를 의미합니다. MEV는 특정 체인에만 국한된 현상이 아니라, 블록 생산자가 트랜잭션 순서를 제어하는 모든 블록체인의 근본적인 특성입니다. 차익 거래와 같은 일부 MEV 형태는 DEX 간 가격 불일치를 수정하여 시장 효율성을 높이는 데 기여합니다. 반면 샌드위치 공격과 같은 형태는 사용자로부터 직접 가치를 탈취합니다. DeFi 애플리케이션을 개발하는 개발자에게는 이로 인해 거래 실행 품질 저하와 수익 손실이 발생할 수 있습니다.
이 가이드는 유해한 MEV의 대표적 형태인 샌드위치 공격과, Jito의 dontfront 기능을 활용한 완화 방법에 초점을 맞춥니다.
사전 학습 권장 자료: Jito 번들
Solana의 MEV
Solana의 아키텍처는 공개 멤풀을 보유한 체인에 비해 MEV 노출 범위를 이미 상당히 줄여줍니다. 트랜잭션은 공유 멤풀에 대기하지 않고 다음 블록 리더에게 직접 전달되며, 처리되지 않은 트랜잭션은 약 150블록(~1분) 후에 만료됩니다. 이로 인해 검색자가 대기 중인 트랜잭션을 관찰하고 행동할 수 있는 시간이 크게 단축됩니다.
그럼에도 불구하고 MEV 추출은 여전히 발생합니다. 최적화된 인프라와 validator 직접 연결을 보유한 검색자는 트랜잭션 흐름을 관찰하고 이에 대응할 수 있습니다. Solana에서의 MEV 활동 대부분은 원자적 차익 거래, 즉 단일 트랜잭션 내에서 DEX 간 가격 차이를 수정하는 봇에 해당합니다. 이 유형의 MEV는 시장 전반의 가격 일관성을 향상시키므로 일반적으로 유익한 것으로 간주됩니다.
개발자가 적극적으로 방어해야 할 것은 유해한 유형인 샌드위치 공격입니다.
샌드위치 공격이란?
샌드위치 공격은 검색자가 대기 중인 스왑을 감지하고 트랜잭션 순서를 악용할 때 발생합니다:
- 프론트런: 검색자가 내 거래 전에 토큰을 매수하여 가격을 끌어올립니다
- 내 거래가 실행되면 예상보다 불리한 가격에 체결됩니다
- 백런: 검색자가 내 거래 후 토큰을 매도하여 차익을 챙깁니다
Solana에서는 이 공격이
Jito 번들을 통해 발생할 수 있습니다.
검색자는 [frontrun_tx, your_tx, backrun_tx]와 같이 트랜잭션 번들을 제출하고, 블록 엔진이 이를 순서대로 원자적으로 실행합니다. 피해자는 불리한 실행 가격을 받는 반면, 검색자는 스프레드로 이익을 얻습니다.
DontFront 작동 방식
DontFront는 Jito 블록 엔진의 기능으로, 검색자가 번들 내에서 내 트랜잭션 앞에 트랜잭션을 배치하는 것을 방지합니다.
작동 메커니즘: 트랜잭션의 임의 명령어에 jitodontfront로 시작하는 유효한 Solana 공개 키를 추가합니다. 블록 엔진은 이 접두사를 인식하고 규칙을 적용합니다: 내 트랜잭션이 포함된 번들은 반드시 이를 인덱스 0에 배치해야 합니다.
Without dontfront: [frontrun_tx, your_tx, backrun_tx] ← sandwich possibleWith dontfront: [your_tx, ...] ← your tx must be first
단계별 가이드
-
유효한 주소를 선택합니다.
jitodontfront로 시작하는 주소를 선택하세요(예:jitodontfront111111111111111111111111111111). 해당 계정이 온체인에 존재할 필요는 없으며, 읽거나 쓰는 대상이 아닙니다. 문자열이 유효한 주소인지 확인하려면 @solana/kit의assertIsAddress함수를 사용하거나 Solana Explorer에 주소를 입력하여 확인할 수 있습니다. 다음은 유효하지 않은 주소의 예입니다. -
읽기 전용 비서명자 계정으로 추가합니다. 트랜잭션의 임의 명령어에 읽기 전용으로 표시하여 추가하면 최적의 랜딩 속도를 확보할 수 있습니다. 대부분의 프로그램(System Program 포함)은 예상 범위를 초과하는 추가 계정을 무시합니다.
-
Jito 블록 엔진을 통해 제출합니다:
sendTransaction:https://mainnet.block-engine.jito.wtf/api/v1/transactionssendBundle:https://mainnet.block-engine.jito.wtf/api/v1/bundles
문서: sendTransaction 및 sendBundle
-
블록 엔진이
jitodontfront접두사를 감지하고 순서 규칙을 적용합니다.
블록 엔진에서의 동작
블록 엔진이 jitodontfront 계정을 포함한 트랜잭션을 감지하면:
sendTransaction경유: 해당 트랜잭션이 보호됩니다. 어떤 번들도 이 트랜잭션 앞에 다른 트랜잭션을 배치할 수 없습니다sendBundle경유: 해당 트랜잭션은 반드시 인덱스 0에 위치해야 하며, 그렇지 않으면 전체 번들이 거부됩니다
jitodontfront 계정을 포함하지 않는 트랜잭션 및 번들은 영향을 받지 않습니다.
번들 정렬 규칙
이 규칙은 번들 내에 jitodontfront 트랜잭션이 포함된 경우에 적용됩니다.
허용 패턴
[tx_with_dontfront, tip][tx_with_dontfront, arbitrage, tip][tx_with_dontfront_signer1, tx_with_dontfront_signer1_and_signer2, tip]
하나의 번들에 여러 DontFront 트랜잭션 포함
단일 번들 내 다수의 dontfront 트랜잭션은 두 가지 조건을 모두 충족할 때 허용됩니다:
- 모든 dontfront 트랜잭션이 번들 맨 앞에 연속적으로 배치되어야 합니다
- 각 dontfront 트랜잭션이 첫 번째 dontfront 트랜잭션과 최소 하나의 서명자를 공유해야 합니다
✅ [txA_df, txB_df, txC_df, arbitrage, tip](contiguous at front, overlapping signers)✅ [txA_df_signer1_signer2, txB_df_signer1_signer3, txC_df_signer2_signer4](each shares a signer with txA)
거부 패턴
❌ [tip, tx_with_dontfront]→ dontfront tx is not at index 0❌ [txA_df_signer1, txB_df_signer2]→ no overlapping signer between txA and txB❌ [trade, tx_with_dontfront, arbitrage, tip]→ dontfront tx is not at the front
통합 예제
빠른 코드 레시피는 MEV 보호 쿡북 항목을 참고하세요.
TypeScript (@solana/kit)
핵심 아이디어는 임의의 명령어에 dontfront 계정을 추가하는 헬퍼 함수입니다:
import {address,AccountRole,type Instruction,type Address} from "@solana/kit";const DONT_FRONT: Address = address("jitodontfront111111111111111111111111111111");function withDontFront(ix: Instruction): Instruction {return {...ix,accounts: [...(ix.accounts ?? []),{ address: DONT_FRONT, role: AccountRole.READONLY }]};}
이후 서명된 트랜잭션을 일반 RPC 노드 대신 Jito 블록 엔진에 제출합니다. 항상 base64 인코딩을 사용하세요. Base58은 Jito API에서 더 이상 사용되지 않습니다.
const response = await fetch("https://mainnet.block-engine.jito.wtf/api/v1/transactions",{method: "POST",headers: { "Content-Type": "application/json" },body: JSON.stringify({jsonrpc: "2.0",id: 1,method: "sendTransaction",params: [base64Tx, { encoding: "base64" }]})});
모범 사례
DontFront는 보호의 한 레이어입니다. 견고한 MEV 완화 전략은 여러 접근 방식을 결합합니다:
트랜잭션 수준 보호
-
슬리피지 허용 범위를 엄격하게 설정하세요. 샌드위치 공격에 대한 가장 효과적인 단일 방어책은 스왑 슬리피지를 제한하는 것입니다. 슬리피지 범위를 좁히면 공격자가 얻을 수 있는 이익 마진이 줄어들어 내 트랜잭션이 샌드위치 공격의 대상이 될 가능성이 낮아집니다.
-
적절한 팁과 우선순위 수수료를 설정하세요. 네트워크 혼잡 시 더 높은 팁과 우선순위 수수료는 트랜잭션/번들이 신속하게 처리될 가능성을 높여 검색자가 행동할 시간을 줄입니다. 적절한 팁 설정 방법에 대한 자세한 내용은 Jito의 팁 금액 문서를 참고하세요.
-
컴퓨트 유닛 사용량을 최적화하세요. 각 블록에는 사용 가능한 컴퓨트 유닛 수가 제한되어 있으며(계정별로도 블록당 사용 가능한 컴퓨트 유닛이 제한됩니다), 트랜잭션/번들이 블록에 포함될 가능성을 최대화하려면 컴퓨트 유닛 사용량을 최적화해야 합니다. 자세한 내용은 Solana 컴퓨트 사용량 최적화 방법 가이드를 참고하세요.
DontFront 전용 설정
-
dontfront 계정을 읽기 전용으로 표시하세요. 쓰기 가능으로 표시해도 작동하지만, 읽기 전용으로 설정하면 랜딩 속도가 최적화됩니다.
-
애플리케이션마다 고유한 dontfront pubkey를 사용하세요.
jitodontfront로 시작하는 모든 pubkey가 작동합니다. 고유한 변형(예:jitodontfront111111111111111111111111111123)을 사용하면 온체인 데이터 분석 시 앱별 사용량을 구분할 수 있습니다. -
DontFront는 주소 조회 테이블을 지원합니다. dontfront 계정은 ALT를 통해 포함될 수 있습니다. 단, 팁 계정에는 ALT를 사용하지 마세요.
제한 사항
-
블록 엔진 전용. DontFront는 Jito 블록 엔진에 의해 적용됩니다. validator에 직접 제출된 트랜잭션(Jito를 우회하는 경우)은 보호되지 않습니다.
-
보장되지 않습니다. Jito 문서에 따르면: "이 기능은 샌드위치 공격을 줄이는 데 도움이 될 수 있지만, 이를 보장하지 않으며 제3자에 의한 순서 결정을 포함한 트랜잭션 순서의 모든 변형에 대한 해결책이 아닙니다."
-
메인넷/테스트넷 전용. 이는 Jito 블록 엔진 기능입니다. devnet 또는 localhost에서는 작동하지 않습니다.
참고 자료
Is this page helpful?