[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-deep-evm-9-huff-eoneo-ibmun-maekeuleo-leibeul-wonsi-opkodeu":3},{"article":4,"author":54},{"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":7,"meta_description":16,"focus_keyword":17,"og_image":18,"canonical_url":18,"robots_meta":19,"created_at":15,"updated_at":15,"tags":20,"category_name":34,"related_articles":35},"d5000000-0000-0000-0000-000000000109","a0000000-0000-0000-0000-000000000052","Deep EVM #9: Huff 언어 입문 — 매크로, 레이블, 원시 옵코드","deep-evm-9-huff-eoneo-ibmun-maekeuleo-leibeul-wonsi-opkodeu","Huff에 대한 실습 입문서: 모든 옵코드, 모든 바이트코드 바이트, 모든 가스 단위를 직접 제어할 수 있는 저수준 EVM 어셈블리 언어.","## Huff가 존재하는 이유\n\nSolidity는 훌륭한 추상화입니다 — 그렇지 않을 때까지. 100바이트의 런타임 바이트코드 안에 들어가는 컨트랙트가 필요하거나, 압축된 점프 테이블로 O(1) 함수 디스패치가 필요하거나, 하루에 수백만 번 실행되는 핫 패스에서 200 가스를 절약해야 할 때, 메탈에 더 가까운 무언가가 필요합니다. 그것이 바로 **Huff**입니다.\n\nHuff는 얇은 매크로 시스템이 덧붙여진 저수준 EVM 어셈블리 언어입니다. 변수도, 타입도, 뒤에서 최적화하는 컴파일러도 없습니다. 당신이 쓰는 것이 그대로 온체인에 올라갑니다 — 옵코드 대 옵코드.\n\n## Huff 설치\n\n표준 컴파일러는 Rust로 작성된 `huffc`입니다:\n\n```bash\ncurl -L get.huff.sh | bash\nhuffup\nhuffc --version\n```\n\n이것은 `huffc`를 `~\u002F.huff\u002Fbin`에 설치합니다. PATH에 추가하고 확인하세요:\n\n```bash\n$ huffc --version\nhuffc 0.3.2\n```\n\nFoundry 프로젝트에서 `foundry-huff`를 사용하면 `.huff` 파일을 `.sol` 파일과 동일한 방식으로 배포할 수 있습니다.\n\n## Hello World: 최소 컨트랙트\n\n모든 호출에 32바이트 워드 `0x01`을 반환하는 컨트랙트를 작성해 봅시다:\n\n```huff\n#define macro MAIN() = takes(0) returns(0) {\n    0x01            \u002F\u002F [0x01]\n    0x00            \u002F\u002F [0x00, 0x01]\n    mstore          \u002F\u002F []          — memory[0x00..0x20] = 0x01\n    0x20            \u002F\u002F [0x20]\n    0x00            \u002F\u002F [0x00, 0x20]\n    return          \u002F\u002F halt — return memory[0x00..0x20]\n}\n```\n\n컴파일:\n\n```bash\nhuffc src\u002FHelloWorld.huff -r\n```\n\n`-r` 플래그는 런타임 바이트코드를 출력합니다. `600160005260206000f3`과 같은 것을 볼 수 있습니다 — 10바이트. `1`을 반환하는 Solidity 컨트랙트는 약 200바이트 이상의 런타임 바이트코드로 컴파일됩니다. solc가 전체 함수 디스패처, 메타데이터 해시, 프리 메모리 포인터 설정, ABI 인코더를 생성하기 때문입니다.\n\n## 매크로 vs 함수\n\nHuff에는 두 가지 코드 재사용 기본 요소가 있습니다: **매크로**와 **함수**.\n\n### 매크로 (`#define macro`)\n\n매크로는 모든 호출 사이트에서 인라인됩니다. JUMP 오버헤드도, 추가 가스도 없습니다 — 컴파일러가 문자 그대로 옵코드를 호출자에 복사-붙여넣기합니다. 가스 크리티컬 코드에서는 기본이자 선호되는 선택입니다.\n\n```huff\n#define macro REQUIRE_NOT_ZERO() = takes(1) returns(0) {\n    \u002F\u002F takes: [value]\n    continue        \u002F\u002F [continue_dest, value]\n    jumpi           \u002F\u002F []  — value != 0이면 점프\n    0x00 0x00 revert\n    continue:\n}\n```\n\n### 함수 (`#define fn`)\n\n함수는 실제 JUMP\u002FJUMPDEST 쌍을 생성합니다. 호출당 약 22 가스의 추가 비용(JUMP 8 + JUMPDEST 1 + 스택 조작)으로 바이트코드 크기를 절약합니다. 바이트코드 크기가 가스보다 중요할 때만 사용하세요.\n\n```huff\n#define fn safe_add() = takes(2) returns(1) {\n    \u002F\u002F takes: [a, b]\n    dup2 dup2       \u002F\u002F [a, b, a, b]\n    add             \u002F\u002F [sum, a, b]\n    dup1            \u002F\u002F [sum, sum, a, b]\n    swap2           \u002F\u002F [a, sum, sum, b]\n    gt              \u002F\u002F [overflow?, sum, b]\n    overflow jumpi\n    swap1 pop       \u002F\u002F [sum]\n    back jump\n    overflow:\n        0x00 0x00 revert\n    back:\n}\n```\n\n## 레이블과 점프 대상\n\nHuff에서 레이블은 명명된 JUMPDEST 위치입니다. 컴파일러는 컴파일 시간에 이를 구체적인 바이트코드 오프셋으로 해결합니다.\n\n```huff\n#define macro LOOP_EXAMPLE() = takes(1) returns(1) {\n    \u002F\u002F takes: [n]\n    0x00                \u002F\u002F [acc, n]\n    loop:\n        dup2            \u002F\u002F [n, acc, n]\n        iszero          \u002F\u002F [n==0?, acc, n]\n        done jumpi      \u002F\u002F [acc, n]\n        swap1           \u002F\u002F [n, acc]\n        0x01 swap1 sub  \u002F\u002F [n-1, acc]\n        swap1           \u002F\u002F [acc, n-1]\n        0x01 add        \u002F\u002F [acc+1, n-1]\n        loop jump\n    done:\n        swap1 pop       \u002F\u002F [acc]\n}\n```\n\n각 레이블은 단일 `JUMPDEST` 바이트(`0x5b`)로 컴파일됩니다. 참조(`loop jump`, `done jumpi`)는 `PUSH2 \u003Coffset> JUMP`(또는 `JUMPI`)로 컴파일됩니다. 이것은 원시 EVM 어셈블리에서 직접 작성하는 것과 정확히 같습니다 — Huff가 오프셋 관리만 처리합니다.\n\n## takes()와 returns()\n\n매크로와 함수의 `takes(n)` 및 `returns(m)` 어노테이션은 문서화 및 컴파일러 힌트입니다. 독자 — 그리고 Huff 컴파일러의 스택 검사기 — 에게 블록이 소비하고 생성할 스택 항목 수를 알려줍니다.\n\n```huff\n#define macro ADD_TWO() = takes(2) returns(1) {\n    add  \u002F\u002F 2개 항목 소비, 1개 생성\n}\n```\n\n실제 스택 동작이 어노테이션과 일치하지 않으면 `huffc`가 경고를 발생시킵니다. 이 어노테이션을 간이 타입 시스템으로 취급하세요 — 실수로 스택에 쓰레기를 남기거나 언더플로가 발생하는 것을 방지합니다.\n\n## 비교: Huff vs Solidity 바이트코드\n\n스토리지 슬롯을 반환하는 간단한 `getValue()` view 함수를 생각해 봅시다:\n\n**Solidity:**\n```solidity\nfunction getValue() external view returns (uint256) {\n    return value;\n}\n```\n\nSolc는 디스패처 + ABI 인코딩에 약 40바이트를 생성합니다:\n```\nCALLDATASIZE → CALLDATALOAD → SHR 224 → DUP1 → PUSH4 selector\n→ EQ → PUSH2 dest → JUMPI → ... → SLOAD → PUSH1 0x20\n→ MSTORE → PUSH1 0x20 → PUSH1 0x00 → RETURN\n```\n\n**Huff 등가물:**\n```huff\n#define function getValue() view returns (uint256)\n\n#define macro GET_VALUE() = takes(0) returns(0) {\n    [VALUE_SLOT]    \u002F\u002F [slot]\n    sload           \u002F\u002F [value]\n    0x00 mstore     \u002F\u002F []  — 메모리에 저장\n    0x20 0x00 return\n}\n```\n\nHuff 버전은 본문에 12바이트의 바이트코드입니다. ABI 인코딩 오버헤드도, 프리 메모리 포인터도, 메타데이터 해시도 없습니다. 호출자를 제어할 때(예: 자체 컨트랙트를 호출하는 MEV 봇), Solidity 컴파일러가 필요하다고 가정하는 모든 것을 제거할 수 있습니다.\n\n## 상수와 스토리지 슬롯\n\nHuff 상수는 PUSH 명령으로 인라인되는 컴파일 타임 값입니다:\n\n```huff\n#define constant VALUE_SLOT = 0x00\n#define constant OWNER_SLOT = 0x01\n#define constant MAX_UINT = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n```\n\n사용법: `[VALUE_SLOT]`은 `0x00`을 푸시하고, `[MAX_UINT]`는 전체 32바이트 값을 푸시합니다. 상수는 가스 비용 없이 가독성을 높여줍니다 — 순전히 구문적입니다.\n\n## 인클루드와 프로젝트 구조\n\n실제 Huff 프로젝트는 여러 파일에 코드를 분산합니다:\n\n```huff\n\u002F\u002F src\u002FMain.huff\n#include \".\u002Futils\u002FSafeMath.huff\"\n#include \".\u002Finterfaces\u002FIERC20.huff\"\n#include \".\u002FDispatcher.huff\"\n\n#define macro MAIN() = takes(0) returns(0) {\n    DISPATCHER()\n}\n```\n\n인클루드 시스템은 단순한 텍스트 포함입니다 — 모듈 범위나 네임스페이스는 없습니다. 충돌을 피하기 위해 매크로 이름을 신중하게 지정하세요.\n\n## Huff를 언제 사용해야 하는가\n\nHuff는 범용 언어가 아닙니다. 다음 경우에 사용하세요:\n\n1. **가스가 주요 제약 조건일 때** — 100 가스가 수익성을 결정하는 MEV 컨트랙트.\n2. **바이트코드 크기가 중요할 때** — 다른 컨트랙트에 의해 배포되는 컨트랙트(CREATE2 팩토리)에서 더 작은 initcode = 더 적은 배포 가스.\n3. **커스텀 디스패치가 필요할 때** — 점프 테이블, 비트 패킹된 셀렉터, 또는 비표준 ABI 인코딩.\n4. **EVM을 배우고 있을 때** — 원시 옵코드를 작성하는 것보다 EVM을 더 잘 가르치는 것은 없습니다.\n\n그 외의 모든 것에 대해서는 Solidity를 작성하고 `solc --asm`으로 컴파일러 출력을 읽으세요. 더 생산적이고 오류가 적을 것입니다.\n\n## 요약\n\nHuff는 정신을 유지하기 위한 최소한의 추상화와 함께 EVM 바이트코드에 직접 연결을 제공합니다. 매크로는 제로 오버헤드 재사용을 위해 코드를 인라인합니다. 레이블은 점프 오프셋 관리를 처리합니다. `takes`\u002F`returns` 어노테이션은 스택 오류를 조기에 포착합니다. 다음 기사에서는 스택 관리 — `dup`, `swap`의 기술과 스택의 멘탈 모델을 현실과 동기화하는 방법 — 를 심층적으로 다룹니다.","\u003Ch2 id=\"huff\">Huff가 존재하는 이유\u003C\u002Fh2>\n\u003Cp>Solidity는 훌륭한 추상화입니다 — 그렇지 않을 때까지. 100바이트의 런타임 바이트코드 안에 들어가는 컨트랙트가 필요하거나, 압축된 점프 테이블로 O(1) 함수 디스패치가 필요하거나, 하루에 수백만 번 실행되는 핫 패스에서 200 가스를 절약해야 할 때, 메탈에 더 가까운 무언가가 필요합니다. 그것이 바로 \u003Cstrong>Huff\u003C\u002Fstrong>입니다.\u003C\u002Fp>\n\u003Cp>Huff는 얇은 매크로 시스템이 덧붙여진 저수준 EVM 어셈블리 언어입니다. 변수도, 타입도, 뒤에서 최적화하는 컴파일러도 없습니다. 당신이 쓰는 것이 그대로 온체인에 올라갑니다 — 옵코드 대 옵코드.\u003C\u002Fp>\n\u003Ch2 id=\"huff\">Huff 설치\u003C\u002Fh2>\n\u003Cp>표준 컴파일러는 Rust로 작성된 \u003Ccode>huffc\u003C\u002Fcode>입니다:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">curl -L get.huff.sh | bash\nhuffup\nhuffc --version\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>이것은 \u003Ccode>huffc\u003C\u002Fcode>를 \u003Ccode>~\u002F.huff\u002Fbin\u003C\u002Fcode>에 설치합니다. PATH에 추가하고 확인하세요:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">$ huffc --version\nhuffc 0.3.2\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Foundry 프로젝트에서 \u003Ccode>foundry-huff\u003C\u002Fcode>를 사용하면 \u003Ccode>.huff\u003C\u002Fcode> 파일을 \u003Ccode>.sol\u003C\u002Fcode> 파일과 동일한 방식으로 배포할 수 있습니다.\u003C\u002Fp>\n\u003Ch2 id=\"hello-world\">Hello World: 최소 컨트랙트\u003C\u002Fh2>\n\u003Cp>모든 호출에 32바이트 워드 \u003Ccode>0x01\u003C\u002Fcode>을 반환하는 컨트랙트를 작성해 봅시다:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">#define macro MAIN() = takes(0) returns(0) {\n    0x01            \u002F\u002F [0x01]\n    0x00            \u002F\u002F [0x00, 0x01]\n    mstore          \u002F\u002F []          — memory[0x00..0x20] = 0x01\n    0x20            \u002F\u002F [0x20]\n    0x00            \u002F\u002F [0x00, 0x20]\n    return          \u002F\u002F halt — return memory[0x00..0x20]\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>컴파일:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">huffc src\u002FHelloWorld.huff -r\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>\u003Ccode>-r\u003C\u002Fcode> 플래그는 런타임 바이트코드를 출력합니다. \u003Ccode>600160005260206000f3\u003C\u002Fcode>과 같은 것을 볼 수 있습니다 — 10바이트. \u003Ccode>1\u003C\u002Fcode>을 반환하는 Solidity 컨트랙트는 약 200바이트 이상의 런타임 바이트코드로 컴파일됩니다. solc가 전체 함수 디스패처, 메타데이터 해시, 프리 메모리 포인터 설정, ABI 인코더를 생성하기 때문입니다.\u003C\u002Fp>\n\u003Ch2 id=\"vs\">매크로 vs 함수\u003C\u002Fh2>\n\u003Cp>Huff에는 두 가지 코드 재사용 기본 요소가 있습니다: \u003Cstrong>매크로\u003C\u002Fstrong>와 \u003Cstrong>함수\u003C\u002Fstrong>.\u003C\u002Fp>\n\u003Ch3>매크로 (\u003Ccode>#define macro\u003C\u002Fcode>)\u003C\u002Fh3>\n\u003Cp>매크로는 모든 호출 사이트에서 인라인됩니다. JUMP 오버헤드도, 추가 가스도 없습니다 — 컴파일러가 문자 그대로 옵코드를 호출자에 복사-붙여넣기합니다. 가스 크리티컬 코드에서는 기본이자 선호되는 선택입니다.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">#define macro REQUIRE_NOT_ZERO() = takes(1) returns(0) {\n    \u002F\u002F takes: [value]\n    continue        \u002F\u002F [continue_dest, value]\n    jumpi           \u002F\u002F []  — value != 0이면 점프\n    0x00 0x00 revert\n    continue:\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>함수 (\u003Ccode>#define fn\u003C\u002Fcode>)\u003C\u002Fh3>\n\u003Cp>함수는 실제 JUMP\u002FJUMPDEST 쌍을 생성합니다. 호출당 약 22 가스의 추가 비용(JUMP 8 + JUMPDEST 1 + 스택 조작)으로 바이트코드 크기를 절약합니다. 바이트코드 크기가 가스보다 중요할 때만 사용하세요.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">#define fn safe_add() = takes(2) returns(1) {\n    \u002F\u002F takes: [a, b]\n    dup2 dup2       \u002F\u002F [a, b, a, b]\n    add             \u002F\u002F [sum, a, b]\n    dup1            \u002F\u002F [sum, sum, a, b]\n    swap2           \u002F\u002F [a, sum, sum, b]\n    gt              \u002F\u002F [overflow?, sum, b]\n    overflow jumpi\n    swap1 pop       \u002F\u002F [sum]\n    back jump\n    overflow:\n        0x00 0x00 revert\n    back:\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"\">레이블과 점프 대상\u003C\u002Fh2>\n\u003Cp>Huff에서 레이블은 명명된 JUMPDEST 위치입니다. 컴파일러는 컴파일 시간에 이를 구체적인 바이트코드 오프셋으로 해결합니다.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">#define macro LOOP_EXAMPLE() = takes(1) returns(1) {\n    \u002F\u002F takes: [n]\n    0x00                \u002F\u002F [acc, n]\n    loop:\n        dup2            \u002F\u002F [n, acc, n]\n        iszero          \u002F\u002F [n==0?, acc, n]\n        done jumpi      \u002F\u002F [acc, n]\n        swap1           \u002F\u002F [n, acc]\n        0x01 swap1 sub  \u002F\u002F [n-1, acc]\n        swap1           \u002F\u002F [acc, n-1]\n        0x01 add        \u002F\u002F [acc+1, n-1]\n        loop jump\n    done:\n        swap1 pop       \u002F\u002F [acc]\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>각 레이블은 단일 \u003Ccode>JUMPDEST\u003C\u002Fcode> 바이트(\u003Ccode>0x5b\u003C\u002Fcode>)로 컴파일됩니다. 참조(\u003Ccode>loop jump\u003C\u002Fcode>, \u003Ccode>done jumpi\u003C\u002Fcode>)는 \u003Ccode>PUSH2 &lt;offset&gt; JUMP\u003C\u002Fcode>(또는 \u003Ccode>JUMPI\u003C\u002Fcode>)로 컴파일됩니다. 이것은 원시 EVM 어셈블리에서 직접 작성하는 것과 정확히 같습니다 — Huff가 오프셋 관리만 처리합니다.\u003C\u002Fp>\n\u003Ch2 id=\"takes-returns\">takes()와 returns()\u003C\u002Fh2>\n\u003Cp>매크로와 함수의 \u003Ccode>takes(n)\u003C\u002Fcode> 및 \u003Ccode>returns(m)\u003C\u002Fcode> 어노테이션은 문서화 및 컴파일러 힌트입니다. 독자 — 그리고 Huff 컴파일러의 스택 검사기 — 에게 블록이 소비하고 생성할 스택 항목 수를 알려줍니다.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">#define macro ADD_TWO() = takes(2) returns(1) {\n    add  \u002F\u002F 2개 항목 소비, 1개 생성\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>실제 스택 동작이 어노테이션과 일치하지 않으면 \u003Ccode>huffc\u003C\u002Fcode>가 경고를 발생시킵니다. 이 어노테이션을 간이 타입 시스템으로 취급하세요 — 실수로 스택에 쓰레기를 남기거나 언더플로가 발생하는 것을 방지합니다.\u003C\u002Fp>\n\u003Ch2 id=\"huff-vs-solidity\">비교: Huff vs Solidity 바이트코드\u003C\u002Fh2>\n\u003Cp>스토리지 슬롯을 반환하는 간단한 \u003Ccode>getValue()\u003C\u002Fcode> view 함수를 생각해 봅시다:\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Solidity:\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-solidity\">function getValue() external view returns (uint256) {\n    return value;\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Solc는 디스패처 + ABI 인코딩에 약 40바이트를 생성합니다:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>CALLDATASIZE → CALLDATALOAD → SHR 224 → DUP1 → PUSH4 selector\n→ EQ → PUSH2 dest → JUMPI → ... → SLOAD → PUSH1 0x20\n→ MSTORE → PUSH1 0x20 → PUSH1 0x00 → RETURN\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>\u003Cstrong>Huff 등가물:\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">#define function getValue() view returns (uint256)\n\n#define macro GET_VALUE() = takes(0) returns(0) {\n    [VALUE_SLOT]    \u002F\u002F [slot]\n    sload           \u002F\u002F [value]\n    0x00 mstore     \u002F\u002F []  — 메모리에 저장\n    0x20 0x00 return\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Huff 버전은 본문에 12바이트의 바이트코드입니다. ABI 인코딩 오버헤드도, 프리 메모리 포인터도, 메타데이터 해시도 없습니다. 호출자를 제어할 때(예: 자체 컨트랙트를 호출하는 MEV 봇), Solidity 컴파일러가 필요하다고 가정하는 모든 것을 제거할 수 있습니다.\u003C\u002Fp>\n\u003Ch2 id=\"\">상수와 스토리지 슬롯\u003C\u002Fh2>\n\u003Cp>Huff 상수는 PUSH 명령으로 인라인되는 컴파일 타임 값입니다:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">#define constant VALUE_SLOT = 0x00\n#define constant OWNER_SLOT = 0x01\n#define constant MAX_UINT = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>사용법: \u003Ccode>[VALUE_SLOT]\u003C\u002Fcode>은 \u003Ccode>0x00\u003C\u002Fcode>을 푸시하고, \u003Ccode>[MAX_UINT]\u003C\u002Fcode>는 전체 32바이트 값을 푸시합니다. 상수는 가스 비용 없이 가독성을 높여줍니다 — 순전히 구문적입니다.\u003C\u002Fp>\n\u003Ch2 id=\"\">인클루드와 프로젝트 구조\u003C\u002Fh2>\n\u003Cp>실제 Huff 프로젝트는 여러 파일에 코드를 분산합니다:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">\u002F\u002F src\u002FMain.huff\n#include \".\u002Futils\u002FSafeMath.huff\"\n#include \".\u002Finterfaces\u002FIERC20.huff\"\n#include \".\u002FDispatcher.huff\"\n\n#define macro MAIN() = takes(0) returns(0) {\n    DISPATCHER()\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>인클루드 시스템은 단순한 텍스트 포함입니다 — 모듈 범위나 네임스페이스는 없습니다. 충돌을 피하기 위해 매크로 이름을 신중하게 지정하세요.\u003C\u002Fp>\n\u003Ch2 id=\"huff\">Huff를 언제 사용해야 하는가\u003C\u002Fh2>\n\u003Cp>Huff는 범용 언어가 아닙니다. 다음 경우에 사용하세요:\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Cstrong>가스가 주요 제약 조건일 때\u003C\u002Fstrong> — 100 가스가 수익성을 결정하는 MEV 컨트랙트.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>바이트코드 크기가 중요할 때\u003C\u002Fstrong> — 다른 컨트랙트에 의해 배포되는 컨트랙트(CREATE2 팩토리)에서 더 작은 initcode = 더 적은 배포 가스.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>커스텀 디스패치가 필요할 때\u003C\u002Fstrong> — 점프 테이블, 비트 패킹된 셀렉터, 또는 비표준 ABI 인코딩.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>EVM을 배우고 있을 때\u003C\u002Fstrong> — 원시 옵코드를 작성하는 것보다 EVM을 더 잘 가르치는 것은 없습니다.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>그 외의 모든 것에 대해서는 Solidity를 작성하고 \u003Ccode>solc --asm\u003C\u002Fcode>으로 컴파일러 출력을 읽으세요. 더 생산적이고 오류가 적을 것입니다.\u003C\u002Fp>\n\u003Ch2 id=\"\">요약\u003C\u002Fh2>\n\u003Cp>Huff는 정신을 유지하기 위한 최소한의 추상화와 함께 EVM 바이트코드에 직접 연결을 제공합니다. 매크로는 제로 오버헤드 재사용을 위해 코드를 인라인합니다. 레이블은 점프 오프셋 관리를 처리합니다. \u003Ccode>takes\u003C\u002Fcode>\u002F\u003Ccode>returns\u003C\u002Fcode> 어노테이션은 스택 오류를 조기에 포착합니다. 다음 기사에서는 스택 관리 — \u003Ccode>dup\u003C\u002Fcode>, \u003Ccode>swap\u003C\u002Fcode>의 기술과 스택의 멘탈 모델을 현실과 동기화하는 방법 — 를 심층적으로 다룹니다.\u003C\u002Fp>\n","ko","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:27.997660Z","Huff 저수준 EVM 어셈블리 언어 입문. 매크로, 레이블, takes\u002Freturns, Huff 바이트코드와 Solidity 출력 비교.","huff 언어 evm",null,"index, follow",[21,26,30],{"id":22,"name":23,"slug":24,"created_at":25},"c0000000-0000-0000-0000-000000000016","EVM","evm","2026-03-28T10:44:21.513630Z",{"id":27,"name":28,"slug":29,"created_at":25},"c0000000-0000-0000-0000-000000000020","Gas Optimization","gas-optimization",{"id":31,"name":32,"slug":33,"created_at":25},"c0000000-0000-0000-0000-000000000017","Huff","huff","블록체인",[36,42,48],{"id":37,"title":38,"slug":39,"excerpt":40,"locale":12,"category_name":34,"published_at":41},"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":43,"title":44,"slug":45,"excerpt":46,"locale":12,"category_name":34,"published_at":47},"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":49,"title":50,"slug":51,"excerpt":52,"locale":12,"category_name":34,"published_at":53},"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":55,"slug":56,"bio":57,"photo_url":18,"linkedin":18,"role":58,"created_at":59,"updated_at":59},"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"]