- Оригинальный адрес:Code your own blockchain mining algorithm in Go!
- Оригинальный автор:Coral Health
- Перевод с:Программа перевода самородков
- Постоянная ссылка на эту статью:GitHub.com/rare earth/gold-no…
- Переводчик:EmilyQiRabbit
- Корректор:stormluke,mingxing47
Если у вас есть какие-либо вопросы или предложения по приведенным ниже руководствам, присоединяйтесь к нам. Telegram Группа сообщений, вы можете спросить нас все, что хотите спросить!
В связи с недавними пожарами на майнинге биткойнов и эфириума легко задаться вопросом, почему происходит вся эта суета. Для новичков в этой области они услышат некоторые сумасшедшиеистория: Люди заполняют склады графическими процессорами и каждый месяц зарабатывают криптовалюту на миллионы долларов. Что такое майнинг электронной валюты? Как это работает? Как мне попробовать написать свой алгоритм майнинга?
В этом блоге мы ответим на каждый из вышеперечисленных вопросов и завершим учебник, который научит вас писать собственный алгоритм майнинга. Алгоритм, который мы вам покажем, называетсядоказательство работы, который является основой для двух самых популярных электронных валют, Биткойн и Эфириум. Не волнуйтесь, через минуту мы объясним вам, как это работает.
Что такое майнинг электронной валюты
Чтобы быть ценными, электронные деньги должны иметь определенный дефицит. Если кто-то может производить столько биткойнов, сколько хочет, в любое время, биткойны бесполезны как валюта. (Подождите, разве этим не занимается Федеральная резервная система?пощечина) Алгоритм Биткойн будет выдавать некоторое количество биткойнов выигравшему участнику сети каждые десять минут с максимальным запасом около 122 лет. Этот график выпуска также в определенной степени контролирует инфляцию, поскольку нормированное предложение не полностью высвобождается в самом начале. Распространение будет все медленнее и медленнее с течением времени.
Процесс определения победителя и раздачи биткойнов требует от него выполнения определенной «работы» и конкуренции с кем-то, кто также выполняет эту работу. Этот процесс называетсядобыча, потому что это очень похоже на то, как шахтеры проводят свое время, выполняя свою работу и в конечном итоге (надеюсь) находя золото.
Алгоритм Биткойн требует, чтобы участники или узлы выполняли работу и конкурировали друг с другом, чтобы гарантировать, что биткойны не будут выпущены слишком быстро.
Как работает майнинг?
Быстрый поиск в Google по запросу «как работает майнинг биткойнов?» даст вам много страниц ответов, объясняющих, что для майнинга биткойнов требуется узел (вы или ваш компьютер).решить сложную математическую задачу. Хотя технически это верно, просто называть это «математической» проблемой слишком легкомысленно и банально. Очень интересно понять внутреннюю работу майнинга. Чтобы узнать, как работает майнинг, нам сначала нужно понять алгоритмы шифрования и хэши.
Краткое введение в хэш-шифрование
Одностороннее шифрованиеВходное значение представляет собой читаемый открытый текст, например «Hello world», и применение к нему функции (например, математической задачи) приводит к нечитаемому результату. Эти функции (или алгоритмы) различаются по характеру и сложности. Чем сложнее алгоритм, тем сложнее расшифровать обратную операцию. Таким образом, алгоритмы шифрования могут эффективно защищать такие вещи, как пароли пользователей и военные коды.
Давайте рассмотрим пример SHA-256, популярного алгоритма шифрования. этохэш-сайтПозволяет легко вычислять хэши SHA-256. Давайте хешируем «Hello world», чтобы посмотреть, что мы получим:
Попробуйте хешировать «Hello world» несколько раз. Каждый раз вы будете получать один и тот же хэш. При одних и тех же входных данных в программу повторные вычисления дадут один и тот же результат, который называется идемпотентностью.
Одним из основных свойств алгоритмов шифрования является то, что трудно вывести входное значение с помощью обратной операции, но легко проверить выходное значение (по входному значению). Например, с алгоритмом хеширования SHA-256, описанным выше, кто-то еще, применяя алгоритм хеширования SHA-256 к «Hello world», может легко убедиться, что он действительно выводит тот же результат хеширования, но хочет извлечь тот же хэш из It. получается, что "Hello world" будеточень сложно. Поэтому такие алгоритмы называютсяоднонаправленный.
Принятие биткойновДвойной SHA-256Алгоритм, этот алгоритм просто SHA-256опять такиХэш-значение SHA-256 применено к «Hello world». В этом уроке мы будем применять только алгоритм SHA-256.
добыча
Теперь, когда мы знаем, что такое алгоритм шифрования, мы можем вернуться к вопросу майнинга криптовалюты. Биткойн должен найти какой-то способ «работать» для участников, которые хотят биткойн, чтобы биткойн не выпускался слишком быстро. Биткойн делает это, прося участников продолжать хэшировать числа и буквы, пока они не найдут тот, который начинается с «0» из определенного количества цифр.
Например, вернуться кхэш-сайтЗатем выполните хеш-операцию на «886». Он сгенерирует хеш-значение с префиксом из трех нулей.
Но откуда мы знаем, что «886» дает результат, начинающийся с трех нулей? В этом-то и дело. Прежде чем писать этот блог, мыне имеют ни малейшего представления. По идее, нам нужно перебрать все комбинации цифр и букв, протестировать результаты, пока не получим результат, совпадающий с нужными нам тремя нулями. Чтобы дать вам простой пример, мы на самом деле предварительно вычислили и обнаружили, что хеш-значение «886» начинается с трех нулей.
Любой может легко проверить тот факт, что хеш-результат «886» начинается с трех нулей.доказал: Я проделал массу работы, чтобы протестировать и проверить множество комбинаций букв и цифр, чтобы получить этот результат. Итак, если я первым получу этот результат, я могу пройтиДоказыватьЯ действительно работал, чтобы получить биткойны — доказательство тому, что любой может легко проверить, что хэш «886» соответствует префиксу тройного нуля, как я утверждаю. Вот почему алгоритм консенсуса Биткойн называетсядоказательство работы.
Но что, если мне повезет, и я получу префикс с тройным нулем с первой попытки? Это почти невозможно, и узлы, которые случайно майнят блок в первый раз (доказывая, что они сделали работу), перегружены тысячами людей, которые выполняют дополнительную работу, чтобы найти правильный хэш. Перегружены другими блоками. Чтобы попробовать, введите любую другую комбинацию букв и цифр на сайте, который вычисляет хэш. Бьюсь об заклад, вы не получите результат, начинающийся с тройного нуля.
Требования Биткойна намного сложнее (больше нулей с префиксом!), а возможность динамически корректировать требования гарантирует, что работа не будет ни слишком сложной, ни слишком легкой. Помните, что цель состоит в том, чтобы выпускать биткойны каждые десять минут, поэтому, если майнингом занимается слишком много людей, необходимо скорректировать доказательство работы, чтобы его было сложнее выполнить. это называетсяНастройка сложности. Для наших целей корректировка сложности означает, что требуется больше нулевых префиксов.
Теперь вы знаете, что механизм консенсуса Биткойн гораздо интереснее, чем простое «решение математической задачи»!
Достаточно предыстории. Приступаем к программированию!
Теперь, когда у нас достаточно информации, давайте создадим собственную программу Биткойн, используя алгоритм консенсуса рабочей нагрузки. Мы собираемся написать его на Go, потому что мы используем его в Coral Health, и, честно говоря,Превосходно.
Прежде чем приступить к следующему шагу, я предлагаю читателям прочитать нашу предыдущую запись в блоге,Code your own blockchain in less than 200 lines of Go!.Это несложное требование, но в следующем примере мы будем грубыми. Если вам нужна дополнительная информация, вы можете обратиться к предыдущему блогу. Если вы знакомы с предыдущей статьей, сразу переходите к разделу «Доказательство работы» ниже.
структура
У нас будет сервис Go, мы просто поместим весь код в одинmain.go
в файле. Этот файл будет содержать всю необходимую нам логику блокчейна (включая алгоритм проверки работоспособности) и включать все обработчики интерфейса REST. Данные блокчейна неизменны, нам нужно толькоGET
а такжеPOST
просить. Мы будем использовать браузер для отправкиGET
запрос на просмотр данных и использованиеPostmanотправлятьPOST
запрос на новый блок (curl
так же работает).
упаковка
Начнем со стандартной операции импорта. обязательно используйтеgo get
чтобы получить следующие пакеты
github.com/davecgh/go-spew/spew
Красиво распечатайте свой блокчейн в терминале
github.com/gorilla/mux
Простой в использовании слой для подключения к вашим веб-сервисам
github.com/joho/godotenv
в корневом каталоге.env
Прочитайте переменные среды из файла
Давайте создадим его в корневом каталоге.env
файл, который просто содержит переменную среды, которую мы будем использовать через мгновение. существует.env
Напишите строку в файле:ADDR=8080
.
Сделайте объявление на пакете и в корневом каталогеmain.go
Импорт определения:
package main
import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
"strconv"
"strings"
"sync"
"time"
"github.com/davecgh/go-spew/spew"
"github.com/gorilla/mux"
"github.com/joho/godotenv"
)
если ты читаешьпредыдущие статьи, вы должны запомнить эту схему. Блоки в блокчейне можно сравнивать, сравниваяprevious hashЗначение атрибута и хэш предыдущего блока проверяются. Вот как блокчейн защищает свою целостность и почему хакерские группы не могут изменить историю блокчейна.
BPM
это частота сердечных сокращений, то есть количество ударов в минуту. Мы будем использовать ваше количество сердечных сокращений за одну минуту в качестве данных, которые мы помещаем в блокчейн. Положите два пальца на запястье и посчитайте, сколько раз ваш пульс бьется за одну минуту, и запомните это число.
некоторые основные зонды
Давайте добавим модель данных и другие переменные, которые понадобятся после импорта вmain.go
документ
const difficulty = 1
type Block struct {
Index int
Timestamp string
BPM int
Hash string
PrevHash string
Difficulty int
Nonce string
}
var Blockchain []Block
type Message struct {
BPM int
}
var mutex = &sync.Mutex{}
difficulty
— это константа, определяющая количество нулевых префиксов, которые мы хотим получить в результате хеширования. Чем больше нулей вам нужно получить, тем сложнее найти правильный ввод хеша. Начнем с нуля.
Block
является моделью данных каждого блока. не волнуйся не понимаюNonce
, что мы объясним позже.
Blockchain
это серияBlock
, представляющий полную цепочку.
Message
то, что мы используем в интерфейсе RESTPOST
Запрос передан для создания новогоBlock
Информация.
Объявляем тот, который будет использоваться позжеmutex
Чтобы предотвратить конкуренцию данных и гарантировать, что несколько блоков не будут генерироваться в один и тот же момент времени.
веб-сервис
Быстро подключимся к сетевому сервису. Создаватьrun
функцию, позже вmain
Позвоните ему, чтобы поддержать службу. также нужноmakeMuxRouter()
Объявите функцию обработчика маршрута в . Помните, нам нужно использовать толькоGET
метод отслеживания содержимого блокчейна,POST
метод создания блока. Блокчейн нельзя изменить, поэтому нам не нужно изменять и удалять операции.
func run() error {
mux := makeMuxRouter()
httpAddr := os.Getenv("ADDR")
log.Println("Listening on ", os.Getenv("ADDR"))
s := &http.Server{
Addr: ":" + httpAddr,
Handler: mux,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
if err := s.ListenAndServe(); err != nil {
return err
}
return nil
}
func makeMuxRouter() http.Handler {
muxRouter := mux.NewRouter()
muxRouter.HandleFunc("/", handleGetBlockchain).Methods("GET")
muxRouter.HandleFunc("/", handleWriteBlock).Methods("POST")
return muxRouter
}
httpAddr := os.Getenv("ADDR")
начнется с того, что мы только что создали.env
Вытащить порт из файла:8080
. Мы можем получить доступ к браузеру[http://localhost:8080](http://localhost:8080)
для доступа к приложению.
Давай напишемGET
Функция обработчика для распечатки блокчейна в браузере. Мы также добавим простойrespondwithJSON
функция, она сообщит нам сообщение об ошибке в формате JSON, когда возникнет ошибка при вызове интерфейса.
func handleGetBlockchain(w http.ResponseWriter, r *http.Request) {
bytes, err := json.MarshalIndent(Blockchain, "", " ")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
io.WriteString(w, string(bytes))
}
func respondWithJSON(w http.ResponseWriter, r *http.Request, code int, payload interface{}) {
w.Header().Set("Content-Type", "application/json")
response, err := json.MarshalIndent(payload, "", " ")
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("HTTP 500: Internal Server Error"))
return
}
w.WriteHeader(code)
w.Write(response)
}
Помните, если вы считаете, что эта часть объяснения слишком схематична, обратитесь кпредыдущие статьи, каждый шаг этой части более подробно объясняется здесь.
написать сейчасPOST
функция обработчика. С помощью этой функции мы добавляем новые блоки. Мы используем Postman для отправкиPOST
Запросите, отправьте тело JSON, например{“BPM”:60}
,прибыть[http://localhost:8080](http://localhost:8080)
, и укажите частоту сердечных сокращений, которую вы измерили ранее.
func handleWriteBlock(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
var m Message
decoder := json.NewDecoder(r.Body)
if err := decoder.Decode(&m); err != nil {
respondWithJSON(w, r, http.StatusBadRequest, r.Body)
return
}
defer r.Body.Close()
//ensure atomicity when creating new block
mutex.Lock()
newBlock := generateBlock(Blockchain[len(Blockchain)-1], m.BPM)
mutex.Unlock()
if isBlockValid(newBlock, Blockchain[len(Blockchain)-1]) {
Blockchain = append(Blockchain, newBlock)
spew.Dump(Blockchain)
}
respondWithJSON(w, r, http.StatusCreated, newBlock)
}
уведомлениеmutex
Блокировка (блокировка) и разблокировка (разблокировка). Перед записью нового блока необходимо заблокировать блокчейн, иначе многократная запись приведет к гонкам данных. Проницательные читатели также заметятgenerateBlock
функция. Это ключевая функция для работы с доказательством работы. Мы объясним это позже.
Основные функции блокчейна
Перед запуском алгоритма проверки работоспособности давайте подключим основные функции блокчейна. мы добавимisBlockValid
функция, чтобы убедиться, что индекс увеличивается правильно, а текущий блокPrevHash
и предыдущий блокHash
значение совпадает.
Мы также добавимcalculateHash
функция, которая генерирует то, что нам нужно использовать для созданияHash
а такжеPrevHash
хэш-значение. Это индекс, метка времени, BPM, хэш предыдущего блока иNonce
Хэш SHA-256 (мы объясним, что это такое позже).
func isBlockValid(newBlock, oldBlock Block) bool {
if oldBlock.Index+1 != newBlock.Index {
return false
}
if oldBlock.Hash != newBlock.PrevHash {
return false
}
if calculateHash(newBlock) != newBlock.Hash {
return false
}
return true
}
func calculateHash(block Block) string {
record := strconv.Itoa(block.Index) + block.Timestamp + strconv.Itoa(block.BPM) + block.PrevHash + block.Nonce
h := sha256.New()
h.Write([]byte(record))
hashed := h.Sum(nil)
return hex.EncodeToString(hashed)
}
доказательство работы
Давайте посмотрим на алгоритм майнинга, или Proof of Work. Мы хотим убедиться, что алгоритм проверки работоспособности разрешает новый блокBlock
добавить в блокчейнblockchain
Это было сделано раньше. Начнем с простой функции, которая проверяет, соответствует ли хеш-значение, сгенерированное в алгоритме доказательства работы, установленным нами требованиям.
Наши требования следующие:
- Хэш-значение, сгенерированное алгоритмом проверки работоспособности, должно начинаться с определенного количества нулей.
- Количество нулей определяется константой
difficulty
решение, определяется в самом начале программы (в примере это 1) - Мы можем усложнить алгоритм проверки работоспособности, увеличив значение сложности
Выполните следующую функцию,isHashValid
:
func isHashValid(hash string, difficulty int) bool {
prefix := strings.Repeat("0", difficulty)
return strings.HasPrefix(hash, prefix)
}
Иди в егоstrings
Удобно в сумкеRepeat
а такжеHasPrefix
функция. мы определяем переменныеprefix
как мы вdifficulty
Копия определенных нулей. Затем мы проверяем значение хеша, чтобы увидеть, начинается ли оно с этих нулей, и если да, возвращаемTrue
в противном случае вернутьсяFalse
.
Теперь мы создаемgenerateBlock
функция.
func generateBlock(oldBlock Block, BPM int) Block {
var newBlock Block
t := time.Now()
newBlock.Index = oldBlock.Index + 1
newBlock.Timestamp = t.String()
newBlock.BPM = BPM
newBlock.PrevHash = oldBlock.Hash
newBlock.Difficulty = difficulty
for i := 0; ; i++ {
hex := fmt.Sprintf("%x", i)
newBlock.Nonce = hex
if !isHashValid(calculateHash(newBlock), newBlock.Difficulty) {
fmt.Println(calculateHash(newBlock), " do more work!")
time.Sleep(time.Second)
continue
} else {
fmt.Println(calculateHash(newBlock), " work done!")
newBlock.Hash = calculateHash(newBlock)
break
}
}
return newBlock
}
мы создалиnewBlock
и поместите хэш предыдущего блока вPrevHash
свойств, чтобы обеспечить непрерывность блокчейна. Значения других свойств просты:
-
Index
Инкрементный -
Timestamp
это строка, представляющая текущее время -
BPM
это частота сердечных сокращений, которую вы записали ранее -
Difficulty
Он напрямую получается из константы в начале программы. Мы не будем использовать это свойство в этом руководстве, но если нам нужно выполнить дополнительную проверку и подтвердить, что значение сложности фиксировано для результата хеширования (т. е. результат хеширования начинается с N нулей, тогда значение сложности также должно быть равно N, иначе блокчейн сломается), это полезно.
for
Цикл является критической частью этой функции. Рассмотрим подробнее, что здесь сделано:
- мы установим
Nonce
равныйi
шестнадцатеричное представление . нам нужна функцияcalculateHash
Метод добавления изменяющегося значения к сгенерированному хэшу, чтобы, если мы не получили ожидаемое количество нулевых префиксов, мы могли повторить попытку с новым значением.Значение изменения, которое мы добавляем к объединенной строке**calculateHash**
под названием "Ононс" - В цикле мы используем
i
и Nonce на основе 0 для вычисления хеш-значения и проверки, начинается ли результат с константыdifficulty
Начинается с определенного количества нулей. Если нет, мы начинаем следующий цикл с увеличивающимся Nonce и пытаемся снова. - Мы добавили задержку в одну секунду, чтобы имитировать время решения алгоритма проверки работоспособности.
- Мы продолжаем цикл, пока не получим нулевой префикс, который нам нужен, что означает, что мы успешно завершили доказательство работы. Если и только после этого наша
Block
пройти черезhandleWriteBlock
добавлена функция обработчикаblockchain
.
Мы написали все функции, теперь давайте закончимmain
функция:
func main() {
err := godotenv.Load()
if err != nil {
log.Fatal(err)
}
go func() {
t := time.Now()
genesisBlock := Block{}
genesisBlock = Block{0, t.String(), 0, calculateHash(genesisBlock), "", difficulty, ""}
spew.Dump(genesisBlock)
mutex.Lock()
Blockchain = append(Blockchain, genesisBlock)
mutex.Unlock()
}()
log.Fatal(run())
}
Мы используемgodotenv.Load()
Функция загружает переменные среды, которые используются для доступа в браузере.:8080
порт.
Процедура go создает блок генезиса, потому что он нужен нам как отправная точка для блокчейна.
Используем только что созданныйrun()
Функция запускает сетевую службу.
законченный! Время запустить его!
Полный код здесь.
Давайте попробуем запустить этого ребенка!
использоватьgo run main.go
чтобы запустить программу
а затем используйте браузер для доступа[http://localhost:8080](http://localhost:8080)
:
Блок генезиса был создан для нас. Теперь откройте Postman и отправьтеPOST
запрос, отправляющий ранее измеренное значение сердечного ритма в теле в формате JSON по тому же маршруту.
После отправки запроса,Посмотрите, что происходит в терминале. Вы увидите, что ваша машина занята созданием новых хэшей с увеличением значений Nonce, пока не найдет нужное значение с нулевым префиксом.
Когда алгоритм доказательства работы завершен, мы получаем полезныйwork done!
сообщение, мы можем проверить хеш-значение, чтобы увидеть, действительно ли оно соответствует тому, что мы установили.difficulty
начать с нуля. Это означает, что теоретически новый блок, в который мы пытались добавить информацию о BPM = 60, уже добавлен в наш блокчейн.
Обновим браузер и увидим:
удалось! Наш второй блок был добавлен после блока генезиса. Это означает, что мы успешноPOST
Блок отправляется в запросе, этот запрос запускает процесс майнинга, и он добавляется в цепочку блоков тогда и только тогда, когда алгоритм доказательства работы завершен.
следующий
отличный! То, что вы только что узнали, действительно важно. Алгоритм доказательства работы является основой Биткойн, Эфириум и многих других крупных блокчейн-платформ. То, что мы только что узнали, не тривиально; хотя в нашем примере мы использовали низкое значение сложности, увеличьте его до относительно большого значения.точноКак алгоритм проверки работоспособности блокчейна работает в производственной среде.
Теперь, когда у вас есть четкое представление об основных частях технологии блокчейна, вам решать, как изучать ее дальше. Я рекомендую вам следующие ресурсы:
- в нашемNetworking tutorialИз этого руководства вы узнаете, как работают сетевые блокчейны.
- в нашемIPFS tutorialИз этого руководства вы узнаете, как хранить большие файлы распределенным образом и взаимодействовать с блокчейном.
Если вы готовы совершить еще один технический скачок, попробуйте научитьсяДоказательство долиалгоритм. В то время как большинство блокчейнов используют алгоритм доказательства работы в качестве алгоритма консенсуса, алгоритм доказательства доли получает все больше и больше внимания. Многие считают, что Ethereum в будущем перейдет с алгоритма доказательства работы на алгоритм доказательства доли.
Хотите увидеть руководство по сравнению алгоритмов proof-of-work и proof-of-stake? Нашли ошибку в коде выше? Как то, что мы делаем? Ненавидите то, что мы делаем?
пройти через Присоединяйтесь к нашей группе в Telegram Поделитесь с нами вашими мыслями! Вы получите восторженный отклик от автора этого руководства и остальных членов команды Coral Health.
Чтобы узнать больше о Coral Health и о том, как мы используем блокчейн для улучшения исследований в области личной медицины, посетите нашВеб-сайт.
Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из Интернета сНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,продукт,дизайн,искусственный интеллектЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.