---
title: "Yul이란 무엇인가?"
description: "Yul로 스마트 컨트랙트를 작성하는 방법과 Solidity와의 차이점 알아보기"
---

# Yul이란 무엇인가?

Yul은 [프로그래밍 언어](https://www.alchemy.com/overviews/web3-programming-languages)의 일종으로, [스마트 컨트랙트](https://www.alchemy.com/overviews/solidity-smart-contract) 내부에서 일종의 어셈블리 언어를 작성하는 데 사용할 수 있습니다. Yul은 스마트 컨트랙트 내부에서 사용되는 경우가 많지만, 스마트 컨트랙트 전체를 Yul로 작성하는 것도 가능합니다.

Yul을 이해하면 스마트 컨트랙트를 한 단계 발전시킬 수 있고, [solidity](https://www.alchemy.com/overviews/solidity) 내부에서 실제로 어떤 일이 일어나는지 파악할 수 있으며, 이는 결과적으로 사용자의 가스 비용을 절감하는 데 도움이 됩니다.

다음과 같은 문법을 통해 스마트 컨트랙트 안에서 Yul을 식별할 수 있습니다.

이 글의 나머지 부분에서는 예제를 통해 Yul의 기본 사항을 다룰 것이며, Remix에서 직접 따라 해볼 것을 권장합니다.

## **yul에서의 변수 할당, 연산, 평가**

가장 먼저 다뤄야 할 주제는 간단한 연산입니다. Yul에는 \+, -, , /, %, , &lt;, &gt;, = 가 있습니다.

&gt;= 와 &lt;= 는 사용 가능한 Yul 연산자 목록에 포함되어 있지 않은데, 이는 Yul에 이러한 연산자가 존재하지 않기 때문입니다. 또한, 평가 결과는 true나 false가 아니라 각각 1 또는 0으로 표현됩니다. 그럼 이제 Yul을 배워봅시다!

<EmbeddedTable
  table={{
    columns: [
      { key: "1", width: 200, title: "Instruction", dataType: "object" },
      { key: "2", width: 200, title: "Explanation", dataType: "object" },
    ],
    data: [
      {
        "1": { title: "<p>let</p>", tooltip: "", icon: "" },
        "2": { title: "<p>This is required before defining a variable. Since all values are bytes, there is no need to assign a value type.</p>", tooltip: "", icon: "" },
        id: 0,
      },
      {
        "1": { title: "<p>:=</p>", tooltip: "", icon: "" },
        "2": { title: "<p>Solidity equivalent: x = y</p>", tooltip: "", icon: "" },
        id: 1,
      },
      {
        "1": { title: "<p>add(x,y)</p>", tooltip: "", icon: "" },
        "2": { title: "<p>Solidity equivalent: x + y</p>", tooltip: "", icon: "" },
        id: 2,
      },
      {
        "1": { title: "<p>sub(x,y)</p>", tooltip: "", icon: "" },
        "2": { title: "<p>Solidity equivalent: x - y</p>", tooltip: "", icon: "" },
        id: 3,
      },
      {
        "1": { title: "<p>mul(x,y)</p>", tooltip: "", icon: "" },
        "2": { title: "<p>Solidity equivalent: x * y</p>", tooltip: "", icon: "" },
        id: 4,
      },
      {
        "1": { title: "<p>div(x,y)</p>", tooltip: "", icon: "" },
        "2": { title: "<p>Solidity equivalent: x / y (or 0 if y equals 0)</p>", tooltip: "", icon: "" },
        id: 5,
      },
      {
        "1": { title: "<p>mod(x,y)</p>", tooltip: "", icon: "" },
        "2": { title: "<p>Solidity equivalent: x % y (or 0 if y equals 0)</p>", tooltip: "", icon: "" },
        id: 6,
      },
      {
        "1": { title: "<p>lt(x,y)</p>", tooltip: "", icon: "" },
        "2": { title: "<p>Solidity equivalent: x < y</p>", tooltip: "", icon: "" },
        id: 7,
      },
      {
        "1": { title: "<p>gt(x,y)</p>", tooltip: "", icon: "" },
        "2": { title: "<p>Solidity equivalent: x > y</p>", tooltip: "", icon: "" },
        id: 8,
      },
      {
        "1": { title: "<p>eq(x,y)</p>", tooltip: "", icon: "" },
        "2": { title: "<p>Solidity equivalent: x == y</p>", tooltip: "", icon: "" },
        id: 9,
      },
      {
        "1": { title: "<p>iszero(x)</p>", tooltip: "", icon: "" },
        "2": { title: "<p>Solidity equivalent: x == 0</p>", tooltip: "", icon: "" },
        id: 10,
      },
    ],
  }}
/>

계속하기 전에 예제를 간단히 살펴보겠습니다.

## **yul에서의 for 반복문과 if 조건문**

for 반복문과 if 조건문을 모두 배우기 위해, 어떤 수열에서 짝수의 개수를 세는 함수를 작성해 보겠습니다.

if 조건문의 문법은 Solidity와 비슷하지만, 조건을 괄호 안에 넣을 필요가 없습니다.

for 반복문에서는 _i_를 선언하고 증가시킬 때는 중괄호를 사용하지만, 조건을 평가할 때는 사용하지 않는다는 점에 주목하세요. 또한 반복의 한 번을 건너뛰기 위해 _continue_를 사용했습니다. Yul에서는 break 문도 사용할 수 있습니다.

## **yul에서 스토리지가 작동하는 방식**

스마트 컨트랙트에는 2²⁵⁶개의 슬롯이 있습니다. 변수를 선언할 때는 슬롯 0부터 시작해서 순차적으로 증가시킵니다. 각 슬롯의 길이는 256비트(32바이트)이며, uint256과 bytes32라는 이름도 여기서 유래했습니다. 모든 변수는 16진수로 변환됩니다. uint128과 같은 변수가 사용되는 경우, 슬롯 전체를 차지하지 않고 왼쪽에 0으로 패딩됩니다.

[Yul 스토리지가 작동하는 방식](http://www.alchemy.com/overviews/yul-storage)에 대해 더 알아보려면, 다음 내용을 다루는 다른 글을 읽어보세요:

1. 배열
1. 동적 배열
1. 매핑
1. 중첩된 매핑

## **yul에서 패킹된 변수를 읽고 쓰는 방법**

변수를 패킹한다는 것은 여러 변수의 스토리지 합이 32바이트 이하가 되도록 순서를 정해, 하나의 슬롯에 함께 들어갈 수 있게 하는 것을 말합니다! 변수를 패킹하면 가스를 절약할 수 있으며, 스마트 컨트랙트 최적화에 필수적인 기법입니다.

예를 들어, `0x000000000000000000000000000002`과 `0x000000000000000000000000000001`은 각각 16바이트(슬롯의 절반)를 차지하기 때문에 같은 슬롯에 완벽하게 함께 들어갑니다.

[Yul에서 패킹된 스토리지 변수를 읽고 쓰는 방법](http://www.alchemy.com/overviews/yul-packed-storage-variables)에 대해 더 알아보려면, 심화 자료를 읽어보세요!

## **yul에서 메모리는 어떻게 작동할까?**

메모리는 영구적이지 않기 때문에(즉, 함수 실행이 끝나면 모든 변수가 지워집니다) 스토리지와는 다르게 동작합니다. Yul에서 메모리는 다음과 같은 용도로 사용됩니다:

1. 외부 호출에 대한 반환값 설정
1. 외부 호출을 위한 함수 값 설정
1. 외부 호출로부터 값 가져오기
1. 오류 문자열과 함께 되돌리기(revert)
1. 메시지 로깅

[Yul 메모리가 작동하는 방식](http://www.alchemy.com/overviews/yul-memory)에 대해 더 알아보려면, 이 주제를 더 깊이 다루는 다른 글을 읽어보세요!

## **yul에서 컨트랙트 호출은 어떻게 작동할까?**

Yul의 문법, 스토리지, 메모리 작동 방식을 이해했다면, 이제 컨트랙트를 호출할 차례입니다. Yul 시리즈의 마지막 글에서는 [Yul에서 컨트랙트가 호출되는 방식](http://www.alchemy.com/overviews/yul-contract-calls)을 다음 항목들을 중심으로 설명합니다:

1. `call()` - 주소 a에 있는 컨트랙트를 호출하며, 오류 시 0을, 성공 시 1을 반환
1. `staticcall()` - call\(g, a, 0, in, insize, out, outsize\)와 동일하지만 상태 변경을 허용하지 않음
1. `delegatecall()` - callcode와 동일하지만 caller와 callvalue를 그대로 유지

컨트랙트 호출 정의에 대한 더 자세한 정보는 [Yul 언어 문서](https://docs.soliditylang.org/en/v0.8.19/yul.html#yul-call-return-area)에서 확인할 수 있습니다.
