diff --git a/week-04/quiz/quiz-04-solution.md b/week-04/quiz/quiz-04-solution.md
new file mode 100644
index 00000000..60d10788
--- /dev/null
+++ b/week-04/quiz/quiz-04-solution.md
@@ -0,0 +1,388 @@
+# Week 4 Quiz: Network/Block + wagmi
+
+> **제출 방법:** 이 파일을 복사하여 답변을 작성한 후, PR로 제출하세요.
+> **평가 기준:** 개념 이해도 중심 - 문법 오류보다 논리적 설명을 중시합니다.
+
+---
+
+## 문제 1: 블록 헤더 필드 (객관식)
+
+다음 상황을 고려하세요:
+
+```
+블록 100의 해시: 0xabc123...
+블록 101의 해시: 0xdef456...
+```
+
+블록 101의 `parentHash` 필드에는 어떤 값이 저장되어 있나요? 그리고 **왜** 이런 방식으로 연결하나요?
+
+**보기:**
+A) 0xdef456... - 자기 자신의 해시를 저장하여 무결성을 보장한다
+B) 0xabc123... - 이전 블록의 해시를 저장하여 체인 연결과 불변성을 보장한다
+C) 블록 번호 100 - 숫자로 순서를 추적한다
+D) 빈 값 - 헤더에는 해시가 저장되지 않는다
+
+**답변:**
+B) 블록 101의 parentHash에는 바로 이전 블록인 블록 100의 해시 `0xabc123...`이 저장됩니다. 이것이 "블록체인"이라 불리는 이유입니다 — 각 블록이 이전 블록의 해시를 참조하여 체인처럼 연결됩니다. A는 자기 자신의 해시를 저장하는 것으로, 해시는 블록 내용 전체로부터 계산되므로 자기 참조는 불가능합니다. C는 단순 번호로는 데이터 무결성을 보장할 수 없습니다. D는 사실이 아닙니다. parentHash를 통한 연결은 한 블록만 변조해도 그 뒤의 모든 블록 해시가 불일치하게 만들어, 변조를 즉시 감지할 수 있는 불변성의 핵심 메커니즘입니다.
+
+
+---
+
+## 문제 2: MPT 목적 (객관식)
+
+이더리움에서 Merkle Patricia Trie(MPT)를 사용하는 **가장 중요한 이유**는 무엇인가요?
+
+**보기:**
+A) 데이터를 암호화하여 외부에서 읽을 수 없게 한다
+B) 트랜잭션 처리 속도를 10배 이상 높인다
+C) 전체 데이터 없이도 특정 데이터의 존재와 정확성을 효율적으로 증명한다
+D) 블록 크기를 줄여서 저장 공간을 절약한다
+
+**답변:**
+C) MPT의 핵심 가치는 **효율적인 증명(proof)**입니다. Light Node는 블록 헤더의 Root Hash만 가지고 있어도, 전체 상태 데이터(수백 GB)를 다운로드하지 않고 특정 계정의 잔액이나 트랜잭션이 실제로 존재하는지 검증할 수 있습니다. Merkle Proof라는 짧은 경로 데이터만 있으면 Root Hash와 대조하여 데이터의 정확성을 수학적으로 입증할 수 있습니다. 이 덕분에 모바일 지갑이나 저사양 기기에서도 블록체인을 신뢰성 있게 사용할 수 있습니다. A는 틀렸습니다 — 블록체인 데이터는 공개됩니다.
+
+
+---
+
+## 문제 3: 체인 연결과 보안 (객관식)
+
+공격자가 블록 50의 트랜잭션을 수정하려고 합니다. 현재 체인의 최신 블록은 100입니다. 이 공격이 **왜** 어려운가요?
+
+**보기:**
+A) 블록 50은 너무 오래되어서 시스템에서 접근할 수 없다
+B) 블록 50을 수정하면 해시가 바뀌고, 블록 51부터 100까지 모든 블록의 parentHash가 불일치하게 된다
+C) 블록 50은 이미 암호화되어 있어서 복호화 키가 필요하다
+D) 네트워크 관리자만 과거 블록을 수정할 수 있다
+
+**답변:**
+B) 블록 50의 내용을 수정하면 블록 50의 해시가 변합니다. 그러면 블록 51의 parentHash가 더 이상 블록 50의 새 해시와 일치하지 않으므로, 블록 51도 수정해야 합니다. 블록 51을 수정하면 블록 51의 해시도 변하므로 블록 52도 수정해야 하고... 이렇게 블록 100까지 총 50개 블록을 모두 다시 계산해야 합니다. PoS에서는 이 모든 블록에 대해 검증자들의 서명을 위조해야 하므로, 전체 스테이킹의 2/3 이상을 장악하지 않는 한 사실상 불가능합니다. 이것이 블록체인의 불변성(immutability)이 작동하는 원리입니다.
+
+
+---
+
+## 문제 4: MPT 진화 과정 (단답형)
+
+MPT(Merkle Patricia Trie)는 세 가지 자료구조의 장점을 결합한 것입니다:
+1. **Trie** -> 2. **Patricia Trie** -> 3. **Merkle Patricia Trie**
+
+**왜** 각 단계의 발전이 필요했나요? 각 단계가 해결하는 문제를 간단히 설명하세요.
+
+**답변:**
+1. **Trie가 해결하는 문제:**
+ 키-값 데이터를 효율적으로 검색할 수 있는 트리 구조를 제공합니다. 키의 각 문자(이더리움에서는 hex nibble)가 트리의 한 레벨이 되어, 키를 따라가면 해당 값을 찾을 수 있습니다. 해시 테이블과 달리 순서가 보장되어 같은 데이터 집합은 항상 같은 트리 구조를 만듭니다.
+
+2. **Patricia Trie가 해결하는 문제 (Trie의 한계):**
+ 일반 Trie는 공통 접두사가 긴 키들이 많으면 빈 노드가 과도하게 생겨 공간 낭비가 심합니다. Patricia Trie는 공통 접두사를 하나의 노드로 **압축(path compression)**하여 공간 효율성을 크게 향상시킵니다. 이더리움 주소는 40자리 hex로 매우 길어서 이 압축이 필수적입니다.
+
+3. **Merkle Patricia Trie가 해결하는 문제 (Patricia Trie의 한계):**
+ Patricia Trie만으로는 데이터의 무결성을 검증할 수 없습니다. Merkle Tree의 해시 연결 방식을 결합하여, 루트 해시(Root Hash) 하나로 전체 트리의 무결성을 증명할 수 있게 됩니다. Light Node가 전체 데이터 없이도 특정 데이터의 존재를 효율적으로 검증(Merkle Proof)할 수 있습니다.
+
+
+---
+
+## 문제 5: Eclipse Attack 방어 (단답형)
+
+Eclipse Attack은 공격자가 피해자 노드의 **모든 피어 연결**을 자신이 통제하는 노드로 바꾸는 공격입니다.
+
+1) 이 공격이 성공하면 피해자에게 **어떤 피해**가 발생할 수 있나요?
+2) 개인 노드 운영자가 이 공격을 **방어**하기 위해 할 수 있는 행동은 무엇인가요?
+
+**답변:**
+1) 가능한 피해:
+ - **이중 지불 공격**: 공격자가 피해자에게 가짜 트랜잭션(이미 다른 곳에서 사용된 ETH)을 보여주고, 피해자는 이를 유효하다고 믿습니다.
+ - **검열**: 피해자의 트랜잭션을 네트워크에 전파하지 않거나, 특정 트랜잭션을 숨길 수 있습니다.
+ - **셀피시 마이닝 지원**: 공격자가 만든 블록만 보여주어 피해자의 해시파워를 공격자의 체인에 낭비하게 합니다.
+ - **잘못된 체인 정보**: 피해자가 실제 정규 체인이 아닌 공격자의 포크를 따르게 됩니다.
+
+2) 방어 방법:
+ - **신뢰할 수 있는 노드를 수동으로 피어 목록에 추가**: 알려진 부트노드나 신뢰할 수 있는 피어를 고정(static peer)으로 설정합니다.
+ - **다양한 네트워크 경로 사용**: 여러 ISP나 VPN을 통해 연결하여 단일 경로 차단을 방지합니다.
+ - **피어 연결 수 모니터링**: 비정상적으로 같은 IP 대역에서 많은 연결이 들어오면 의심합니다.
+ - **피어 다양성 제한 설정**: 같은 /24 서브넷에서 연결되는 피어 수를 제한하여 하나의 공격자가 모든 슬롯을 차지하지 못하게 합니다.
+
+
+---
+
+## 문제 6: 노드 종류 선택 (단답형)
+
+친구가 이더리움 개발을 시작하려고 합니다. 다음 세 가지 상황에서 각각 어떤 노드 타입(Full, Light, Archive)을 추천하시겠습니까? **왜** 그 노드를 추천하는지도 설명하세요.
+
+**답변:**
+1) 모바일 지갑 앱:
+ 추천 노드: **Light Node**
+ 이유: 모바일 기기는 저장 공간과 대역폭이 제한적입니다. Light Node는 블록 헤더만 저장하므로 몇 MB 수준이며, Merkle Proof를 통해 필요한 데이터를 검증합니다. 실시간 잔액 확인과 트랜잭션 전송에 충분합니다.
+
+2) 블록체인 데이터 분석 서비스:
+ 추천 노드: **Archive Node**
+ 이유: 데이터 분석에는 과거 모든 블록의 모든 상태(특정 블록 높이에서의 잔액, 컨트랙트 상태 등)가 필요합니다. Archive Node는 모든 역사적 상태를 보존하므로 "100번째 블록에서 이 계정의 잔액은?"같은 쿼리가 가능합니다. 수 TB의 저장 공간이 필요하지만 분석에는 필수입니다.
+
+3) 일반적인 dApp 백엔드:
+ 추천 노드: **Full Node**
+ 이유: dApp 백엔드는 현재 상태 조회, 트랜잭션 전송, 이벤트 모니터링 등이 주요 기능입니다. Full Node는 최신 상태와 최근 블록 데이터를 모두 보유하면서도 Archive Node보다 저장 공간이 적습니다(약 500GB~1TB). 과거 모든 상태가 필요 없다면 Full Node가 비용 대비 효율적입니다.
+
+
+---
+
+## 문제 7: useAccount Hook (빈칸 채우기)
+
+다음 코드의 빈칸을 채워서 지갑 연결 상태를 표시하는 컴포넌트를 완성하세요:
+
+```typescript
+import { _________________ } from 'wagmi';
+
+function WalletStatus() {
+ // TODO: useAccount hook에서 필요한 값들을 가져오세요
+ const { _________________, _________________ } = useAccount();
+
+ if (!isConnected) {
+ return
;
+}
+```
+
+**왜 이렇게 작성했나요:**
+`useReadContract`는 컨트랙트의 view/pure 함수를 호출하는 Hook입니다. 필수 설정:
+- `abi`: 컨트랙트의 ABI (Application Binary Interface). 함수의 이름, 파라미터, 반환 타입 등을 정의합니다. 이것이 있어야 wagmi가 올바른 함수 시그니처를 인코딩할 수 있습니다.
+- `functionName`: 호출할 함수 이름. ABI에 정의된 함수명과 일치해야 합니다.
+
+`data`를 표시할 때 `data?.toString()`을 사용하는 이유는, 컨트랙트에서 반환되는 uint256 값이 JavaScript의 `BigInt` 타입이기 때문입니다. BigInt는 직접 JSX에 렌더링할 수 없으므로 문자열로 변환해야 합니다. `?.`는 data가 undefined일 수 있으므로 옵셔널 체이닝을 사용합니다.
+
+
+---
+
+## 문제 9: useWriteContract 버그 (취약점 찾기)
+
+다음 코드에서 **문제점**을 찾고 수정하세요:
+
+```typescript
+// BAD CODE - 문제점 찾기
+import { useWriteContract } from 'wagmi';
+
+function IncrementButton() {
+ const { writeContract, isPending } = useWriteContract();
+
+ const handleClick = () => {
+ // 문제가 있는 코드
+ writeContract({
+ address: '0x1234...5678',
+ functionName: 'increment',
+ // abi가 없음!
+ });
+ };
+
+ return (
+
+ );
+}
+```
+
+**1) 발견한 문제점:**
+`writeContract` 호출에 `abi`가 빠져 있습니다. ABI는 wagmi에서 컨트랙트 함수를 호출할 때 필수 파라미터입니다.
+
+
+**2) 왜 이것이 문제인가:**
+ABI가 없으면 wagmi는 `increment` 함수의 시그니처(파라미터 타입, 반환 타입 등)를 알 수 없습니다. 함수를 호출하려면 함수 시그니처를 keccak256으로 해시하여 함수 셀렉터(4바이트)를 만들어야 하는데, ABI 없이는 이 과정이 불가능합니다. TypeScript 단계에서 타입 에러가 발생하거나, 런타임에서 인코딩 실패 에러가 발생합니다.
+
+
+**3) 올바른 수정 방법:**
+```typescript
+import { useWriteContract } from 'wagmi';
+
+const counterABI = [
+ {
+ name: 'increment',
+ type: 'function',
+ stateMutability: 'nonpayable',
+ inputs: [],
+ outputs: [],
+ },
+] as const;
+
+function IncrementButton() {
+ const { writeContract, isPending } = useWriteContract();
+
+ const handleClick = () => {
+ writeContract({
+ address: '0x1234...5678',
+ abi: counterABI,
+ functionName: 'increment',
+ });
+ };
+
+ return (
+
+ );
+}
+```
+
+---
+
+## 문제 10: 블록 연결 구조 (다이어그램 해석)
+
+```mermaid
+graph LR
+ subgraph B0["제네시스 블록"]
+ H0["hash: 0xabc..."]
+ end
+ subgraph B1["블록 1"]
+ PH1["parent: 0xabc..."]
+ H1["hash: 0xdef..."]
+ end
+ subgraph B2["블록 2"]
+ PH2["parent: 0xdef..."]
+ H2["hash: 0x123..."]
+ end
+ subgraph B3["블록 3"]
+ PH3["parent: ???"]
+ H3["hash: 0x789..."]
+ end
+
+ B0 --> B1 --> B2 --> B3
+```
+
+**질문:**
+
+1) 블록 3의 `parent: ???` 에 들어갈 값은 무엇인가요?
+
+**답변:** `0x123...` — 블록 2의 해시입니다. 각 블록의 parentHash는 바로 직전 블록의 해시를 참조합니다.
+
+
+2) 만약 블록 1의 내용이 수정되면, 블록 2와 블록 3에 **어떤 영향**이 있나요? 왜 그런가요?
+
+**답변:** 블록 1의 내용이 수정되면 블록 1의 해시(0xdef...)가 변합니다. 그러면 블록 2의 parentHash(0xdef...)가 더 이상 블록 1의 새 해시와 일치하지 않아 블록 2가 무효화됩니다. 블록 2를 수정하면 블록 2의 해시(0x123...)도 변하므로 블록 3의 parentHash와 불일치가 발생합니다. 결국 블록 1 이후의 모든 블록을 다시 계산해야 합니다. 이것이 블록체인이 과거 데이터 변조에 강한 이유입니다.
+
+
+3) 제네시스 블록(블록 0)의 parentHash는 어떤 특별한 값을 가지나요? 왜 그런가요?
+
+**답변:** 제네시스 블록의 parentHash는 `0x0000...0000` (64개의 0, 32바이트 영값)입니다. 제네시스 블록은 체인의 첫 번째 블록이므로 참조할 이전 블록이 존재하지 않습니다. 따라서 규약상 영(zero) 해시를 parentHash로 사용하여 "이전 블록이 없음"을 나타냅니다.
+
+
+---
+
+## 문제 11: MPT 트리 구조 (다이어그램 해석)
+
+```mermaid
+graph TD
+ ROOT["Root Hash: 0xfff..."] --> EXT1["Extension Node path: 0a"]
+ ROOT --> EXT2["Extension Node path: 0b"]
+
+ EXT1 --> BRANCH["Branch Node (16개 슬롯)"]
+ BRANCH --> LEAF1["Leaf: 계정 A 주소: 0a1234..."]
+ BRANCH --> LEAF2["Leaf: 계정 B 주소: 0a5678..."]
+
+ EXT2 --> LEAF3["Leaf: 계정 C 주소: 0b9999..."]
+```
+
+**질문:**
+
+1) 계정 A와 계정 B가 같은 Branch Node 아래에 있는 이유는 무엇인가요?
+
+**답변:** 계정 A(0a1234...)와 계정 B(0a5678...)는 주소의 앞부분 `0a`가 동일합니다. Extension Node가 공통 접두사 `0a`를 처리하고, 그 이후 분기가 필요한 시점(A는 `1`, B는 `5`)에서 Branch Node가 사용됩니다. Branch Node는 16개의 hex nibble(0-f) 슬롯을 가지며, A는 슬롯 `1`로, B는 슬롯 `5`로 분기합니다.
+
+
+2) Extension Node가 하는 역할은 무엇인가요? 없다면 어떤 문제가 생기나요?
+
+**답변:** Extension Node는 여러 키가 공유하는 공통 경로를 하나의 노드로 압축(path compression)합니다. Extension Node가 없다면, `0a`라는 2자리 경로를 표현하기 위해 2개의 Branch Node(첫째는 `0`, 둘째는 `a`)가 필요합니다. 이더리움 주소는 40자리 hex이므로 공통 접두사가 길 경우 수십 개의 불필요한 Branch Node가 생겨 트리의 깊이와 저장 공간이 크게 낭비됩니다. Extension Node 덕분에 트리가 훨씬 효율적으로 됩니다.
+
+
+3) Root Hash만 알면 어떻게 특정 계정의 데이터 존재를 **증명**할 수 있나요?
+
+**답변:** Light Client는 Full Node에게 특정 계정에 대한 **Merkle Proof**를 요청합니다. 이 Proof는 Root에서 해당 Leaf까지의 경로상 모든 노드의 해시값입니다. 예를 들어 계정 A를 증명하려면: Root Hash → Extension Node(0a) 해시 → Branch Node 해시 → Leaf A 해시 경로를 받습니다. Light Client는 Leaf A의 데이터를 해시하고, 경로를 따라 올라가면서 각 해시를 계산하여 최종적으로 Root Hash와 일치하는지 확인합니다. 일치하면 해당 데이터가 전체 상태 트리에 실제로 포함되어 있음이 수학적으로 증명됩니다. 전체 상태 데이터 없이 경로 데이터(수 KB)만으로 검증이 가능합니다.
+
+
+---
+
+## 제출 전 체크리스트
+
+- [x] 모든 문제에 답변을 작성했는가?
+- [x] 객관식 문제: 정답 선택 **이유**를 설명했는가?
+- [x] 단답형 문제: 2-3문장 이상으로 충분히 설명했는가?
+- [x] 코드 문제: 완성된 코드와 **왜 그렇게 작성했는지** 설명했는가?
+- [x] 다이어그램 문제: 각 질문에 논리적으로 답변했는가?