altnara 자금흐름 데스크는 값을 내주는 쪽이 그 값을 어떻게 적어 두었는지를 점검합니다. 지금까지는 거래소 창구를 열어 규격을 셌는데, 이번 노트의 대상은 거래소가 아니라 체인이 스스로 적어 둔 설정 파일 한 개입니다. 운영자 보유 가능성: 본 매체는 비트코인·주요 알트 및 스테이블코인 보유 가능성을 명시합니다.
결론을 먼저 적겠습니다. 수이 공식 저장소에는 프로토콜 상수를 한곳에 모아 둔 파일이 있고, 그 파일의 1판 기본값 덩어리에는 상수 358개가 한 줄씩 적혀 있습니다. 2판부터 137판까지 버전 갈래가 136개 열려 있고 그 갈래들 안에서 값을 다시 넣는 줄만 652줄인데, 358개 가운데 112개는 그 652줄 중 어느 줄에서도 자기 이름이 불리지 않습니다. 이 파일 안에서는 1판에 적힌 값이 아직 그대로라는 뜻입니다.
먼저 112라는 수가 무엇을 센 값인지 갈라 두겠습니다. 112는 파일 전체를 대상으로, 그 이름에 값을 다시 넣는 줄이 한 줄이라도 있는가로 센 값입니다. 같은 파일을 메인넷이 실제로 밟는 경로만 따라가며 세면 114개가 됩니다. 차이 두 개는 vdf_hash_to_input_cost 와 vdf_verify_vdf_cost 인데, 이 둘은 파일 안에 대입 줄이 한 줄씩 있지만 그 줄이 메인넷이 아닐 때만 도는 조건 안에 들어 있습니다. 그래서 파일을 통째로 훑으면 112, 메인넷 경로를 따라가면 114입니다. 세는 기준이 다른 두 수이고 둘 다 맞습니다. 이 글은 두 수를 모두 적고, 어느 문단이 어느 기준인지 그때마다 밝혀 두겠습니다.
범위도 먼저 좁혀 두겠습니다. 이 노트가 확인한 것은 소스 파일이 그렇게 적어 두었다까지입니다. 노드를 돌리지 않았고, RPC 를 한 번도 부르지 않았으며, 메인넷이 지금 몇 번째 버전을 실행 중인지는 확인하지 않았습니다. 137은 파일이 스스로 이 빌드가 지원하는 최대 버전이라고 적어 둔 값입니다. 릴리스 태그가 아니라 main 브랜치의 2026년 9월 14일 상태이고, 며칠 뒤 137이 138이 되어 있어도 이상한 일이 아닙니다.
![]()
파일이 스스로 적어 둔 규칙에서 출발합니다
대상은 crates/sui-protocol-config/src/lib.rs 한 개입니다. 인증 없이 받을 수 있고, 이번에 받은 것은 268,335바이트 5,567줄이며 sha256 은 26cf5436decf85cd 로 시작합니다. 이 파일 맨 위에 지원 범위가 상수 두 개로 박혀 있습니다.
/// The minimum and maximum protocol versions supported by this build.
const MIN_PROTOCOL_VERSION: u64 = 1;
const MAX_PROTOCOL_VERSION: u64 = 137;
그리고 기본값 덩어리 바로 앞에 이 파일의 운영 규칙이 두 줄로 적혀 있습니다.
// IMPORTANT: Never modify the value of any constant for a pre-existing protocol version.
// To change the values here you must create a new protocol version with the new values!
이미 존재하는 버전의 값을 고치지 말고 새 버전을 만들어 거기에 새 값을 적으라는 규칙입니다. 값을 덮어쓰는 대신 판을 하나 더 붙이는 구조라 이 파일은 지운 기록이 없는 누적 장부에 가깝습니다. 그래서 1판에 적힌 값이 아직 살아 있는지를 세는 일이 가능해집니다. 어느 판에서 값이 바뀌었다면 그 판의 갈래에 대입 줄이 한 줄 남아 있어야 하고, 남아 있지 않다면 1판 값이 그대로인 것입니다. 이 노트가 센 것이 정확히 그 대입 줄입니다.
거래소마다 같은 코인의 식별자가 어긋나는 자리를 전수로 정리한 노트에서 쓴 방법과 같은 방법입니다. 그때는 창구가 내주는 규격을 한 행씩 세었고, 이번에는 체인이 저장소에 올려 둔 소스를 한 줄씩 셉니다. 세는 대상이 응답에서 소스로 바뀌었을 뿐 절차는 같습니다.
무엇을 분모로 삼았는지부터 갈라 두겠습니다
세는 단위는 1판 기본값 덩어리에 한 줄로 적힌 상수 이름입니다. 구조체 선언 쪽과 기본값 덩어리 쪽의 개수가 서로 다르기 때문에 어느 쪽을 분모로 삼았는지가 중요합니다.
| 구분 | 파일 안 위치 | 개수 |
|---|---|---|
| 설정 구조체에 선언된 필드 | 1441행부터 2266행 | 361 |
| 그중 값이 없을 수 있는 형으로 선언된 상수 | 357 | |
| 값이 없을 수 있는 형이 아닌 넷 | version · chain · feature_flags · aliased_addresses | |
| 1판 기본값 덩어리의 항목 | 2596행부터 3102행 | 358 |
| 그중 1판에서 값이 들어 있는 것 | 154 | |
| 그중 1판에서 값이 비어 있는 것 | 203 | |
| 빈 목록 하나 | 1 (aliased_addresses) |
손으로 검산하면 154 더하기 203 더하기 1은 358이고, 357 더하기 1도 358입니다. 361에서 358로 줄어드는 자리는 version 과 chain 과 feature_flags 인데, 이 셋은 설정값이 아니라 설정을 고르는 쪽의 정보라 기본값 덩어리에 값으로 적히지 않습니다. 이 글이 말하는 상수 358개는 구조체 선언 361개가 아니라 기본값 덩어리 358개 기준입니다.
기능 플래그는 따로 셉니다. 별도 구조체에 494행부터 1293행까지 188개가 선언되어 있고, 그중 180개는 켜짐과 꺼짐 하나로 쓰는 형입니다. 나머지 여덟은 참과 거짓이 아니라 방식을 고르는 값이라 따로 두었습니다. 상수와 플래그를 한 통에 넣고 세면 분모가 흐려지므로 이 글은 끝까지 둘을 섞지 않습니다.
358개 가운데 112개는 파일 어디에서도 이름이 다시 불리지 않습니다
파일 기준으로 센 결과는 이렇습니다.
| 항목 | 개수 |
|---|---|
| 1판 기본값 항목 | 358 |
| 적어도 한 번은 값이 다시 대입되는 것 | 246 |
| 다시 대입되는 줄이 한 줄도 없는 것 | 112 |
| 메인넷 경로만 따졌을 때 다시 대입되지 않는 것 | 114 |
여기서 눈에 걸리는 대목이 하나 있습니다. 112개의 1판 값을 갈라 보면 값이 들어 있는 것이 111개, 빈 목록이 1개이고, 값이 비어 있는 것은 0개입니다. 1판에서 비워 둔 203개는 전부 어느 판에선가 값을 받았다는 뜻입니다. 비워 두고 나중에 채우는 자리와, 처음부터 값을 적고 그대로 두는 자리가 이 파일 안에서 갈라져 있습니다. 다만 왜 그렇게 갈라졌는지는 이 노트가 확인하지 않았습니다. 확인한 것은 갈라져 있다는 사실까지입니다.
이 112라는 수는 서로 다른 두 방법이 일치한 값입니다. 하나는 버전 갈래를 1판부터 137판까지 순서대로 해석해 값이 덮이는 과정을 재현한 방법이고, 다른 하나는 1판 항목 358개의 이름을 하나씩 뽑아 파일 전체에서 그 이름에 값을 넣는 줄이 몇 줄인지만 세는 단순 대조입니다. 두 방법이 내놓은 집합의 차집합이 양쪽 다 비어 있었습니다. 방법을 하나만 썼다면 이 글은 수치를 내놓지 않았을 것입니다.
1판 값 그대로인 한도와 요율 43개
112개 가운데 성능 한도와 요율 계열만 뽑으면 43개입니다. 값은 소스에 적힌 표기 그대로 옮겼고, 곱셈식도 소스가 그렇게 적어 둔 것입니다.
| 상수 이름 | 1판 값 |
|---|---|
max_tx_size_bytes | 128 * 1024 |
max_input_objects | 2048 |
max_serialized_tx_effects_size_bytes | 512 * 1024 |
max_serialized_tx_effects_size_bytes_system_tx | 512 * 1024 * 16 |
max_gas_payment_objects | 256 |
max_arguments | 512 |
max_type_arguments | 16 |
max_type_argument_depth | 16 |
max_pure_argument_size | 16 * 1024 |
max_programmable_tx_commands | 1024 |
max_move_object_size | 250 * 1024 |
max_move_package_size | 100 * 1024 |
max_move_vector_len | 256 * 1024 |
max_event_emit_size | 250 * 1024 |
max_checkpoint_size_bytes | 30 * 1024 * 1024 |
max_loop_depth | 5 |
max_value_stack_size | 1024 |
max_type_nodes | 256 |
max_basic_blocks | 1024 |
max_push_size | 10000 |
max_dependency_depth | 100 |
max_fields_in_struct | 32 |
max_function_definitions | 1000 |
max_function_parameters | 128 |
max_struct_definitions | 200 |
max_generic_instantiation_length | 32 |
max_back_edges_per_function | 10_000 |
max_back_edges_per_module | 10_000 |
max_gas_computation_bucket | 5_000_000 |
max_num_new_move_object_ids | 2048 |
max_num_new_move_object_ids_system_tx | 2048 * 16 |
max_num_deleted_move_object_ids | 2048 |
max_num_deleted_move_object_ids_system_tx | 2048 * 16 |
max_num_transferred_move_object_ids | 2048 |
max_num_transferred_move_object_ids_system_tx | 2048 * 16 |
storage_rebate_rate | 9900 |
storage_fund_reinvest_rate | 500 |
obj_access_cost_read_per_byte | 15 |
obj_access_cost_mutate_per_byte | 40 |
obj_access_cost_delete_per_byte | 40 |
obj_access_cost_verify_per_byte | 200 |
obj_data_cost_refundable | 100 |
obj_metadata_cost_non_refundable | 50 |
한 건의 트랜잭션 크기 상한, 한 객체의 크기 상한, 체크포인트 크기 상한, 저장 보증금 환급 요율처럼 체인을 쓰는 쪽이 가장 자주 부딪히는 자리들이 이 표에 몰려 있습니다. 이 값들이 1판에 적힌 뒤 137판까지 다시 대입되지 않았다는 것이 이 노트가 확인한 내용입니다. 다만 이 표를 가지고 지금 메인넷이 이 한도로 돈다고 읽지는 마시기 바랍니다. 파일이 그 값을 바꾸는 줄을 적어 두지 않았다는 것까지가 확인된 범위이고, 메인넷이 실행 중인 버전은 이 노트가 확인하지 않았습니다.
112개 전체를 겹치지 않게 넷으로 쪼개면 이렇습니다.
| 갈래 | 개수 |
|---|---|
위 표의 한도와 요율 계열이면서 이름에 cost 가 없는 것 | 37 |
한도와 요율 계열이면서 이름에 cost 도 있는 것 | 6 |
이름에 cost 만 있는 것, 즉 무브 실행 비용표 계열 | 64 |
| 그 밖 | 5 |
37 더하기 6 더하기 64 더하기 5는 112입니다. 여기서 두 분류를 더하면 안 됩니다. 이름에 cost 가 들어간 것은 6 더하기 64로 70개이고, 위 표의 43개와 6개가 겹칩니다. 43 더하기 70을 해서 113을 만드는 셈은 틀립니다. 그리고 메인넷 기준 114개로 세면 cost 포함이 72개가 되므로, 112 기준의 하위 숫자와 114 기준의 하위 숫자를 섞어 인용하지 마시기 바랍니다.

112와 114를 가르는 자리는 상수 두 개입니다
앞에서 적은 두 상수를 자세히 보겠습니다. vdf_hash_to_input_cost 와 vdf_verify_vdf_cost 는 파일 안에 대입 줄이 한 줄씩 있습니다. 그래서 파일을 통째로 훑는 방법으로는 다시 대입되는 상수로 잡히고, 112개 바깥에 놓입니다. 그런데 그 한 줄이 메인넷이 아닐 때만 실행되는 조건 안에 들어 있어서, 메인넷 경로만 따라가면 그 줄에 닿지 못합니다. 그래서 메인넷 기준으로 세면 이 둘이 되돌아와 114개가 됩니다.
같은 자리를 다른 각도로 보면 이렇게 됩니다.
| 경로 | 137판까지 와도 값이 채워지지 않은 상수 |
|---|---|
| 메인넷 | 2개 (vdf_hash_to_input_cost · vdf_verify_vdf_cost) |
| 테스트넷 | 같은 2개 |
| 그 밖의 경로 | 0개 |
같은 자리에서 enable_vdf 플래그도 메인넷 경로에서는 한 번도 대입되지 않습니다. 비용 상수가 비어 있는 것과 기능 플래그가 꺼져 있는 것이 같은 자리에서 맞물려 있습니다. 다만 이 맞물림이 의도된 것인지는 이 노트가 확인하지 않았습니다. 확인한 것은 파일이 그렇게 적혀 있다는 사실까지입니다.
버전 갈래 136개 가운데 7개는 중괄호 안이 비어 있습니다
버전 갈래는 판 번호마다 하나씩 열려 있습니다. 1판은 갈래 머리가 있어도 안쪽이 도달 불가로 표시되어 있어 실제 갈래가 아니고, 그래서 실제 갈래는 2판부터 137판까지 136개입니다.
| 항목 | 값 |
|---|---|
| 갈래 머리 총수 | 137 |
| 실제 갈래 | 136 |
| 그중 중괄호 안이 비어 있는 갈래 | 7 |
| 비어 있는 갈래의 판과 행 | 13판 3185행 · 34판 3371행 · 40판 3461행 · 42판 3497행 · 47판 3539행 · 103판 4382행 · 117판 4527행 |
| 갈래 블록 안의 상수 대입 줄 | 395 |
| 같은 블록 안의 기능 플래그 대입 줄 | 257 |
| 대입 줄 합계 | 652 |
395 더하기 257은 652입니다. 갈래 블록은 3103행에서 4784행까지이고, 그 안에 체인을 따지는 조건 블록이 90개 들어 있습니다.
| 조건 문구 | 개수 |
|---|---|
chain != Chain::Mainnet | 43 |
chain != Chain::Mainnet && chain != Chain::Testnet | 29 |
chain != Chain::Testnet && chain != Chain::Mainnet | 8 |
chain == Chain::Mainnet | 8 |
chain == Chain::Unknown | 1 |
chain == Chain::Testnet | 1 |
43 더하기 29 더하기 8 더하기 8 더하기 1 더하기 1은 90입니다. 세 번째 줄과 두 번째 줄은 뜻이 같은 조건인데 적는 순서만 다릅니다. 조건 블록이 90개나 되기 때문에 같은 137판이라도 체인마다 실제로 적용되는 대입 줄 수가 달라집니다.
| 경로 | 적용된 상수 대입 | 적용된 플래그 대입 | 적용 합계 | 조건에 걸려 건너뛴 줄 |
|---|---|---|---|---|
| 메인넷 | 327 | 171 | 498 | 154 |
| 테스트넷 | 349 | 211 | 560 | 92 |
| 그 밖 | 390 | 248 | 638 | 14 |
498 더하기 154, 560 더하기 92, 638 더하기 14가 모두 652로 맞습니다. 세 경로 모두 같은 652줄을 놓고 갈리는 것이라 이 검산이 맞지 않으면 해석이 틀린 것입니다. 메인넷은 파일에 적힌 대입 줄의 약 4분의 1을 건너뜁니다. 이 자리가 파일 하나를 눈으로 읽어서는 잡히지 않는 부분입니다. 줄이 거기 적혀 있다고 해서 메인넷에서 그 값이 들어가는 것이 아니기 때문입니다.
거래소가 서버 시간을 어떻게 적어 두는지 창구별로 실측한 노트에서도 같은 모양을 만났습니다. 문서에 칸이 있다는 사실과 그 칸이 이 경로에서 값을 준다는 사실은 다른 문제입니다. 그때는 창구가 대상이었고 이번에는 조건문이 대상이지만, 적혀 있는 것과 적용되는 것을 갈라 세야 한다는 점은 같습니다.

이 파일 안에서 한 줄도 바뀌지 않는 판이 메인넷 기준 17개입니다
갈래가 비어 있는 7개 말고도, 갈래에 줄이 적혀 있는데 그 줄이 전부 조건에 걸려 건너뛰어지는 판이 있습니다. 두 가지를 합쳐 세면 이렇게 됩니다.
| 경로 | 상수도 플래그도 한 줄 안 바뀌는 판 | 개수 |
|---|---|---|
| 메인넷 | 8 · 13 · 21 · 34 · 39 · 40 · 42 · 47 · 65 · 66 · 67 · 75 · 83 · 93 · 103 · 117 · 121 | 17 |
| 그 밖의 경로 | 8 · 13 · 34 · 39 · 40 · 42 · 47 · 56 · 58 · 65 · 66 · 67 · 93 · 103 · 117 | 15 |
여기서 문장 하나를 정확히 적어 두겠습니다. 이것은 그 판을 올렸을 때 아무 일도 일어나지 않았다는 뜻이 아닙니다. 프로토콜 버전은 이 파일 밖에서도 움직입니다. 무브 프레임워크 쪽 변경이나 노드 동작 변경은 이 파일에 한 줄도 남기지 않고 지나갈 수 있습니다. 이 파일 안에서 바뀌는 줄이 없다는 한정을 빼면 그 순간 틀린 문장이 됩니다. 인용하실 때 이 한정을 같이 옮겨 주시기 바랍니다.
기능 플래그 188개 가운데 27개는 어느 판에서도 대입되지 않습니다
플래그 쪽은 상수와 다른 모양이 나옵니다.
| 항목 | 값 |
|---|---|
| 선언된 플래그 | 188 |
| 어느 판에서든 한 번이라도 대입되는 것 | 161 |
| 어느 판에서도 한 번도 대입되지 않는 것 | 27 |
| 메인넷 경로에서 한 번도 대입되지 않는 것 | 35 |
| 메인넷 경로에서 마지막 대입이 켜짐인 것 | 143 |
161 더하기 27은 188입니다. 마지막 줄의 143은 켜짐과 꺼짐 하나로 쓰는 180개를 분모로 한 값입니다. 파일은 기본값 덩어리 바로 앞에 // All flags are disabled in V1 이라고 적어 두었고, 실제로 1판 기본값은 전부 꺼짐입니다. 그래서 한 번도 대입되지 않는 27개는 선언되어 있고 꺼져 있는 상태입니다.
여기서도 한 발 앞서 나가지 않겠습니다. 이 27개를 죽은 코드나 버려진 기능이라고 부를 근거를 이 노트는 확인하지 않았습니다. 앞으로 켜려고 미리 이름만 잡아 둔 자리일 수도 있고, 다른 파일에서 쓰이는 자리일 수도 있습니다. 확인한 것은 이 파일 안에서 한 번도 대입되지 않고 기본값이 꺼짐이라는 사실까지입니다.
플래그 이름을 보면 합의 처리와 체크포인트 쪽 이름이 눈에 띕니다. 합의 관련 이름이 여럿이고, 업그레이드 시점 검사나 프롤로그 기록과 관련된 이름도 있습니다. 다만 이름으로 기능을 추정하는 일은 이 노트의 범위 밖입니다.
조건 블록은 90개인데 137판에서 남는 차이는 두 자리입니다
앞에서 본 조건 블록 90개는 체인마다 다른 길을 만듭니다. 그런데 137판까지 다 밟고 나면 메인넷과 테스트넷 사이에 남는 차이는 이만큼입니다.
| 갈래 | 137판에서 메인넷과 테스트넷이 갈리는 개수 |
|---|---|
| 상수 | 0 |
| 기능 플래그 | 2 (enable_ristretto255_group_ops · enable_verify_bulletproofs_ristretto255) |
상수 쪽은 값이 들어갔는지 여부로 갈리는 자리가 하나도 없습니다. 앞 표의 조건 문구를 더해 보면 메인넷을 제외하는 블록만 43 더하기 29 더하기 8로 80개이고, 메인넷에서만 도는 블록이 8개입니다. 그렇게 갈라 두고도 결과가 이만큼 모이는 것은 갈라 두었다가 뒤 판에서 다시 합치는 패턴이 반복되기 때문입니다. 먼저 메인넷 바깥에서 켜고, 몇 판 뒤에 조건 없이 다시 켜는 줄을 적으면 최종 상태는 같아집니다.
메인넷 경로에서는 대입되지 않고 그 밖 경로에서는 대입되는 플래그가 8개 있습니다. check_object_funds_withdraw_in_execution · create_forwarding_address_registry · defer_owned_object_double_spend · enable_group_ops_native_function_msm · enable_ristretto255_group_ops · enable_vdf · enable_verify_bulletproofs_ristretto255 · zklogin_circuit_mode 입니다.
이 대목을 안전하다거나 같다는 결론으로 옮기지 마시기 바랍니다. 이 파일이 재는 것은 이 파일 안의 값뿐입니다. 두 경로의 최종 설정이 이 파일 기준으로 두 자리만 다르다는 관측이고, 그것이 네트워크 동작이 같다는 뜻은 아닙니다.
반대쪽에는 열두 번 고쳐 온 상수가 있습니다
112개가 한쪽 끝이라면 반대쪽 끝도 세어 두어야 분포가 읽힙니다. 메인넷 경로 기준으로 가장 자주 값이 다시 들어간 상수는 이렇습니다.
| 상수 | 다시 대입된 횟수 | 1판 값 |
|---|---|---|
gas_model_version | 12 | 값 있음 |
max_accumulated_txn_cost_per_object_in_mysticeti_commit | 5 | 비어 있음 |
execution_version | 4 | 비어 있음 |
random_beacon_reduction_lower_bound | 4 | 비어 있음 |
consensus_max_transactions_in_block_bytes | 3 | 비어 있음 |
max_tx_gas | 2 | 값 있음 |
표의 맨 아래 max_tx_gas 는 1판에 100억이 적혀 있었고 3판에서 500억으로 올라간 뒤 한 번 더 손을 탔습니다. 재대입이 두 번뿐인 상수가 상위 여섯 안에 들어온다는 점은 짚어 둘 만합니다. 다만 재대입 횟수별 분포 전체를 이 노트가 센 것은 아니므로, 상위 여섯 바깥이 어떤 모양인지는 여기서 말할 수 없습니다.
기능 플래그 쪽에서 가장 자주 고쳐진 것은 per_object_congestion_control_mode 로 12회이고, 그다음이 defer_unpaid_amplification 으로 4회입니다. 한 판이 건드린 상수가 가장 많았던 곳은 메인넷 경로 기준 70판의 55개이고, 41판과 53판이 각각 30개로 뒤를 잇습니다. 플래그를 가장 많이 건드린 판은 124판의 8개입니다.
여기서 읽히는 것은 한 파일 안에 성격이 다른 두 무리가 같이 있다는 점입니다. 가스 모델 버전이나 합의 처리 한도처럼 계속 조정되는 자리가 있고, 크기 한도나 비용표처럼 처음 적은 값으로 버티는 자리가 있습니다. 이 파일을 인용할 때 앞쪽 무리의 값을 보고 뒤쪽 무리도 자주 바뀐다고 넘겨짚거나, 그 반대로 넘겨짚는 일이 생길 수 있습니다.
이 파일 바깥의 대조 두 가지
첫째는 같은 저장소의 프레임워크 스냅숏 대장입니다. crates/sui-framework-snapshot/manifest.json 은 101,118바이트이고 프로토콜 버전을 키로 삼습니다. 키는 105개이고 가장 낮은 키가 3, 가장 높은 키가 137입니다. 3과 137 사이에서 키가 없는 판이 30개 있습니다. 다만 키가 없다는 것이 무슨 뜻인지는 이 노트가 확인하지 못했습니다. 그 판에서 프레임워크가 바뀌지 않았다는 뜻으로 읽고 싶어지지만, 그 해석을 뒷받침할 근거를 확인하지 않았으므로 대장에 키가 없다까지만 적습니다.
둘째는 다른 체인이 같은 일을 어떤 파일 모양으로 하는지입니다. 솔라나 쪽 클라이언트인 아가베 저장소의 feature-set/src/lib.rs 를 같은 날 같은 방식으로 받아 세었더니 95,636바이트 2,711줄에 주소 선언이 289개였고 그중 287개가 이름표 표에 올라 있었으며 나머지 둘은 기능 게이트가 아니라 버퍼 주소였고, 활성화 여부를 담는 참과 거짓 칸은 63개였습니다. 수이는 판 번호로 묶은 설정 덩어리를 쓰고 솔라나는 주소를 붙인 개별 게이트를 쓴다는 구조 차이가 파일 모양에서 그대로 드러납니다. 다만 여기서 확인한 것은 두 파일의 선언 개수뿐이며, 어느 쪽이 더 유연하다거나 완성도가 높다는 비교는 이 수치로 할 수 없습니다.
솔라나 클라이언트 자체를 다룬 축은 솔라나 파이어댄서 클라이언트를 5팀이 평가한 노트에 따로 있습니다. 그쪽은 클라이언트 구현과 검증인 채택 이야기이고, 이 절은 기능 게이트가 파일에 몇 개 선언되어 있는지를 센 것이라 축이 다릅니다.
세는 도구를 세 번 고쳤습니다
수치를 내기 전에 도구가 틀린 자리를 세 번 잡았습니다. 이 과정을 적어 두는 이유는, 첫 결과를 그대로 발표했다면 세 번 다 틀린 숫자가 나갔을 것이기 때문입니다.
- 첫 파서가 갈래 7개를 통째로 놓쳤습니다. 중괄호 안이 한 줄로 비어 있는 갈래를 만나면 닫는 괄호를 찾다가 다음 갈래를 삼켜 버렸습니다. 그래서 14판과 35판과 41판과 43판과 48판과 104판과 118판이 없는 갈래로 잡혔습니다. 해당 행을 눈으로 열어 보고 잡았고, 14판은 3186행에 멀쩡히 있었습니다.
- 첫 파서가 주석 속 대입을 진짜 대입으로 셌습니다. 선언에는 없는데 대입은 된다고 잡힌 플래그가 하나 있었는데, 실물은 3209행의 주석 처리된 한 줄이었습니다. 주석을 걸러 내니 사라졌습니다.
- 첫 파서가 비교 연산을 대입으로 셀 뻔했습니다. 같음을 묻는 두 글자짜리 연산자를 대입 한 글자와 구분하도록 고쳤습니다.
이 세 가지를 고친 뒤에야 앞에서 적은 두 방법의 결과가 맞아떨어졌습니다. 도구가 내놓은 첫 숫자를 믿지 않은 것이 이 노트에서 제일 중요한 절차였습니다.
같은 값을 직접 확인하는 절차
인증이 필요 없어서 브라우저와 명령 몇 줄로 같은 자리에 닿을 수 있습니다.
https://raw.githubusercontent.com/MystenLabs/sui/main/crates/sui-protocol-config/src/lib.rs를 받습니다. 받은 파일의 sha256 이26cf5436decf85cd로 시작하고 크기가 268,335바이트이면 이 노트가 읽은 것과 같은 파일입니다. 다르면 그 사이에 커밋이 들어온 것이므로 아래 숫자들이 달라질 수 있습니다.- 파일 39행부터 41행을 열어 봅니다. 지원 최소 버전과 최대 버전이 상수로 박혀 있습니다. 이 글의 137은 여기서 읽은 값입니다.
- 2594행과 2595행의 주석 두 줄을 읽습니다. 기존 버전의 값을 고치지 말라는 규칙이 이 파일의 전제입니다.
- 3185행과 3371행과 3461행으로 가 봅니다. 갈래 안이 비어 있는 판 셋입니다. 비어 있는 갈래는 모두 일곱이며 나머지 넷은 3497행과 3539행과 4382행과 4527행입니다.
- 아무 상수 이름이나 하나 골라 파일 전체에서 그 이름에 값을 넣는 줄을 찾아봅니다.
max_tx_size_bytes를 넣으면 기본값 덩어리의 한 줄 말고는 나오지 않고,gas_model_version을 넣으면 여러 줄이 나옵니다. 이 차이가 이 글이 센 그 차이입니다. - 같은 파일의 최근 커밋은
https://api.github.com/repos/MystenLabs/sui/commits?path=crates/sui-protocol-config/src/lib.rs&per_page=3으로 확인할 수 있습니다. 이 노트가 받은 시점의 직전 커밋은 2026년 9월 12일이었습니다.
확인하지 못한 것
- 노드를 돌리지 않았습니다. 전부 소스 파일이 그렇게 적어 두었다까지입니다.
- 메인넷이 지금 몇 판을 실행 중인지 확인하지 않았습니다. 137은 파일이 이 빌드가 지원하는 최대라고 적은 값이고, RPC 를 부르지 않았습니다.
- 릴리스 태그가 아니라 main 최신 커밋 기준입니다. 커밋이 들어오면 137이 138이 될 수 있습니다.
- 체인 조건 해석은 이 노트가 파이썬으로 재현한 것입니다. 러스트로 컴파일해 돌려 본 결과가 아니며, 근거는 서로 다른 두 방법이 일치했다는 점까지입니다.
- 한 번도 대입되지 않은 플래그 27개가 왜 남아 있는지 확인하지 않았습니다.
- 프레임워크 스냅숏 대장에서 판 30개가 빠진 이유를 확인하지 않았습니다.
- 이 수치들은 가격과 아무 관계가 없습니다. 상수가 몇 개 그대로인지는 토큰 시세를 설명하는 값이 아니며, 이 글은 그런 연결을 한 줄도 하지 않습니다.
정리
세 줄로 줄이면 이렇습니다.
첫째, 판은 137까지 올라갔는데 1판 값이 그대로인 상수가 112개입니다. 기본값 덩어리 358개 가운데 112개는 파일 어디에도 값을 다시 넣는 줄이 없고, 그중 111개는 1판부터 값이 들어 있던 자리입니다. 트랜잭션 크기 상한과 객체 크기 상한과 저장 보증금 환급 요율이 그 안에 들어 있습니다.
둘째, 112와 114 가운데 어느 쪽을 쓰는지 밝혀야 합니다. 파일 전체를 훑으면 112이고 메인넷 경로만 따라가면 114입니다. 차이는 조건 안에 들어 있는 대입 줄 두 개뿐이지만, 기준을 밝히지 않고 인용하면 읽는 쪽이 두 수를 맞대 보다가 한쪽을 오류로 판정하게 됩니다.
셋째, 적혀 있는 줄과 적용되는 줄은 다릅니다. 갈래 안 대입 줄은 652줄인데 메인넷은 조건에 걸려 154줄을 건너뛰고 498줄만 적용합니다. 조건 블록이 90개나 되기 때문에 파일을 눈으로 읽어 내려가는 방식으로는 이 차이가 잡히지 않습니다.
이 파일을 인용하실 때는 어느 기준으로 센 값인지와 어느 커밋을 읽은 값인지를 함께 적어 두시는 편이 정확합니다. 다만 이 노트는 소스 파일을 센 기록일 뿐이며 어떤 거래도 권하지 않습니다.
FAQ
Q. 137이라는 숫자는 언제 바뀌나요?
A. main 브랜치에 새 버전 갈래가 커밋되고 파일 위쪽의 최대 버전 상수가 함께 올라갈 때 바뀝니다. 이 글의 수치는 2026년 9월 14일에 받은 커밋 기준이고 그때 직전 커밋은 9월 12일이었습니다. 며칠 뒤에 같은 주소를 열면 137이 아닐 수 있으므로, 인용하실 때는 파일의 sha256 이나 커밋 해시를 함께 적어 두시는 편이 안전합니다.
Q. 112개가 그대로라는 말은 지금 메인넷이 그 값으로 돈다는 뜻인가요? A. 그렇게 읽으면 한 칸 넘어갑니다. 이 노트는 노드를 돌리지 않았고 메인넷이 실행 중인 판이 몇 번인지 확인하지 않았습니다. 확인한 것은 이 파일 안에 그 값을 바꾸는 줄이 없다는 사실까지입니다. 메인넷이 137판을 실행 중이라는 전제가 별도로 확인될 때에만 그 문장이 성립합니다.
Q. 112와 114 가운데 어느 쪽을 쓰면 되나요?
A. 파일 자체를 이야기할 때는 112, 메인넷에서 실제로 적용되는 값을 이야기할 때는 114가 맞습니다. 두 수의 차이는 vdf_hash_to_input_cost 와 vdf_verify_vdf_cost 두 개이고, 이 둘은 대입 줄이 메인넷을 제외하는 조건 안에 들어 있습니다. 어느 쪽을 쓰든 기준을 한 줄 붙여 주시면 됩니다.
Q. 값이 안 바뀌었다는 것은 그 자리가 방치되었다는 뜻인가요? A. 이 파일만으로는 그렇게 읽을 수 없습니다. 파일이 스스로 기존 버전의 값을 고치지 말라고 적어 둔 구조라, 값을 바꾸려면 새 판을 만들어 대입 줄을 남겨야 합니다. 대입 줄이 없다는 것은 판을 새로 만들어 바꾼 적이 없다는 뜻이고, 그 자리를 들여다본 적이 있는지 없는지는 이 파일에 기록되지 않습니다.
Q. 갈래가 비어 있는 판 7개는 왜 만들어졌나요? A. 이유는 이 노트가 확인하지 않았습니다. 확인한 것은 13판과 34판과 40판과 42판과 47판과 103판과 117판의 갈래 안이 비어 있다는 사실과 그 행 번호까지입니다. 프로토콜 버전은 이 파일 밖에서도 움직이므로, 갈래가 비어 있다는 것과 그 판에서 아무 일도 없었다는 것은 다른 이야기입니다.
Q. 조건 블록 90개는 메인넷과 테스트넷이 크게 다르다는 뜻인가요? A. 과정에서는 다르고 결과에서는 거의 같습니다. 137판까지 전부 밟은 뒤 두 경로가 갈리는 자리는 상수 0개, 기능 플래그 2개입니다. 갈라 두었다가 뒤 판에서 조건 없이 다시 적용하는 패턴이 반복되기 때문입니다. 다만 이 비교는 이 파일 안의 값에 한정되며 네트워크 동작이 같다는 뜻은 아닙니다.
Q. 다른 체인도 같은 방식으로 셀 수 있나요? A. 파일 모양이 달라서 세는 단위를 다시 정해야 합니다. 솔라나 쪽 아가베 저장소는 판 번호가 아니라 기능마다 주소를 붙이는 구조라, 같은 질문을 던지려면 판별 대입 줄이 아니라 주소 선언과 이름표 등재를 세게 됩니다. 그 파일에서는 선언 289개 가운데 287개가 이름표 표에 올라 있었습니다. 두 체인의 우열을 재는 값은 아닙니다.
함께 보면 좋은 글
- 거래소마다 같은 코인의 식별자가 어긋나는 자리를 전수로 정리한 노트: 이번 노트가 빌려 온 세는 방법이 처음 쓰인 자리입니다. 그쪽은 창구 응답을 세었고 이번에는 저장소 소스를 세었습니다.
- 거래소가 서버 시간을 어떻게 적어 두는지 창구별로 실측한 노트: 적혀 있는 칸과 실제로 값이 오는 칸을 갈라 세야 한다는 같은 문제를 다른 대상에서 다룹니다.
- 솔라나 파이어댄서 클라이언트를 5팀이 평가한 노트: 체인 클라이언트 자체를 다룬 축입니다. 이 글의 솔라나 대조 문단은 클라이언트가 아니라 기능 게이트 선언 개수를 센 것이라 축이 다릅니다.
데이터·개념 출처
본 노트의 수치는 2026년 9월 14일 12시 6분 49초부터 12시 31분 41초(KST) 사이에 깃허브 공개 주소를 인증 없이 호출해 받은 파일을 직접 센 것입니다. 받은 파일은 전부 저장한 뒤 다시 파싱해 재계산했고, 앞 문장을 근거로 삼은 숫자는 없습니다.
수이 쪽 본문은 https://raw.githubusercontent.com/MystenLabs/sui/main/crates/sui-protocol-config/src/lib.rs 입니다. 268,335바이트 5,567줄이고 sha256 은 26cf5436decf85cdb88cc465d4837aecc1da10890782afab9046fbf1232b1e7f 입니다. 같은 주소로 다섯 번 받아 바이트를 대조했고 다섯 번 전부 같은 해시였으며, 확인한 창은 24분 52초입니다. 다만 이 파일은 시세와 달리 커밋이 들어와야 바뀌므로 이 창의 동일성은 안정성의 증거로는 약합니다. 더 단단한 고정점은 해시와 커밋 해시입니다.
같은 파일의 최근 커밋은 https://api.github.com/repos/MystenLabs/sui/commits?path=crates/sui-protocol-config/src/lib.rs&per_page=3 으로 받았습니다. 직전 커밋은 7a34409c02bd 로 2026년 9월 12일 05시 18분 57초(UTC)이고, 그 앞이 f8dc1baa58c2 로 9월 11일, 그 앞이 a0ca4162565a 로 9월 10일입니다.
프레임워크 스냅숏 대장은 https://raw.githubusercontent.com/MystenLabs/sui/main/crates/sui-framework-snapshot/manifest.json 이며 101,118바이트입니다. 솔라나 대조는 https://raw.githubusercontent.com/anza-xyz/agave/master/feature-set/src/lib.rs 이며 95,636바이트 2,711줄입니다. 처음 시도한 두 경로가 404 였고, 깃허브 트리 목록을 받아 실제 경로를 찾아 다시 받았습니다. 못 열었다로 굳히지 않고 재시도해 열었다는 점을 적어 둡니다.
집계는 두 가지 독립한 방법으로 각각 계산했습니다. 하나는 버전 갈래를 1판부터 137판까지 순서대로 해석해 값이 덮이는 과정을 재현한 방법이고, 다른 하나는 1판 항목의 이름을 하나씩 뽑아 파일 전체에서 대입 줄 수만 세는 단순 대조입니다. 두 결과의 차집합이 양쪽 다 비어 있었고, 메인넷 기준 114와의 차이 두 개는 본문에 적은 그 둘뿐이었습니다. 손검산으로 맞춘 항등식은 154 더하기 203 더하기 1은 358, 395 더하기 257은 652, 498 더하기 154와 560 더하기 92와 638 더하기 14가 각각 652, 161 더하기 27은 188, 37 더하기 6 더하기 64 더하기 5는 112입니다.
이 글은 공개 저장소의 소스 파일을 정리한 정보 제공 목적의 자료이며 특정 종목이나 네트워크의 이용 권유가 아닙니다. 본 노트는 진입가·손절가·목표가를 제시하지 않고, 어떤 자산도 매수 또는 매도 대상으로 지목하지 않으며, 어느 체인의 설정 구조가 더 낫다는 판단도 하지 않습니다. 여기에 적힌 수치는 특정 커밋 시점의 스냅숏이라 저장소에 커밋이 들어오면 달라지며, 이 파일에 적힌 값이 실제 네트워크에서 어떻게 적용되고 있는지는 이 글에서 확인하지 않았습니다. 가상자산은 가격 변동성이 크고 원금 전액을 잃을 수 있습니다. 투자 판단과 그 결과는 전적으로 본인 책임입니다.