Yul이란 무엇인가?
작성자 Mark Jonathas
Yul은 프로그래밍 언어의 일종으로, 스마트 컨트랙트 내부에서 일종의 어셈블리 언어를 작성하는 데 사용할 수 있습니다. Yul은 스마트 컨트랙트 내부에서 사용되는 경우가 많지만, 스마트 컨트랙트 전체를 Yul로 작성하는 것도 가능합니다.
Yul을 이해하면 스마트 컨트랙트를 한 단계 발전시킬 수 있고, solidity 내부에서 실제로 어떤 일이 일어나는지 파악할 수 있으며, 이는 결과적으로 사용자의 가스 비용을 절감하는 데 도움이 됩니다.
다음과 같은 문법을 통해 스마트 컨트랙트 안에서 Yul을 식별할 수 있습니다.
이 글의 나머지 부분에서는 예제를 통해 Yul의 기본 사항을 다룰 것이며, Remix에서 직접 따라 해볼 것을 권장합니다.
yul에서의 변수 할당, 연산, 평가
가장 먼저 다뤄야 할 주제는 간단한 연산입니다. Yul에는 +, -, , /, %, , <, >, = 가 있습니다.
>= 와 <= 는 사용 가능한 Yul 연산자 목록에 포함되어 있지 않은데, 이는 Yul에 이러한 연산자가 존재하지 않기 때문입니다. 또한, 평가 결과는 true나 false가 아니라 각각 1 또는 0으로 표현됩니다. 그럼 이제 Yul을 배워봅시다!
계속하기 전에 예제를 간단히 살펴보겠습니다.
yul에서의 for 반복문과 if 조건문
for 반복문과 if 조건문을 모두 배우기 위해, 어떤 수열에서 짝수의 개수를 세는 함수를 작성해 보겠습니다.
if 조건문의 문법은 Solidity와 비슷하지만, 조건을 괄호 안에 넣을 필요가 없습니다.
for 반복문에서는 _i_를 선언하고 증가시킬 때는 중괄호를 사용하지만, 조건을 평가할 때는 사용하지 않는다는 점에 주목하세요. 또한 반복의 한 번을 건너뛰기 위해 _continue_를 사용했습니다. Yul에서는 break 문도 사용할 수 있습니다.
yul에서 스토리지가 작동하는 방식
스마트 컨트랙트에는 2²⁵⁶개의 슬롯이 있습니다. 변수를 선언할 때는 슬롯 0부터 시작해서 순차적으로 증가시킵니다. 각 슬롯의 길이는 256비트(32바이트)이며, uint256과 bytes32라는 이름도 여기서 유래했습니다. 모든 변수는 16진수로 변환됩니다. uint128과 같은 변수가 사용되는 경우, 슬롯 전체를 차지하지 않고 왼쪽에 0으로 패딩됩니다.
Yul 스토리지가 작동하는 방식에 대해 더 알아보려면, 다음 내용을 다루는 다른 글을 읽어보세요:
- 배열
- 동적 배열
- 매핑
- 중첩된 매핑
yul에서 패킹된 변수를 읽고 쓰는 방법
변수를 패킹한다는 것은 여러 변수의 스토리지 합이 32바이트 이하가 되도록 순서를 정해, 하나의 슬롯에 함께 들어갈 수 있게 하는 것을 말합니다! 변수를 패킹하면 가스를 절약할 수 있으며, 스마트 컨트랙트 최적화에 필수적인 기법입니다.
예를 들어, 0x000000000000000000000000000002과 0x000000000000000000000000000001은 각각 16바이트(슬롯의 절반)를 차지하기 때문에 같은 슬롯에 완벽하게 함께 들어갑니다.
Yul에서 패킹된 스토리지 변수를 읽고 쓰는 방법에 대해 더 알아보려면, 심화 자료를 읽어보세요!
yul에서 메모리는 어떻게 작동할까?
메모리는 영구적이지 않기 때문에(즉, 함수 실행이 끝나면 모든 변수가 지워집니다) 스토리지와는 다르게 동작합니다. Yul에서 메모리는 다음과 같은 용도로 사용됩니다:
- 외부 호출에 대한 반환값 설정
- 외부 호출을 위한 함수 값 설정
- 외부 호출로부터 값 가져오기
- 오류 문자열과 함께 되돌리기(revert)
- 메시지 로깅
Yul 메모리가 작동하는 방식에 대해 더 알아보려면, 이 주제를 더 깊이 다루는 다른 글을 읽어보세요!
yul에서 컨트랙트 호출은 어떻게 작동할까?
Yul의 문법, 스토리지, 메모리 작동 방식을 이해했다면, 이제 컨트랙트를 호출할 차례입니다. Yul 시리즈의 마지막 글에서는 Yul에서 컨트랙트가 호출되는 방식을 다음 항목들을 중심으로 설명합니다:
call()- 주소 a에 있는 컨트랙트를 호출하며, 오류 시 0을, 성공 시 1을 반환staticcall()- call(g, a, 0, in, insize, out, outsize)와 동일하지만 상태 변경을 허용하지 않음delegatecall()- callcode와 동일하지만 caller와 callvalue를 그대로 유지
컨트랙트 호출 정의에 대한 더 자세한 정보는 Yul 언어 문서에서 확인할 수 있습니다.
관련 개요

블록체인 매직을 만드세요
Alchemy는 가장 강력한 Web3 개발자 제품 및 도구를 리소스, 커뮤니티, 그리고 전설적인 지원과 결합합니다.


