<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>EVM on Jeongseup Blog</title><link>https://jeongseup.github.io/tags/evm/</link><description>Recent content in EVM on Jeongseup Blog</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Wed, 25 Feb 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://jeongseup.github.io/tags/evm/index.xml" rel="self" type="application/rss+xml"/><item><title>EVM은 왜 정수(uint)만 지원하는가?</title><link>https://jeongseup.github.io/p/evm-integer-only-design/</link><pubDate>Wed, 25 Feb 2026 00:00:00 +0000</pubDate><guid>https://jeongseup.github.io/p/evm-integer-only-design/</guid><description>&lt;blockquote&gt;
&lt;p&gt;Solidity에 float이 없는 이유와 블록체인 합의의 관계&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="핵심-이유-부동소수점은-합의를-깨뜨린다"&gt;핵심 이유: 부동소수점은 합의를 깨뜨린다
&lt;/h2&gt;&lt;p&gt;블록체인은 수천 개 노드가 동일한 계산을 수행하고 &lt;strong&gt;같은 결과에 합의&lt;/strong&gt;해야 하는 시스템이다.&lt;/p&gt;
&lt;p&gt;그런데 IEEE 754 부동소수점(&lt;code&gt;float&lt;/code&gt;/&lt;code&gt;double&lt;/code&gt;)은 하드웨어마다 미세하게 다른 결과를 낼 수 있다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;0.1 + 0.2 =
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Node A (Intel x86): 0.30000000000000004
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Node B (ARM Cortex): 0.30000000000000001
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Node C (AMD Ryzen): 0.30000000000000004
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;→ A와 C는 같은 상태 해시, B는 다른 상태 해시
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;→ 합의 실패 → 체인 포크!
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;반면 정수 연산은 어떤 CPU에서든 동일하다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;800 * 1e18 / 1000 = 800000000000000000
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;→ 100% 결정론적(deterministic) → 합의 보장
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="이유-1-결정론determinism--가장-근본적"&gt;이유 1: 결정론(Determinism) — 가장 근본적
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;float&lt;/code&gt;이 비결정론적인 구체적 원인들을 살펴보자.&lt;/p&gt;
&lt;h3 id="반올림-모드-차이"&gt;반올림 모드 차이
&lt;/h3&gt;&lt;p&gt;IEEE 754에는 4가지 반올림 모드가 있다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Round to nearest (even)&lt;/strong&gt; — 기본값이지만 바꿀 수 있음&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Round toward zero&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Round toward +∞&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Round toward -∞&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CPU나 컴파일러 설정에 따라 모드가 달라질 수 있다.&lt;/p&gt;
&lt;h3 id="비결합법칙-non-associativity"&gt;비결합법칙 (Non-associativity)
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;정수: (a + b) + c = a + (b + c) ← 항상 같음
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;float: (a + b) + c ≠ a + (b + c) ← 다를 수 있음!
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;예를 들어 &lt;code&gt;a=1e20, b=-1e20, c=1.0&lt;/code&gt;일 때:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(a + b) + c = 0 + 1.0 = 1.0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;a + (b + c) = 1e20 + (-1e20) = 0.0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;컴파일러 최적화가 연산 순서를 바꾸면 결과가 달라진다.&lt;/p&gt;
&lt;h3 id="특수값-처리-차이"&gt;특수값 처리 차이
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;NaN&lt;/code&gt;, &lt;code&gt;Infinity&lt;/code&gt;, &lt;code&gt;-0&lt;/code&gt;, denormalized numbers 등 특수값들의 비교·연산 동작이 구현마다 미세하게 다르다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="이유-2-금융-정밀도--float은-돈-계산에-위험"&gt;이유 2: 금융 정밀도 — float은 돈 계산에 위험
&lt;/h2&gt;&lt;p&gt;은행도 &lt;code&gt;float&lt;/code&gt;을 쓰지 않는다:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;시스템&lt;/th&gt;
&lt;th&gt;방식&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;COBOL&lt;/td&gt;
&lt;td&gt;고정소수점 (packed decimal)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Java&lt;/td&gt;
&lt;td&gt;&lt;code&gt;BigDecimal&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;td&gt;&lt;code&gt;decimal&lt;/code&gt; 모듈&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;블록체인&lt;/td&gt;
&lt;td&gt;&lt;code&gt;uint256&lt;/code&gt; + 1e18 스케일링&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;float&lt;/code&gt;의 위험을 구체적으로 보면:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;잔고 100.10 USDC를 float로 저장하면?
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;→ 실제 저장값: 100.09999999999999...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;→ 100만 번 더하기/빼기 반복하면 오차 누적
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;→ 잔고 불일치 → 자금 손실 또는 무한 인출 취약점
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;uint256&lt;/code&gt; + PRECISION 방식:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;100.10 USDC = 100_100_000 (USDC는 6 decimals)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;→ 정확히 이 값. 오차 없음. 1000만 번 연산해도 동일.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="이유-3-evm-설계-단순화"&gt;이유 3: EVM 설계 단순화
&lt;/h2&gt;&lt;p&gt;EVM은 &lt;strong&gt;256비트 워드 기반 스택 머신&lt;/strong&gt;이다. &lt;code&gt;uint256&lt;/code&gt; 하나로 통일하면:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;장점&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Opcode 수 적음 (&lt;code&gt;ADD&lt;/code&gt;, &lt;code&gt;MUL&lt;/code&gt;, &lt;code&gt;DIV&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;가스 비용 계산 간단 (고정 비용)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;구현 버그 감소&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;상태 저장 단순 (32 bytes 슬롯)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;만약 &lt;code&gt;float&lt;/code&gt;을 추가한다면:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;추가 복잡도&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FADD&lt;/code&gt;, &lt;code&gt;FMUL&lt;/code&gt;, &lt;code&gt;FDIV&lt;/code&gt;, &lt;code&gt;FSQRT&lt;/code&gt; opcode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;반올림 모드 명세&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;NaN&lt;/code&gt;, &lt;code&gt;Infinity&lt;/code&gt;, &lt;code&gt;-0&lt;/code&gt; 처리 규칙&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;가스 비용 산정 (연산마다 다름)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;int↔float&lt;/code&gt; 변환 opcode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;모든 EVM 구현체의 동작 일치 검증&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;복잡도 대비 이점이 없다. 정수 스케일링으로 충분하기 때문이다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="다른-블록체인도-마찬가지인가"&gt;다른 블록체인도 마찬가지인가?
&lt;/h2&gt;&lt;p&gt;L2도 &lt;code&gt;float&lt;/code&gt;을 명시적으로 제거한다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Optimism (Bedrock)&lt;/strong&gt;: float 연산 제외 — fraud proof 검증을 위해&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Arbitrum Nitro&lt;/strong&gt;: float 연산 제외 — 동일한 이유&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;다른 체인들도 마찬가지다:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;체인&lt;/th&gt;
&lt;th&gt;방식&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Solana (BPF)&lt;/td&gt;
&lt;td&gt;정수 연산만 지원, float는 프로그램 레벨에서 처리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cosmos (CosmWasm)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Decimal256&lt;/code&gt; 타입 제공 (uint 기반 구현)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Move (Sui/Aptos)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;u8&lt;/code&gt;/&lt;code&gt;u64&lt;/code&gt;/&lt;code&gt;u128&lt;/code&gt;/&lt;code&gt;u256&lt;/code&gt;만 지원, float 없음&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;블록체인 VM에서 float 배제는 업계 표준&lt;/strong&gt;이다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="defi의-우회-방법들"&gt;DeFi의 우회 방법들
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;float&lt;/code&gt; 없이 소수점을 다루는 방법들:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;방식&lt;/th&gt;
&lt;th&gt;사용 사례&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;1e18 (Mantissa)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Compound — 범용 비율 계산&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;1e27 (Ray)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Aave V3 — 더 높은 정밀도 필요 시&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;2^96 (Q notation)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Uniswap V3 — 제곱근 가격 계산 최적화&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Token decimals&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;USDC(6), WETH(18) — 토큰 단위 표현&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;WAD/RAY 라이브러리&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ds-math, WadRayMath — 안전한 연산&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;공통 패턴: &lt;strong&gt;&amp;ldquo;정수로 표현하고, 나눗셈은 최대한 늦추고, 곱셈을 먼저&amp;rdquo;&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="결론"&gt;결론
&lt;/h2&gt;&lt;p&gt;EVM이 &lt;code&gt;uint&lt;/code&gt;만 지원하는 이유를 우선순위로 정리하면:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;합의 안전성&lt;/strong&gt; — float은 노드 간 결과 차이를 만들 수 있음&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;금융 정확성&lt;/strong&gt; — 돈 계산에 부동소수점은 위험&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;설계 단순성&lt;/strong&gt; — opcode와 가스 모델 복잡도 최소화&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;이것은 **&amp;ldquo;기술적 한계&amp;quot;가 아니라 &amp;ldquo;의도적 설계 결정&amp;rdquo;**이다.&lt;/p&gt;
&lt;p&gt;분산 합의가 필요 없는 시스템(게임 엔진, 과학 계산)에서는 float이 적합하지만, &lt;strong&gt;&amp;ldquo;수천 대 컴퓨터가 같은 답을 내야 하는&amp;rdquo; 블록체인에서는 정수가 유일한 선택&lt;/strong&gt;이다.&lt;/p&gt;</description></item></channel></rss>