From 3fa3b219828d518da87c1cb0d8274cff100cacee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=B1=EC=9A=B0=ED=97=8C?= Date: Mon, 9 Feb 2026 18:28:37 +0900 Subject: [PATCH 1/4] feat(week-01): complete counter assignment --- week-01/dev/src/Counter.sol | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/week-01/dev/src/Counter.sol b/week-01/dev/src/Counter.sol index f9687e3..308226a 100644 --- a/week-01/dev/src/Counter.sol +++ b/week-01/dev/src/Counter.sol @@ -30,6 +30,7 @@ contract Counter { /// @notice 카운트를 1 증가시킵니다 /// @dev count 값을 1만큼 증가시키는 로직을 구현하세요 function increment() public { + count += 1; // TODO: count를 1 증가시키세요 // 힌트: count += 1; 또는 count = count + 1; 또는 count++; } @@ -37,6 +38,8 @@ contract Counter { /// @notice 카운트를 1 감소시킵니다 /// @dev count가 0일 때 감소시키면 언더플로우가 발생합니다 function decrement() public { + require(count > 0, "Count cannot go below zero"); + count -= 1; // TODO: count를 1 감소시키세요. 단, count가 0이면 revert해야 합니다. // 힌트: require(조건, "에러 메시지"); 를 사용하세요 // 힌트: require(count > 0, "Count cannot go below zero"); @@ -45,6 +48,7 @@ contract Counter { /// @notice 카운트를 0으로 초기화합니다 /// @dev count 값을 0으로 설정하는 로직을 구현하세요 function reset() public { + count = 0; // TODO: count를 0으로 초기화하세요 // 힌트: count = 0; } From 695e2d226093c31ab710b449c525cd4c34460211 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=B1=EC=9A=B0=ED=97=8C?= Date: Tue, 10 Feb 2026 10:09:36 +0900 Subject: [PATCH 2/4] feat(week-01): add theory quiz solutions --- week-01/theory/quiz-01-solution.md | 67 ++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 week-01/theory/quiz-01-solution.md diff --git a/week-01/theory/quiz-01-solution.md b/week-01/theory/quiz-01-solution.md new file mode 100644 index 0000000..c764692 --- /dev/null +++ b/week-01/theory/quiz-01-solution.md @@ -0,0 +1,67 @@ +# Week 1 이론 퀴즈 + +이 퀴즈를 복사하여 `quiz-01-solution.md`로 저장한 후 답변을 작성하세요. + +--- + +## 문제 1: 블록체인 기초 + +블록체인의 핵심 목적은 무엇인가요? 중앙화된 데이터베이스와 비교하여 설명해주세요. + +**답변:** +블록체인의 목적을 이해하기 위한 핵심은 분산 노드입니다. 중앙화된 데이터 베이스와 달리 전 세계의 분산된 노드에 정보를 저장하고 서로 검증을 하며 신뢰성을 형성하기에 +중앙의 제3자가 존재하지 않아도 됩니다. 이러한 탈중앙성을 통해 검열, 해킹, 조작을 방지하며 합의 과정을 통한 검증작업을 하기에 투명성을 보장받을 수 있습니다. + +--- + +## 문제 2: 이더리움의 특징 + +이더리움이 비트코인과 다른 점은 무엇인가요? 스마트 컨트랙트의 관점에서 설명해주세요. + +**답변:** +비트코인은 송금과 같은 가치 인전에 초첨이 맞춰져 있지만 이더리움은 송금 목적을 넘어 스마트 컨트랙트를 EVM을 통해 실행하여 DeFi, NFT, dApp과 같이 범용적입니다. + +--- + +## 문제 3: Solidity 기초 + +다음 Solidity 코드에서 `public`과 `view` 키워드의 의미를 각각 설명하세요. + +```solidity +function count() public view returns (uint256) { + return _count; +} +``` + +**답변:** +- `public`: public은 함수에 사용할 시 누구나 이 함수를 호출할 수 있으며 상태 변수에 사용시 자동으로 getter함수를 만들고 트랜잭션을 통해 상태를 바꿀 수 있게 해줍니다. +- `view`: view는 함수를 읽기 전용으로 만들어 주며 이 때문에 상태를 바꿀 수 없으며 가스가 소모되지 않습니다. + +--- + +## 문제 4: 상태 변수 + +Solidity에서 상태 변수(state variable)와 지역 변수(local variable)의 차이점을 설명하세요. + +**답변:** +상태 변수는 블록체인에 영구적으로 저장되는 변수로 함수 바깥에 존재하며 public으로 선언 될 시 자동으로 getter함수가 만들어집니다. 블록체인에 영구적으로 저장되기에 +가스비가 상대적으로 높습니다. 반면에 지역 변수는 함수 내부에서 선언되며 메모리에 임시적으로 저장되며 함수가 종료될 시 삭제가 됩니다. 그렇기에 가스비가 상태 변수에 +비해 상대적으로 낮습니다. + +--- + +## 문제 5: Gas 개념 + +이더리움에서 Gas란 무엇이며, 왜 필요한가요? + +**답변:** +이더리움에서 가스는 수수료의 역할을 합니다. 이더리움은 하나의 거대한 세계 컴퓨터를 분산된 노드에 실행을 합니다. 가스는 연산비용으로서 작용하여 무한 루프, 과도한 연산을 + 통해 네트워크에 대한 공격을 방지하며 또한 동시에 검증자에게 보상의 역할을 합니다. + +--- + +**제출 방법:** +1. 이 파일을 복사하여 `quiz-01-solution.md`로 저장 +2. 각 문제에 대한 답변 작성 +3. Git으로 커밋 및 푸시 +4. Pull Request 생성 From c3bf752b613fc0f171795c4105a9ea881a33223c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=B1=EC=9A=B0=ED=97=8C?= Date: Tue, 10 Feb 2026 11:47:25 +0900 Subject: [PATCH 3/4] feat(week-01): add quiz solutions --- week-01/quiz/quiz-01-solution.md | 285 +++++++++++++++++++++++++++++++ 1 file changed, 285 insertions(+) create mode 100644 week-01/quiz/quiz-01-solution.md diff --git a/week-01/quiz/quiz-01-solution.md b/week-01/quiz/quiz-01-solution.md new file mode 100644 index 0000000..34b284d --- /dev/null +++ b/week-01/quiz/quiz-01-solution.md @@ -0,0 +1,285 @@ +# Week 1 퀴즈: State/Account + Solidity 기초 + +**제출 방법:** +1. 이 파일을 복사하여 `quiz-01-solution.md`로 저장 +2. 각 문제에 답변 작성 (왜 그런지 설명 포함) +3. Pull Request 생성 (`quiz_submission` 템플릿 사용) + +**평가 기준:** +- 정답 여부보다 **개념 이해도**를 중점 평가합니다 +- "왜"에 대한 설명이 충분한지 확인합니다 +- 문법 오류는 크게 감점하지 않습니다 + +--- + +## 문제 1: [이론] 상태 머신 (객관식) + +이더리움에서 "상태 전이가 원자적(atomic)이다"라는 말의 의미를 가장 잘 설명한 것은? + +다음 상황을 고려하세요: + +``` +Alice가 Bob에게 1 ETH를 보내는 트랜잭션을 실행합니다. +중간에 가스가 부족해져서 트랜잭션이 실패했습니다. +``` + +**보기:** +A) Alice의 잔액만 감소하고 Bob의 잔액은 변하지 않는다 +B) Alice의 잔액과 Bob의 잔액 모두 변하지 않고, 가스비만 소모된다 +C) 네트워크가 자동으로 부족한 가스를 보충해서 트랜잭션을 완료한다 +D) 트랜잭션이 절반만 실행되어 0.5 ETH만 전송된다 + +**답변:** +B. 원자는 물리세계에서 더 이상 쪼갤 수 없는 최소 단위인 것 처럼 상태 전이가 원자적이라는 것은 과정이 쪼개지지 않음을 의미한다. 더 정확히 그 의미를 이해하면 상태를 +변화시키는 트랜잭션은 완전히 실행되거나 아니면 완전히 실행되지 않는다. 위의 상태를 살펴보면 중간에 가스가 부족해져 트랜잭션이 실패했기에 완전히 실행되지 않았어야 +한다. 그렇기에 정답은 B이다. + + +--- + +## 문제 2: [이론] 결정론적 실행 (객관식) + +이더리움 EVM이 "결정론적(deterministic)"으로 실행된다는 것의 핵심 이유는 무엇인가요? + +**보기:** +A) 모든 노드가 같은 하드웨어를 사용해야 해서 +B) 같은 입력(트랜잭션)이 주어지면 모든 노드가 같은 결과(상태)를 도출해야 하므로 +C) 중앙 서버가 모든 계산을 수행하고 결과를 배포해서 +D) 트랜잭션이 항상 1초 안에 처리되어야 해서 + +**답변:** +B. 이더리움은 분산된 노드들이 독립적으로 실행과 검증을 진행한다. 이때 같은 상태 S와 트랜잭션이 주어졌을 때 동일한 결과인 상태 S'가 보장되어야 하며 이러한 것을 +EVM이 결정론적으로 실행된다는 것의 핵심 이유이자 설명이다. 예시와 같이 노드 A와 B가 다른 결과를 얻는다면 독립된 노드 간의 합의는 불가능 할 것 이다. + + +--- + +## 문제 3: [이론] EOA vs CA (객관식) + +다음 중 EOA(Externally Owned Account)와 CA(Contract Account)의 차이를 올바르게 설명한 것은? + +**보기:** +A) EOA는 코드를 실행할 수 있고, CA는 코드를 실행할 수 없다 +B) EOA만 트랜잭션을 시작할 수 있고, CA는 EOA에 의해 호출될 때만 실행된다 +C) CA만 ETH를 보유할 수 있고, EOA는 ETH를 보유할 수 없다 +D) EOA와 CA는 동일한 기능을 가지며 이름만 다르다 +ㅍ +**답변:** +B. EOA는 개인키를 통해 트랜잭션을 생성, 서명할 수 있으며 Eth를 소유, 전송 할 수 있다. CA는 스마트 컨트랙트 계정으로 스스로 트랜잭션을 실행 할 수는 없고, EOA의 호출을 +통해 실행된다. + + +--- + +## 문제 4: [이론] 계정 상태 필드 (객관식) + +이더리움 계정 상태의 4가지 필드 중 `nonce`의 역할을 올바르게 설명한 것은? + +다음 상황을 고려하세요: + +``` +Alice의 현재 nonce: 5 +Alice가 두 개의 트랜잭션을 동시에 전송합니다: +- TX-A: nonce=5, Bob에게 1 ETH 전송 +- TX-B: nonce=5, Charlie에게 2 ETH 전송 +``` + +**보기:** +A) 두 트랜잭션 모두 성공적으로 처리된다 +B) TX-A만 처리되고 TX-B는 무시된다 (또는 그 반대) +C) 두 트랜잭션 모두 실패하고 Alice의 자산이 동결된다 +D) 네트워크가 자동으로 TX-B의 nonce를 6으로 변경한다 + +**답변:** +B. nonce는 일종의 변호표 역할을 하며 계정의 현재 nonce와 트랜잭션의 nonce가 다를 시 상태 전이를 막아 중복, 위조등을 방지한다. 현재 Alice의 nonce가 5이며 두개의 +트랜잭션 모두 nonce가 5라면 둘 중 하나의 트랜잭션만 처리되며 나머지 하나의 트랜잭션은 실패한다. + + +--- + +## 문제 5: [이론] World State (객관식) + +World State에 대한 설명 중 올바른 것은? + +**보기:** +A) World State는 최신 100개 블록의 트랜잭션만 저장한다 +B) World State는 모든 계정의 현재 상태(주소 -> 상태 매핑)를 나타낸다 +C) World State는 EOA의 정보만 저장하고 CA 정보는 별도로 관리한다 +D) World State는 각 노드마다 다른 값을 가질 수 있다 + +**답변:** +B. World State는 EOA, CA등 모든 현재 계정들의 상태를 의미한다. 즉 이더리움 네트워크에 존재하는 모든 계정의 주소를 키로 그 계정의 상태의 묶음이기에 일종의 거대한 +딕셔너리이자 전화번호부라고 볼 수 있다. + + +--- + +## 문제 6: [이론] 상태 변수 vs 지역 변수 (단답형) + +Solidity에서 `상태 변수(state variable)`와 `지역 변수(local variable)`의 차이는 무엇인가요? + +다음 코드를 보고 설명하세요: + +```solidity +contract Example { + uint256 public count; // 상태 변수 + + function calculate(uint256 input) public pure returns (uint256) { + uint256 result = input * 2; // 지역 변수 + return result; + } +} +``` + +**답변:** +상태 변수는 스토리지에 저장되며 트랜잭션이 종료되더라도 영구적으로 저장이되기에 가스비가 상대적으로 높다. 그러나 지역 변수는 함수 내부에서 선언 되어 함수가 실행될때 + 메모리에 임시적으로 저장되게에 트랜잭션이 종료되면 저장되지 않는다. 그렇기에 상태 변수에 비해 상대적으로 가스비가 낮다. + + +--- + +## 문제 7: [이론] 원자성의 이유 (단답형) + +이더리움에서 트랜잭션이 "원자적(atomic)"으로 처리되어야 하는 이유는 무엇인가요? + +**왜** 부분적으로 성공하는 트랜잭션을 허용하면 문제가 될까요? 구체적인 예시와 함께 설명하세요. + +**답변:** + + + +--- + +## 문제 8: [이론] 계정 구조 설명 (단답형) + +EOA에는 `codeHash`와 `storageRoot`가 왜 의미가 없나요? + +**답변:** +CA는 코드가 존재하지만 EOA는 코드를 저장하고 있지 않기에 codeHash가 빈 코드의 해쉬값이다. 마찬가지로 CA는 스마트 컨트랙트에 필요한 상태 정보인 스토리지 데이터가 +존재하지만 EOA는 스마트 컨트랙트가 존재하지 않기에 비어있다. + + +--- + +## 문제 9: [코드] Counter 읽기 (코드 읽기) + +다음 Counter.sol 코드를 분석하세요: + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + +contract Counter { + uint256 public count; + + function getCount() public view returns (uint256) { + return count; + } + + function increment() public { + count += 1; + } + + function decrement() public { + require(count > 0, "Count cannot go below zero"); + count -= 1; + } +} +``` + +**1) `public` 키워드의 역할:** +`count` 변수에 `public`이 붙으면 어떤 일이 자동으로 일어나나요? + +**답변:** +변수 count는 상태변수로 public을 통해 자동으로 getter함수가 생성되며 이러한 getter함수의 모습은 아래 getCount함수의 모습과 동일하다. + + +**2) `view` 키워드의 의미:** +`getCount()` 함수에 `view`가 붙은 이유는 무엇인가요? `view`를 제거하면 어떻게 될까요? + +**답변:** +view함수는 읽기 전용 함수로 블록체인의 상태를 변경하지 않고 읽기만을 수행함을 명시한다. 상태를 변경하지 않기에 가스를 소모하지 않는다. view를 제거하더라도 함수의 +동작이 변경되지는 않으나 의도가 명확해지지 않는다. + + +--- + +## 문제 10: [코드] Counter 동작 예측 (코드 읽기) + +위의 Counter 컨트랙트에서 다음 시나리오를 분석하세요: + +**시나리오:** +``` +초기 상태: count = 0 + +1. increment() 호출 +2. increment() 호출 +3. decrement() 호출 +4. decrement() 호출 +5. decrement() 호출 +``` + +**질문 1:** 5번째 `decrement()` 호출의 결과는 무엇인가요? + +**답변:** +"Count cannot go below zero" +decrement()는 count가 0보다 클 시 1을 감소시키는 데 4번째 decrement()때 count값이 0이 되었기에 위와 같이 호출 결과가 뜹니다. + +**질문 2:** 왜 `decrement()` 함수에 `require(count > 0, ...)` 조건이 필요한가요? + +**답변:** +개발 과제에서 위의 코드를 만들때 @dev에 의하면 count가 0이하일때 1만큼 감소를 시키면 언더플로우가 발생한다고 나와있다. 언더플로우란 변수가 가질 수 있는 최소값보다 +작은 값을 부여할 시 발생하는 오류이다. 상태 변수 count의 type이 uint256인데 uint256의 최소값은 0이기에 require()가 필요하다. + + +--- + +## 자기 평가 + +모든 문제를 풀었다면, 아래 체크리스트로 자기 평가를 해보세요: + +- [ o ] 상태 머신과 원자성 개념을 이해했다 +- [ o ] EOA와 CA의 차이를 설명할 수 있다 +- [ o ] 계정 상태의 4가지 필드(nonce, balance, storageRoot, codeHash)를 이해했다 +- [ o ] Solidity 기본 문법(public, view, require)을 이해했다 +- [ o ] 상태 변수와 지역 변수의 차이를 설명할 수 있다 + +--- + +## 참고 자료 + +- 이론: `eth-materials/week-01/theory/slides.md` +- 코드: `eth-homework/week-01/dev/src/Counter.sol` +- 용어: `eth-materials/resources/glossary.md` From d0aa81c33a60771a30c75c0e48ff66ae344235f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=B1=EC=9A=B0=ED=97=8C?= Date: Tue, 10 Feb 2026 15:57:06 +0900 Subject: [PATCH 4/4] chore(week-01) : remove TODO comments in Counter --- week-01/dev/src/Counter.sol | 8 -------- 1 file changed, 8 deletions(-) diff --git a/week-01/dev/src/Counter.sol b/week-01/dev/src/Counter.sol index 308226a..35a9a19 100644 --- a/week-01/dev/src/Counter.sol +++ b/week-01/dev/src/Counter.sol @@ -22,7 +22,6 @@ contract Counter { function getCount() public view returns (uint256) { return count; } - // ============================================================ // 쓰기 함수 (State-Changing Functions) // ============================================================ @@ -31,8 +30,6 @@ contract Counter { /// @dev count 값을 1만큼 증가시키는 로직을 구현하세요 function increment() public { count += 1; - // TODO: count를 1 증가시키세요 - // 힌트: count += 1; 또는 count = count + 1; 또는 count++; } /// @notice 카운트를 1 감소시킵니다 @@ -40,16 +37,11 @@ contract Counter { function decrement() public { require(count > 0, "Count cannot go below zero"); count -= 1; - // TODO: count를 1 감소시키세요. 단, count가 0이면 revert해야 합니다. - // 힌트: require(조건, "에러 메시지"); 를 사용하세요 - // 힌트: require(count > 0, "Count cannot go below zero"); } /// @notice 카운트를 0으로 초기화합니다 /// @dev count 값을 0으로 설정하는 로직을 구현하세요 function reset() public { count = 0; - // TODO: count를 0으로 초기화하세요 - // 힌트: count = 0; } }