Bitcoin Forum
May 03, 2024, 10:03:45 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: [?] крошечный блокчейн  (Read 264 times)
bomj (OP)
Sr. Member
****
Offline Offline

Activity: 1337
Merit: 288


0xbt


View Profile WWW
February 08, 2020, 08:28:28 PM
Merited by Symmetrick (3), klarki (1), mikhailr (1)
 #1

Преамбула.
Набрел сегодня на любопытную статью:
Давайте построим самый крошечный блокчейн
В принципе данная статья как бы не подходит для новичков, но тем не менее привлекательна  д/самостоятельных экспериментов на компе)).
Так как сам себя считаю новичком во многих вещах, хотелось бы услышать:
- доступный разбор разбор статьи
- рекомендуемые инструменты
- и порядок действий

Готовый перевод данной статьи нашел на https://lambda-it.ru/post/krokhotnyi-blokchein-na-python-v-50-strok


Крохотный блокчейн на Python в 50 строк [часть-1]

Несмотря на то, что некоторые воспринимают блокчейн как волшебную палочку, застывшую в ожидании проблем для решения, нет никаких сомнений в том, что эта новая технология – настоящее чудо в информационном мире. Но что же такое блокчейн?

Блокчейн - Цифровой “блокнот” в котором транзакции, проводимые в системе биткоин (или другой криптовалюты) записываются в хронологическом порядке и публично доступны.

В более общих словах - это публичная база данных, где новые данные хранятся в контейнерах, называемых блоками, и добавляются в иммутабельную (неизменяемую) цепочку вместе с данными, добавленными тудав прошлом. В случае биткоина и других криптовалют, данными являются группы транзакций. Но, естественно, данные могут быть любыми.

Технология блокчейна дала толчок новым, полностью цифровым валютам, таким как биткоин и лайткоин которые не контролируются и не выпускаются централизованно. Это дает новые свободы тем, кто считает современную банковскую систему жульнической. Блокчейн также произвел революцию в системах распределенных вычислений в виде таких технологий, как эфириум, которые представили концепт умных контрактов.

В этой статье я создам простой блокчейн в несколько десятков строчек кода на Python 3. Он будет называться SnakeCoin.

Начнем с определения вида нашего блока. В блокчейне каждый блок содержит временную метку и, опционально, номер. В SnakeCoin мы будем записывать обе позиции. И чтобы убедиться в целостности всего блокчейна, каждый блок будет иметь идентификационный хэш. Как в биткоине, хэш каждого блока будет криптографическим хэшем номера блока, его временной метки, данных и хэша предыдущего блока. Да, с данными может быть все, что угодно.

Code:
import hashlib as hasher

class Block:
  def __init__(self, index, timestamp, data, previous_hash):
    self.index = index
    self.timestamp = timestamp
    self.data = data
    self.previous_hash = previous_hash
    self.hash = self.hash_block()
 
  def hash_block(self):
    sha = hasher.sha256()
    sha.update(str(self.index) +
               str(self.timestamp) +
               str(self.data) +
               str(self.previous_hash))
    return sha.hexdigest()

Отлично! У нас есть структура нашего блока, но мы создаем цепочку таких блоков (блокчейн). Нам нужно добавлять блоки в некую последовательность. Как я сказал ранее, каждый блок содержит информацию из предыдущего блока. Поэтому встает вопрос - как нам добавить самый первый блок? Ну, первый или первородный блок (genesis block) - это необычный блок. В большинстве случаев,  он добавляется вручную или имеет особую логику, позволяющую его добавить.

Мы создадим функцию, которая будет возвращать нам genesis block, чтобы сделать жизнь чуть проще. Этот блок будет иметь номер 0 и произвольные данные с произвольным значением хэша “предыдущего блока”.

Code:
import datetime as date

def create_genesis_block():
  # Manually construct a block with
  # index zero and arbitrary previous hash
  return Block(0, date.datetime.now(), "Genesis Block", "0")

Теперь, когда мы можем создать genesis block, нам нужна функция, которая будет создавать следующие блоки в цепочке. Эта функция будет принимать предыдущий блок в цепи, как параметр, создавать данные и возвращать новый блок с корректными хэшами. Когда новый блок хэширует информацию из предыдущего блока, надежность всей цепи увеличивается с каждым новым блоком. Если этого не делать, злоумышленникам будет проще “изменить прошлое” и заменить нашу цепочку их собственной. Цепь хэшей играет роль криптографического доказательства и дает гарантию, что однажды добавленный в блокчейн блок нельзя будет изменить или вовсе удалить.

Code:
def next_block(last_block):
  this_index = last_block.index + 1
  this_timestamp = date.datetime.now()
  this_data = "Hey! I'm block " + str(this_index)
  this_hash = last_block.hash
  return Block(this_index, this_timestamp, this_data, this_hash)

Это большая часть сложной работы. Теперь можем запустить наш блокчейн! В нашем случае, это будет простой питоновский список (list). Первым элементом будет наш первородный блок (genesis block). И, конечно, нам нужно добавить последующие блоки. Так как SnakeCoin - это крохотный блокчейн, мы добавим всего 20 новых блоков. Можем сделать это в цикле.

Code:
# Create the blockchain and add the genesis block
blockchain = [create_genesis_block()]
previous_block = blockchain[0]

# How many blocks should we add to the chain
# after the genesis block
num_of_blocks_to_add = 20

# Add blocks to the chain
for i in range(0, num_of_blocks_to_add):
  block_to_add = next_block(previous_block)
  blockchain.append(block_to_add)
  previous_block = block_to_add
  # Tell everyone about it!
  print "Block #{} has been added to the blockchain!".format(block_to_add.index)
  print "Hash: {}\n".format(block_to_add.hash)




Не переживай. Добавятся все 20 блоков Smiley

Отлично, наш блокчейн работает! Если хочешь увидеть больше информации о каждом блоке, можешь запустить полный исходный текст в консоли.

В принципе, это все, что SnakeCoin имеет сейчас предложить. Чтобы сделать SnakeCoin пригодным для использования в современных условиях индустрии, в него нужно добавить множество фичей, например: сервер, отслеживающий цепочку на нескольких машинах и алгоритм proof-of-work, чтобы ограничить количество блоков, добавляемых  за определенный промежуток времени.

Если хочется больше технических подробностей, то можно прочитать оригинальный доклад Биткоина здесь. Удачи и веселого хакинга!


https://gist.github.com/aunyks/47d157f8bc7d1829a729c2a6a919c173
Кроме того один товарищ сделал это же на js:
https://github.com/zacanger/tiny-blockchain

Есть продолжение(часть-2):
Давайте сделаем самый крошечный блокчейн больше
Переводить не стал, чтобы не наделать некорректных ошибок, может кто возьмется......





1714773825
Hero Member
*
Offline Offline

Posts: 1714773825

View Profile Personal Message (Offline)

Ignore
1714773825
Reply with quote  #2

1714773825
Report to moderator
The forum was founded in 2009 by Satoshi and Sirius. It replaced a SourceForge forum.
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
1714773825
Hero Member
*
Offline Offline

Posts: 1714773825

View Profile Personal Message (Offline)

Ignore
1714773825
Reply with quote  #2

1714773825
Report to moderator
1714773825
Hero Member
*
Offline Offline

Posts: 1714773825

View Profile Personal Message (Offline)

Ignore
1714773825
Reply with quote  #2

1714773825
Report to moderator
ilyapx
Member
**
Offline Offline

Activity: 237
Merit: 29


View Profile
March 19, 2020, 10:07:35 PM
 #2

крутяк  Smiley Но я рекомендую попробовать сделать блокчейн на erlang
mikhailr
Sr. Member
****
Offline Offline

Activity: 812
Merit: 443


★777Coin.com★ Fun BTC Casino!


View Profile
March 24, 2020, 06:44:04 PM
Merited by xandry (7), bomj (2), Symmetrick (1)
 #3

Давайте сделаем самый крошечный блокчейн больше
Часть 2: с большим количеством строк Python




Примечание. В этой статье предполагается, что вы прочитали первую часть

Самый крошечный блокчейн был чрезвычайно прост, и его было относительно легко сделать. Но вместе с его простотой появилось и несколько недостатков. Во-первых, SnakeCoin работал только на одной машине, поэтому он был далек от распространения, не говоря уже о децентрализации. Во-вторых, блоки могут быть добавлены в цепочку так же быстро, как главный компьютер может создать объект Python и добавить его в список. В случае простого блокчейна это не проблема, но теперь мы собираемся позволить SnakeCoin быть реальной криптовалютой, поэтому нам нужно будет контролировать количество блоков (и монет), которые могут быть созданы одновременно.

Отныне данные SnakeCoin будут транзакциями, поэтому поле данных каждого блока будет представлять собой список некоторых транзакций. Мы определим транзакцию следующим образом. Каждая транзакция будет представлять собой объект JSON с подробным описанием отправителя монеты, получателя монеты и суммы переводимого SnakeCoin.
Примечание. Транзакции выполняются в формате JSON по причине, которую я скоро опишу.

Code:
{
  "from": "71238uqirbfh894-random-public-key-a-alkjdflakjfewn204ij",
  "to": "93j4ivnqiopvh43-random-public-key-b-qjrgvnoeirbnferinfo",
  "amount": 3
}

Теперь, когда мы знаем, как будут выглядеть наши транзакции, нам нужен способ добавить их на один из компьютеров в нашей блокчейн сети, называемый узлом. Для этого мы создадим простой HTTP сервер, чтобы любой пользователь мог сообщить нашим узлам, что произошла новая транзакция. Узел сможет принять POST запрос с транзакцией (как показано выше) в качестве тела запроса. Вот почему транзакции в формате JSON; нам нужно, чтобы они передавались на наш сервер в теле запроса.



Code:
from flask import Flask
from flask import request
node = Flask(__name__)

# Store the transactions that
# this node has in a list
this_nodes_transactions = []

@node.route('/txion', methods=['POST'])
def transaction():
  if request.method == 'POST':
    # On each new POST request,
    # we extract the transaction data
    new_txion = request.get_json()
    # Then we add the transaction to our list
    this_nodes_transactions.append(new_txion)
    # Because the transaction was successfully
    # submitted, we log it to our console
    print "New transaction"
    print "FROM: {}".format(new_txion['from'])
    print "TO: {}".format(new_txion['to'])
    print "AMOUNT: {}\n".format(new_txion['amount'])
    # Then we let the client know it worked out
    return "Transaction submission successful\n"

node.run()

Потрясающе! Теперь у нас есть способ вести учет пользователей, когда они отправляют монеты друг другу. Вот почему люди называют блокчейны публичными распределенными бухгалтерскими книгами: все транзакции хранятся для всеобщего обозрения и хранятся на каждом узле в сети.

Но возникает вопрос: где люди могут получить SnakeCoins? Пока нигде. Еще нет такого понятия, как SnakeCoin, потому что еще не было создано и выпущено ни одной монеты. Чтобы создавать новые монеты, люди должны добывать (майнить) новые блоки SnakeCoin. Когда они успешно добывают новые блоки, создаются новые SnakeCoin и вознаграждается то, кто добыл блок. Затем монета получает распространение, как только майнер отправляет SnakeCoin другому человеку.

Мы не хотим, чтобы было слишком легко добывать новые блоки SnakeCoin, потому что это создаст слишком много SnakeCoin, и они будут иметь небольшую ценность. И наоборот, мы не хотим, чтобы было слишком сложно добывать новые блоки, потому что тогда не будет достаточно монет для всех, чтобы тратить их, и они будут слишком дорогими на наш вкус. Чтобы контролировать сложность майнинга новых SnakeCoins, мы реализуем алгоритм Proof-of-Work (PoW). Алгоритм Proof-of-Work - это по сути алгоритм, который генерирует элемент, который сложно создать, но легко проверить. Предмет называется доказательством и как звучит, является доказательством того, что компьютер выполнил определенный объем работы.

В SnakeCoin мы создадим несколько простой алгоритм Proof-of-Work. Чтобы создать новый блок, компьютер майнера должен будет увеличить число. Когда это число делится на 9 (количество букв в «SnakeCoin») и номер доказательства последнего блока, будет добыт новый блок SnakeCoin, и майнер получит новый SnakeCoin.

Code:
# ...blockchain
# ...Block class definition

miner_address = "q3nf394hjg-random-miner-address-34nf3i4nflkn3oi"

def proof_of_work(last_proof):
  # Create a variable that we will use to find
  # our next proof of work
  incrementor = last_proof + 1
  # Keep incrementing the incrementor until
  # it's equal to a number divisible by 9
  # and the proof of work of the previous
  # block in the chain
  while not (incrementor % 9 == 0 and incrementor % last_proof == 0):
    incrementor += 1
  # Once that number is found,
  # we can return it as a proof
  # of our work
  return incrementor

@node.route('/mine', methods = ['GET'])
def mine():
  # Get the last proof of work
  last_block = blockchain[len(blockchain) - 1]
  last_proof = last_block.data['proof-of-work']
  # Find the proof of work for
  # the current block being mined
  # Note: The program will hang here until a new
  #       proof of work is found
  proof = proof_of_work(last_proof)
  # Once we find a valid proof of work,
  # we know we can mine a block so
  # we reward the miner by adding a transaction
  this_nodes_transactions.append(
    { "from": "network", "to": miner_address, "amount": 1 }
  )
  # Now we can gather the data needed
  # to create the new block
  new_block_data = {
    "proof-of-work": proof,
    "transactions": list(this_nodes_transactions)
  }
  new_block_index = last_block.index + 1
  new_block_timestamp = this_timestamp = date.datetime.now()
  last_block_hash = last_block.hash
  # Empty transaction list
  this_nodes_transactions[:] = []
  # Now create the
  # new block!
  mined_block = Block(
    new_block_index,
    new_block_timestamp,
    new_block_data,
    last_block_hash
  )
  blockchain.append(mined_block)
  # Let the client know we mined a block
  return json.dumps({
      "index": new_block_index,
      "timestamp": str(new_block_timestamp),
      "data": new_block_data,
      "hash": last_block_hash
  }) + "\n"

Теперь мы можем контролировать количество блоков, добываемых за определенный период времени, и мы можем выпускать новые монеты для людей в сети для отправки друг другу. Но, как мы уже говорили, мы делаем это только на одном компьютере. Если блокчейны децентрализованы, как мы можем быть уверены, что одна и та же цепочка находится на каждом узле? Для этого мы заставляем каждый узел транслировать свою версию цепочки другим узлам и позволяем им принимать цепочки других узлов. После этого каждый узел должен проверить цепочки других узлов, чтобы каждый узел в сети мог прийти к консенсусу о том, как будет выглядеть результирующий блокчейн.. Это называется консенсусным алгоритмом.

Наш алгоритм консенсуса будет довольно простым: если цепочка одного узла отличается от другой (т.е. есть конфликт), то самая длинная цепочка в сети остается, а все более короткие цепочки будут удалены. Если нет конфликта между цепочками в нашей сети, то мы продолжаем.

Code:
@node.route('/blocks', methods=['GET'])
def get_blocks():
  chain_to_send = blockchain
  # Convert our blocks into dictionaries
  # so we can send them as json objects later
  for block in chain_to_send:
    block_index = str(block.index)
    block_timestamp = str(block.timestamp)
    block_data = str(block.data)
    block_hash = block.hash
    block = {
      "index": block_index,
      "timestamp": block_timestamp,
      "data": block_data,
      "hash": block_hash
    }
  # Send our chain to whomever requested it
  chain_to_send = json.dumps(chain_to_send)
  return chain_to_send

def find_new_chains():
  # Get the blockchains of every
  # other node
  other_chains = []
  for node_url in peer_nodes:
    # Get their chains using a GET request
    block = requests.get(node_url + "/blocks").content
    # Convert the JSON object to a Python dictionary
    block = json.loads(block)
    # Add it to our list
    other_chains.append(block)
  return other_chains

def consensus():
  # Get the blocks from other nodes
  other_chains = find_new_chains()
  # If our chain isn't longest,
  # then we store the longest chain
  longest_chain = blockchain
  for chain in other_chains:
    if len(longest_chain) < len(chain):
      longest_chain = chain
  # If the longest chain wasn't ours,
  # then we set our chain to the longest
  blockchain = longest_chain

Мы уже почти закончили. После запуска полного кода сервера SnakeCoin выполните следующие команды в своем терминале. При условии, что у вас установлен cURL.

1. Создать транзакцию.

Code:
curl "localhost:5000/txion" \
     -H "Content-Type: application/json" \
     -d '{"from": "akjflw", "to":"fjlakdj", "amount": 3}'

2. Майнить новый блок.

Code:
curl localhost:5000/mine]

3. Проверьте результаты. В окне клиента мы видим это.



С небольшим количеством красивой печати мы видим, что после майнинга мы получаем некоторую крутую информацию о нашем новом блоке.

Code:
{
  "index": 2,
  "data": {
    "transactions": [
      {
        "to": "fjlakdj",
        "amount": 3,
        "from": "akjflw"
      },
      {
        "to": "q3nf394hjg-random-miner-address-34nf3i4nflkn3oi",
        "amount": 1,
        "from": "network"
      }
    ],
    "proof-of-work": 36
  },
  "hash": "151edd3ef6af2e7eb8272245cb8ea91b4ecfc3e60af22d8518ef0bba8b4a6b18",
  "timestamp": "2017-07-23 11:23:10.140996"
}

Вот и все! На данный момент мы сделали блокчейн довольно большого размера. Теперь SnakeCoin может быть запущен на нескольких машинах для создания сети, а реальные SnakeCoin могут быть добыты. Пожалуйста, не стесняйтесь возиться с кодом сервера SnakeCoin столько раз, сколько захотите, и задавайте столько вопросов, сколько вам нужно! В следующей части мы обсудим создание кошелька SnakeCoin, чтобы пользователи могли отправлять, получать и хранить свои SnakeCoin.

Большое спасибо за чтение!
Twitter , Github , Snapchat , Instagram

Перевод.
Оригинал: https://medium.com/crypto-currently/lets-make-the-tiniest-blockchain-bigger-ac360a328f4d

Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!