Documentation Index Fetch the complete documentation index at: https://daehan-base.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Base-Solana 브릿지는 Base와 Solana 네트워크 간의 양방향 토큰 전송 및 메시지 전달을 가능하게 합니다. 이 브릿지를 통해 다음을 할 수 있습니다:
토큰 전송 : Base와 Solana 간 토큰 이동
임의의 크로스체인 메시지 전송
두 흐름 결합 (임의 호출과 함께 전송)
랩핑된 토큰 배포 : 어느 체인에서든 가능
이 가이드는 브릿지 아키텍처, 프로덕션 주소, 그리고 실용적인 구현 패턴을 다룹니다.
작동 방식
Base에서
Base 브릿지 컨트랙트는 Solana로 토큰을 전송할 때 토큰을 잠그거나 소각하고, Solana에서 토큰을 수신할 때 토큰을 민팅하거나 잠금 해제합니다. Bridge 컨트랙트 자체는 나가는 메시지로부터 머클 트리를 구성합니다. 검증자는 약 ~300개의 최종 확정된 블록마다 머클 루트를 확인하고 Solana로 전달합니다. 그런 다음 메시지가 트리에 존재함을 증명하여 Solana에서 전송을 완료합니다.
Base 네이티브 토큰은 Solana로 브릿징할 때 잠기고, Solana 네이티브 토큰은 소각됩니다.
Solana 네이티브 토큰은 Base로 브릿징할 때 민팅되고, Base 네이티브 토큰은 잠금 해제됩니다.
핵심 스마트 컨트랙트:
Twin Contract이란?
각 Solana 지갑은 Base 위의 Twin 컨트랙트에 결정론적으로 매핑됩니다. 브릿지 메시지에 컨트랙트 호출을 첨부하면, 해당 호출은 이 Twin 컨트랙트에서 실행됩니다. 즉, Twin이 Base에서 msg.sender가 됩니다.
Solana에서
Solana 브릿지 프로그램은 토큰을 잠그거나 소각하고 이벤트를 발생시켜 토큰 전송을 처리합니다. 메시징의 경우, 검증자가 이 이벤트를 Base로 전달하여 Twin 컨트랙트를 통해 실행됩니다.
핵심 프로그램 (Solana Mainnet-Beta):
릴레이어 프로그램은 핵심 브릿지의 일부가 아닙니다. Solana → Base 방향에서 Solana 사용자를 대신하여 Base 가스 수수료를 지불할 수 있는 선택적 편의 레이어입니다. 사용자는 여전히 Solana 트랜잭션에 PayForRelay를 추가하여 가스 수수료를 지불해야 합니다.
사용자가 PayForRelay를 추가하지 않으면 릴레이어 프로그램이 가스 수수료를 지불하지 않습니다.
전체 저장소는 여기에서 접근할 수 있습니다:
브릿징 흐름
Solana → Base Base에서 즉시 실행을 위한 선택적 릴레이어가 있는 푸시 기반
Base → Solana 완전한 커스터디와 함께 증명 기반 소각 및 잠금 해제
Terminally Onchain 브릿징 + 컨트랙트 호출을 위한 프로덕션 터미널 UI
Solana에서 Base로
흐름: SOL/SPL 잠금 → (선택 사항) 릴레이 비용 지불 → 검증자 승인 → Base에서 민팅 + 실행
Solana에서 Base 브릿지는 3단계가 필요한 풀 기반 모델을 사용합니다:
Solana에서 브릿지 시작 - Solana 볼트에 SOL 또는 네이티브 SPL 토큰 잠금
검증자가 메시지를 사전 승인할 때까지 대기 - 검증자가 브릿지 메시지를 확인하고 승인
Base에서 메시지 실행 - 승인된 메시지가 Base에서 실행되어 SOL을 민팅하고 추가적인 임의 호출 실행
Solana에서 Base로 브릿징할 때, 네이티브 SOL/SPL이 잠기고 Base에서 ERC20 SOL이 민팅됩니다.
Solana → Base 메시지에 실행할 호출이 포함된 경우, ABI 인코딩된 호출이 Base에서 실행 가능 한지 확인해야 합니다. Base에서 실행할 수 없는 호출은 취소될 수 없습니다 . 동일한 트랜잭션에서 토큰을 브릿징하는 경우, 해당 토큰은 잠깁니다 .
참조 스크립트(자동 릴레이, 토큰 랩핑, CLI 유틸리티)는 공식 저장소의 scripts/ 디렉토리에 있습니다:
자동 릴레이 예시
자동 릴레이로 SOL을 브릿징하는 방법을 보여주는 샘플 스크립트입니다
solToBaseWithAutoRelay/index.ts
// Configure
const TO = "0x8c1a617bdb47342f9c17ac8750e0b070c372c721" ; // Base address
const AMOUNT = 0.001 ; // SOL amount
// Bridge SOL with auto-relay
const ixs = [
getBridgeSolInstruction ({
payer ,
from: payer ,
solVault: solVaultAddress ,
bridge: bridgeAccountAddress ,
outgoingMessage ,
to: toBytes ( TO ),
remoteToken: toBytes ( "0xC5b9112382f3c87AFE8e1A28fa52452aF81085AD" ), // SOL on Base
amount: BigInt ( AMOUNT * 10 ** 9 ),
}),
await buildPayForRelayIx ( RELAYER_PROGRAM_ID , outgoingMessage , payer )
];
await buildAndSendTransaction ( SOLANA_RPC_URL , ixs , payer );
See all 20 lines
자세한 내용은 Solana에서 Base 릴레이 스크립트 를 참조하세요.
커스텀 SPL 토큰 랩핑
위 예시는 네이티브 SOL을 Base로 브릿징하는 방법을 보여줍니다.
커스텀 SPL 토큰을 브릿징하려면 CrossChainERC20Factory를 사용하여 Base에서 랩핑된 ERC20 표현을 만들어야 합니다.
wrapSolTokenOnBase/index.ts
// Deploy wrapped token on Base
const mintBytes32 = getBase58Codec (). encode ( SOLANA_SPL_MINT_ADDRESS ). toHex ();
await client . writeContract ({
address: "0x58207331CBF8Af87BB6453b610E6579D9878e4EA" , // Factory
abi: TokenFactory ,
functionName: "deploy" ,
args: [ `0x ${ mintBytes32 } ` , "Token Name" , "SYMBOL" , 9 ],
});
See all 9 lines
Base에서 Solana로
흐름: Base에서 ERC20 SOL 소각 → 최종성 대기 → 머클 증명 생성 → Solana에서 실행
Base에서 랩핑된 토큰을 소각하고, 메시지가 증명 가능해질 때까지 기다린 다음, Solana에서 증명을 실행하여 네이티브 자산을 잠금 해제합니다. 이 경로는 완전한 커스터디를 제공하며 증명자가 필요합니다.
bridgeSolFromBaseToSolana/index.ts
// Step 1: Burn SOL on Base
const transfer = {
localToken: "0xC5b9112382f3c87AFE8e1A28fa52452aF81085AD" , // SOL (on Base)
remoteToken: pubkeyToBytes32 ( SOL_ADDRESS ),
to: pubkeyToBytes32 ( solanaAddress ),
remoteAmount: BigInt ( AMOUNT * 10 ** 9 ),
};
const txHash = await client . writeContract ({
address: "0xB2068ECCDb908902C76E3f965c1712a9cF64171E" , // Bridge
abi: Bridge ,
functionName: "bridgeToken" ,
args: [ transfer , []],
});
// Step 2: Wait for finalization
const isProvable = await isBridgeMessageProvable ( txHash );
// Step 3: Generate proof
const { event , rawProof } = await generateProof ( txHash , baseBlockNumber );
// Step 4: Execute on Solana
const proveIx = getProveMessageInstruction ({
nonce: event . message . nonce ,
sender: toBytes ( event . message . sender ),
data: toBytes ( event . message . data ),
proof: rawProof . map ( e => toBytes ( e )),
messageHash: toBytes ( event . messageHash ),
});
const relayIx = getRelayMessageInstruction ({ message: messagePda });
await buildAndSendTransaction ( SOLANA_RPC_URL , [ proveIx , relayIx ], payer );
See all 32 lines
Base → Solana 방향에서 사용자를 위해 Solana 트랜잭션에 서명하고 제출하는 릴레이어를 운영하는 경우, 릴레이어 pubkey를 서명자로 요구하는 트랜잭션에 서명하지 마세요 .악의적인 사용자는 릴레이어 pubkey를 필수 서명자로 포함하는 트랜잭션을 인코딩할 수 있습니다. 서명하고 제출하면 릴레이어 자금을 훔칠 수 있는 명령을 포함한 임의 명령을 의도치 않게 승인할 수 있습니다. 기본적인 완화 조치로 pubkey를 서명자로 지정하는 트랜잭션을 무시하세요.
유틸리티
저장소에는 Solana와 Base 주소 형식 간 변환, 트랜잭션 서명을 위한 Solana CLI 키페어 가져오기, Solana 트랜잭션 빌드 및 전송을 위한 유틸리티가 포함되어 있습니다.
주소 변환
Base 컨트랙트용으로 Solana pubkey를 bytes32로 변환:
// Convert Solana pubkey to bytes32 for Base contracts
import { pubkeyToBytes32 } from "./utils/pubkeyToBytes32" ;
const bytes32Address = pubkeyToBytes32 ( solanaAddress );
키페어 관리
트랜잭션 서명을 위한 Solana CLI 키페어 가져오기:
import { getSolanaCliConfigKeypairSigner } from "./utils/keypair" ;
const payer = await getSolanaCliConfigKeypairSigner ();
트랜잭션 빌딩
Solana 트랜잭션 빌드 및 전송:
import { buildAndSendTransaction } from "./utils/buildAndSendTransaction" ;
const signature = await buildAndSendTransaction ( SOLANA_RPC_URL , ixs , payer );
Terminally Onchain 예시
Terminally Onchain 은 커맨드 터미널 UI를 통해 브릿지를 노출하는 프로덕션 Next.js 앱입니다. 사용자는 Solana 지갑을 연결하고 Base에서 브릿지 및 컨트랙트 호출과 같은 명령을 입력합니다:
bridge 0.0001 sol 0xYourTwin --call-contract 0x311935Cd80B76769bF2ecC9D8Ab7635b2139cf82 \
--call-selector "transfer(address,uint256)" \
--call-args 0x0000000000000000000000000000000000000000 100000000000000
워크플로우:
명령 파싱: 터미널 파서가 자산, 목적지, 선택적 Base 호출(셀렉터 + 인수 + 값)을 분석합니다.
브릿지 스테이징: queueBridge가 SPL 오버라이드를 검증하고, encodeFunctionData를 통해 Base 호출을 ABI 인코딩하며, 릴레이 오버라이드를 스테이징합니다.
실행: solanaBridge.bridge()가 목적지(ENS/Basename)를 분석하고, 잔액을 확인하며, realBridgeImplementation을 호출하여 Solana 트랜잭션에 서명하고 전송합니다.
릴레이 + 호출: 릴레이 가스가 선불로 지불된 경우, Base 릴레이어는 ERC20 SOL이 민팅된 직후 사용자의 Twin 컨트랙트에서 첨부된 호출을 실행합니다.
핵심 구현 참조:
src/lib/bridge.ts: 자산 분석(민트 주소 지원), 환경 인식 RPC 연결, 호출 첨부 지원.
src/lib/realBridgeImplementation.ts: 환경별 PDA 및 가스 수신자를 사용하여 PayForRelay + bridge_sol/bridge_spl 명령으로 Solana 트랜잭션을 빌드합니다.
src/components/MainContent.tsx: 명령 스테이징, 로그 뷰어, 임의 Base 호출을 위한 ABI 인코딩이 포함된 터미널 UI.
src/components/WalletConnection.tsx: 연결된 Solana 지갑을 위해 Base Mainnet/Sepolia에서 결정론적 Twin 주소를 가져옵니다.
터미널 실행
git clone https://github.com/base/sol2base.git
cd sol2base
npm install --legacy-peer-deps
# Configure env (RPC URLs, relayer addresses, CDP API keys, etc.)
cp env.template .env.local
npm run dev # defaults to http://localhost:3000
터미널은 Base Sepolia ↔ Solana Devnet과 Base Mainnet ↔ Solana Mainnet 모두를 노출합니다. UI의 네트워크 드롭다운을 사용하여 전환하세요. .env 파일에 CDP_API_KEY를 설정하면 파우셋에 접근할 수 있습니다.
컨트랙트 주소
Base 메인넷
{
"Bridge" : "0x3eff766C76a1be2Ce1aCF2B69c78bCae257D5188" ,
"BridgeValidator" : "0xAF24c1c24Ff3BF1e6D882518120fC25442d6794B" ,
"CrossChainERC20Factory" : "0xDD56781d0509650f8C2981231B6C917f2d5d7dF2" ,
"SOL" : "0x311935Cd80B76769bF2ecC9D8Ab7635b2139cf82"
}
Solana 메인넷
{
"BridgeProgram" : "HNCne2FkVaNghhjKXapxJzPaBvAKDG1Ge3gqhZyfVWLM" ,
"BaseRelayerProgram" : "g1et5VenhfJHJwsdJsDbxWZuotD5H4iELNG61kS4fb9"
}
Base Sepolia
{
"Bridge" : "0x01824a90d32A69022DdAEcC6C5C14Ed08dB4EB9B" ,
"BridgeValidator" : "0xa80C07DF38fB1A5b3E6a4f4FAAB71E7a056a4EC7" ,
"CrossChainERC20Factory" : "0x488EB7F7cb2568e31595D48cb26F63963Cc7565D" ,
"SOL" : "0xCace0c896714DaF7098FFD8CC54aFCFe0338b4BC" ,
"FLYWHEEL_ADDRESS" : "0x00000F14AD09382841DB481403D1775ADeE1179F" ,
"BRIDGE_CAMPAIGN_ADDRESS" : "0xE2AD1C34382410C30d826B019A0B3700F5c4e6c9"
}
Solana Devnet
{
"BridgeProgram" : "7c6mteAcTXaQ1MFBCrnuzoZVTTAEfZwa6wgy4bqX3KXC" ,
"BaseRelayerProgram" : "56MBBEYAtQAdjT4e1NzHD8XaoyRSTvfgbSVVcEcHj51H" ,
"GasFeeReceiver" : "AFs1LCbodhvwpgX3u3URLsud6R1XMSaMiQ5LtXw4GKYT"
}
리소스
Base Bridge 저장소 소스 코드, 컨트랙트, 프로그램, 스크립트
Solana 탐색기 Solana mainnet-beta 트랜잭션 모니터링
Base 탐색기 Base 메인넷 트랜잭션 모니터링
Discord 지원 Base 커뮤니티에서 도움 받기