Блокчейн, как известно, сложен для понимания. Я решил узнать, как это работает, построив его на Go. Мои причины выбрать Go:

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

Предварительные требования

Следуйте инструкциям по установке двоичного файла Go.

Git клонирует репозиторий, содержащий код для запуска сети:

git clone https://github.com/bcaton85/go-blockchain
cd go-blockchain

Обзор

Этот проект был создан, чтобы увидеть, как работает блокчейн. Проект основан на этой замечательной статье о создании узла Blockchain на Python. Я внес следующие изменения, чтобы узел работал как сеть:

  • Все межсетевые запросы имеют заголовок node-uuid. Если заголовок не найден в полученном запросе, распространите изменение на все другие узлы.
  • Любые новые транзакции на одном узле распространяются на все остальные узлы.
  • Любые вновь зарегистрированные узлы распространяются на все остальные узлы.
  • Когда блок добывается, этот узел отправляет запрос всем другим узлам для разрешения самой длинной цепочки.

Рекомендуется прочитать статью, чтобы узнать, как работает блокчейн, а затем использовать этот проект, чтобы увидеть, как сеть работает в действии. Обратите внимание, что это всего лишь базовый пример, используемый в качестве наглядного пособия.

Запуск сети

  1. Сначала соберите проект: go build

2. Это создаст двоичный файл в том же каталоге с именем go-blockchain. Запустите двоичный файл с ./go-blockchain 8000, где 8000 - порт, на котором будет работать узел. Это даст следующий результат:

Здесь был добавлен наш исходный блок, был назначен уникальный идентификатор узла, и он прослушивает порт 8000.

3. Для создания сети нам понадобится еще один узел. Откройте другой терминал и снова запустите тот же двоичный файл с другим портом: ./go-blockchain 8001. (Здесь мы создадим только два узла, но, если хотите, создадим больше)

4. Теперь нам нужно зарегистрировать узел 8001 в узле 8000. Мы можем сделать это, нажав конечную точку /nodes/register REST на node8000. Здесь мы будем использовать curl, но Postman, Insomnia или любой другой инструмент, который выполняет запросы REST, будут работать.

curl --location --request POST \
'http://localhost:8000/nodes/register' \
--header 'Content-Type: application/json' \
--data-raw '{
 "nodes": [
  "http://localhost:8001"
  ]
}'

У нас есть только одно поле nodes, которое содержит массив узлов, которые нужно зарегистрировать. Каждый узел регистрируется по своему имени хоста. Отправка запроса дает нам:

Из журнала мы видим, что узел 8001 был зарегистрирован на узел 8000 и наоборот.

5. Теперь мы можем добавлять транзакции в сеть. Это отображается в конечной точке /transactions/newREST:

curl --location --request POST \
'http://localhost:8000/transactions/new' \
--header 'Content-Type: application/json' \
--data-raw '{
 "sender":"sender1",
 "recipient":"recipient2",
 "amount": 12
}'

Журнал Added new transaction должен появиться в выходных данных для обоих узлов, поскольку новые транзакции распространяются на каждый узел в сети.

6. Перед добычей нового блока просмотрите текущую цепочку блоков, нажав конечную точку /chain на узле 8000: curl http://localhost:8000/chain. Это должно дать следующее:

Здесь мы видим текущую текущую цепочку для узла 8000, она содержит только начальный блок. Мы не видим текущие транзакции, потому что они еще не были добыты. Мы можем сделать это, используя /mine конечную точку: curl http://localhost:8000/mine. Это дает нам следующий результат для каждого узла:

Здесь недавно добытый блок был добавлен в цепочку для узла 8000. После того, как блок будет добыт, он вызовет /nodes/resolve на других узлах. Конечная точка разрешения получит цепочку от других узлов, проверит, что это допустимая цепочка, и, если она длиннее, она заменит цепочку на этом узле новой более длинной цепочкой. Это потому, что самая длинная цепочка

7. Теперь мы можем снова проверить цепочку на узле 8000:

Теперь мы видим, что новый блок был добыт и добавлен в цепочку, при этом новый запрос и транзакция предоставили текущему узлу 1 монету для добычи блока.

Заключение

Благодаря этому мы можем увидеть, как работает смоделированная сеть, регистрируя узлы, отправляя запросы, добывая блоки и определяя самую длинную цепочку между узлами. Фактический блокчейн для чего-то вроде Биткойна работает не так, но это простой пример, чтобы понять суть. У меня был большой опыт работы с Go, и я с нетерпением жду возможности использовать его в других проектах в будущем.