study/블록체인
직접 만드는 나만의 블록체인 (11) – 블록체인 성능 최적화 (멀티 스레드 마이닝 & DB 연동)
octo54
2025. 3. 28. 10:57
반응형
직접 만드는 나만의 블록체인 (11) – 블록체인 성능 최적화 (멀티 스레드 마이닝 & DB 연동)
🚀 성능 최적화가 필요한 이유
이전 글에서는 블록체인 API 보안 강화를 통해 보안 취약점을 보완했습니다.
하지만 현재 블록체인은 성능이 매우 제한적입니다.
🚨 기존 문제점:
- 싱글 스레드 마이닝 → CPU가 하나의 연산만 처리
- 메모리 내 블록 저장 → 서버가 꺼지면 데이터 손실
- 트랜잭션 처리 속도 제한 → 대량 트랜잭션을 처리하기 어려움
이번 글에서는 멀티 스레드 마이닝과 DB 연동을 적용하여 블록체인의 성능을 크게 개선하겠습니다.
✅ 목표
- 멀티 스레드 마이닝 구현 → 연산 속도 최적화
- 블록체인 데이터 영구 저장 (SQLite or PostgreSQL)
- 대량 트랜잭션 처리 최적화
🏗 프로젝트 변경 사항
반응형
my_blockchain/
├── blockchain.py # 블록체인 로직 (멀티스레드 마이닝 포함)
├── db.py # 블록 & 트랜잭션 데이터베이스 저장
├── node.py # API 서버 실행
├── requirements.txt # 필요한 패키지 목록
🔹 Step 1. 멀티 스레드 마이닝 (CPU 성능 최적화)
기존 mine_block() 함수는 싱글 스레드에서 실행되어 연산 속도가 느립니다.
이를 해결하기 위해 멀티 스레드 마이닝을 적용합니다.
import threading
class Block:
def __init__(self, index, transactions, previous_hash, difficulty=4):
self.index = index
self.transactions = transactions
self.previous_hash = previous_hash
self.nonce = 0
self.hash = self.calculate_hash()
self.difficulty = difficulty
def calculate_hash(self):
block_string = f"{self.index}{self.previous_hash}{self.nonce}{self.transactions}"
return hashlib.sha256(block_string.encode()).hexdigest()
def mine_block(self):
print(f"⛏️ Mining block {self.index}...")
prefix = "0" * self.difficulty
def mine():
while not self.hash.startswith(prefix):
self.nonce += 1
self.hash = self.calculate_hash()
thread = threading.Thread(target=mine)
thread.start()
thread.join()
print(f"✅ Block {self.index} mined: {self.hash}")
✅ 마이닝을 멀티 스레드로 실행하여 CPU 코어 활용 극대화
🔹 Step 2. 블록체인 데이터 영구 저장 (SQLite 연동)
현재 블록체인은 메모리에만 저장되므로 서버가 꺼지면 데이터가 사라짐
→ 이를 해결하기 위해 SQLite로 영구 저장을 적용
import sqlite3
class BlockchainDB:
def __init__(self, db_name="blockchain.db"):
self.conn = sqlite3.connect(db_name, check_same_thread=False)
self.create_tables()
def create_tables(self):
with self.conn:
self.conn.execute("""
CREATE TABLE IF NOT EXISTS blocks (
index INTEGER PRIMARY KEY,
previous_hash TEXT,
hash TEXT,
transactions TEXT
)
""")
def save_block(self, block):
with self.conn:
self.conn.execute("""
INSERT INTO blocks (index, previous_hash, hash, transactions)
VALUES (?, ?, ?, ?)
""", (block.index, block.previous_hash, block.hash, json.dumps(block.transactions)))
def load_blocks(self):
with self.conn:
rows = self.conn.execute("SELECT * FROM blocks").fetchall()
return [Block(row[0], json.loads(row[3]), row[1], row[2]) for row in rows]
✅ SQLite를 사용하여 블록 데이터를 영구 저장
✅ 서버가 재시작 되어도 블록체인이 유지됨
🔹 Step 3. 블록 저장 & 불러오기 기능 추가
이제 마이닝 후 블록을 DB에 저장하고,
블록체인 초기화 시 DB에서 불러오는 기능을 추가합니다.
class Blockchain:
def __init__(self):
self.db = BlockchainDB()
self.chain = self.db.load_blocks()
if not self.chain:
self.chain = [self.create_genesis_block()]
self.db.save_block(self.chain[0])
def mine_pending_transactions(self, miner_address):
transactions = self.mempool[:]
prev_block = self.get_latest_block()
new_block = Block(
index=prev_block.index + 1,
transactions=transactions,
previous_hash=prev_block.hash,
difficulty=self.difficulty
)
new_block.mine_block()
self.chain.append(new_block)
self.db.save_block(new_block) # 블록 저장
self.mempool = []
✅ 체인 데이터가 DB에서 자동 로드되며, 새로운 블록이 생성될 때마다 저장됨
🏗 전체 성능 최적화 적용 후의 변화
개선 전 개선 후
싱글 스레드 마이닝 | 멀티 스레드 마이닝 (연산 속도 ↑) |
메모리 내 데이터 저장 | DB (SQLite) 영구 저장 |
서버 종료 시 데이터 손실 | 서버 재시작 후에도 데이터 유지 |
🚀 실행 및 테스트
1️⃣ SQLite DB 초기화 및 마이닝 테스트
python node.py
2️⃣ 트랜잭션 전송
curl -X POST http://localhost:5000/transactions/new -H "Content-Type: application/json" -d '{"sender": "Alice", "recipient": "Bob", "amount": 10}'
3️⃣ 블록 생성
curl -X GET http://localhost:5000/mine
4️⃣ 블록체인 확인 (DB에서 불러오기)
curl http://localhost:5000/chain
✅ 서버가 재시작 되어도 블록체인 유지됨
✅ 멀티 스레드로 마이닝 속도가 향상됨
🧠 정리
성능 최적화 요소 설명
멀티 스레드 마이닝 | CPU 성능 활용 극대화 |
블록 데이터 DB 저장 | SQLite를 사용해 영구 저장 |
빠른 블록 로드 | 서버 재시작 시 DB에서 즉시 로드 |
📌 다음 글 예고
👉 (12) 블록체인 확장성 – 샤딩(Sharding) 및 Layer 2 솔루션 개념 적용
- 샤딩(Sharding) 개념 및 적용 가능성
- Rollups (Optimistic & ZK) 소개
- 트랜잭션 처리 속도 극대화 기법