⚡ 신작: 엘리시움 Testnet QuicknodeTestnet HyperEVM 상의 Kinetiq EVM 체인 엔드포인트
[받기] endpointSOC 2 Type II 인증 · ISO 27001
Solana v1 트랜잭션 설명: 크기 제한 및 호환성 변경 사항
Transaction v1은 ‘ Solana ’의 최대 트랜잭션 크기를 1,232바이트에서 4,096바이트로 늘리고, 주소 조회 테이블(Address Lookup Tables)을 제거합니다. 다음은 ‘ Solana ’ 데이터를 읽는 애플리케이션과 해당 데이터를 전송하는 애플리케이션에 적용되는 변경 사항입니다.

2026년 9월 1일 — 읽는 데 10분 소요

Solana 에서 복잡한 애플리케이션을 개발하는 개발자들은 수년 동안 트랜잭션 크기 제한을 우회하기 위해 노력해 왔습니다. v0에서는 주소 조회 테이블이 도입되어, 트랜잭션이 1,232바이트를 초과하지 않으면서도 더 많은 계정을 참조할 수 있게 되었습니다. 이번 최신 업그레이드에서는 v1 트랜잭션이 도입되어, 제한 자체를 3.3배로 늘렸습니다.
트랜잭션 v1은 직렬화된 트랜잭션의 최대 크기를 1,232바이트에서 4,096바이트로 확대하며, 2026년 9월 초 Agave v4.2 출시와 함께 적용됩니다. 제로 지식(ZK) 앱, 다중 서명(multisig) 시스템 및 복잡한 DeFi 기본 요소를 개발하는 팀들에게 있어, 이 추가된 공간은 그동안 사용해야 했던 온갖 우회 방식을 없앨 것입니다.
v1을 도입하지 않아도 그 영향은 피할 수 없습니다. Solana 데이터를 읽는 모든 것은, v1 트랜잭션을 전송하든 안 하든 상관없이 그 영향을 받게 됩니다.
1,232바이트 제한은 UDP에서 비롯된 것이었습니다. Solana 는 몇 년 전 트랜잭션 수집을 QUIC으로 전환함으로써 해당 제약 조건을 제거했습니다. 하지만 제한은 그대로 남아 있었습니다. 개발팀들은 계속해서 트랜잭션을 분할하고, 조회 테이블을 구축하며, 더 이상 밑바탕이 되는 전송 프로토콜과 맞지 않는 상한선을 기준으로 시스템을 설계해야 했습니다.
새로운 제한은 네트워킹 제약에 기반한 것이 아닙니다. 4,096바이트는 검증자 메모리 페이지와 정렬됩니다. 이를 통해 ZK 증명, BLS 서명 방식, 기밀 전송, 오라클 가격 업데이트 요청을 처리할 수 있는 공간이 확보되며, 번들 방식을 사용하지 않고도 단일 트랜잭션에 더 많은 명령어를 포함할 수 있게 됩니다. 또한 64개 계정 세트 전체를 인라인으로 수용할 수 있기 때문에, v1에서는 주소 조회 테이블(Address Lookup Tables)을 완전히 제거했습니다.
v1 트랜잭션은 최대 4,096바이트까지 지원하는 새로운 ‘ Solana ’ 전송 형식입니다. 이는 단순히 한도만 늘어난 v0 버전이 아니며, 두 버전 간에는 다음 다섯 가지 차이점이 있습니다:
버전 바이트 0x81 오프셋 0에 위치하므로, 모든 수신자는 단 한 바이트만으로 형식을 식별할 수 있습니다.
서명은 메시지 앞이 아닌 트랜잭션의 맨 뒤로 이동합니다.
고정 너비 u8 카운트가 compact-u16 인코딩을 대체합니다
명령 헤더는 페이로드보다 앞서 그룹화되어 있어, 경계를 직접 계산할 수 있다
리소스 제한이 헤더 구성 마스크로 이동합니다
v1에서는 주소 조회 테이블(Address Lookup Tables)에 대한 지원이 제거되었습니다. 이제 모든 계정은 32바이트 길이의 전체 공개 키 형태로 인라인으로 전송되며, 최대 64개의 주소 세트가 2,048바이트를 차지하는데, 이는 단일 명령어가 추가되기 전의 새로운 엔벨로프 크기의 절반에 해당합니다.
Solana mainnet 트래픽 전반에 걸쳐 비용을 측정했습니다. v0 트랜잭션의 약 62%가 적어도 하나의 조회 테이블을 참조합니다. 이를 v1로 변환했을 때, 절반은 420바이트 미만의 초과 용량을 보였고, 90%는 1,400바이트 미만을 보였습니다. 여러 테이블을 참조하여 각각 소수의 주소만 가져오는 트랜잭션의 경우, 테이블 오버헤드가 압축으로 얻는 이득보다 더 큰 비용을 초래했기 때문에 트랜잭션 크기가 더 작아졌습니다.
룩업 테이블을 제거하면 유효성 검사기의 데이터 수집 과정도 간소화됩니다. v0에서는 유효성 검사기가 트랜잭션이 어떤 계정에 영향을 미치는지 파악하기도 전에 상태에 따른 테이블 해결을 강제합니다. 반면 v1에서는 트랜잭션 자체에 전체 계정 세트가 전달되므로, 수수료 및 우선순위 계산이 더 일찍 이루어집니다.
페이로드가 많은 애플리케이션은 증명 및 명령어 데이터가 계정 슬롯을 차지하지 않으면서도 바이트를 소비하기 때문에 용량이 늘어납니다. 다중 거래소 라우팅 및 광범위한 프로토콜 조합을 포함한 계정 중심의 애플리케이션은, 새로 확보된 공간의 대부분을 조회 테이블이 압축하던 주소를 다시 인라인 처리하는 데 사용합니다. 이러한 팀의 경우 64개 계정 상한선이 이제 가장 큰 제약 조건이므로, v0 버전을 계속 사용하는 것이 합리적인 선택입니다.
v1에서 유일한 제한은 바이트 수입니다. 계정 수는 64개, 명령어 수는 64개, 서명 수는 12개로 유지됩니다.
Solana 데이터를 읽거나 색인화하는 애플리케이션은 쿼리 대상 블록에 v1 트랜잭션이 처음 나타날 때 오류가 발생합니다. 트랜잭션을 앞쪽부터 읽는 코드는 레거시 및 v0 서명이 위치하는 메시지 데이터 영역에 도달하게 되므로, 파서의 길이 검사를 강화하는 것만으로는 이 문제를 해결할 수 없습니다.
v1 지원을 명시하지 않은 호출은 오류를 반환합니다. -32015 해당 트랜잭션에 닿는 즉시 전체 블록 읽기 작업이 실패합니다. 인덱서 및 백필 작업은 구문 분석할 수 없는 해당 트랜잭션을 건너뛰지 않고 중단됩니다. 설정 maxSupportedTransactionVersion: 1 두 통화 모두에서, JSON 정수로서 1. 이 문자열 "1" 실패하고, 또한 0, 따라서 v0 출시 기간 동안 v0 지원을 선택했던 코드는 아직 해당 범위에 포함되지 않습니다. getSignaturesForAddress 트랜잭션 본문을 검사하지 않기 때문에 영향을 받지 않습니다.
다음과 같이 오류가 발생하는 호출:
{
"jsonrpc": "2.0",
"id": 1,
"method": "getBlock",
"params": [402184291, { "encoding": "json" }]
}수정된 동일한 호출입니다. base58은 1,232바이트를 초과하는 트랜잭션을 인코딩할 수 없기 때문에, version 매개변수와 함께 Base64가 필요합니다:
{
"jsonrpc": "2.0",
"id": 1,
"method": "getBlock",
"params": [
402184291,
{
"encoding": "base64",
"maxSupportedTransactionVersion": 1
}
]
}blockSubscribe 방출한다 null v1 트랜잭션에 도달하면 처리 속도가 느려지지만, 포착할 오류는 발생하지 않습니다. 오류율을 기반으로 구축된 모니터링은 작동하지 않으므로, 구독은 첫 번째 v1 슬롯에서 멈춰 버리고 그 상태로 유지됩니다. 설정 maxSupportedTransactionVersion: 1 구독과 관련하여, 다음을 처리하십시오 블록: null 빈 블록이 아닌 오류로 처리하고, 다른 방법으로는 이 문제가 드러나지 않으므로 유효성 검사를 추가해야 합니다.
v1에서는 컴퓨팅 제한 및 우선순위 수수료를 명령어에서 메시지 수준 구성으로 옮겼습니다. ComputeBudget 명령어를 스캔하는 인덱서는 일치하는 항목을 찾지 못하며, 어떤 레이어에서도 오류가 발생하지 않은 채 모든 다운스트림 데이터셋에 0을 기록합니다. 대신 트랜잭션 구성에서 제한값을 읽어오십시오. 이 정보는 옵트인된 응답의 메시지 내에 포함되지만, 레거시 및 v0의 경우 전혀 포함되지 않습니다. 설정되지 않은 필드는 그대로 반환됩니다. null:
"message": {
"instructions": ["… no ComputeBudget instruction here …"],
"recentBlockhash": "GsdgFbNBoZmAB5uPHfk2xUFYyM4Wg2hYZBfBrxrqjxfF",
"transactionConfig": {
"computeUnitLimit": 30000,
"heapSize": null,
"loadedAccountsDataSizeLimit": 200000,
"priorityFee": null
}
}레거시 버전과 v0 버전은 수수료를 컴퓨트 단위당 마이크로 람포트로 표시합니다. v1 버전은 람포트로 표시된 절대 총액으로 나타냅니다. v0 버전의 가격에 거래에서 요청된 컴퓨트 단위 한도를 곱한 다음, 1,000,000으로 나누어 두 값을 하나의 대시보드에 함께 표시할 수 있습니다:
20,000 CU × 250,000 마이크로 램포트/CU = 5,000 램포트 // v0
5,000 램포트 // v1과 동일변환 과정을 생략하면 합계는 아무런 의미가 없습니다.
스트리밍 이용자들에게는 이에 상응하는 것이 없다. 최대 지원 트랜잭션 버전 그리고 이를 해제할 방법이 없습니다. Yellowstone 의 geyser 플러그인을 15.1.1로 업그레이드하고, 12.6.0 이상 버전에서 protobuf 스텁을 다시 생성하면, 다음이 추가됩니다. Message.config 필드. 스테일 컨슈머는 v1에서 오류를 발생시키지 않습니다. 이 컨슈머는 트랜잭션을 컴퓨트 예산이 없는 v0으로 읽습니다.
다음에서 구조적으로 버전을 감지합니다. Message.config, 그리고 다음 순서대로 확인해 주세요:
다음 순서대로 확인해 주세요. | 버전 |
|---|---|
config 필드가 존재함 | v1 |
구성 정보 없음, 버전 관리 활성화됨 | v0 |
둘 다 아니다 | 레거시 |
순서가 중요한 이유는, 버전 관리됨 이는 v0과 v1 모두에 해당합니다. 이를 테스트하면 모든 v1 트랜잭션이 v0으로 분류되며, 계산 예산이 0으로 설정된 채 아무런 오류 메시지 없이 처리됩니다.
function messageVersion(message: Message): "legacy" | "v0" | "v1" {
if (message.config !== undefined) {
return "v1";
}
return message.versioned ? "v0" : "legacy";
}설정 이는 하위 메시지이며, proto3에서는 하위 메시지 필드가 항상 명시적인 존재 여부를 갖기 때문에, 디코더가 기본값을 어떻게 처리하든 상관없이 이 검사는 유효합니다.
Yellowstone 15.1.1 이전 버전의 geyser 플러그인은 v1 트랜잭션을 네트워크로 전송되기 전에 v0 형식으로 변환합니다. 스트림은 계속 작동하지만, 스트림이 전달하는 내용은 더 이상 체인에서 실행된 내용과 일치하지 않습니다. 15.1.1 이상으로 업그레이드하고, 이전 버전을 실행하는 동안 스트림 데이터를 체인 상태와 대조하여 조정했던 모든 작업에서 발생한 불일치를 고려해야 합니다.
위의 오류들은 equipe 가 v1을 채택하든 그렇지 않든 상관없이 발생합니다. 하지만 아래의 오류들은 그렇지 않습니다. 애플리케이션이 직접 v1 트랜잭션을 생성하여 제출하기 전까지는 아래에 언급된 어떤 상황도 발생하지 않으며, 모든 항목은 트랜잭션이 읽히는 방식이 아닌 구성 방식에 대한 변경 사항입니다. 레거시 및 v0 트랜잭션은 1,232바이트 크기로 변함없이 계속 작동하므로, v1을 전송할지 여부는 용량에 따라 결정됩니다. 1,232바이트 이상이 필요한 트랜잭션의 경우 다른 선택지가 없습니다.
트랜잭션에서 별도 지정이 없는 경우, 레거시 및 v0 버전은 명령어당 200,000 컴퓨트 유닛과 64 MiB의 로드된 계정 데이터로 기본값이 설정됩니다. v1 버전은 0으로 기본값이 설정되며 트랜잭션이 실패합니다. 모든 v1 트랜잭션은 컴퓨트 유닛 제한과 로드된 계정 데이터 크기 제한을 명시적으로 설정합니다. @solana/kit 8.0 ComputeBudget 지시문에서 해당 항목들을 제거하고 메시지 구성으로 옮깁니다:
import { setTransactionMessageConfig } from '@solana/kit';
const message = setTransactionMessageConfig(
{
computeUnitLimit: 20_000,
loadedAccountsDataSizeLimit: 64 * 1024,
priorityFeeLamports: 5_000n,
},
baseMessage,
);두 한계값을 모두 각 값을 최대로 설정한 상태에서 하나의 시뮬레이션 실행을 통해 측정하고, 반환된 값을 기록합니다. 소비된 단위 수 그리고 계정 데이터 로드 크기 다시 구성 파일로 돌아갑니다. 데이터 크기를 다음 32 KiB 페이지 단위로 올림 처리하십시오. 블록 비용 모델은 32 KiB 페이지 단위로 요금을 부과하므로, 다음 경계 미만의 여유 공간은 무료로 사용됩니다.
시뮬레이션 결과보다 여유 공간을 더 확보하십시오. 존재하지 않는 계정을 불러오는 데는 비용이 들지 않지만, 일단 생성되면 64바이트와 해당 데이터에 해당하는 비용이 발생하므로, 시뮬레이션 결과와 정확히 일치하는 크기로 제한을 설정하면 다음 오류가 발생합니다. 최대 계정 데이터 크기 초과 거래가 처리되기 전에 해당 계정이 표시되는 경우.
v1은 이를 수용하고, 각각 150 컴퓨트 유닛을 소모하며, 구성 설정에서는 이를 무시합니다. ComputeBudget 명령만 포함하고 메시지 구성이 없는 트랜잭션은 유효성 검사를 통과한 후 제한 없이 실행됩니다. v1 빌더에서 이를 완전히 제거하십시오. 메시지 구성이 이를 대체하며, 남아 있는 각 항목은 사용 가능한 64개의 명령 슬롯 중 하나를 차지하고 150 컴퓨트 유닛을 소모하면서도 아무런 작업도 수행하지 않습니다.
v1에서는 우선순위 수수료를 절대 램포트 합계로 설정합니다. v0에서 사용되던 ‘연산 단위당 마이크로 램포트’ 계산 방식은 적용되지 않습니다. 이 값은 bigint이며, 레거시 및 v0 메시지의 경우 세터가 컴파일 시점에 거부됩니다:
import { setTransactionMessagePriorityFeeLamports } from '@solana/kit';
const message = setTransactionMessagePriorityFeeLamports(5_000n, baseMessage);해당 규모를 초과하는 거래의 경우 다음이 필요합니다. 인코딩: "base64" 제출 시. base58을 하드코딩한 신청서는 v1에서 지원하는 대용량 트랜잭션 처리 시 오류가 발생합니다.
{
"jsonrpc": "2.0",
"id": 1,
"method": "sendTransaction",
"params": [
"<base64-encoded transaction>",
{ "encoding": "base64" }
]
}Legacy와 v0은 한 거래 내에서 계정 주소가 중복되는 것을 허용합니다. v1은 이를 거부합니다.
v1 지원은 다음부터 시작됩니다. @solana/kit 8.0.0, 4.2.x 버전의 Rust 크레이트, solders 0.29.0, 그리고 solana-go 1.23.0.
도서관 | 최소 버전 | 지원 |
|---|---|---|
@solana/kit | 8.0.0 | 읽기 및 보내기 |
@solana/web3.js 1.x | 1.99.0 (출시 예정) | 읽기 전용이며, 빌드, 서명 또는 전송할 수 없습니다. |
@solana/web3.js 3.x | rc-0.3 (출시 예정) | 읽기 및 보내기 |
v1 형식은 현재 별도의 기능 활성화 설정 없이 로컬 검증기에서 실행됩니다. solana-테스트-검증기 버전 4.2부터 이를 지원하며, Surfpool은 버전 1.5부터 지원하며, 그리고 SIMD-0296용으로 구성된 에페메랄 서프넷 호스팅 서비스를 제공합니다.
Quicknode RPC 엔드포인트와 API는 활성화 시 v1 트랜잭션을 지원합니다. endpoint 마이그레이션, 계획 변경, 구성 플래그 설정 또는 지원 티켓 제출이 필요하지 않습니다.
Quicknode 현재 Alpenglow 클러스터에서는 이미 v1 트랜잭션을 처리하고 있으므로, 해당 형식은 testnet 에 반영되기 전에 실제 endpoint 환경에서 테스트할 수 있습니다. Testnet 는 SIMD-0385 트랜잭션 V1 활성화가 완료될 때까지 보류 중이며, 활성화 예정일은 2026년 9월 2일 수요일 UTC 기준 10:30입니다.
나머지 작업은 애플리케이션 코드에 포함되어 있습니다. 통과 maxSupportedTransactionVersion: 1 ~에 getTransaction 그리고 getBlock, 위에 나열된 클라이언트 버전으로 업그레이드하고, ComputeBudget 명령어 스캔을 메시지 구성으로 대체하며, 모든 형식에서 우선순위 수수료 단위를 표준화하고, 1,232바이트를 초과하는 트랜잭션에 대해서는 base64 인코딩으로 전환하십시오.
2017년에 설립된 Quicknode 은 개발자와 기업을 위해 엔터프라이즈급 블록체인 인프라를 제공합니다. 99.99%의 가동률과 76개 이상의 체인을 지원함으로써, 팀들은 타협 없이 온체인 애플리케이션을 구축하고 확장할 수 있습니다.
최신 엔지니어링 인사이트, 제품 업데이트, 웹3 뉴스를 여러분의 이메일로 바로 받아보세요.
4.2.x |
읽기 및 보내기 |
솔더 (Python) | 0.29.0 | 읽기 및 보내기 |
solana-이동 | 1.23.0 | 읽기 및 보내기 |
Yellowstone geyser 플러그인 | 15.1.1 | 이전 빌드에서는 v1이 v0으로 다운그레이드됩니다. |
Protobuf 스텁 | 12.6.0 | Message.config 추가 |