이더리움 PoS에서 트랜잭션이 블록에 포함되고 최종화되기까지

개요 이더리움 PoS에서 한 트랜잭션이 네트워크에 전파되고 블록에 포함된 뒤 최종화되기까지의 핵심 흐름 정리 노드별 로컬 mempool, 슬롯 기반 제안자 선정, 검증자 attestation, 포크 선택, 최종화 순서로 진행 현실적으로 일부 제안자는 외부 빌더를 사용할 수 있으나 프로토콜 관점의 기본 흐름을 기준으로 설명 전체 흐름 1 트랜잭션 발생 및 전파 사용자가 서명된 트랜잭션 전송 여러 노드가 트랜잭션을 수신하고 각자 로컬 mempool에 저장 mempool은 전역 공유가 아닌 노드 로컬 데이터 구조 2 슬롯과 제안자 선정 ...

January 28, 2026

이더리움 PoS 노드의 종류와 역할 정리

개요 이더리움 PoS 환경에서 노드 역할은 레이어 분리로 명확해졌음. 실행을 담당하는 EL, 합의를 담당하는 CL, 검증자 키와 서명을 담당하는 VC로 나뉨. 이 조합으로 일반 풀노드와 밸리데이터 노드가 구성됨. 아래는 각 컴포넌트와 노드 타입의 역할 차이를 실무 관점에서 정리함 레이어 기준 정의 EL (Execution Layer) 트랜잭션 실행과 상태 전이 수행 EVM 실행과 가스 계산 담당 mempool 유지 및 트랜잭션 선별 블록 본문에 담기는 실제 tx 처리 관할 무슨 일이 일어났는지 계산하는 층 CL (Consensus Layer) ...

January 26, 2026

nonce가 꼬인다? 트랜잭션 상태별 nonce의 변화

개요 Ethereum에서 트랜잭션 순서를 보장하는 핵심 메커니즘은 nonce임. 네트워크에서 자주 겪는 “nonce 꼬임"은 대개 트랜잭션 상태와 nonce 소비 규칙을 혼동해서 발생함. 아래는 EOA와 트랜잭션 관계, nonce 정의, 트랜잭션 상태별 nonce 변화 정리 EOA와 트랜잭션 Ethereum 계정은 두 종류로 구분 EOA, 개인 키로 서명해 트랜잭션 전송 가능 Contract Account, 스스로 트랜잭션 전송 불가, 외부에서 온 트랜잭션의 실행 흐름 내에서만 호출됨 트랜잭션을 보낸다는 것은 EOA가 서명 후 네트워크에 브로드캐스트한다는 의미. 컨트랙트는 내부 호출과 생성 같은 메시지 호출을 발생시킬 수 있지만 이는 트랜잭션이 아님. 최상위 트랜잭션의 발신자는 항상 EOA ...

January 21, 2026

이더리움 단위 정리: ETH, Gwei, Wei와 ERC-20 decimals 18

개요 이더리움 단위 체계는 10의 지수 기반으로 딱 떨어지게 설계됨 EVM은 부동소수점을 지원하지 않으므로 모든 값은 정수로 표현, 단위 나눔과 스케일링이 필수 단위 환산 1 ETH = 10^9 Gwei = 10^18 Wei 풀어서 보면 다음과 같음 1 ETH = 1,000,000,000 Gwei (10억 그웨이) = 1,000,000,000,000,000,000 Wei (100경 웨이) 용도별 구분 Wei: 최소 단위, 스마트 컨트랙트 내부 연산에 사용. Solidity에 소수점 개념 없음 Gwei: 10^9 Wei. 가스 가격 표시 단위로 사용, 사람이 읽고 비교하기 쉬움 Ether: 10^18 Wei. 지갑 잔고, 일상적 송금 금액 표시에 사용 개발자 상식: ERC-20 decimals = 18 ERC-20 토큰에서 decimals를 18로 두는 관례는 이더리움 기본 최소 단위(Wei) 스케일을 그대로 따름 의미: 토큰 1개가 10^18의 최소 단위로 분할 가능 예외: 스테이블 코인처럼 법정화폐 소수 자리를 맞추는 토큰은 decimals 6 등으로 설정하는 경우 있음 ...

January 20, 2026

ERC-4337 Account Abstraction의 장단점과 EntryPoint 병목 정리

개념/배경 Account Abstraction(AA, 계정 추상화)은 키 기반 EOA에 고정된 지갑 모델을 스마트 컨트랙트로 일반화해 UX를 끌어올리는 접근법. ERC-4337은 이를 프로토콜 변경 없이 애플리케이션 레이어에서 구현하는 표준. 목적은 블록체인을 몰라도 쓸 수 있는 경험을 제공하는 것. 대가로 추가 가스비와 인프라 복잡도가 뒤따름 장점 요약 가스비 대납과 가스 추상화 지원. Paymaster를 통해 사용자가 ETH 없이도 트랜잭션 가능. 서비스가 대납하거나 보유 토큰으로 지불하는 경로 구성 가능 소셜 복구 및 프로그래머블 보안. 시드 문구 분실 시 다중 승인 기반 복구, 전송 한도, 화이트리스트 등 정책 내장 가능 트랜잭션 배치. Approve → Swap 같은 연속 작업을 한 번의 서명으로 처리, 서명 피로와 왕복 비용 감소 세션 키. 제한된 권한과 기간으로 자동 서명 흐름 구성 가능. 게임 등 빈번한 액션에 유효 단점 요약 높은 가스비. EntryPoint를 경유하며 검증/실행 로직이 추가되어 오버헤드 발생. 메인넷에서는 체감 비용 큼, L2에서는 상대적으로 부담 완화 가능 인프라 복잡도 증가. 노드만으로 부족, Bundler·Paymaster·Aggregator 등 별도 컴포넌트 필요. 이들 장애 시 트랜잭션 정지 리스크 존재 DApp 호환성 이슈. EOA 전제 코드와 충돌 가능. EIP-1271 기반 서명 검증 경로를 지원하지 않는 레거시 DApp에서 로그인/서명 실패 발생 여지 지갑 생성 비용. AA 지갑은 컨트랙트이므로 최초 배포 비용 발생. 첫 트랜잭션 시 지연 배포로 UX 노출 최소화 가능 EntryPoint 병목 구조 ERC-4337에서는 사용자 요청(UserOperation)이 단일 싱글톤 컨트랙트인 EntryPoint를 통해 처리됨. Bundler가 여러 UserOp를 모아 EntryPoint의 handleOps를 호출하는 구조. 병목의 핵심은 서버 과부하라기보다 가스비 오버헤드와 검증 복잡도 증가 ...

January 19, 2026

CEI 패턴 Checks-Effects-Interactions로 재진입 방어

개념/배경 CEI 패턴은 Checks-Effects-Interactions의 약자 스마트 컨트랙트 함수에서 실행 순서를 명확히 해 재진입 공격을 줄이는 코드 규칙 핵심은 검증 후 상태 변경을 먼저 완료하고, 외부 호출을 마지막에 수행하는 흐름 유지 3단계 순서 1. Checks (검증) ↓ 2. Effects (상태 변경) ↓ 3. Interactions (외부 호출)이 순서를 지키면 외부로 제어권이 나가기 전에 내부 상태가 이미 안전하게 반영됨 재진입 시도는 변경된 상태에 의해 자연스럽게 차단됨 예시로 이해하기 잘못된 순서 위험 function withdraw(uint256 amount) external { // 1. Checks require(balances[msg.sender] >= amount); // 2. Interactions ← 너무 빠름 (bool success, ) = msg.sender.call{value: amount}(""); require(success); // 3. Effects ← 너무 늦음 balances[msg.sender] -= amount; }문제점 ...

January 17, 2026

스마트 컨트랙트 재진입 공격 방지 가이드 — CEI 패턴과 ReentrancyGuard

개요 리엔트란시 재진입은 외부 호출 중 컨트랙트의 같은 함수 또는 다른 함수가 다시 호출되는 상황을 의미함 상태 변경 전 외부 호출이 발생하면 공격자가 재진입을 통해 상태 검증을 우회하거나 중복 실행을 유도할 수 있음 대표적 피해 사례로 The DAO 사건이 알려져 있음 실무 기본 원칙은 CEI 패턴 Checks-Effects-Interactions 준수와 ReentrancyGuard를 통한 보강 적용임 두 방법을 함께 쓰는 것이 표준에 가까움 유명한 사례와 최소 취약 패턴 취약한 순서 패턴 핵심 외부 전송 또는 외부 컨트랙트 호출이 상태 변경보다 먼저 발생 이후 상태 변경이 이루어져도 재진입 시점에는 이전 상태가 유효하여 중복 집행 가능 최소 취약 스니펫 예시 ...

January 15, 2026

ERC-721 승인 패턴 정리 approve vs setApprovalForAll 사용법과 권한 확인

개요 ERC-721에서 전송 권한 위임을 처리하는 두 가지 승인 방식 정리 권한 범위와 사용 시나리오가 달라 오용 시 과권한 위험 발생 가능 핵심 동작과 권한 확인 패턴 중심으로 정리 핵심 개념 approve(address to, uint256 tokenId) 특정 NFT 1개에 대한 전송 권한만 부여 예 123번 토큰만 지정한 대상이 전송 가능 토큰별 개별 승인 필요 setApprovalForAll(address operator, bool approved) 소유한 모든 NFT에 대한 전송 권한 일괄 부여 한 번 승인 시 현재 보유분 + 이후 수령분까지 포함 관리 편의성 높지만 권한 범위 큼 권한 확인 패턴 컨트랙트에서 호출 주체가 대상 토큰에 대해 승인 받았는지 확인 필요 두 방식 모두 대응하는 조건을 만족해야 안전 ...

January 14, 2026

ERC-1155 vs ERC-721: 멀티 토큰 표준과 단일 NFT 표준의 차이와 선택 기준

개요 ERC-1155는 게임 아이템처럼 대량의 토큰을 효율적으로 관리하기 위해 등장한 멀티 토큰 표준으로, ERC-721의 전송·배포 측면 비효율을 줄이려는 목적을 가짐 편의점 비유로 직관화 가능 ERC-721 개별 포장 모델, 물건 10개 결제에 결제 10번·영수증 10장 ERC-1155 장바구니 모델, 물건 10개를 한 번에 결제·영수증 1장 핵심 개념 ERC-721 단일 NFT 표준, 토큰 ID 하나가 유일한 자산을 대표 ERC-1155 멀티 토큰 표준, 하나의 컨트랙트에서 다수의 ID 발행과 각 ID별 수량 관리 동일 ID에 수량이 붙는 구조로 FT·NFT·SFT를 한 컨트랙트에서 혼합 가능 세미 펀지블 SFT, 같은 ID를 공유하는 동일 품질의 여러 개 토큰을 표현 동작과 구조 단일 컨트랙트에 다수의 tokenId와 balance 맵핑 보유 전송 함수 safeTransferFrom 단건, safeBatchTransferFrom 묶음 전송 지원 이벤트는 TransferSingle과 TransferBatch로 발행, 동일 ID 다건 이동에 최적화 메타데이터는 ID 기반 템플릿 URI 방식 활용이 일반적 {id} 플레이스홀더 패턴 사용 장점 비교 A. 가스비 및 처리량 개선 ...

January 7, 2026

EIP-712 기반 signTypedData 가이드와 지갑 연동 핵심

개요 signTypedData는 EIP-712 표준을 구현한 서명 메서드로 구조화된 데이터에 서명하기 위한 표준 인터페이스를 제공함 지갑은 사람이 읽을 수 있는 형태로 서명 내용을 표시하고, 서명은 특정 도메인과 체인에 귀속되어 재사용 공격을 줄임 signTypedData와 EIP-712의 관계 정의 signTypedData는 EIP-712 규격을 따르는 구조화 데이터 서명 메서드 이더리움 지갑 및 제공자에서 eth_signTypedData, eth_signTypedData_v3, eth_signTypedData_v4 형태로 노출 버전 signTypedData 최초 버전 signTypedData_v3 signTypedData_v4 가장 널리 사용되는 최신 버전 라이브러리 사용 ethers에서는 _signTypedData로 제공 const signature = await signer._signTypedData(domain, types, value) 지갑 연동은 일반적으로 provider에 직접 요청하는 방식 사용 const signature = await ethereum.request({ method: 'eth_signTypedData_v4', params: [account, JSON.stringify({ domain, types, message: value })], })동작 원리 요약 타입화된 구조체 정의 예시 구조체와 필드 타입을 정형화해 명세 도메인 분리자 사용 이름, 버전, 체인 ID, 검증 컨트랙트 주소를 포함해 서명 범위 고정 타입 해시와 데이터 해시 생성 타입 정의를 keccak256으로 해싱 후 데이터 인코딩 해시 생성 최종 해시에 서명 및 검증 지갑에서 서명 생성, 컨트랙트에서 도메인과 타입을 동일하게 재현해 검증 사용 예시 간단한 도메인, 타입, 메시지 구성 예시 const domain = { name: 'MyApp', version: '1', chainId, verifyingContract } const types = { Action: [ { name: 'user', type: 'address' }, { name: 'amount', type: 'uint256' } ] } const value = { user: userAddress, amount } // ethers 서명 const sig = await signer._signTypedData(domain, types, value) // 지갑 요청 v4 서명 const sig2 = await ethereum.request({ method: 'eth_signTypedData_v4', params: [account, JSON.stringify({ domain, types, message: value })], }) 컨트랙트 검증 예시 요약 // OpenZeppelin EIP712, ECDSA 사용 가정 bytes32 digest = _hashTypedDataV4( keccak256(abi.encode( keccak256("Action(address user,uint256 amount)"), user, amount )) ) require(ECDSA.recover(digest, signature) == signer, "Invalid signature")EIP-712 핵심 개념 정리 목적 사람이 읽을 수 있는 서명 메시지 제공 도메인에 귀속된 서명으로 리플레이 공격 저감 구조 타입화된 데이터 스키마와 도메인 분리자 타입 해시와 데이터 해시를 조합한 최종 해시 장점 지갑 UI에서 의미 있는 정보 노출로 UX 개선 다른 dApp이나 체인에서 재사용 어려움으로 보안 강화 주의사항과 팁 v4 사용 권장 v4는 가장 널리 지원되고 구조체 및 배열 표현이 안정적임 provider 요청 방식 web3 라이브러리 함수보다 ethereum.request의 eth_signTypedData_v4 사용이 호환성 측면에서 안전함 타입 정의 일치 컨트랙트와 클라이언트의 타입 이름, 필드 순서, 정수 크기 등 완전 일치 필요 도메인 정합성 chainId와 verifyingContract가 실제 네트워크와 배포 주소와 일치해야 검증 성공 데이터 인코딩 JS 측 정수값은 문자열 또는 BigNumber 형태 사용 권장, 오버플로와 반올림 이슈 회피 ethers 사용 시 types에 EIP712Domain을 포함하지 않음, _signTypedData가 도메인을 별도로 처리함 v4 메시지 포맷 params에 JSON.stringify로 { domain, types, message } 형태 전달 필요 마무리 signTypedData는 곧 EIP-712 사용을 의미하며 구조화된 데이터에 대한 안전한 서명을 가능하게 함 ethers의 _signTypedData 또는 지갑의 eth_signTypedData_v4를 사용해 서명하고, 컨트랙트에서는 동일한 도메인과 타입으로 해시를 재현해 검증하면 됨 명세 일치와 도메인 정합성만 확보하면 안전하고 예측 가능한 서명 흐름을 구현 가능 ...

December 20, 2025