검색결과 리스트
글
파이썬으로 나만의 블록체인 만들기 #3
#참고 : 이 글은 @ecomusing 님의 포스트를 제 맘대로 번역한 글입니다. 원문보기
#참고2 : 전체 Jupyter / iPython 소스코드 받기
체인 유효성 검사
어떻게 새로운 블록들을 만들고 블록들이 체인 안으로 어떻게 서로 연결이 되는지 확인하였으니 이제 새로운 블록들이 유효한지, 더 나아가 전체 체인이 유효한지 확인하는 함수를 정의해보도록 합시다.
블록체인 네트워크에서 유효성 검사는 다음과 같은 두 가지 의미에서 중요합니다.
◆ 노드를 초기 설정할 떄, 전체 블록체인 히스토리를 다운로드 합니다. 체인의 다운로드 이후에는 시스템 상태 확인을 위해서 블록체인을 훓어보는 것이 필요합니다. 누군가가 유효하지 않은 거래내역을 체인 앞단에 삽입한는 것을 방지하지 위해서 이 초기 다운로드된 체인 전체에 대한 유효성 검사를 하는 것이 필요합니다.
◆ 노드가 네트워크와 동기화 되었을 때(최신의 블록체인 사본을 갖고 시스템이 준비된 상태), 네트워크에 브로드캐스트(broadcast)하여 새로운 블록들에 대한 유효성 검사를 하는 것이 필요합니다.
이 유효성 검사를 위해서 3가지 함수들이 필요합니다.
◆ checkBlockHash : 블록의 내용(contents)가 해쉬값과 동일한지 확인 시켜주는 간단한 helper function 입니다
◆ checkBlockValidity : 블록의 부모 및 현재 시스템 상태를 고려한 블록에 대한 유효성 검사를 합니다. 만약 블록이 유효하면 업데이트된 상태를 리턴하고, 유효하지 않으면 에러를 발생시킵니다.
◆ checkChain : 모든 체인에 대해서 유효성 검사를 하고 genesis block 을 포함한 시스템 상태에 대한 확인을 수행합니다. 만약 체인이 유요하다면 시스템 상태를 리턴해주고 그렇지 않으면 에러를 발생시킵니다.
def checkBlockHash(block):
# Raise an exception if the hash does not match the block contents
expectedHash = hashMe( block['contents'] )
if block['hash']!=expectedHash:
raise Exception('Hash does not match contents of block %s'%
block['contents']['blockNumber'])
return
def checkBlockValidity(block,parent,state):
# We want to check the following conditions:
# - Each of the transactions are valid updates to the system state
# - Block hash is valid for the block contents
# - Block number increments the parent block number by 1
# - Accurately references the parent block's hash
parentNumber = parent['contents']['blockNumber']
parentHash = parent['hash']
blockNumber = block['contents']['blockNumber']
# Check transaction validity; throw an error if an invalid transaction was found.
for txn in block['contents']['txns']:
if isValidTxn(txn,state):
state = updateState(txn,state)
else:
raise Exception('Invalid transaction in block %s: %s'%(blockNumber,txn))
checkBlockHash(block) # Check hash integrity; raises error if inaccurate
if blockNumber!=(parentNumber+1):
raise Exception('Hash does not match contents of block %s'%blockNumber)
if block['contents']['parentHash'] != parentHash:
raise Exception('Parent hash not accurate at block %s'%blockNumber)
return state
def checkChain(chain):
# Work through the chain from the genesis block (which gets special treatment),
# checking that all transactions are internally valid,
# that the transactions do not cause an overdraft,
# and that the blocks are linked by their hashes.
# This returns the state as a dictionary of accounts and balances,
# or returns False if an error was detected
## Data input processing: Make sure that our chain is a list of dicts
if type(chain)==str:
try:
chain = json.loads(chain)
assert( type(chain)==list)
except: # This is a catch-all, admittedly crude
return False
elif type(chain)!=list:
return False
state = {}
## Prime the pump by checking the genesis block
# We want to check the following conditions:
# - Each of the transactions are valid updates to the system state
# - Block hash is valid for the block contents
for txn in chain[0]['contents']['txns']:
state = updateState(txn,state)
checkBlockHash(chain[0])
parent = chain[0]
## Checking subsequent blocks: These additionally need to check
# - the reference to the parent block's hash
# - the validity of the block number
for block in chain[1:]:
state = checkBlockValidity(block,parent,state)
parent = block
return state
이제 유효성 검사를 해봅시다.
In [17]:
checkChain(chain)
비록 우리는 텍스트 파일(백업을 하거나 초기에 불러오는 작업에 쓰일 수 있는)에서 체인을 불러왔지만, 우리는 체인의 무결성을 확인할 수 있었고 현재 상태(거래 결과)를 확인할 수 있습니다.
chainAsText = json.dumps(chain,sort_keys=True)
checkChain(chainAsText)
'정보보안' 카테고리의 다른 글
파이썬으로 나만의 블록체인 만들기 #4 (0) | 2017.11.16 |
---|---|
파이썬으로 나만의 블록체인 만들기 #2 (0) | 2017.11.15 |
파이썬으로 나만의 블록체인 만들기 #1 (0) | 2017.11.14 |
OLE 파일 구조의 이해 (0) | 2012.09.11 |
정보보안? 정보보호? (0) | 2011.08.08 |