파이썬 블록 체인 구현 | 비트코인 채굴의 원리를 파이썬으로 구현해보자! 150 개의 베스트 답변

당신은 주제를 찾고 있습니까 “파이썬 블록 체인 구현 – 비트코인 채굴의 원리를 파이썬으로 구현해보자!“? 다음 카테고리의 웹사이트 you.tfvp.org 에서 귀하의 모든 질문에 답변해 드립니다: https://you.tfvp.org/blog/. 바로 아래에서 답을 찾을 수 있습니다. 작성자 빵형의 개발도상국 이(가) 작성한 기사에는 조회수 70,300회 및 좋아요 1,203개 개의 좋아요가 있습니다.

파이썬 블록 체인 구현 주제에 대한 동영상 보기

여기에서 이 주제에 대한 비디오를 시청하십시오. 주의 깊게 살펴보고 읽고 있는 내용에 대한 피드백을 제공하세요!

d여기에서 비트코인 채굴의 원리를 파이썬으로 구현해보자! – 파이썬 블록 체인 구현 주제에 대한 세부정보를 참조하세요

* 빵형처럼 되고 싶은 사람들을 위한 가장 쉽게 배우는 머신러닝 강의: http://bit.ly/mlbasic6
블록체인의 개념을 간단하게 알아보고 비트코인 채굴의 원리를 파이썬 코드 30줄로 간단하게 구현해보겠습니다!
Source code(Github): https://github.com/kairess/bitcoin-mining-wonri
Dependency:
– Python 3
비트코인 설명: http://tcpschool.com/webbasic/bitcoin
Bitcoin explorer: https://www.blockchain.com/explorer?view=btc
SHA-256 설명: http://wiki.hash.kr/index.php/SHA256
Chapters:
00:00 Intro
00:15 블록체인 설명
01:32 SHA-256
03:20 코드 설명
06:14 코드 실행
06:48 실제 채굴의 경우
07:20 Outro
사업 및 개발문의: [email protected]
빵형의 개발도상국 후원: https://toon.at/donate/helloworld

파이썬 블록 체인 구현 주제에 대한 자세한 내용은 여기를 참조하세요.

파이썬으로 간단한 블록체인 만들기 – Kaden Sungbin Cho

블록체인은 블록이라고 불리는 것들이 암호기법을 통해 체인처럼 연결된 것 … 이번 글에서는 파이썬으로 구현된 간단한(100줄 이내 ^^) 블록체인을 …

+ 더 읽기

Source: kadensungbincho.tistory.com

Date Published: 12/9/2021

View: 7729

파이썬(python)으로 만드는 간단한 블록 체인(block chain)

까지만 이해할 수 있게 아주 가볍게 만들어 보겠습니다. (네트워킹 쪽은 pass). 블록체인이 암호화폐에서만 쓰이는 게 아니라 유통 과정을 기록하는 등에 …

+ 더 읽기

Source: comdoc.tistory.com

Date Published: 6/11/2021

View: 9226

파이썬으로 블록체인 만들기 Part 1 – Medium

채굴은 추후에 더 얘기하도록 하자. 추가로 ‘genesis block’ 을 만드는 것 이외로, new_block() , new_transaction() , hash() 을 구현하려고 …

+ 더 읽기

Source: medium.com

Date Published: 7/2/2021

View: 2743

[python] 파이썬 블록 체인 시작 – BelieveCom

[python] 파이썬 블록 체인 시작 … 블록체인(Blockchain)은 거래 기록이 담긴 블록이 … 파이썬(python)으로 간단하게 구현이 가능하기 때문에.

+ 여기에 표시

Source: believecom.tistory.com

Date Published: 11/16/2022

View: 7616

[Python] 블록체인 원리 및 구현

[Python] 블록체인 원리 및 구현. by Edward Park. July 5, 2021. in Python. Block Chain. 사전 용어 정리. Block Chain. 말 그대로 데이터(Block)을 연결(Chain)한것 …

+ 여기에 보기

Source: parkeunsang.github.io

Date Published: 7/26/2022

View: 2355

Python으로 비트코인 구현하기 – 초코쨔응 – Tistory

Block 체인에 필요한 필수 함수는 다음과 같습니다. init 함수; new block 생성 함수; new transaction 생성 함수; hash 함수; last_block (이전 블록).

+ 여기를 클릭

Source: computer-choco.tistory.com

Date Published: 6/26/2021

View: 2371

파이썬으로 간단한 블록체인 구현해보기

Step 1 : Building a Blockchain · 1. 블록체인 기본 구조 · 2. 블록의 기본 구조 · 3. 블록에 새로운 트랜잭션 추가 · 4. 새로운 블록 만들기 · 6. PoW 구현.

+ 더 읽기

Source: coding-moomin.tistory.com

Date Published: 4/2/2021

View: 2050

[블록체인] 파이썬으로 블록체인을 구현해보자 – 1 (블록생성 …

블록체인에서 가장 최초의 블록인 genesis block을 생성해야 합니다. import hashlib import json from time import time Blockchain …

+ 여기에 표시

Source: blog.naver.com

Date Published: 3/28/2021

View: 2059

파이썬 Python 블록 체인 개발 입문 – 미국 실리콘밸리 현역 …

Facebook의 가상통화 Libra, Amazon, Microsoft, IBM 등으로 인해 다시 블록 체인 기술이 각광 받고 있습니다. IoT, 의료, 부동산의 분야에서도 기대받고 있는 차세대 …

+ 더 읽기

Source: www.udemy.com

Date Published: 6/13/2021

View: 9356

python으로 간단한 블록체인 만들기 (1) – Steemit

블록체인의 가장 기초적인 기능인 블록을 만들고 생성된 블록들을 체인으로 연결하는 법을 구현해보겠습니다. … 간단하게 블록체인을 python으로 구현해봤습니다.

+ 여기에 보기

Source: steemit.com

Date Published: 12/15/2022

View: 6486

주제와 관련된 이미지 파이썬 블록 체인 구현

주제와 관련된 더 많은 사진을 참조하십시오 비트코인 채굴의 원리를 파이썬으로 구현해보자!. 댓글에서 더 많은 관련 이미지를 보거나 필요한 경우 더 많은 관련 기사를 볼 수 있습니다.

비트코인 채굴의 원리를 파이썬으로 구현해보자!
비트코인 채굴의 원리를 파이썬으로 구현해보자!

주제에 대한 기사 평가 파이썬 블록 체인 구현

  • Author: 빵형의 개발도상국
  • Views: 조회수 70,300회
  • Likes: 좋아요 1,203개
  • Date Published: 2021. 2. 7.
  • Video Url link: https://www.youtube.com/watch?v=JM3j7uBKnt8

파이썬으로 간단한 블록체인 만들기

반응형

블록체인은 블록이라고 불리는 것들이 암호기법을 통해 체인처럼 연결된 것 [1]을 말합니다.

흔히 아래와 같은 형태로 표현되는데요:

Abstract blockchain – Image from Author

위의 정의에서 ‘암호기법을 통해 연결된다’와 같은 부분들은 실제로 간단한 블록체인을 만들어보면 복잡한 설명이 필요없이 쉽게 이해가 됩니다. 이번 글에서는 파이썬으로 구현된 간단한(100줄 이내 ^^) 블록체인을 살펴보면서, 블록체인의 일반적인 구조를 알아보겠습니다:

블록체인 클래스 구조

flask를 이용해 api로 제공하기

블록체인 클래스 구조

먼저, Blockchain이라는 클래스는 아래와 같은 생성자로 만들어 볼 수 있습니다:

import datetime import hashlib import json class Blockchain: def __init__(self): self.chain = [] self.create_block(proof = 1, previous_hash = ‘0’) def create_block(self, proof, previous_hash): block = { ‘index’: len(self.chain) + 1, ‘timestamp’: str(datetime.datetime.now()), ‘proof’: proof, ‘previous_hash’: previous_hash } self.chain.append(block) return block

chain이라는 인스턴스 변수에 리스트가 할당되고, create_block 메소드를 호출합니다. create_block은 json으로 구조화된 block을 생성하고 chain이라는 인스턴스 변수에 append 해주고 block을 리턴합니다. 생성자 __init__ 안에서 호출되는 self.create_block은 가장 처음 블록인 제네시스(genesis) 블록을 생성해주기 위해 proof = 1, previous_hash = ‘0’이라는 아규먼트를 사용합니다.

추가적으로 Block 클래스에는 아래와 같은 get_previous_block, proof_of_work, hash라는 메소드를 가집니다:

def get_previous_block(self): return self.chain[-1] def proof_of_work(self, previous_proof): new_proof = 1 check_proof = False while check_proof is False: hash_operation = hashlib.sha256(str(new_proof**2 – previous_proof**2).encode()).hexdigest() if hash_operation.startswith(‘0000’): check_proof = True else: new_proof += 1 return new_proof def hash(self, block): encoded_block = json.dumps(block, sort_keys = True).encode() return hashlib.sha256(encoded_block).hexdigest()

각각 아래와 같은 기능을 수행하는데요:

get_previous_block: chain 리스트에 있는 가장 마지막 블록을 리턴

proof_of_work: 이전 proof 값을 받고 previous_proof와의 연산 해시 값이 특정 조건을 만족하는 new_proof를 찾아 리턴함

hash: 딕셔너리 형태의 block을 받아서 json으로 dump하고 인코딩하여 해시값을 얻어 리턴함

위와 같은 클래스를 통해서 아래와 같이 블록을 채굴(mine)할 수 있습니다:

blockchain = Blockchain() previous_block = blockchain.get_previous_block() previous_proof = previous_block[‘proof’] proof = blockchain.proof_of_work(previous_proof) previous_hash = blockchain.hash(previous_block) block = blockchain.create_block(proof, previous_hash) print(blockchain.chain) #output [{‘index’: 1, ‘timestamp’: ‘2021-12-14 17:21:13.498696’, ‘proof’: 1, ‘previous_hash’: ‘0’}, {‘index’: 2, ‘timestamp’: ‘2021-12-14 17:21:13.500686’, ‘proof’: 533, ‘previous_hash’: ‘4fb3563bc622a0e4b3fea0f8c5b3eedd975e3d2f76825eedcb2bc7fbbf7163a8’}]

위의 상태를 이미지로 표현하면, 2개의 블록이 아래와 같은 형태로 연결되어 있다는 사실을 알 수 있습니다:

2 Blocks in a chain – Image from Author

이러한 블록체인이 규칙에 맞게 생성되어 있는지 확인하기 위해서는 아래의 is_valid_chain과 같은 메소드를 추가할 수 있습니다:

def is_valid_chain(self, chain): previous_block = chain[0] block_index = 1 while block_index < len(chain): block = chain[block_index] if block['previous_hash'] != self.hash(previous_block): return False previous_proof = previous_block['proof'] proof = block['proof'] hash_operation = hashlib.sha256(str(proof**2 - previous_proof**2).encode()).hexdigest() if not hash_operation.startswith('0000'): return False previous_block = block block_index += 1 return True 검증 방식은 genesis block의 다음 블록부터 마지막 블록까지 previous_hash 값이 이전 블록의 hash값과 동일한지 proof값이 previous_proof 값과 연산 후 해시 값 계산 시 특정 조건('0000'으로 시작)을 만족하는지 체크합니다. flask를 이용해 api로 제공하기 flask를 이용해 위에서 만든 간단한 블록체인을 API로 제공할 수 있습니다. from flask import Flask, jsonify app = Flask(__name__) app.config['JSONIFY_PRETTYPRINT_REGULAR'] = False blockchain = Blockchain() @app.route('/mine_block', methods = ['GET']) def mine_block(): previous_block = blockchain.get_previoous_block() previous_proof = previous_block['proof'] proof = blockchain.proof_of_work(previous_proof) previous_hash = blockchain.hash(previous_block) block = blockchain.create_block(proof, previous_hash) responses = { 'message': 'Congratulations, you just mined a block!', **block } return jsonify(responses), 200 @app.route('/get_chain', methods = ['GET']) def get_chain(): response = { 'chain': blockchain.chain, 'length': len(blockchain.chain) } return jsonify(response), 200 app.run(host = '0.0.0.0', port = 6000) 이후 Block 클래스와 flask API로 구성된 파일을 실행하고 Postman으로 호출하여 확인해 볼 수 있습니다. GET /mine_block - Image from Author GET /get_chain - Image from Author 최종 코드 [2] #!/usr/bin/env python3 # -*- coding: utf-8 -*- import datetime import hashlib import json from flask import Flask, jsonify class Blockchain: def __init__(self): self.chain = [] self.create_block(proof = 1, previous_hash = '0') def create_block(self, proof, previous_hash): block = { 'index': len(self.chain) + 1, 'timestamp': str(datetime.datetime.now()), 'proof': proof, 'previous_hash': previous_hash } self.chain.append(block) return block def get_previous_block(self): return self.chain[-1] def proof_of_work(self, previous_proof): new_proof = 1 check_proof = False while check_proof is False: hash_operation = hashlib.sha256(str(new_proof**2 - previous_proof**2).encode()).hexdigest() if hash_operation.startswith('0000'): check_proof = True else: new_proof += 1 return new_proof def hash(self, block): encoded_block = json.dumps(block, sort_keys = True).encode() return hashlib.sha256(encoded_block).hexdigest() def is_valid_chain(self, chain): previous_block = chain[0] block_index = 1 while block_index < len(chain): block = chain[block_index] if block['previous_hash'] != self.hash(previous_block): return False previous_proof = previous_block['proof'] proof = block['proof'] hash_operation = hashlib.sha256(str(proof**2 - previous_proof**2).encode()).hexdigest() if not hash_operation.startswith('0000'): return False previous_block = block block_index += 1 return True app = Flask(__name__) app.config['JSONIFY_PRETTYPRINT_REGULAR'] = False blockchain = Blockchain() @app.route('/mine_block', methods = ['GET']) def mine_block(): previous_block = blockchain.get_previous_block() previous_proof = previous_block['proof'] proof = blockchain.proof_of_work(previous_proof) previous_hash = blockchain.hash(previous_block) block = blockchain.create_block(proof, previous_hash) responses = { 'message': 'Congratulations, you just mined a block!', **block } return jsonify(responses), 200 @app.route('/get_chain', methods = ['GET']) def get_chain(): response = { 'chain': blockchain.chain, 'length': len(blockchain.chain) } return jsonify(response), 200 app.run(host = '0.0.0.0', port = 5000) Reference [1] https://en.wikipedia.org/wiki/Blockchain [2] https://www.udemy.com/course/build-your-blockchain-az/ 반응형

파이썬(python)으로 만드는 간단한 블록 체인(block chain)

반응형

제 블로그에서 가장 인기 있는 글이 해시더군요.

해시가 나온 김에 간단한 블록체인을 만들어 보겠습니다.

‘블록체인의 의미’,

‘블록체인이 어떻게 데이터의 보안을 유지하나’

까지만 이해할 수 있게 아주 가볍게 만들어 보겠습니다.

(네트워킹 쪽은 pass)

블록체인이 암호화폐에서만 쓰이는 게 아니라

유통 과정을 기록하는 등에도 사용되니까

위 두 개념만 알아도 꽤 써먹을 데가 많습니다.

선수학습:

파이썬 해시 라이브러리

import hashlib h = hashlib.sha256() h.update(b’Genesis’) print(h.hexdigest())

81ddc8d248b2dccdd3fdd5e84f0cad62b08f2d10b57f9a831c13451e5c5c80a5

파이썬 해시 라이브러리의 사용법을 알아야겠습니다.

직관적이라 어렵지 않습니다만, 다음에 주의하세요.

update()에 문자열을 넣을 수 없다. bytes 만 가능. m.update(b”abc”)와 m.update(b” def”)를 하면, m.update(b”abc def”)와 같다.

genesis는 기원이라는 뜻입니다.

블록체인의 기초

해시를 해시하자

블록체인은 해시를 해시하는 것부터 이해하면 될 것 같습니다.

from hashlib import sha256 prev_hash = b’Genesis’ for _ in range(3): print(prev_hash.hex()) prev_hash = sha256(prev_hash).digest() print(prev_hash.hex())

update를 쓰지 않고 줄였습니다. 깔끔하군요.

동적 타입 언어에 익숙해져 있다가…

bytes를 다루는 건 좀 헷갈리는 일입니다.

type()로 확인해가면서 처리합시다.

47656e65736973 81ddc8d248b2dccdd3fdd5e84f0cad62b08f2d10b57f9a831c13451e5c5c80a5 408ebd7408dda81b20d6d0c3d3664d15536bb3ea17d0e8baa0022011c3c590da dfa6ca742b4a970b543ad95f6a743e7dee8381eda9e29ceb08c91d45e06c4b79

이런 식으로 해시를 나열하면

해시의 특성 때문에

중간의 해시값을 하나라도 조작하면

그 뒤로는 해시값들이 줄줄이 산으로 갑니다.

이 원리를 보안에 이용하는 것이 블록체인입니다.

블록을 만들자.

단순히 해시값을 해시해서는 별 의미가 없습니다.

여기에 데이터를 넣어야 의미가 있겠죠?

데이터와 이전 해시값을 합친 값을

해시함수에 넣어서 새 해시를 만듭시다.

연결 리스트(Linked List)와 자료구조가 유사합니다.

이 경우에도 ‘해시를 해시하자’의 결론과 같이

중간의 ‘데이터’나 ‘해시값’을 조작하면

그 뒤의 해시값들은

줄줄이 산으로 간다는 것을 알 수 있습니다.

데이터와, 이전 해시값, 새 해시값을 합친 것을

‘블록’이라고 합시다.

* 일반적으론 다수의 거래내역을 묶어서 블록을 구성합니다.

* 블록의 index나 시간 기록 등은 간략히 코딩하기 위해 생략했습니다.

특수한 블록 제네시스

블록체인의 처음에는 이전 해시값이 없는

특수한 블록이 있습니다.

보통 genesis 블록 등으로 이름 짓습니다.

블록체인이란…

이 블록들을 체인처럼 모은 것을

‘블록체인’이라고 합시다.

일반적으로 블록체인이란

체인처럼 연결한 뒤,

네트워크 상의 노드들에 ‘분산 저장’하는 것까지를 의미합니다만,

간단한 코딩을 위하여… 네트워크는 pass

블록을 검증하자.

마지막으로 검증이 있습니다.

검증은

0. ‘현 블록의 이전 해시값’과 ‘이전 블록의 현 해시값’ 비교

1. 이전 블록의 해시값 재확인

2. 현 블록의 해시값 재확인

으로 이루어집니다.

from hashlib import sha256 blockchain = [] def make_genesis_block(): “””첫 블록을 만듭니다””” data = ‘Genesis’ prev_hash = b” current_hash = make_hash(data, prev_hash) blockchain.append((data, prev_hash, current_hash)) def make_hash(data: str, prev_hash: bytes) -> bytes: “””해시를 만듭니다.””” # 코드 한 줄이지만, 여기 저기 쓰이니 함수로 분리하는 게 좋습니다. # bytes형은 str형이랑 왔다 갔다 헷갈리는 경우가 있어서. # 파라미터 뒤에 타입을 기록해 두면 편하더군요. return sha256(data.encode() + prev_hash).digest() def add_block(data: str): “””블록을 블록 체인에 추가합니다.””” _, _, prev_hash = blockchain[-1] current_hash = make_hash(data, prev_hash) blockchain.append((data, prev_hash, current_hash)) def show_blockchain(): “””블록 체인을 보여줍니다.””” # 해시값을 bytes형으로 저장했기 때문에 # hex()로 16진수 str로 변환해야 print 시 읽기 좋습니다. for i, (data, prev_hash, current_hash) in enumerate(blockchain): print(f’블록 {i}

{data}

{prev_hash.hex()}

{current_hash.hex()}’) def verify_blockchain(): “””블록 체인을 검증합니다.””” for i in range(1, len(blockchain)): data, prev_hash, current_hash = blockchain[i] last_data, last_prev_hash, last_current_hash = blockchain[i – 1] # 변수명이 뭐 같습니다. 코딩보다 작명이 더 어려운 것 같습니다. if prev_hash != last_current_hash: # 1. 현 블록의 이전 해시 값과 # 이전 블록의 현재 해시 값이 일치하는 지 확인합니다. print(f”블록 {i} 이전 해시 != 블록 {i – 1} 현 해시.

” f”{prev_hash.hex()} !=

{last_current_hash.hex()}”) return False if last_current_hash != (temp := make_hash(last_data, last_prev_hash)): # 2. 이전 블록을 해시 함수로 검증합니다. # 이 부분이 없으면 genesis 블록의 검증이 안됩니다. print(f”블록 {i – 1} 검증 실패.

” f”{last_current_hash.hex()} !=

{temp.hex()}”) return False if current_hash != (temp := make_hash(data, prev_hash)): # 3. 현 블록을 해시 함수로 검증합니다. print(f”블록 {i}, 검증 실패.

” f”{current_hash.hex()} !=

{temp.hex()}”) return False # print(f'[Block {i}: {blockchain[i][0]}] has been verified.’) return True make_genesis_block() add_block(‘나는미남이다’) add_block(‘진짜미남이다’) add_block(‘아님말고’) show_blockchain() print() print(verify_blockchain())

블록 0 Genesis 81ddc8d248b2dccdd3fdd5e84f0cad62b08f2d10b57f9a831c13451e5c5c80a5 블록 1 나는미남이다 81ddc8d248b2dccdd3fdd5e84f0cad62b08f2d10b57f9a831c13451e5c5c80a5 40405b3990f4fa49832a9b268aaf7001ac0c389e099958bba121c44eb5deeabd 블록 2 진짜미남이다 40405b3990f4fa49832a9b268aaf7001ac0c389e099958bba121c44eb5deeabd 33901bb3c92fed28f2e08d4872caf30b48f60b518c6603834931eea560178498 블록 3 아님말고 33901bb3c92fed28f2e08d4872caf30b48f60b518c6603834931eea560178498 7bb2fca9e4724c28cf9ddc42efc72240009239bcb66a7c0d67b04c5679a356cf True

블록 1을 조작합시다.

# Block 1번을 조작합시다. blockchain[1] = (‘너는미남이아니다’, blockchain[0][2], make_hash(‘너는미남이아니다’, blockchain[0][2])) show_blockchain() print() print(verify_blockchain())

블록 0 Genesis 81ddc8d248b2dccdd3fdd5e84f0cad62b08f2d10b57f9a831c13451e5c5c80a5 블록 1 너는미남이아니다 81ddc8d248b2dccdd3fdd5e84f0cad62b08f2d10b57f9a831c13451e5c5c80a5 2dd22979b6a370836be47cab599c021452d499af99b71e6d5ab2eac0747a2403 블록 2 진짜미남이다 40405b3990f4fa49832a9b268aaf7001ac0c389e099958bba121c44eb5deeabd 33901bb3c92fed28f2e08d4872caf30b48f60b518c6603834931eea560178498 블록 3 아님말고 33901bb3c92fed28f2e08d4872caf30b48f60b518c6603834931eea560178498 7bb2fca9e4724c28cf9ddc42efc72240009239bcb66a7c0d67b04c5679a356cf 블록 2 이전 해시 != 블록 1 현 해시. 40405b3990f4fa49832a9b268aaf7001ac0c389e099958bba121c44eb5deeabd != 2dd22979b6a370836be47cab599c021452d499af99b71e6d5ab2eac0747a2403 False

지금까지 코딩한 것을 보면,

블록체인은 유통 과정 등을 기록하는데 적당한 구조라는 걸 알 수 있습니다.

유통과정, 시간 등을 블록체인에 기록하면 중간 과정을 고칠 수가 없습니다.

하지만 전체나, 특정 단계 이후를 모두 조작하는 식의 조작은 가능하고,

따라서 추가적인 장치가 필요함을 알 수 있습니다.

PoW (Proof of Works, 작업 증명)

이제 그 추가적인 장치 중 핵심인 POW (Proof Of Works)를 살펴봅시다.

POW란 우리가 블록을 만들 때 마지막으로 해싱을 하는데요.

이때 해싱이 어렵도록 하는 장치입니다.

어떻게(how) 어렵게 만들까요?

how와 why를 중심으로 생각하면 좋습니다.

특정 조건의 해시값을 찾습니다.

00으로 시작하는 해시값을 찾아라….

0의 개수가 늘어날수록

해시 값 찾기가 어렵겠죠?

난이도(0의 개수)도 블록에 추가됩니다.

검증을 위해 다시 해시를 검산할 때 0의 개수가 필요합니다.

블록에만 난이도를 기록하는 건 ‘해킹해주세요’라는 것 과 같습니다.

쉬운 난이도로 긴 위조 체인을 만들어서 뿌릴 수 있기 때문입니다.

하지만 간단히 코딩하기 위해.. 여기까지만..

그런데 이런 의문이 생깁니다.

데이터와 이전 해시값이 고정되어 묶여있고,

이 고정된 값에 대한 해시값은 역시 하나로 고정되어 있는데..

어떻게(how) 특정 조건의 해시값을 찾으란 말이지?

(하나의 데이터에 대한 해시값은 오직 하나입니다.)

그래서 블록에 nonce라는 항목이 추가됩니다.

nonce 값을 바꿔가면서 엄청나게 해싱을 반복해서

00…으로 시작하는 해시값을 찾는 거죠.

찾으면 나 찾았다. (심봤다)

데이터에 nonce값 xxxxxxxx을 추가해서 해싱을 하니까..

00…으로 시작하는 해시 값이 나왔다..

너네들 확인해봐..

(네트워킹 쪽은 코딩하지 않습니다만…)

라고 주위 노드에게 뿌립니다.

주위 노드들은 데이터에 nonce 값을 추가한 뒤 해싱해서

00으로 시작되는 지 확인합니다.

검증은 한 번에 끝납니다.

nonce와 hash를 비교할 때 편하도록

hash의 자료형을 bytes에서 str로 바꿨습니다.

digest()에서 hexdigest()로…

add_block함수명을 add_normal_block으로 바꾸고 교통정리도 했습니다.

전역 변수도 생기고 코드가 조금 지저분해졌네요.

클래스의 필요가 느껴집니다.

from hashlib import sha256 blockchain = [] difficulty = 4 def add_genesis_block(): “””첫 블록을 만들고, 블록 체인에 추가합니다””” data = ‘Genesis’ prev_hash = ” nonce, current_hash = make_hash(data, prev_hash, difficulty) add_block(data, prev_hash, difficulty, nonce, current_hash) def make_hash(data: str, prev_hash: str, difficulty_: int) -> (int, str): “””해시를 만듭니다. PoW””” new_hash = ‘ ‘ * difficulty_ checker = ‘0’ * difficulty_ nonce = 0 while new_hash[:difficulty_] != checker: new_hash = sha256((data + str(nonce) + prev_hash).encode()).hexdigest() nonce += 1 return nonce, new_hash def add_block(data, prev_hash, difficulty_, nonce, current_hash): “””실제로 블록을 추가합니다.””” # 한 줄이라고 두 함수의 공통 부분을 방치했더니 # 기능 추가시 양쪽을 다 수정해야만 했습니다. # 단순한 복붙에도 실수를 할 수 있습니다. # 공통 부분은 최대한 모아야 합니다. blockchain.append((data, prev_hash, difficulty_, nonce, current_hash)) def add_normal_block(data: str): “””일반 블록을 만들고, 블록 체인에 추가합니다.””” _, _, _, _, prev_hash = blockchain[-1] nonce, current_hash = make_hash(data, prev_hash, difficulty) add_block(data, prev_hash, difficulty, nonce, current_hash) def show_blockchain(): “””블록 체인을 보여줍니다.””” for i, (data, prev_hash, difficulty_, nonce, current_hash) in enumerate(blockchain): print(f’블록 {i}

‘ f'{data}, {difficulty_}, {nonce}

‘ f'{prev_hash}

‘ f'{current_hash}’) def verify_blockchain(): “””블록 체인을 검증합니다.””” for i in range(1, len(blockchain)): data, prev_hash, difficulty_, nonce, current_hash = blockchain[i] last_data, last_prev_hash, last_difficulty, last_nonce, last_current_hash \ = blockchain[i – 1] if prev_hash != last_current_hash: print(f”[블록 {i}] 이전 해시 != [블록 {i – 1}] 현 해시.

” f”{prev_hash} !=

{last_current_hash}”) return False if (last_nonce, last_current_hash) != \ (temp := make_hash(last_data, last_prev_hash, last_difficulty)): show_verify_failed(i – 1, last_nonce, last_current_hash, temp[0], temp[1]) return False if (nonce, current_hash) != (temp := make_hash(data, prev_hash, difficulty_)): show_verify_failed(i, nonce, current_hash, temp[0], temp[1]) return False return True def show_verify_failed(block_num, ori_nonce, ori_hash, new_nonce, new_hash): print(f”블록 {block_num} 검증 실패.

” f”{ori_nonce} != {new_nonce}

” f”{ori_hash} !=

{new_hash}”) add_genesis_block() add_normal_block(‘나는미남이다’) add_normal_block(‘진짜미남이다’) add_normal_block(‘아님말고’) show_blockchain() print() print(verify_blockchain())

블록 0 Genesis, 4, 100816 00000551fb3e39f4f36d2121a6043c71999059f733ab13561539ebfe57f85961 블록 1 나는미남이다, 4, 21340 00000551fb3e39f4f36d2121a6043c71999059f733ab13561539ebfe57f85961 0000f818c1e5d987dbced40a9e40f1095248635e90cac77eba0e7332d8e85a44 블록 2 진짜미남이다, 4, 25151 0000f818c1e5d987dbced40a9e40f1095248635e90cac77eba0e7332d8e85a44 00002cfa10b49be7eb01dfe8623b4a1566284c4fb8835d62b1f7bcbf05f2be60 블록 3 아님말고, 4, 5344 00002cfa10b49be7eb01dfe8623b4a1566284c4fb8835d62b1f7bcbf05f2be60 0000093cfe16f29477622e7621b4cc18f38a46d43f0d0300a8f0b7effa6e5259 True

blockchain[1] = (‘너는미남이아니다’, blockchain[0][4], blockchain[0][2], *make_hash(‘너는미남이아니다’, blockchain[0][4], blockchain[0][2])) show_blockchain() print() print(verify_blockchain())

블록 0 Genesis, 4, 100816 00000551fb3e39f4f36d2121a6043c71999059f733ab13561539ebfe57f85961 블록 1 너는미남이아니다, 4, 11661 00000551fb3e39f4f36d2121a6043c71999059f733ab13561539ebfe57f85961 00003bfc5c576c53bc0d753912967ac737304bd60cf05d9be82c2a4d0d354e1f 블록 2 진짜미남이다, 4, 25151 0000f818c1e5d987dbced40a9e40f1095248635e90cac77eba0e7332d8e85a44 00002cfa10b49be7eb01dfe8623b4a1566284c4fb8835d62b1f7bcbf05f2be60 블록 3 아님말고, 4, 5344 00002cfa10b49be7eb01dfe8623b4a1566284c4fb8835d62b1f7bcbf05f2be60 0000093cfe16f29477622e7621b4cc18f38a46d43f0d0300a8f0b7effa6e5259 [블록 2] 이전 해시 != [블록 1] 현 해시. 0000f818c1e5d987dbced40a9e40f1095248635e90cac77eba0e7332d8e85a44 != 00003bfc5c576c53bc0d753912967ac737304bd60cf05d9be82c2a4d0d354e1f False

PoW의 Why

PoW(작업증명)의 how는 필요한 만큼은 알려드린 것 같습니다.

그런데 why를 알려드리진 않은 것 같네요.

코딩도 끝나고 머리도 가벼워지셨을 테니 다시 채워보겠습니다.

PoW의 역사부터..

1992년 (~1993년) 심시아 더크(Cynthia Dwork)와 모니 나노어(Moni Naor)이 작업 증명의 기본 개념을 고안했다.

http://www.wisdom.weizmann.ac.il/~naor/PAPERS/pvp.pdf

1997년 최초로 아담 백(Adam Back)이 해시캐시에 적용했다.

해시캐시(hashcash)는 대량 스팸메일을 막기 위해 개발한 암호화폐이다.

http://hashcash.org

1999년 마커스 제이콥슨(Markus_Jakobsson)과 아리 쥬엘스(Ari Juels)에 의해 Proof of Work라는 명칭이 붙었다.

2009년 사토시 나카모토 비트코인(bitcoin)에 적용

http://wiki.hash.kr/index.php/%EC%9E%91%EC%97%85%EC%A6%9D%EB%AA%85

가끔 Bitcoin 창시자인 Satoshi Nakamoto가 PoW의 창시자라는 말을 하시는 분들도 계신데, 그건 좀…..

해시캐시의 원리

해시캐시가 어떤 원리로 작동되는지는 다음 링크에 자세히 나와 있습니다.

https://www.joinc.co.kr/w/man/12/blockChain/hashcash

메일을 보내기 위해서는 아주 많은 연산을 해야 하고,

메일을 확인하기 위해서는 약간의 연산이 필요할 뿐이다.

즉 보내는 쪽이 대부분의 비용(=연산)을 책임진다.

스팸 메일을 보내기 위해 스팸으로 벌 수 있는 돈보다

큰 비용을 들여 연산을 하지 않을 것이다.

3자가 개입하지 않는 검증 시스템이라는 데 큰 의미가 있다.

생각보다 간단한 원리네요….

PoW의 단점

단점이 먼저 나오는 게 순서상 이상합니다만…

절반 이상의 해시 파워 를 가지게 된다면 블록 내용의 조작이 가능합니다.

를 가지게 된다면 블록 내용의 조작이 가능합니다. 긴 체인이 올바른 것으로 판단 합니다. 체인이 버려지는 경우 트랜잭션이 무효가 될 수 있습니다.

(이를 방지하기 위한 장치도 존재합니다만…)

합니다. 체인이 버려지는 경우 트랜잭션이 무효가 될 수 있습니다. (이를 방지하기 위한 장치도 존재합니다만…) 합의를 통해 신뢰성을 확인 하기 때문에, 정보의 확산 및 합의에 걸리는 시간이 필요 합니다.

필요 이상의 많은 자원(전력)을 소모 합니다.

블록의 생성 과정

블록은 거래내역과 이전 해시값을 합쳐서 거래 기록들을 전달받는다.

특정 숫자를 찾아서 블록을 생성한다.

생성한 블록을 블록체인에 추가하고 전달하여 새롭게 채굴된 비트코인을 보상으로 받는다.

https://brunch.co.kr/@ashhan/16

https://steemit.com/kr/@feyee95/4-1 http://wiki.hash.kr/index.php/%EB%B8%94%EB%A1%9D%EC%83%9D%EC%84%B1%EC%9E%90

블록을 위조하려면…

위에서 가장 긴 블록체인이 진짜라고 말씀드렸습니다.

짧은 걸 진짜라고는 할 수는 없으니…

빡센 연산은 위조 시에도 똑같이 적용이 됩니다.

본인을 제외한 전 세계 비트코인 노드들의 해시파워의 총합보다

더 큰 해시 파워(보통 초당 해시 생성수 =연산력)를 가지고 있다면,

더 긴 가짜 블록체인을 만들어 공격을 할 수 있습니다.

비트코인의 위조가능성

현실적으로 불가능합니다.

16년에 100경 해시였었는데요..

m.blog.naver.com/softmate1/220609722117

19년 8월에 비트코인 네트워크의 총 해시는 초당 7143경이었다고 합니다.

https://www.coindeskkorea.com/news/articleView.html?idxno=53404

점점 늘어나죠..

18년 기준으로 4조 정도의 금액이 들어간다고 하네요.

medium.com/@woohyuk.jung88

알트코인의 51% 공격 사례

하지만 해시 파워가 약한 알트 코인계에서는 꽤 많은 공격 성공사례가 있습니다.

버지, 모나코인, 비트코인골드, 젠캐시, 이더리움 클래식

wiki.hash.kr/index.php/51%25_%EA%B3%B5%EA%B2%A9#51.25_.EA.B3.B5.EA.B2.A9_.EC.82.AC.EB.A1.80

‘초대형’ 코인에서 하드포크를 한 알트코인 ‘신생’이 있다고 합시다.

‘신생’ 코인은 ‘초대형’ 코인에서 하드포크를 했으니까 ‘초대형’코인과 똑같은 방식으로 작동합니다.

그렇다면 ‘초대형’ 코인 채굴기의 설정을 조금만 바꾸면 새로운 ‘신생’ 코인을 채굴할 수 있겠죠?

그런데 ‘초대형’ 코인의 해시파워에 비해서 ‘신생’ 코인의 해시파워는 아주 약할겁니다.

이 때 ‘초대형’ 코인 채굴기의 소유자가

본인의 해시파워가 ‘신생’ 코인의 절반보다 크고

‘신생’ 코인을 해킹했을 때의 이익이

‘초대형’ 코인의 빡빡한 채굴 환경에서의 이익보다 큰 상황이 되면………

기타

비잔티움(비잔틴) 장군 문제도 같이 봐주면 좋습니다.

이런 영상도 좋습니다. youtu.be/bBC-nXj3Ng4

반응형

[python] 파이썬 블록 체인 시작

블록체인(Blockchain)은 거래 기록이 담긴 블록이

체인처럼 서로 연결되어 있는 구조를 말합니다.

요즘 많은 사람들이 암호화폐에 대해서 관심 있어서

블록체인(Blockchain)은 더욱더 인기가 높아지고 있습니다.

오늘은 파이썬(python)을 사용해서 간단한

블록체인(Blockchain)을 만들어보겠습니다.

먼저 블록체인(Blockchain) 특징을 알아보겠습니다.

블록체인은 3가지 특징이 있습니다.

첫 번째 특징 분산화

블록체인에 저장된 모든 정보가 전체

네트워크의 한 단위로 동작합니다.

중앙 집중식 권한이 없이 모든 노드 간의

정보 공유가 가능합니다.

두 번째 특징 불변성

블록체인의 모든 데이터는 추가 적용됩니다.

데이터를 삭제하지 않으며

과거에 무언가를 수정하려면

새로운 주석 데이터를 추가해야 합니다.

세 번째 특징 분산 원장

블록체인은 공개 또는 비공개가 가능합니다.

하지만 특정 누구에게 속하는 것이

아닌 그룹에만 속합니다.

[Python] 블록체인 원리 및 구현

Block Chain

사전 용어 정리

Block Chain

말 그대로 데이터(Block)을 연결(Chain)한것

구조체를 링크드리스트로 연결하는것과 유사

Hash

임의의 크기를 가진 데이터(Key)를 고정된 크기의 데이터(Value)로 변화시켜 저장하는 것

출력값으로 입력값을 예측할 수 없는것, 같은내용을 입력값으로 주면 결과값은 항상 같다.

Key가 정수일때 m으로 나눈 나머지를 Value로 취하는 것도 해시 함수라고 할 수 있다(Value의 충돌이 잦으므로 좋은 해시함수라고는 할 수 없음).

해시함수 종류: HAS-160, SHA-1, SHA-256 등

Block Chain 구현

Block의 구성요소

이전 블록의 해시값 현재 블록에서 저장할 정보 Nonce

Chain 구현

시작 블록(Genesis Block) 설정 이전 블록의 해시값과 현재 블록의 데이터를 해시함수에 넣어 다음 블록의 해시값을 구하는것을 반복

출처 : https://www.stechstar.com/user/zbxe/AlgorithmPython/59573

Nonce의 역할/작업 증명

단순히 이전 해시값을 해시함수에 넣어 계속 해시를 구하는 과정은 간단하기 때문에 블록들의 연결을 구현하기가 너무 쉬움(O(n))

-> 이전 블록의 해시값 끝에 데이터를 추가하고, nonce(0이상의 정수)를 추가해 만들어진 해시값의 처음 n개의 값이 0이 되게(0000ed268b…)하는 가장 작은 nonce값 채택 // 이를 작업 증명(Proof of Work)라고 함

Code

Genesis Block을 포함한 10개의 Block Chain 만들기

import hashlib class Block: def __init__(self, data, prevhash, n): self.data = data self.prevhash = prevhash self.n = n # 앞에 0이 몇개 나오는지 def get_hash(self): nonce = 0 if self.prevhash == None: # 시작 블록 self.nonce = 0 self.hash = hashlib.sha256(self.data.encode()).hexdigest() return 0 pad = ‘0’ * self.n while True: hash = self.prevhash + str(self.data) + str(nonce) hash = hashlib.sha256(hash.encode()).hexdigest() if hash.startswith(pad): self.nonce = nonce self.hash = hash break nonce += 1 return 0 def block_chain_printer(block_chain): for block in block_chain: print(f’nonce:{block.nonce}’) print(f’data:{block.data}’) print(f’prevhash:{block.prevhash}’) print(f’hash:{block.hash}’) print() GenesisBlock = Block(‘Genesis Block’, None, 4) GenesisBlock.get_hash() block_chain = [GenesisBlock] for i in range(10): prior_block = block_chain[-1] NextBlock = Block(i+1, prior_block.hash, 4) NextBlock.get_hash() block_chain.append(NextBlock) block_chain_printer(block_chain)

결과

Genesis Block이후 모든 블록에 대해 hash값의 맨처음 4자리는 0이다. Nonce가 5이상이 되면 10개의 블록을 만드는데도 적지 않은 시간이 걸린다.

Block Chain의 장점

데이터 변경이 어렵다 – 중간 블록의 데이터를 변경한다면 이후의 블록들에 대해 다시 nonce를 다 계산해줘야하므로

초코쨔응의 데스크탑 초코쨔응의 데스크탑

반응형

Python으로 비트코인 구현하기

본 게시물은 유튜브 강의 ❝[블록집착남] 블록체인, 제가 직접 만들어 보겠습니다 (상)❞ 를 기반으로 학습한 내용입니다.

강의에 사용된 원본 소스코드는 여기를 확인하시면 되고, 본 게시물에 작성된 제 소스코드는 여기를 확인하시면 됩니다.

강의에서는 python 2.x 를 사용하였으나, 제 코드는 python 3.7을 기반으로 작성하였습니다.

Python으로 진행하기 때문에 초심자에게 적합한 학습 코스입니다.

Blockchain 필수 함수

Block 체인에 필요한 필수 함수는 다음과 같습니다.

init 함수

new block 생성 함수

new transaction 생성 함수

hash 함수

last_block (이전 블록)

따라서 blockchain.py 파일을 만들고, 각 함수들의 간단한 원형을 만들어주고 시작하였습니다.

class Blockchain(object): def __init__(self): self.chain = [] self.current_transactions = [] def new_block(self): # Creates a new Block and adds it to the chain pass def new_transaction(self): # Adds a new transaction to the list of transaction pass @staticmethod def hash(block): # Hashes a Block pass @property def last_block(self): # Returns the last Block in the chain pass

Block 들에는 다음과 같은 정보가 들어가게 됩니다.

index: 몇 번째 블록인지

Timestamp: 언제 블록이 생성되었는지

Transaction: 거래 목록

Proof: 마이닝의 결과

Prev_hash: 블록의 무결성을 검증하기 위한 것

이제 각 함수들을 구현해봅니다. 위에서 소개한 필수 함수 외에 검증에 사용되는 pow 함수와 valid proof 함수를 추가로 구현하였습니다. (skip 하고 바로 아래 blockchain.py 전체 소스코드를 훑어보셔도 됩니다)

init 함수: 클래스의 생성자. Block이 만들어지면 가장 먼저 실행되는 함수입니다. 이 함수에서 하는 동작은 다음과 같습니다. chain 연결 임시 transaction 저장 genesis block 생성 def __init__(self): self.chain = [] # chain에 여러 block들 들어옴 self.current_transaction = [] # 임시 transaction 넣어줌 # genesis block 생성 self.new_block(previous_hash=1, proof=100)​

new block 생성 함수이며, 이 함수에서 하는 동작은 다음과 같습니다. block 구조 생성 chain에 생성된 block 추가 def new_block(self, proof, previous_hash=None): # Creates a new Block and adds it to the chain block = { ‘index’ : len(self.chain)+1, ‘timestamp’ : time(), # timestamp from 1970 ‘transactions’ : self.current_transaction, ‘proof’ : proof, ‘previous_hash’ : previous_hash or self.hash(self.chain[-1]), } self.current_transaction = [] self.chain.append(block) return block​

new transaction 함수이며, 이 함수에서 하는 동작은 다음과 같습니다. 새 transaction 생성하고 연결 def new_transaction(self, sender, recipient, amount): # Adds a new transaction to the list of transaction self.current_transaction.append( { ‘sender’ : sender, # 송신자 ‘recipient’ : recipient, # 수신자 ‘amount’ : amount # 금액 } ) return self.last_block[‘index’] + 1​

hash 함수이며, 이 함수에서는 hash 변환을 하게 됩니다. 이미 존재하는 sha256 라이브러리를 사용하면 된다 @staticmethod def hash(block): # Hashes a Block block_string = json.dumps(block, sort_keys=True).encode() # hash 라이브러리로 sha256 사용 return hashlib.sha256(block_string).hexdigest()​

pow 함수이며, 이 함수에서 하는 동작은 다음과 같습니다. valid_proof 함수를 통해 맞을 때까지 반복적으로 검증하면서 proof 증가하다가 찾으면 proof 번호 반환 이전 proof p와 현재 구해야할 proof p’ 가 있을 때 Hash(p + p’) 의 앞 4자리 == “0000” 이 되는 이러한 p’를 구한다. def pow(self, last_proof): proof = 0 # valid proof 함수를 통해 맞을 때까지 반복적으로 검증 while self.valid_proof(last_proof, proof) is False: proof += 1 return proof​

valid proof 함수이며, 이 함수에서 하는 동작은 다음과 같습니다. 앞의 4자리가 000 으로 시작하는 해시값을 찾는 함수 @staticmethod def valid_proof(last_proof, proof): # 전 proof와 구할 proof 문자열 연결 guess = str(last_proof + proof).encode() # 이 hash 값 저장 guess_hash = hashlib.sha256(guess).hexdigest() # 앞 4자리가 0000 이면 True return guess_hash[:4] == “0000” # nonce​

필요한 라이브러리를 포함하여, 전체 코드는 다음과 같습니다. (blockchain.py)

import hashlib # hash 함수용 sha256 사용할 라이브러리 import json from time import time # from urlparse import urlparse from urllib.parse import urlparse class Blockchain(object): def __init__(self): self.chain = [] # chain에 여러 block들 들어옴 self.current_transaction = [] # 임시 transaction 넣어줌 # genesis block 생성 self.new_block(previous_hash=1, proof=100) def new_block(self, proof, previous_hash=None): # Creates a new Block and adds it to the chain block = { ‘index’ : len(self.chain)+1, ‘timestamp’ : time(), # timestamp from 1970 ‘transactions’ : self.current_transaction, ‘proof’ : proof, ‘previous_hash’ : previous_hash or self.hash(self.chain[-1]), } self.current_transaction = [] self.chain.append(block) return block def new_transaction(self, sender, recipient, amount): # Adds a new transaction to the list of transaction self.current_transaction.append( { ‘sender’ : sender, # 송신자 ‘recipient’ : recipient, # 수신자 ‘amount’ : amount # 금액 } ) return self.last_block[‘index’] + 1 @staticmethod def hash(block): # Hashes a Block block_string = json.dumps(block, sort_keys=True).encode() # hash 라이브러리로 sha256 사용 return hashlib.sha256(block_string).hexdigest() @property def last_block(self): # Returns the last Block in the chain return self.chain[-1] def pow(self, last_proof): proof = 0 # valid proof 함수를 통해 맞을 때까지 반복적으로 검증 while self.valid_proof(last_proof, proof) is False: proof += 1 return proof @staticmethod def valid_proof(last_proof, proof): # 전 proof와 구할 proof 문자열 연결 guess = str(last_proof + proof).encode() # 이 hash 값 저장 guess_hash = hashlib.sha256(guess).hexdigest() # 앞 4자리가 0000 이면 True return guess_hash[:4] == “0000” # nonce

Blockchain을 위한 서버 구현

그리고 blockchain.py가 동작하는 것을 쉽게 볼 수 있고, 새 transaction 도 요청하기 쉽도록 웹 서버 형식으로 구현해봅니다. python의 flask 프레임워크를 사용하였습니다. flask가 설치되지 않은 경우 windows에서는 명령 프롬프트를 열고 다음과 같이 설치합니다.

pip install Flask

웹 서버에는 다음과 같이 3 개의 URL을 구현할 예정입니다.

/chain: 현재 블록체인 보여줍니다

/transaction/new: 새 트랜잭션을 생성합니다

/mine: server에게 새 블록 채굴을 요청합니다

서버를 구현할 것인데, 포트 번호는 5000 번으로 하였습니다.

if __name__ == ‘__main__’: app.run(host=’0.0.0.0′, port=5000)

그리고 flask 구현을 위해 윗부분에 다음과 같이 코드를 입력합니다.

app = Flask(__name__) # Universial Unique Identifier # 노드 식별을 하기 위해 uuid 함수를 사용! node_identifier = str(uuid4()).replace(‘-‘,”) # 아까 짜놓은 블록체인 객체를 선언 blockchain = Blockchain()

/chain은 다음과 같이 구현합니다. 전체 block을 출력합니다.

@app.route(‘/chain’, methods=[‘GET’]) def full_chain(): response = { ‘chain’ : blockchain.chain, # 블록체인을 출력 ‘length’ : len(blockchain.chain), # 블록체인 길이 출력 } return jsonify(response), 200

/transactions/new는 다음과 같이 구현합니다. transaction 요청이 오면 transaction을 생성합니다.

# post는 url에 데이터를 붙여서 보내는 get과 달리 숨겨서 보내는 방식 @app.route(‘/transactions/new’, methods=[‘POST’]) def new_transaction(): values = request.get_json() # json 형태를 받아서 저장 required = [‘sender’, ‘recipient’, ‘amount’] # 해당 데이터가 존재해야함 # 데이터가 없으면 에러를 띄움 if not all(k in values for k in required): return ‘missing values’, 400 # Create a new Transaction # 새 트랜잭션 만들고 삽입 index = blockchain.new_transaction(values[‘sender’],values[‘recipient’],values[‘amount’]) response = {‘message’ : ‘Transaction will be added to Block {%s}’ % index} return jsonify(response), 201

/mine은 다음과 같이 구현합니다. coinbase transaction으로 구현하여, 채굴시 1 코인씩 얻을 수 있도록 하였습니다.

# 채굴이 되게 할 것 # coinbase transaction: 채굴할 때마다 1 코인씩 준다 @app.route(‘/mine’, methods=[‘GET’]) def mine(): last_block = blockchain.last_block last_proof = last_block[‘proof’] proof = blockchain.pow(last_proof) blockchain.new_transaction( sender=’0′, # 채굴시 생성되는 transaction (0 = 운영자) recipient=node_identifier, # 지갑 주소처럼 사용 amount=1 # coinbase transaction ) # Forge the new Block by adding it to the chain # 전 블록에 대한 hash를 떠놓고 previous_hash = blockchain.hash(last_block) # 검증하는 걸 넣어서 블록을 새로 생성 block = blockchain.new_block(proof, previous_hash) # block 이 제대로 mine 되었다는 정보를 json 형태로 띄워줌 response = { ‘message’ : ‘new block found’, ‘index’ : block[‘index’], ‘transactions’ : block[‘transactions’], ‘proof’ : block[‘proof’], ‘previous_hash’ : block[‘previous_hash’] } return jsonify(response), 200

헤더를 포함한 전체 소스코드는 다음과 같습니다. (server.py)

from flask import Flask, request, jsonify import json from uuid import uuid4 # Our blockchain.py API from blockchain import Blockchain app = Flask(__name__) # Universial Unique Identifier # 노드 식별을 하기 위해 uuid 함수를 사용! node_identifier = str(uuid4()).replace(‘-‘,”) # 아까 짜놓은 블록체인 객체를 선언 blockchain = Blockchain() @app.route(‘/chain’, methods=[‘GET’]) def full_chain(): response = { ‘chain’ : blockchain.chain, # 블록체인을 출력 ‘length’ : len(blockchain.chain), # 블록체인 길이 출력 } # json 형태로 리턴 (200 은 웹 사이트 에러가 없을 때 뜨는 숫자) return jsonify(response), 200 # post는 url에 데이터를 붙여서 보내는 get과 달리 숨겨서 보내는 방식 @app.route(‘/transactions/new’, methods=[‘POST’]) def new_transaction(): values = request.get_json() # json 형태를 받아서 저장 required = [‘sender’, ‘recipient’, ‘amount’] # 해당 데이터가 존재해야함 # 데이터가 없으면 에러를 띄움 if not all(k in values for k in required): return ‘missing values’, 400 # Create a new Transaction # 새 트랜잭션 만들고 삽입 index = blockchain.new_transaction(values[‘sender’],values[‘recipient’],values[‘amount’]) response = {‘message’ : ‘Transaction will be added to Block {%s}’ % index} return jsonify(response), 201 # 채굴이 되게 할 것 # coinbase transaction: 채굴할 때마다 1 코인씩 준다 @app.route(‘/mine’, methods=[‘GET’]) def mine(): last_block = blockchain.last_block last_proof = last_block[‘proof’] proof = blockchain.pow(last_proof) blockchain.new_transaction( sender=’0′, # 채굴시 생성되는 transaction (0 = 운영자) recipient=node_identifier, # 지갑 주소처럼 사용 amount=1 # coinbase transaction ) # Forge the new Block by adding it to the chain # 전 블록에 대한 hash를 떠놓고 previous_hash = blockchain.hash(last_block) # 검증하는 걸 넣어서 블록을 새로 생성 block = blockchain.new_block(proof, previous_hash) # block 이 제대로 mine 되었다는 정보를 json 형태로 띄워줌 response = { ‘message’ : ‘new block found’, ‘index’ : block[‘index’], ‘transactions’ : block[‘transactions’], ‘proof’ : block[‘proof’], ‘previous_hash’ : block[‘previous_hash’] } return jsonify(response), 200 if __name__ == ‘__main__’: app.run(host=’0.0.0.0′, port=5000)

결과

visual studio code 에서 작업시에는 Terminal > New Terminal을 선택하고 cmd로 다음을 실행하였습니다.

C:\주소…\Blockchain> python server.py * Serving Flask app ‘server’ (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: off * Running on all addresses. WARNING: This is a development server. Do not use it in a production deployment. * Running on http://192.168.212.150:5000/ (Press CTRL+C to quit)

Terminal로 server 실행

그리고 결과를 보기 위해 http://localhost:5000/chain 에 접속하였습니다. 존재하는 block 정보들을 볼 수 있습니다.

block chain 정보 확인

http://localhost:5000/mine 에 접속하여 채굴을 해서 새 block을 얻어보았습니다. url을 여러 번 쳐서 여러번 채굴하였습니다.

서버에 채굴 요청

여러 번 채굴 후에 http://localhost:5000/chain 를 다시 치면 다음과 같이 block들이 늘어난 것을 확인할 수 있습니다.

block chain 정보 다시 확인

new transaction은 URL 접속으로 바로 할 수 없어서 postman 사이트를 이용하거나 혹은 다음과 같이 테스트 스크립트를 작성하여 진행할 수도 있습니다. requests 라이브러리가 없는 경우 다음과 같이 명령 프롬프트에 입력하여 설치해줍니다.

pip install requests

그리고 다음 소스코드를 입력합니다. (test_transaction.py)

import requests import json headers = {‘Content-Type’ : ‘application/json; charset=utf-8’} data = { “sender”: 1004, “recipient”: 0, “amount”: 1004, } print(requests.post(“http://localhost:5000/transactions/new”, headers=headers, data=json.dumps(data)).content)

해당 소스코드를 실행합니다. 웹 서버가 중지되지 않고 계속 실행된 상태에서 해당 코드를 실행을 해야하기 때문에 visual studio code에서 새 terminal을 다시 열어서 코드를 실행하였습니다.

C:\주소…\Blockchain> python test_transaction.py

transaction 결과 확인을 url 접속으로 바로 할 수는 없지만 채굴을 했을 때 이전 transaction 결과를 간접적으로 확인할 수 있습니다.

이전 transaction이 새로 생성된 block 에서 보임

소스 코드

게시글 맨 윗 부분에 언급한 것과 같이 유튜브 강의 링크 및 소스코드 링크는 다음과 같습니다.

유튜브 강의: https://www.youtube.com/watch?v=Gno15LgVbcc

원본 소스코드: https://github.com/tr0y-kim/ez_blockchain

본 게시물의 소스코드: https://github.com/BY1994/Blockchain

반응형

파이썬으로 간단한 블록체인 구현해보기

반응형

지금까지 배운 블록체인 개념을 파이썬으로 구현해보고자 하였습니다.

아래 링크를 참고하여 만들었습니다.

https://hackernoon.com/learn-blockchains-by-building-one-117428612f46

Step 1 : Building a Blockchain

1. 블록체인 기본 구조

블록체인의 기본 뼈대를 만들었습니다. 새로운 블록 그리고 그 안에 새로운 트랜잭션(거래), 위조를 방지하는 해시, 그리고 마지막 블록 함수를 정의했습니다 .

class Blockchain(object): def __init__(self): self.chain = [] self.current_transactions = [] def new_block(self): # 새로운 블록 만들어서 블록체인에 넣기 pass def new_transaction(self): # 새로운 트랜잭션 만들어서 트랜잭션 리스트에 넣기 pass @staticmethod def hash(block): # 블록의 해시 pass @property def last_block(self): # chian의 마지막 block return pass

2. 블록의 기본 구조

다음은 블록 1개의 예시입니다

# 블록 1개 기본 예시 block = { ‘index’: 1, ‘timestamp’: 1506057125.900785, ‘transactions’: [ { ‘sender’: “8527147fe1f5426f9dd545de4b27ee00”, ‘recipient’: “a77f5cdfa2934df3954a5c7c7da5df1f”, ‘amount’: 5, } #거래내역 ], ‘proof’: 324984774000, ‘previous_hash’: “2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824” #이전의 해시값 저장 }

3. 블록에 새로운 트랜잭션 추가

이제 만들어진 블록에 새로운 트랜잭션을 추가해보겠습니다

param : 보내는 사람, 받는 사람의 주소, 돈의 양

return : 마지막 블록의 다음 블록 반환

class Blockchain(object): … def new_transaction(self, sender, recipient, amount): “”” 새롭게 채굴된 블록에 들어갈 새로운 트랜잭션 생성 :param sender: Sender의 Address :param recipient: Recipient의 Address :param amount: Amount :return: 트랜잭션이 받을 블록의 인덱스 “”” self.current_transactions.append({ ‘sender’: sender, ‘recipient’: recipient, ‘amount’: amount, }) return self.last_block[‘index’] + 1

4. 새로운 블록 만들기

이제 새로운 블록을 만들어보겠습니다.

일단, 최초의 블록(genesis block)을 만들고, 새로운 블록을 만들어 그 안에 트랜잭션을 넣습니다.

import hashlib import json from time import time class Blockchain(object): def __init__(self): self.current_transactions = [] self.chain = [] # 최초의 블록 생성 self.new_block(previous_hash=1, proof=100) def new_block(self, proof, previous_hash=None): “”” 블록체인에 새로운 블록을 생성한다 :param proof: PoW 알고리즘에서 받는 Proof :param previous_hash: (Optional) 이전 블록 해시 :return: 새로운 블록 “”” block = { ‘index’: len(self.chain) + 1, ‘timestamp’: time(), ‘transactions’: self.current_transactions, ‘proof’: proof, ‘previous_hash’: previous_hash or self.hash(self.chain[-1]), } # 현재 트랙잭션 list reset self.current_transactions = [] self.chain.append(block) return block def new_transaction(self, sender, recipient, amount): “”” 새롭게 채굴된 블록에 들어갈 새로운 트랜잭션 생성 :param sender: Sender의 Address :param recipient: Recipient의 Address :param amount: Amount :return: 트랜잭션이 받을 블록의 인덱스 “”” self.current_transactions.append({ ‘sender’: sender, ‘recipient’: recipient, ‘amount’: amount, }) return self.last_block[‘index’] + 1 @property def last_block(self): return self.chain[-1] @staticmethod def hash(block): “”” 블록의 SHA-256 hash 생성 :param block: Block :return: “”” # Dictionary가 ordered 되어야함. 안그러면 hash가 inconsistent block_string = json.dumps(block, sort_keys=True).encode() return hashlib.sha256(block_string).hexdigest()

cf) PoW(Proof of Work)

이제 합의 알고리즘 중 하나인 Proof of Work에 대해서 간단하게 알아보겠습니다.

작업증명의 원리 : 어떤 정수 x와 다른 수 y를 곱해서 “0”으로 끝나야 한다고 결정되면 끝이 0이 되는 수를 찾는 것!

from hashlib import sha256 x = 5 y = 0 # 아직 y가 뭔지 모름 while sha256(f'{x*y}’.encode()).hexdigest()[-1] != “0”: y += 1 print(f’The solution is y = {y}’)

6. PoW 구현

PoW에서 난이도(difficulty)란 hash를 검증할 때 필요한 조건의 난이도를 의미한다.

difficulty : hash의 앞에 4자리가 ‘0000’인가?

import hashlib import json from time import time from uuid import uuid4 class Blockchain(object): … def proof_of_work(self, last_proof): “”” 간단한 PoW 알고리즘 – hash가 앞에 ‘0000’을 가지고 있는 p’을 찾아라. – p : previous proof, p’ : new proof :param last_proof: :return: “”” proof = 0 while self.valid_proof(last_proof, proof) is False: proof += 1 return proof @staticmethod def valid_proof(last_proof, proof): “”” Proof 검증 : hash(last_proof, proof)가 앞에 ‘0000’을 가지고 있나? :param last_proof: Previous Proof :param proof: Current Proof :return: True if correct, False if not. “”” guess = f'{last_proof}{proof}’.encode() guess_hash = hashlib.sha256(guess).hexdigest() return guess_hash[:4] == “0000”

Step 2: Our Blockchain as an API

/transactions/new : 블록에 새로운 트랜잭션 생성

2. /mine : 서버에게 새로운 블록 mining 알려줌

3. /chain: Full Blockchain return

0. 플라스크에 대한 이해

route : 플라스크 서버로 요청이 들어왔을 때 어떤 함수를 호출할 것인지 조절함.

– 127.0.0.1 : 인터넷 루프백 주소

– :5000 -> 웹서버가 실행중인 프로토콜 번호 (플라스크 : 5000)

from flask import Flask # 플라스크 인스턴스 생성 app = Flask(__name__) @app.route(‘/’) # @ : 데코레이터 # flask에서는 @가 url 연결에 활용된다. def hello() -> str: # -> : str로 나온다! return “Hello World from Flask” app.run()

1. API 뼈대 만들기

import hashlib import json from textwrap import dedent from time import time from uuid import uuid4 from flask import Flask class Blockchain(object): … # 노드 시작 app = Flask(__name__) # 이 노드의 고유 번호 생성 node_identifier = str(uuid4()).replace(‘-‘, ”) # 블록체인 시작 blockchain = Blockchain() # Create the /mine endpoint, which is a GET request. @app.route(‘/mine’, methods=[‘GET’]) def mine(): return “We’ll mine a new Block” # Create the /transactions/new endpoint, which is a POST request, since we’ll be sending data to it. @app.route(‘/transactions/new’, methods=[‘POST’]) def new_transaction(): return “We’ll add a new transaction” # Create the /chain endpoint, which returns the full Blockchain. @app.route(‘/chain’, methods=[‘GET’]) def full_chain(): response = { ‘chain’: blockchain.chain, ‘length’: len(blockchain.chain), } return jsonify(response), 200 # Runs the server on port 5000. if __name__ == ‘__main__’: app.run(host=’0.0.0.0′, port=5000)

2. The Transactions Endpoint

import hashlib import json from textwrap import dedent from time import time from uuid import uuid4 from flask import Flask, jsonify, request … @app.route(‘/transactions/new’, methods=[‘POST’]) def new_transaction(): values = request.get_json() # Check that the required fields are in the POST’ed data required = [‘sender’, ‘recipient’, ‘amount’] if not all(k in values for k in required): return ‘Missing values’, 400 # 새로운 트랜잭션 생성 index = blockchain.new_transaction(values[‘sender’], values[‘recipient’], values[‘amount’]) response = {‘message’: f’Transaction will be added to Block {index}’} return jsonify(response), 201

3. The Mining Endpoint

PoW 계산

트랜잭션 추가한 miner에게 코인 제공

chain에 새로운 블록 넣기

import hashlib import json from time import time from uuid import uuid4 #실행될 때마다 다른값 반환하는 모듈 from flask import Flask, jsonify, request … @app.route(‘/mine’, methods=[‘GET’]) def mine(): #다음 proof 를 얻기 위해 PoW 알고리즘 돌림 last_block = blockchain.last_block last_proof = last_block[‘proof’] proof = blockchain.proof_of_work(last_proof) # Proof 찾은것에 대한 보상이 필요 # sender=”0″ : 이 노드는 새로운 coin을 받았다고 명시. blockchain.new_transaction( sender=”0″, recipient=node_identifier, amount=1, ) # chain에 트랜젹션 넣고 new block forge previous_hash = blockchain.hash(last_block) block = blockchain.new_block(proof, previous_hash) response = { ‘message’: “New Block Forged”, ‘index’: block[‘index’], ‘transactions’: block[‘transactions’], ‘proof’: block[‘proof’], ‘previous_hash’: block[‘previous_hash’], } return jsonify(response), 200

Step 3: Consensus(합의)

이는 새로운 노드를 추가할 때, 이를 결정하는 합의 알고리즘에 관핸 내용이다.

1. 새로운 노드 추가

일단, 노드 리스트에 새로운 노드를 추가한다.

… from urllib.parse import urlparse … class Blockchain(object): def __init__(self): … self.nodes = set() #중복 허용 X … def register_node(self, address): “”” 노드 리스트에 새로운 노드 추가 :param address: 노드 주소. Eg. ‘http://192.168.0.5:5000’ :return: None “”” parsed_url = urlparse(address) self.nodes.add(parsed_url.netloc)

2. 합의 알고리즘 시행

블록체인이 타당한지 아닌지 검증한다.

… import requests class Blockchain(object) … def valid_chain(self, chain): “”” 블록체인이 타당한지 결정 :param chain: A blockchain :return: T / F “”” last_block = chain[0] current_index = 1 while current_index < len(chain): block = chain[current_index] print(f'{last_block}') print(f'{block}') print(" ----------- ") # hash block이 맞는지 확인한다. if block['previous_hash'] != self.hash(last_block): return False # PoW가 잘 작동하는지 확인한다. if not self.valid_proof(last_block['proof'], block['proof']): return False last_block = block current_index += 1 return True def resolve_conflicts(self): """ 합의 알고리즘 : 가장 긴것 채택 :return: True if our chain was replaced, False if not “”” neighbours = self.nodes new_chain = None # 우리 체인보다 긴것만 봄 max_length = len(self.chain) # 우리 네트워크의 모든 노드들 다 검증 for node in neighbours: response = requests.get(f’http://{node}/chain’) if response.status_code == 200: length = response.json()[‘length’] chain = response.json()[‘chain’] # 길이가 긴지 보고, chain이 타당한지 확인 if length > max_length and self.valid_chain(chain): max_length = length new_chain = chain # 새로운 타당한 긴 체인을 찾으면 이로 대체함. if new_chain: self.chain = new_chain return True return False

3. As API

@app.route(‘/nodes/register’, methods=[‘POST’]) def register_nodes(): values = request.get_json() nodes = values.get(‘nodes’) if nodes is None: return “Error: Please supply a valid list of nodes”, 400 for node in nodes: blockchain.register_node(node) response = { ‘message’: ‘New nodes have been added’, ‘total_nodes’: list(blockchain.nodes), } return jsonify(response), 201 @app.route(‘/nodes/resolve’, methods=[‘GET’]) def consensus(): replaced = blockchain.resolve_conflicts() if replaced: response = { ‘message’: ‘Our chain was replaced’, ‘new_chain’: blockchain.chain } else: response = { ‘message’: ‘Our chain is authoritative’, ‘chain’: blockchain.chain } return jsonify(response), 200

반응형

파이썬 Python 블록 체인 개발 입문 – 미국 실리콘밸리 현역 엔지니어와 함께 블록 체인을 구현해봅시다

이 코스에서는 블록 체인의 기술과 Python 으로 가상통화의 송금 시스템을 구축합니다. 블록 체인의 기본이 되는 기술, 사고 방식과 그 응용 방법을 직접 코딩을 해 가며 공부를 할 수 있습니다.

Blockchain 기술은 난해한 설명 자료가 많으며 “블록 체인 = 가상통화 = 수상하다” 라는 이미지를 가지기 쉽지만, 블록 체인의 기술은 IT 업계의 상식을 뒤집어 차세대의 네트워크의 분산 시스템 플랫폼 위에서 미지의 가능성을 내포하고 있습니다.

블록 체인 네트워크에서는 송금 결제, 지역 통화, 포인트 서비스, 그 외 디지털 자산의 교환을 할 수 있지만, 자산의 소유권을 기록 할 수 있기 때문에 블록 체인이 신뢰하는 ID로서, 토지 관리, 재산의 소유권, 기타 물적 재산의 소유권을 나타낼 수도 있습니다. 또한 투표나 여권 취득, 권리와 서비스에 사용할 수 있습니다. 또한 매일 서류로 이루어지고있는 행정 서비스 및 부동산 거래 등의 신뢰도 입증 할 수 있습니다. 여기서 언급 된 이상 많은 분야에서 사용 될 가능성이 높습니다.

Facebook이 Libra의 가상 통화를 발표하고, Amazon, Microsoft, IBM 등의 대기업에서는 블록 체인의 플랫폼을 제공하기 시작했습니다. 이것은 향후 블록 체인의 인프라를 사용하는 기회가 늘어날 것으로 예측하고 있기 때문에라고 생각합니다.

또한 블록 체인을 다룰 수 있는 엔지니어의 구인은 실리콘밸리에서도 증가하고있어 향후 블록 체인을 개발할 수있는 엔지니어의 희소성이 높아질 것으로 기대할 수 있습니다.

블록 체인의 엔지니어가 되지 않더라도 블록 체인을 구현을 한 경험은 반드시 취업이나 전직시에 제출하는 이력서 중에서도 눈에 띄는 한줄이 되리라고 생각합니다. 이 기회에 블록 체인의 구현을 해 보는 것은 어떨까요.!

그럼 앞으로도 여러분의 활약을 기원하겠습니다!

python으로 간단한 블록체인 만들기 (1) — Steemit

자바스크립트 버전 을 python으로 포팅한 내용입니다.

블록체인의 가장 기초적인 기능인 블록을 만들고 생성된 블록들을 체인으로 연결하는 법을 구현해보겠습니다.

블록 구성요소를 보면 1. index (블록 인덱스 값) 2.timestamp(블록이 생성된 시간) 3. data (블록에 저장된 데이터, 트랜잭션 등등) 4. previous hash (체인을 구성하기 위한 이 전 블록의 해쉬 값) 5. hash (현재 블록의 해쉬 값) 으로 구성하겠습니다.

class Block(): def __init__(self, index, timestamp, data): self.index = index self.timestamp = timestamp self.data = data self.previousHash = 0 self.hash = self.calHash()

init 생성자를 통해서 Block 객체가 생성될 때 초기화를 해줍니다. 현재 블록의 해쉬 값은 calHash()함수를 통해서 생성합니다.

import hashlib class Block(): def __init__(self, index, timestamp, data): self.index = index self.timestamp = timestamp self.data = data self.previousHash = 0 self.hash = self.calHash() def calHash(self): return hashlib.sha256(str(self.index).encode() + str(self.data).encode() + str(self.timestamp).encode() + str(self.previousHash).encode()).hexdigest()

calHash함수에서 hash함수로 SHA256을 사용하겠습니다. 파이썬에서는 sha256을 hashlib에서 제공하고 있습니다. hashlib를 import 합니다. sha256에 들어갈 수 있는 데이터 타입은 byte입니다. 그래서 index, timestamp,data, previousHash 를 string으로 변환 후 encode로 한 번 더 변환합니다.

마지막으로 해쉬 값을 16진수로 표현하기 위해서 hexdigest 함수를 사용합니다.

이제 블록체인 클래스를 만들어보겠습니다. 블록체인 클래스에는 블록들이 들어갈 리스트 변수 chain을 만들고 최초 블록을 생성하는 createGenesis함수와 블록을 체인에 추가하는 addBlock함수, 체인이 유효한지 검사하는 isValid 함수로 구성됩니다.

class BlockChain: def __init__(self): self.chain = [] self.createGenesis() def createGenesis(self): self.chain.append(Block(0, time.time(), ‘Genesis’)) def addBlock(self, nBlock): nBlock.previousHash = self.chain[len(self.chain)-1].hash nBlock.hash = nBlock.calHash() self.chain.append(nBlock) def isValid(self): i = 1 while(i

키워드에 대한 정보 파이썬 블록 체인 구현

다음은 Bing에서 파이썬 블록 체인 구현 주제에 대한 검색 결과입니다. 필요한 경우 더 읽을 수 있습니다.

이 기사는 인터넷의 다양한 출처에서 편집되었습니다. 이 기사가 유용했기를 바랍니다. 이 기사가 유용하다고 생각되면 공유하십시오. 매우 감사합니다!

사람들이 주제에 대해 자주 검색하는 키워드 비트코인 채굴의 원리를 파이썬으로 구현해보자!

  • 개발
  • 파이썬
  • python
  • bitcoin
  • blockchain
  • cryptocurrency
  • 암호화폐
  • 블록체인
  • 비트코인
  • 채굴
  • mining

비트코인 #채굴의 #원리를 #파이썬으로 #구현해보자!


YouTube에서 파이썬 블록 체인 구현 주제의 다른 동영상 보기

주제에 대한 기사를 시청해 주셔서 감사합니다 비트코인 채굴의 원리를 파이썬으로 구현해보자! | 파이썬 블록 체인 구현, 이 기사가 유용하다고 생각되면 공유하십시오, 매우 감사합니다.

Leave a Comment