본문으로 건너뛰기
전체 글

수수료가 0이어도 가스는 필요한 이유

· 약 7분
Bankware Global Engineering

수수료를 받지 않는 블록체인에서 거래가 “가스 부족”으로 실패했다. 돈을 내지 않는데 무엇이 부족하다는 뜻일까?

실패한 거래에서 무엇은 취소되고 무엇은 남는지를 살펴본 앞 글은, 송금이 취소돼도 거래를 처리한 기록과 비용은 남을 수 있다는 이야기로 끝났다. 이번에는 그 비용을 더 나누어 본다. 얼마나 실행하도록 허용할 것인가와, 그 실행에 얼마를 청구할 것인가는 서로 다른 결정이다.

nigo-protocol의 ZERO 수수료 정책은 금전 수수료를 0으로 만든다. 거래를 처리하는 규칙과 실행 한도까지 없애지는 않는다. 그 차이를 같은 20 X 송금으로 따라가 보자.

돈을 내지 않아도 실행에는 끝이 있어야 한다​

A에게 100 X가 있고 B에게는 없다. X는 수수료 자산 NIGO와 다른 자산이며, A는 20 X를 보내려 한다. 추가 발행이나 소각은 없다. 아래의 성공·실패 경우는 모두 이 초기 상태에서 따로 시작한다.

먼저 EVM의 업무 계약 P를 이용한다고 하자. 앞 글처럼 A가 P에 30 X의 사용을 승인한 별도 거래는 이미 확정돼 있다. P는 지급 조건을 확인한 뒤 그중 20 X를 B에게 보낸다.

거래의 gas 한도를 100,000으로 두고, 성공한 처리 결과에 60,000 gas가 기록됐다고 가정하자. 숫자는 설명용이며 실제 송금의 측정값이나 권장 설정이 아니다. 결과는 A=80 X, B=20 X, 남은 승인=10 X다. ZERO에서는 이 거래의 금전 수수료가 0이다.

그렇다면 P가 잘못된 반복문에 빠지면 어떻게 될까? 수수료를 받지 않는다는 이유로 실행을 계속 허용하면, 하나의 거래가 끝나지 않아 다른 거래를 처리할 기회를 빼앗을 수 있다. gas 한도는 이런 실행을 정해진 예산 안에서 끝내기 위한 규칙이다. 바깥 EVM 거래가 한도를 소진해 실패하면 업무 변경은 취소되고 X 잔액은 100/0, 승인은 30으로 남는다. 청구할 금액은 여전히 0이어도 실행은 실패할 수 있다.

이때 gas는 컴퓨터가 실제로 사용한 밀리초를 재는 초시계가 아니다. 정해진 비용표에 따라 연산과 상태 접근 등의 비용을 누적하는 단위다. 같은 상태와 입력, 같은 실행 규칙을 적용한 노드들이 동일한 한도와 처리 결과를 판단할 수 있어야 한다. 빠른 컴퓨터라는 이유로 같은 거래에 더 많은 실행을 허용하지 않는다.

한도, 사용량, 가격, 정산을 나누어 읽기​

앞의 성공 거래에는 서로 다른 네 가지 값과 단계가 있다.

  • 한도: 이 거래에 허용한 최대 gas는 100,000이다.
  • 사용량: 정해진 계량 규칙을 적용한 최종 처리 결과에는 60,000 gas가 기록된다.
  • 가격: ZERO에서는 gas를 금액으로 바꾸는 단가가 0이다.
  • 정산: 적용되는 수수료 정책과 실행 결과에 따라 실제 NIGO 금액을 원장에 반영한다.

수수료가 0이라는 정보는 이 중 가격과 금액 정산에 관한 것이다. 한도와 사용량은 여전히 의미가 있다. 반대로 gas 한도가 크다고 그만큼을 항상 최종 청구하는 것도 아니다.

gas 비용표도 모든 실행 경로가 같지는 않다. nigo-protocol의 일반 EVM은 현재 Osaka 실행 규칙에 맞춘 비용표를 사용하고, Native 프로그램과 Direct Cell은 각 경로의 비용표를 사용한다. 서로 다른 경로의 gas 숫자를 실제 CPU 시간이나 처리 속도의 직접 비교값으로 읽어서는 안 된다.

같은 송금을 유료 정책에서 처리한다면​

이번에는 같은 EVM 송금을 FIXED 정책에서 처리한다고 하자. FIXED는 거래 한 건의 금액이 고정이라는 뜻이 아니라, gas의 금액 환산 단가가 고정이라는 뜻이다. 현재 FIXED 정책에서 정산한 수수료는 소각된다.

계산을 위해 단가를 gas당 NIGO 최소 단위 2로 둔다. 아래 금액은 모두 NIGO 최소 단위이며 실제 운영 단가를 제안하는 숫자가 아니다. 다른 NIGO 전송은 없고, A가 수수료용으로 제공한 NIGO 입력도 정확히 200,000이라고 가정한다.

gas 한도 100,000에 단가 2를 곱하면 최대 비용은 200,000이다. 실행 전에는 이 금액을 감당할 수 있는 입력을 확보한다. 하지만 최대 비용의 확보는 전액 소각과 다르다. 실행 결과가 나온 뒤 실제 비용과 돌려줄 금액을 결정한다.

처리 결과영수증의 gas소각액 / 돌아오는 금액
성공60,000120,000 / 80,000
업무 조건 거절로 전체 REVERT40,00080,000 / 120,000
바깥 거래의 gas 한도 소진100,000200,000 / 0

각 행은 별도의 실행이며, gas도 설명용 가정이다. 표의 영수증 값에는 거래 기본 비용과 실행 비용, 적용되는 EVM gas 환급 규칙이 반영돼 있다. 여기서 “돌아오는 금액”은 미리 확보한 NIGO 중 최종 비용을 제외한 금액이다.

성공한 행에서는 X가 80/20으로 바뀌고 승인은 10이 된다. 실패한 두 행에서는 X가 100/0, 승인은 30으로 돌아가지만, 원장에 포함되어 처리된 실패의 수수료는 남는다. 업무가 취소돼도 그 결과를 판단하기까지 실행한 일이 사라지지는 않기 때문이다. 세 경우 모두 소각액과 돌아오는 금액을 합하면 최초 수수료 입력 200,000과 같다.

이 표는 유효한 EVM 거래가 실행된 뒤 포함되는 결과를 비교한다. 서명이나 입력이 잘못돼 실행 전에 거절된 요청, 혹은 시뮬레이션에 같은 청구가 발생한다는 뜻은 아니다.

Direct Cell과 Native에도 같은 계산식을 적용할 수 있을까​

공통 자산 모델에서는 같은 자산을 Direct Cell이나 프로그램 실행으로 다룰 수 있다. 그렇다고 자산의 소유자가 규칙을 무시하고 더 싼 경로를 고르는 것은 아니다. 해당 자산의 현재 통제와 권한이 허용하는 경로여야 한다.

Direct Cell에는 VM 프로그램 실행이 없지만, 거래 데이터를 처리하고 소유권과 수량 보존을 검증하는 일이 남는다. 현재는 정해진 형식으로 직렬화한 거래 데이터의 길이 등에 따라 gas를 계산한다. 이 거래 데이터를 envelope라고 부른다. VM을 실행하지 않는다고 gas가 0인 것은 아니다. Direct Cell의 gas 한도가 이 기본 처리량보다 작으면 실행 전 유효성 검사에서 거절된다.

Native 프로그램은 envelope 처리에 더해 프로그램의 실행량도 측정한다. 조합된 정책의 여러 모듈은 거래 전체의 실행 예산을 나누어 쓰므로, 모듈을 추가할 때마다 새 무제한 예산을 얻지 않는다. ZERO에서도 이 예산과 프로토콜의 상한은 유지된다.

다만 현재 Native의 영수증에 기록된 전체 gas와, 수수료를 계산하는 gas의 범위는 다르다.

실행 경로영수증에 기록하는 gas현재 금전 수수료의 계산 기준
Direct Cellenvelope 처리량envelope gas와 단가
Native Programenvelope와 프로그램 실행량의 합. 실패 시 계량 규칙 적용envelope gas와 단가
EVMEVM 규칙을 반영한 전체 거래 gas최종 EVM gas와 단가

Native는 실행 전에 envelope를 기준으로 금전 수수료를 정하고, 프로그램의 실행량은 한도 검사와 영수증에 반영한다. 따라서 프로그램 실행량이 늘었다는 사실만으로 현재 청구 금액도 같은 비율로 늘었다고 읽으면 안 된다. 정책 거절이나 실행 예산 소진으로 포함되는 Native 실패도 이 envelope 기준 수수료를 사용한다. 조합형 정책이 예산을 소진하면, 서명한 한도와 프로토콜 상한으로 정한 실행 예산을 사용한 것으로 기록한다. EVM의 gas 한도 소진 행을 Native에 그대로 옮겨 “서명한 gas 한도 전액을 소각한다”고 설명하면 틀린다.

이 부분은 현행 구현의 동작이다. Native 유료 정책에서 실행량과 청구액을 어떤 기준으로 맞출지는 별도의 설계 검토 과제로 남아 있다. 실행을 측정하는 이유를 설명할 수 있다고 해서, 모든 경로의 과금 방식이 하나로 완성됐다는 뜻은 아니다.

P가 EVM 안에서 Native 자산 정책을 호출하는 경우도 구분한다. Native 승인과 EVM 사용을 연결한 예제처럼 정책을 실행해도, 별도 Native 거래 한 건의 수수료를 다시 붙이지 않는다. 내부 정책 실행의 비용은 바깥 EVM의 gas 예산에 반영되고, 금전 수수료는 바깥 EVM 거래가 정산한다.

같은 블록을 처리하는 노드는 같은 가격을 적용해야 한다​

ZERO와 FIXED를 노드 운영자가 매번 임의로 고른다면, 같은 거래를 보고도 서로 다른 잔돈과 공급량을 계산할 수 있다. nigo-protocol은 수수료 정책과 적용할 블록 높이의 일정을 원장의 시작 상태인 genesis에 묶는다. 기존 원장을 여는 노드는 저장된 정책과 자신이 기대하는 설정이 일치하는지 확인한다.

그래서 앱이 거래의 수수료를 조회했을 때의 예상과, 실제 포함되는 블록의 정산 기준도 구분해야 한다. 최종 실행은 해당 블록에 적용되는 정책을 따른다. 현재의 FIXED를 혼잡도에 따라 가격을 조정하는 Ethereum 수수료 시장과 동일하게 설명해서도 안 된다.

gas는 이런 공통 규칙으로 실행을 제한하지만 서버의 모든 비용을 대신 측정하지는 않는다. 동일한 거래를 검증하기 위한 재실행이나 저장소의 실제 작업 비용까지 영수증 gas와 일대일로 같지는 않다. 거래 한도를 둔다는 것과 서비스 전체가 모든 부하를 감당한다는 것도 별도의 문제다.

금액이 0이어도 원장의 계산은 남는다​

20 X 송금을 끝까지 따라가면, 사용자가 보내려던 자산의 양, 실행에 허용한 gas, 결과에 기록된 gas, 실제 청구한 NIGO가 각각 다른 값이라는 것을 볼 수 있다. ZERO는 거래 수수료를 0으로 두면서도 원장이 실행을 계량하고 제한할 수 있게 한다.

이 글은 2026년 10월 28일 확인한 설계 문서와 구현·회귀 테스트의 범위를 설명한다. 예제의 gas와 금액은 원리를 설명하기 위한 가정이며 제품 성능이나 실측 수수료가 아니다.

여기서 다음 질문이 생긴다. FIXED에서 여러 거래의 수수료가 소각된다면, 블록 전체의 NIGO 총공급량은 어떻게 정확히 맞출까? 모든 거래가 같은 공급량 기록을 직접 고쳐야 할까, 아니면 최종적으로 살아남은 경제 효과를 모아 검증할 수 있을까? 다음 글에서는 거래별 정산을 블록 전체의 공급 회계로 이어가 본다.