파이썬에서 간단하게 블록체인을 구현하는 예제 코드와 채굴
안녕하세요. 오늘은 파이썬으로 간단하게 블록체인을 구현하는 방법에 대해 상세하게 알려드리겠습니다. 블록체인이란? 분산된 데이터베이스로, 여러 참여자들이 공유하고 검증할 수 있는 연결된 블록들의 체인입니다. 각 블록은 이전 블록의 해시값, 트랜잭션 데이터, 타임스탬프 등의 정보를 포함하여 데이터의 무결성, 보안, 탈중앙화를 보장하며 비트코인, 이더리움 등의 암호화폐를 비롯하여 다양한 분야에서 활용될 수 있습니다.
블록체인 구현
파이썬은 간결하고 표현력이 뛰어난 프로그래밍 언어로 블록체인을 구현하기에 적합합니다. 구현하기 위해서는 다음과 같은 단계를 따릅니다.
블록 클래스 정의
블록체인 클래스 정의
트랜잭션 생성
새로운 블록 채굴
블록체인 유효성 검사
블록 클래스 정의
먼저 블록체인의 기본 단위인 블록을 표현하는 클래스를 정의해야 합니다. 블록 클래스는 다음과 같은 속성을 가집니다.
인덱스: 블록체인에서의 블록의 위치를 나타냅니다. 제네시스 블록(최초의 블록)의 인덱스는 0입니다.
타임스탬프: 블록이 생성된 시간을 나타냅니다. 유닉스 시간을 사용합니다.
트랜잭션: 블록에 포함된 트랜잭션의 목록입니다. 트랜잭션은 송신자, 수신자, 금액 등의 정보를 가집니다.
이전 해시: 이전 블록의 해시값을 나타냅니다. 이를 통해 연결성을 보장합니다.
논스: 블록의 해시값이 특정 조건을 만족하도록 하는 임의의 숫자입니다. 채굴 과정에서 사용됩니다.
블록 클래스는 다음과 같은 메서드를 가집니다.
해시 계산하기: 블록의 속성을 문자열로 변환하고, SHA-256 알고리즘을 사용하여 해시값을 계산합니다.
블록 검증하기: 블록의 해시값이 특정 조건을 만족하는지 확인합니다. 예를 들어 해시값의 앞부분에 0이 4개 이상 있는지 검사합니다.
아래는 블록 클래스를 정의하는 예제입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import hashlib
import time
class Block :
def __init__ ( self , index , transactions , previous_hash , nonce = 0 ) :
self . index = index # 블록의 인덱스
self . timestamp = time . time ( ) # 블록의 생성 시간
self . transactions = transactions # 블록의 트랜잭션 목록
self . previous_hash = previous _ hash # 이전 블록의 해시값
self . nonce = nonce # 블록의 논스
def compute_hash ( self ) :
# 블록의 속성을 문자열로 변환하고, SHA-256 알고리즘을 사용하여 해시값을 계산한다.
block_string = "{}{}{}{}{}" . format ( self . index , self . timestamp , self . transactions , self . previous_hash , self . nonce )
return hashlib . sha256 ( block_string . encode ( ) ) . hexdigest ( )
def validate_hash ( self , difficulty ) :
# 블록의 해시값이 특정 조건을 만족하는지 확인한다.
# 예를 들어 difficulty가 4라면, 해시값의 앞부분에 0이 4개 이상 있는지 검사한다.
return self . compute_hash ( ) . startswith ( "0" * difficulty )
블록체인 클래스 정의
다음으로 블록들을 연결하여 블록체인을 표현하는 클래스를 정의해야 합니다. 다음과 같은 속성을 가집니다.
체인: 블록의 목록을 나타냅니다. 제네시스 블록을 포함합니다.
난이도: 블록의 해시값이 만족해야 하는 조건의 난이도를 나타냅니다. 난이도가 높을수록 채굴하기 어렵습니다.
보상: 새로운 블록을 채굴한 참여자에게 주어지는 보상의 금액을 나타냅니다.
보류중인 트랜잭션: 아직 블록에 포함되지 않은 트랜잭션의 목록을 나타냅니다.
블록체인 클래스는 다음과 같은 메서드를 가집니다.
제네시스 블록 생성하기: 최초의 블록을 생성하고, 체인에 추가합니다. 제네시스 블록은 특별한 블록으로, 이전 해시값이 없고, 트랜잭션도 없습니다.
새로운 트랜잭션 생성하기: 보류중인 트랜잭션 목록에 새로운 트랜잭션을 추가합니다. 트랜잭션은 송신자, 수신자, 금액 등의 정보를 가집니다.
새로운 블록 채굴하기: 보류중인 트랜잭션들을 블록에 포함시키고, 블록의 해시값이 난이도 조건을 만족하도록 논스를 조정합니다. 채굴에 성공한 블록을 체인에 추가하고, 보류중인 트랜잭션 목록을 비웁니다. 채굴한 참여자에게 보상을 주기 위해, 새로운 트랜잭션을 생성합니다.
유효성 검사하기: 블록체인의 모든 블록이 해시값과 이전 해시값이 일치하고 난이도 조건을 만족하는지 확인합니다. 또한 블록체인의 길이가 가장 긴 것인지 확인합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
class Blockchain :
def __init__ ( self , difficulty = 4 , reward = 10 ) :
self . chain = [ ] # 블록의 목록
self . difficulty = difficulty # 블록의 해시값이 만족해야 하는 조건의 난이도
self . reward = reward # 새로운 블록을 채굴한 참여자에게 주어지는 보상의 금액
self . pending_transactions = [ ] # 아직 블록에 포함되지 않은 트랜잭션의 목록
self . create_genesis_block ( ) # 제네시스 블록을 생성하고 체인에 추가한다.
def create_genesis_block ( self ) :
# 제네시스 블록은 특별한 블록으로, 인덱스가 0이고, 이전 해시값이 없고, 트랜잭션도 없다.
genesis_block = Block ( 0 , [ ] , "0" )
self . chain . append ( genesis_block )
def create_new_transaction ( self , sender , receiver , amount ) :
# 보류중인 트랜잭션 목록에 새로운 트랜잭션을 추가한다.
# 트랜잭션은 송신자, 수신자, 금액 등의 정보를 가진다.
transaction = {
"sender" : sender ,
"receiver" : receiver ,
"amount" : amount
}
self . pending_transactions . append ( transaction )
def mine_new_block ( self , miner ) :
# 보류중인 트랜잭션들을 블록에 포함시키고, 블록의 해시값이 난이도 조건을 만족하도록 논스를 조정한다.
# 채굴에 성공한 블록을 체인에 추가하고, 보류중인 트랜잭션 목록을 비운다.
# 채굴한 참여자에게 보상을 주기 위해, 새로운 트랜잭션을 생성한다.
last_block = self . chain [ - 1 ] # 체인의 마지막 블록을 가져온다.
new_index = last_block . index + 1 # 새로운 블록의 인덱스를 계산한다.
new_timestamp = time . time ( ) # 새로운 블록의 생성 시간을 가져온다.
new_transactions = self . pending _ transactions # 보류중인 트랜잭션들을 가져온다.
new_previous_hash = last_block . compute_hash ( ) # 이전 블록의 해시값을 계산한다.
new_nonce = 0 # 새로운 블록의 논스를 초기화한다.
new_block = Block ( new_index , new_transactions , new_previous_hash , new_nonce ) # 새로운 블록을 생성한다.
while not new_block . validate_hash ( self . difficulty ) : # 블록의 해시값이 난이도 조건을 만족할 때까지 반복한다.
new_nonce += 1 # 논스를 1씩 증가시킨다.
new_block . nonce = new _ nonce # 블록의 논스를 업데이트한다.
self . chain . append ( new_block ) # 채굴에 성공한 블록을 체인에 추가한다.
self . pending_transactions = [ ] # 보류중인 트랜잭션 목록을 비운다.
self . create_new_transaction ( "0" , miner , self . reward ) # 채굴한 참여자에게 보상을 주는 트랜잭션을 생성한다.
def validate_chain ( self ) :
# 모든 블록이 해시값과 이전 해시값이 일치하는지, 난이도 조건을 만족하는지 확인하고
# 블록체인의 길이가 가장 긴 것인지 확인한다.
for i in range ( 1 , len ( self . chain ) ) : # 체인의 두 번째 블록부터 순회한다.
current_block = self . chain [ i ] # 현재 블록을 가져온다.
previous_block = self . chain [ i - 1 ] # 이전 블록을 가져온다.
if current_block . previous_hash != previous_block . compute_hash ( ) : # 현재 블록의 이전 해시값과 이전 블록의 해시값이 일치하지 않으면
return False # 유효하지 않음
if not current_block . validate_hash ( self . difficulty ) : # 현재 블록의 해시값이 난이도 조건을 만족하지 않으면
return False # 유효하지 않음
return True # 유효함
트랜잭션 생성
블록체인에서는 거래가 발생할 때마다 트랜잭션을 생성해야 합니다. 트랜잭션은 송신자, 수신자, 거래 금액 등의 정보를 포함하고 있습니다. 이 정보들은 블록에 저장되어 전체 네트워크에 공유됩니다.
blockchain = Blockchain ( )
# 새로운 트랜잭션 생성
blockchain . create_new_transaction ( "Alice" , "Bob" , 10 )
blockchain . create_new_transaction ( "Bob" , "Charlie" , 5 )
새로운 블록 채굴
새로운 블록을 추가하기 위해서는 블록을 채굴해야 합니다. 블록을 채굴하는 과정은 이전 블록의 해시값을 포함하고, 난이도에 맞는 새로운 해시값을 계산하는 것입니다.
# 블록 채굴
miner = "Miner1"
blockchain . mine_new_block ( miner )
블록체인 유효성 검사
블록체인에서는 모든 블록이 유효한지 확인해야 합니다. 이는 블록의 해시값과 이전 해시값이 일치하고, 난이도에 맞는 해시값을 가지고 있는지 확인하는 것을 의미합니다.
# 유효성 검사
is_valid = blockchain . validate_chain ( )
if is_valid :
print ( "Blockchain is valid." )
else :
print ( "Blockchain is not valid." )
이렇게 파이썬을 사용하여 간단한 블록체인을 구현할 수 있습니다. 블록체인은 여러 분야에서 활용되며 이를 구현함으로써 기술에 대한 이해를 높일 수 있습니다. 여기서 더 복잡한 기능들을 추가하면 실제 앱도 만들 수 있으니 코드를 한 줄 씩 읽어보면서 이해해보시면 좋을 것 같습니다. 다른 개발 정보를 보시려면 블로그 메인 도 방문해주세요. 감사합니다.