[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-deep-evm-11-huff-jeompeu-teibeul-o1-hamsoo-diseupaechi":3},{"article":4,"author":59},{"id":5,"category_id":6,"title":7,"slug":8,"excerpt":9,"content_md":10,"content_html":11,"locale":12,"author_id":13,"published":14,"published_at":15,"meta_title":16,"meta_description":17,"focus_keyword":18,"og_image":19,"canonical_url":19,"robots_meta":20,"created_at":15,"updated_at":15,"tags":21,"category_name":39,"related_articles":40},"d5000000-0000-0000-0000-000000000111","a0000000-0000-0000-0000-000000000052","Deep EVM #11: Huff 점프 테이블 — Solidity 오버헤드 없는 O(1) 함수 디스패치","deep-evm-11-huff-jeompeu-teibeul-o1-hamsoo-diseupaechi","Huff에서 압축된 점프 테이블을 사용하여 O(1) 함수 디스패처를 구축합니다. Solidity의 if-else 체인과 수천 가스를 절약하는 수작업 점프 테이블을 비교합니다.","## Solidity 디스패처의 문제점\n\nSolidity 컨트랙트를 호출하면 EVM이 가장 먼저 실행하는 것은 함수 디스패처입니다. Solidity는 콜데이터의 처음 4바이트(함수 셀렉터)를 각 알려진 셀렉터와 비교하는 선형 if-else 체인을 생성합니다:\n\n```\nCALLDATALOAD 0x00\nSHR 224\nDUP1\nPUSH4 0x70a08231    \u002F\u002F balanceOf(address)\nEQ\nPUSH2 dest1\nJUMPI\nDUP1\nPUSH4 0xa9059cbb    \u002F\u002F transfer(address,uint256)\nEQ\nPUSH2 dest2\nJUMPI\n...\n```\n\nN개의 함수가 있는 컨트랙트의 경우 이것은 O(N)입니다 — 최악의 경우 일치를 찾기 전에 모든 N개 셀렉터를 확인합니다. 각 비교는 약 22 가스(DUP1 + PUSH4 + EQ + PUSH2 + JUMPI)가 듭니다. 20개 함수가 있는 컨트랙트는 디스패치에만 최대 440 가스를 낭비합니다. Solidity 컴파일러(0.8.22 이후)는 때때로 큰 인터페이스에 대해 이진 검색 트리를 사용하여 O(log N)으로 줄이지만, 이것도 최적은 아닙니다.\n\n하루에 수백만 번 호출되는 MEV 봇 컨트랙트의 경우, 호출당 400+ 가스 단위가 실제 ETH로 누적됩니다.\n\n## 점프 테이블 접근법: O(1)\n\n점프 테이블은 비교가 아닌 산술을 사용하여 함수 셀렉터를 코드 오프셋에 직접 매핑합니다. 이 아이디어는 CPU 아키텍처에서 차용되었습니다 — 계산된 GOTO는 1960년대부터 시스템 프로그래밍에서 사용되어 왔습니다.\n\n개념:\n\n1. 콜데이터에서 함수 셀렉터를 추출합니다 (4바이트).\n2. 산술을 사용하여 셀렉터에서 점프 대상을 계산합니다.\n3. 해당 대상으로 직접 JUMP합니다.\n\n비교도 없고, 분기도 없으며, 함수 수에 관계없이 상수 시간입니다.\n\n### 접근법 1: 최소 셀렉터 인코딩\n\n컨트랙트에 소수의 함수(1-8개)가 있는 경우, 첫 번째 바이트나 두 번째 바이트가 고유한 작은 정수를 인코딩하는 배니티 셀렉터를 마이닝하여 셀렉터를 수동으로 할당할 수 있습니다:\n\n```huff\n#define macro DISPATCHER() = takes(0) returns(0) {\n    0x00 calldataload       \u002F\u002F [calldata_word]\n    0xe0 shr                \u002F\u002F [selector]\n\n    \u002F\u002F 라우팅 바이트 추출 — 셀렉터의 첫 번째 바이트\n    0x18 shr                \u002F\u002F [first_byte]\n\n    \u002F\u002F 테이블의 각 항목은 2바이트 (PUSH2 offset)\n    \u002F\u002F 테이블 시작 + first_byte * 2 = 점프 대상 포인터\n    0x02 mul                \u002F\u002F [offset_in_table]\n    __tablestart(JumpTable) \u002F\u002F [table_start, offset_in_table]\n    add                     \u002F\u002F [entry_address]\n    \n    \u002F\u002F 테이블에서 2바이트 점프 대상 로드\n    codecopy_dest:\n    0x00 codecopy           \u002F\u002F 코드에서 메모리로 2바이트 복사\n    0x00 mload              \u002F\u002F [jump_dest (32바이트로 패딩)]\n    0xf0 shr                \u002F\u002F [jump_dest] — 2바이트 값을 얻기 위해 오른쪽 시프트\n    jump                    \u002F\u002F 함수 본문으로 GOTO\n}\n\n#define jumptable JumpTable {\n    swap_exact   \u002F\u002F selector 0x00...\n    add_liq      \u002F\u002F selector 0x01...\n    remove_liq   \u002F\u002F selector 0x02...\n    flash_loan   \u002F\u002F selector 0x03...\n}\n```\n\n### 접근법 2: 압축된 코드 테이블\n\n최대 밀도를 위해 `__tablestart`와 `__tablesize`를 사용하여 점프 테이블을 바이트코드에 직접 패킹할 수 있습니다. Huff는 점프 테이블을 일급 구성 요소로 기본 지원합니다:\n\n```huff\n#define jumptable__packed SELECTOR_TABLE {\n    fn_swap\n    fn_transfer\n    fn_approve\n    fn_balance\n}\n\n#define macro MAIN() = takes(0) returns(0) {\n    0x00 calldataload 0xe0 shr  \u002F\u002F [selector]\n\n    \u002F\u002F 셀렉터를 인덱스(0-3)로 매핑\n    \u002F\u002F 셀렉터 값에 따라 다름 — 상위 바이트가 인덱스가 되도록 마이닝\n    0x18 shr                    \u002F\u002F [index]\n\n    \u002F\u002F 경계 확인\n    dup1 0x04 lt                \u002F\u002F [in_bounds?, index]\n    valid jumpi\n    0x00 0x00 revert\n\n    valid:\n    \u002F\u002F 압축 테이블에서 로드 (항목당 2바이트)\n    __tablestart(SELECTOR_TABLE)\n    swap1 0x02 mul add          \u002F\u002F [table_entry_ptr]\n\n    \u002F\u002F 2바이트 코드 오프셋 읽기\n    0x1e mload                  \u002F\u002F 트릭: codecopy를 통해 코드에서 mload\n    jump\n\n    fn_swap:\n        SWAP_IMPL()\n    fn_transfer:\n        TRANSFER_IMPL()\n    fn_approve:\n        APPROVE_IMPL()\n    fn_balance:\n        BALANCE_IMPL()\n}\n```\n\n## 셀렉터 추출을 위한 콜데이터 비트 시프팅\n\n표준 셀렉터 추출은:\n\n```huff\n0x00 calldataload   \u002F\u002F 콜데이터 위치 0에서 32바이트 로드\n0xe0 shr            \u002F\u002F 상위 4바이트를 분리하기 위해 224비트(256 - 32) 오른쪽 시프트\n```\n\n비용: PUSH1 (3) + CALLDATALOAD (3) + PUSH1 (3) + SHR (3) = 12 가스.\n\n셀렉터의 1-2바이트만 필요한 경우 더 저렴한 대안:\n\n```huff\n0x00 calldataload   \u002F\u002F [calldata_word]\n0xf8 shr            \u002F\u002F [first_byte] — 바이트 0만 얻기 위해 248비트 오른쪽 시프트\n```\n\n같은 가스이지만, 이제 라우팅 키가 1바이트(256개 가능한 값)입니다. 컨트랙트에 256개 이하의 함수가 있다면, 1바이트로 각각을 고유하게 식별할 수 있습니다. 각 함수의 첫 번째 셀렉터 바이트가 고유하도록 배니티 셀렉터를 마이닝합니다(`cast selectors` 또는 커스텀 스크립트 사용).\n\n## 가스 비교\n\n다양한 함수 수에 대한 디스패치 비용을 벤치마킹합시다:\n\n| 함수 수 | Solidity (if-else) | Solidity (이진) | Huff 점프 테이블 |\n|---------|-------------------|-----------------|------------------|\n| 2       | 22-44 가스        | 22-44 가스      | 15 가스          |\n| 4       | 22-88 가스        | 22-66 가스      | 15 가스          |\n| 8       | 22-176 가스       | 22-88 가스      | 15 가스          |\n| 16      | 22-352 가스       | 22-110 가스     | 15 가스          |\n| 32      | 22-704 가스       | 22-132 가스     | 15 가스          |\n\n점프 테이블 비용은 상수입니다: CALLDATALOAD (3) + SHR (3) + 산술 (3-6) + JUMP (8) = 약 15-18 가스. 함수 수에 관계없이 변하지 않습니다.\n\n## 배니티 셀렉터 마이닝\n\n점프 테이블 접근법이 작동하려면 예측 가능한 라우팅 바이트를 가진 함수 셀렉터가 필요합니다. 이를 마이닝할 수 있습니다:\n\n```python\nimport hashlib\nimport itertools\n\ntarget_byte = 0x00  # 셀렉터의 원하는 첫 번째 바이트\nbase_name = \"swap\"\n\nfor suffix in itertools.count():\n    name = f\"{base_name}{suffix}(uint256,address)\"\n    selector = hashlib.sha3_256(name.encode()).digest()[:4]  # keccak256\n    if selector[0] == target_byte:\n        print(f\"Found: {name} -> 0x{selector.hex()}\")\n        break\n```\n\n실무에서는 Foundry의 `cast sig`이나 원하는 접두사를 가진 셀렉터를 찾기 위해 함수 이름을 무차별 대입하는 Rust 도구를 사용합니다. 8개 함수가 있는 컨트랙트의 경우, 8개 호환 셀렉터를 마이닝하는 데 밀리초가 걸립니다.\n\n## 바이트코드 크기 영향\n\n바이트코드 크기는 배포 비용에 직접 영향을 미칩니다 (CREATE를 통해 바이트당 200 가스, 기본 32,000). 비교:\n\n| 접근법 | 런타임 바이트코드 | 배포 가스 (런타임만) |\n|--------|-----------------|---------------------|\n| Solidity (8 함수) | ~800 바이트 | 160,000 가스 |\n| Huff 점프 테이블 (8 함수) | ~200 바이트 | 40,000 가스 |\n| Huff 최소 (2 함수) | ~61 바이트 | 12,200 가스 |\n\n주소 교체나 CREATE2를 통한 매개변수 업데이트를 위해 컨트랙트를 자주 재배포하는 MEV 봇의 경우, 더 작은 바이트코드가 직접적으로 낮은 운영 비용으로 변환됩니다.\n\n## 제한 사항\n\n1. **비표준 ABI** — 외부 도구(Etherscan, 지갑)가 커스텀 ABI 정의 없이는 콜데이터를 디코딩할 수 없습니다.\n2. **셀렉터 마이닝** — 사전 작업이 필요하고 함수 이름을 제약합니다.\n3. **유지보수 비용** — Huff는 Solidity보다 감사하고 수정하기 어렵습니다.\n4. **압축 테이블** — `__tablestart`와 `__tablesize` 내장 함수에 Huff 컴파일러의 엣지 케이스가 있습니다. 철저히 테스트하세요.\n\n## 요약\n\n점프 테이블은 Solidity의 O(N) 디스패치 체인을 O(1) 계산된 점프로 대체합니다. 가스 절약은 수백만 호출에 걸쳐 복합됩니다 — MEV 봇 및 DEX 라우터와 같은 고빈도 컨트랙트에 의미 있는 이점입니다. 배니티 셀렉터 마이닝과 결합하면, 인터페이스 크기에 관계없이 디스패치 오버헤드가 20 가스 미만인 컨트랙트를 구축할 수 있습니다. 다음 기사에서는 고급 Huff 패턴을 탐구합니다: 적응형 실행, 다중 운영자 인증, 메모리 레이아웃 트릭.","\u003Ch2 id=\"solidity\">Solidity 디스패처의 문제점\u003C\u002Fh2>\n\u003Cp>Solidity 컨트랙트를 호출하면 EVM이 가장 먼저 실행하는 것은 함수 디스패처입니다. Solidity는 콜데이터의 처음 4바이트(함수 셀렉터)를 각 알려진 셀렉터와 비교하는 선형 if-else 체인을 생성합니다:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>CALLDATALOAD 0x00\nSHR 224\nDUP1\nPUSH4 0x70a08231    \u002F\u002F balanceOf(address)\nEQ\nPUSH2 dest1\nJUMPI\nDUP1\nPUSH4 0xa9059cbb    \u002F\u002F transfer(address,uint256)\nEQ\nPUSH2 dest2\nJUMPI\n...\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>N개의 함수가 있는 컨트랙트의 경우 이것은 O(N)입니다 — 최악의 경우 일치를 찾기 전에 모든 N개 셀렉터를 확인합니다. 각 비교는 약 22 가스(DUP1 + PUSH4 + EQ + PUSH2 + JUMPI)가 듭니다. 20개 함수가 있는 컨트랙트는 디스패치에만 최대 440 가스를 낭비합니다. Solidity 컴파일러(0.8.22 이후)는 때때로 큰 인터페이스에 대해 이진 검색 트리를 사용하여 O(log N)으로 줄이지만, 이것도 최적은 아닙니다.\u003C\u002Fp>\n\u003Cp>하루에 수백만 번 호출되는 MEV 봇 컨트랙트의 경우, 호출당 400+ 가스 단위가 실제 ETH로 누적됩니다.\u003C\u002Fp>\n\u003Ch2 id=\"o-1\">점프 테이블 접근법: O(1)\u003C\u002Fh2>\n\u003Cp>점프 테이블은 비교가 아닌 산술을 사용하여 함수 셀렉터를 코드 오프셋에 직접 매핑합니다. 이 아이디어는 CPU 아키텍처에서 차용되었습니다 — 계산된 GOTO는 1960년대부터 시스템 프로그래밍에서 사용되어 왔습니다.\u003C\u002Fp>\n\u003Cp>개념:\u003C\u002Fp>\n\u003Col>\n\u003Cli>콜데이터에서 함수 셀렉터를 추출합니다 (4바이트).\u003C\u002Fli>\n\u003Cli>산술을 사용하여 셀렉터에서 점프 대상을 계산합니다.\u003C\u002Fli>\n\u003Cli>해당 대상으로 직접 JUMP합니다.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>비교도 없고, 분기도 없으며, 함수 수에 관계없이 상수 시간입니다.\u003C\u002Fp>\n\u003Ch3>접근법 1: 최소 셀렉터 인코딩\u003C\u002Fh3>\n\u003Cp>컨트랙트에 소수의 함수(1-8개)가 있는 경우, 첫 번째 바이트나 두 번째 바이트가 고유한 작은 정수를 인코딩하는 배니티 셀렉터를 마이닝하여 셀렉터를 수동으로 할당할 수 있습니다:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">#define macro DISPATCHER() = takes(0) returns(0) {\n    0x00 calldataload       \u002F\u002F [calldata_word]\n    0xe0 shr                \u002F\u002F [selector]\n\n    \u002F\u002F 라우팅 바이트 추출 — 셀렉터의 첫 번째 바이트\n    0x18 shr                \u002F\u002F [first_byte]\n\n    \u002F\u002F 테이블의 각 항목은 2바이트 (PUSH2 offset)\n    \u002F\u002F 테이블 시작 + first_byte * 2 = 점프 대상 포인터\n    0x02 mul                \u002F\u002F [offset_in_table]\n    __tablestart(JumpTable) \u002F\u002F [table_start, offset_in_table]\n    add                     \u002F\u002F [entry_address]\n    \n    \u002F\u002F 테이블에서 2바이트 점프 대상 로드\n    codecopy_dest:\n    0x00 codecopy           \u002F\u002F 코드에서 메모리로 2바이트 복사\n    0x00 mload              \u002F\u002F [jump_dest (32바이트로 패딩)]\n    0xf0 shr                \u002F\u002F [jump_dest] — 2바이트 값을 얻기 위해 오른쪽 시프트\n    jump                    \u002F\u002F 함수 본문으로 GOTO\n}\n\n#define jumptable JumpTable {\n    swap_exact   \u002F\u002F selector 0x00...\n    add_liq      \u002F\u002F selector 0x01...\n    remove_liq   \u002F\u002F selector 0x02...\n    flash_loan   \u002F\u002F selector 0x03...\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>접근법 2: 압축된 코드 테이블\u003C\u002Fh3>\n\u003Cp>최대 밀도를 위해 \u003Ccode>__tablestart\u003C\u002Fcode>와 \u003Ccode>__tablesize\u003C\u002Fcode>를 사용하여 점프 테이블을 바이트코드에 직접 패킹할 수 있습니다. Huff는 점프 테이블을 일급 구성 요소로 기본 지원합니다:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">#define jumptable__packed SELECTOR_TABLE {\n    fn_swap\n    fn_transfer\n    fn_approve\n    fn_balance\n}\n\n#define macro MAIN() = takes(0) returns(0) {\n    0x00 calldataload 0xe0 shr  \u002F\u002F [selector]\n\n    \u002F\u002F 셀렉터를 인덱스(0-3)로 매핑\n    \u002F\u002F 셀렉터 값에 따라 다름 — 상위 바이트가 인덱스가 되도록 마이닝\n    0x18 shr                    \u002F\u002F [index]\n\n    \u002F\u002F 경계 확인\n    dup1 0x04 lt                \u002F\u002F [in_bounds?, index]\n    valid jumpi\n    0x00 0x00 revert\n\n    valid:\n    \u002F\u002F 압축 테이블에서 로드 (항목당 2바이트)\n    __tablestart(SELECTOR_TABLE)\n    swap1 0x02 mul add          \u002F\u002F [table_entry_ptr]\n\n    \u002F\u002F 2바이트 코드 오프셋 읽기\n    0x1e mload                  \u002F\u002F 트릭: codecopy를 통해 코드에서 mload\n    jump\n\n    fn_swap:\n        SWAP_IMPL()\n    fn_transfer:\n        TRANSFER_IMPL()\n    fn_approve:\n        APPROVE_IMPL()\n    fn_balance:\n        BALANCE_IMPL()\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"\">셀렉터 추출을 위한 콜데이터 비트 시프팅\u003C\u002Fh2>\n\u003Cp>표준 셀렉터 추출은:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">0x00 calldataload   \u002F\u002F 콜데이터 위치 0에서 32바이트 로드\n0xe0 shr            \u002F\u002F 상위 4바이트를 분리하기 위해 224비트(256 - 32) 오른쪽 시프트\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>비용: PUSH1 (3) + CALLDATALOAD (3) + PUSH1 (3) + SHR (3) = 12 가스.\u003C\u002Fp>\n\u003Cp>셀렉터의 1-2바이트만 필요한 경우 더 저렴한 대안:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">0x00 calldataload   \u002F\u002F [calldata_word]\n0xf8 shr            \u002F\u002F [first_byte] — 바이트 0만 얻기 위해 248비트 오른쪽 시프트\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>같은 가스이지만, 이제 라우팅 키가 1바이트(256개 가능한 값)입니다. 컨트랙트에 256개 이하의 함수가 있다면, 1바이트로 각각을 고유하게 식별할 수 있습니다. 각 함수의 첫 번째 셀렉터 바이트가 고유하도록 배니티 셀렉터를 마이닝합니다(\u003Ccode>cast selectors\u003C\u002Fcode> 또는 커스텀 스크립트 사용).\u003C\u002Fp>\n\u003Ch2 id=\"\">가스 비교\u003C\u002Fh2>\n\u003Cp>다양한 함수 수에 대한 디스패치 비용을 벤치마킹합시다:\u003C\u002Fp>\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>함수 수\u003C\u002Fth>\u003Cth>Solidity (if-else)\u003C\u002Fth>\u003Cth>Solidity (이진)\u003C\u002Fth>\u003Cth>Huff 점프 테이블\u003C\u002Fth>\u003C\u002Ftr>\u003C\u002Fthead>\u003Ctbody>\n\u003Ctr>\u003Ctd>2\u003C\u002Ftd>\u003Ctd>22-44 가스\u003C\u002Ftd>\u003Ctd>22-44 가스\u003C\u002Ftd>\u003Ctd>15 가스\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>4\u003C\u002Ftd>\u003Ctd>22-88 가스\u003C\u002Ftd>\u003Ctd>22-66 가스\u003C\u002Ftd>\u003Ctd>15 가스\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>8\u003C\u002Ftd>\u003Ctd>22-176 가스\u003C\u002Ftd>\u003Ctd>22-88 가스\u003C\u002Ftd>\u003Ctd>15 가스\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>16\u003C\u002Ftd>\u003Ctd>22-352 가스\u003C\u002Ftd>\u003Ctd>22-110 가스\u003C\u002Ftd>\u003Ctd>15 가스\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>32\u003C\u002Ftd>\u003Ctd>22-704 가스\u003C\u002Ftd>\u003Ctd>22-132 가스\u003C\u002Ftd>\u003Ctd>15 가스\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\n\u003Cp>점프 테이블 비용은 상수입니다: CALLDATALOAD (3) + SHR (3) + 산술 (3-6) + JUMP (8) = 약 15-18 가스. 함수 수에 관계없이 변하지 않습니다.\u003C\u002Fp>\n\u003Ch2 id=\"\">배니티 셀렉터 마이닝\u003C\u002Fh2>\n\u003Cp>점프 테이블 접근법이 작동하려면 예측 가능한 라우팅 바이트를 가진 함수 셀렉터가 필요합니다. 이를 마이닝할 수 있습니다:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-python\">import hashlib\nimport itertools\n\ntarget_byte = 0x00  # 셀렉터의 원하는 첫 번째 바이트\nbase_name = \"swap\"\n\nfor suffix in itertools.count():\n    name = f\"{base_name}{suffix}(uint256,address)\"\n    selector = hashlib.sha3_256(name.encode()).digest()[:4]  # keccak256\n    if selector[0] == target_byte:\n        print(f\"Found: {name} -&gt; 0x{selector.hex()}\")\n        break\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>실무에서는 Foundry의 \u003Ccode>cast sig\u003C\u002Fcode>이나 원하는 접두사를 가진 셀렉터를 찾기 위해 함수 이름을 무차별 대입하는 Rust 도구를 사용합니다. 8개 함수가 있는 컨트랙트의 경우, 8개 호환 셀렉터를 마이닝하는 데 밀리초가 걸립니다.\u003C\u002Fp>\n\u003Ch2 id=\"\">바이트코드 크기 영향\u003C\u002Fh2>\n\u003Cp>바이트코드 크기는 배포 비용에 직접 영향을 미칩니다 (CREATE를 통해 바이트당 200 가스, 기본 32,000). 비교:\u003C\u002Fp>\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>접근법\u003C\u002Fth>\u003Cth>런타임 바이트코드\u003C\u002Fth>\u003Cth>배포 가스 (런타임만)\u003C\u002Fth>\u003C\u002Ftr>\u003C\u002Fthead>\u003Ctbody>\n\u003Ctr>\u003Ctd>Solidity (8 함수)\u003C\u002Ftd>\u003Ctd>~800 바이트\u003C\u002Ftd>\u003Ctd>160,000 가스\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Huff 점프 테이블 (8 함수)\u003C\u002Ftd>\u003Ctd>~200 바이트\u003C\u002Ftd>\u003Ctd>40,000 가스\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Huff 최소 (2 함수)\u003C\u002Ftd>\u003Ctd>~61 바이트\u003C\u002Ftd>\u003Ctd>12,200 가스\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\n\u003Cp>주소 교체나 CREATE2를 통한 매개변수 업데이트를 위해 컨트랙트를 자주 재배포하는 MEV 봇의 경우, 더 작은 바이트코드가 직접적으로 낮은 운영 비용으로 변환됩니다.\u003C\u002Fp>\n\u003Ch2 id=\"\">제한 사항\u003C\u002Fh2>\n\u003Col>\n\u003Cli>\u003Cstrong>비표준 ABI\u003C\u002Fstrong> — 외부 도구(Etherscan, 지갑)가 커스텀 ABI 정의 없이는 콜데이터를 디코딩할 수 없습니다.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>셀렉터 마이닝\u003C\u002Fstrong> — 사전 작업이 필요하고 함수 이름을 제약합니다.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>유지보수 비용\u003C\u002Fstrong> — Huff는 Solidity보다 감사하고 수정하기 어렵습니다.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>압축 테이블\u003C\u002Fstrong> — \u003Ccode>__tablestart\u003C\u002Fcode>와 \u003Ccode>__tablesize\u003C\u002Fcode> 내장 함수에 Huff 컴파일러의 엣지 케이스가 있습니다. 철저히 테스트하세요.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2 id=\"\">요약\u003C\u002Fh2>\n\u003Cp>점프 테이블은 Solidity의 O(N) 디스패치 체인을 O(1) 계산된 점프로 대체합니다. 가스 절약은 수백만 호출에 걸쳐 복합됩니다 — MEV 봇 및 DEX 라우터와 같은 고빈도 컨트랙트에 의미 있는 이점입니다. 배니티 셀렉터 마이닝과 결합하면, 인터페이스 크기에 관계없이 디스패치 오버헤드가 20 가스 미만인 컨트랙트를 구축할 수 있습니다. 다음 기사에서는 고급 Huff 패턴을 탐구합니다: 적응형 실행, 다중 운영자 인증, 메모리 레이아웃 트릭.\u003C\u002Fp>\n","ko","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:28.026997Z","Deep EVM #11: Huff 점프 테이블 — O(1) 함수 디스패치","Huff에서 압축된 점프 테이블을 사용한 O(1) 함수 디스패처 구축. Solidity 디스패치와의 가스 비용 비교 및 배니티 셀렉터 마이닝.","huff 점프 테이블 함수 디스패치",null,"index, follow",[22,27,31,35],{"id":23,"name":24,"slug":25,"created_at":26},"c0000000-0000-0000-0000-000000000016","EVM","evm","2026-03-28T10:44:21.513630Z",{"id":28,"name":29,"slug":30,"created_at":26},"c0000000-0000-0000-0000-000000000020","Gas Optimization","gas-optimization",{"id":32,"name":33,"slug":34,"created_at":26},"c0000000-0000-0000-0000-000000000017","Huff","huff",{"id":36,"name":37,"slug":38,"created_at":26},"c0000000-0000-0000-0000-000000000018","Yul","yul","블록체인",[41,47,53],{"id":42,"title":43,"slug":44,"excerpt":45,"locale":12,"category_name":39,"published_at":46},"d0000000-0000-0000-0000-000000000605","Ethereum 상호운용성 레이어: 55개 이상의 L2가 하나의 체인이 되는 방법","ethereum-sangho-unyongseong-layer-55-l2-hana-chain","Ethereum에는 55개 이상의 Layer 2 롤업이 있어 유동성과 사용자 경험이 파편화되어 있습니다. Ethereum 상호운용성 레이어 — 크로스 롤업 메시징, 공유 시퀀서, 베이스드 롤업을 결합하여 — 하나의 조합 가능한 네트워크로 통합하는 것을 목표로 합니다.","2026-03-28T10:44:44.895917Z",{"id":48,"title":49,"slug":50,"excerpt":51,"locale":12,"category_name":39,"published_at":52},"d0000000-0000-0000-0000-000000000604","롤업을 넘어선 ZK 증명: Ethereum에서의 검증 가능한 AI 추론","rolleob-eul-neomeo-zk-jeungmyeong-ethereum-geomjeung-ai-churon","영지식 증명은 더 이상 단순한 스케일링 도구가 아닙니다. 2026년, zkML은 온체인에서 검증 가능한 AI 추론을 가능하게 하고, ZK 코프로세서는 무거운 연산을 오프체인으로 이동시키며 온체인에서 검증하고, SP1과 Jolt 같은 새로운 증명 시스템이 이를 실용적으로 만들고 있습니다.","2026-03-28T10:44:44.890168Z",{"id":54,"title":55,"slug":56,"excerpt":57,"locale":12,"category_name":39,"published_at":58},"d0000000-0000-0000-0000-000000000581","EIP-7702 실전 가이드: Pectra 이후 스마트 계정 플로우 구축","eip-7702-siljeon-gaideu-pectra-ihu-seumateu-gyejeong-peulro-guchuk","EIP-7702는 모든 Ethereum EOA가 단일 트랜잭션 내에서 스마트 컨트랙트로 임시 동작할 수 있게 합니다. 새로운 계정 추상화 프리미티브를 사용한 배치 트랜잭션, 가스 후원, 소셜 리커버리 구현 방법을 소개합니다.","2026-03-28T10:44:43.377765Z",{"id":13,"name":60,"slug":61,"bio":62,"photo_url":19,"linkedin":19,"role":63,"created_at":64,"updated_at":64},"Open Soft Team","open-soft-team","The engineering team at Open Soft, building premium software solutions from Bali, Indonesia.","Engineering Team","2026-03-28T08:31:22.226811Z"]