Как создать свой блокчейн с нуля при помощи Go? Часть 3

Цель этого гайда – разобрать технологические составляющие блокчейна на практике. Для этого рассмотрим кейс разработки собственного блокчейна с нуля.

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

4. Человеческая жадность

Клиент бара BabaYaga слишком увлекся инвестированием. Он забыла, что подходит срок оплаты аренды, и у нее не осталось свободных средств. Баба Яга звонит хозяину квартиры Цезарю.

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

Цезарь: Это еще почему?

Баба Яга: Ну, ICO Blockchain Bar предлагали огромные бонусы и я купил токенов на $2000 всего за $1000. Это была отличная сделка!

Цезарь: Что за дичь? Что за ICO? Что за токены? Заплати мне нормальными деньгами.

Баба Яга: Давай так – я дам тебе 1000 TBB токенов, которые стоят $1000. Ты можешь потратить их в баре и расплачиваться за выпивку! Я позвоню владельцу бара, и он быстренько переведет тебе токены.

Цезарь: Ну ладно, я их приму.

Андрей проводит транзакцию, но решает снять 50 TBB комиссии за потраченное время. Ему-то самому этого, конечно, не хочется, но акционеры бара требуют приносить прибыль как можно быстрее. 

“Баба Яга все равно не заметит крошечной комиссии”, – подумал Андрей. В конце-концов, доступ к базе данных есть только у него.

 // Rent payment
✍tbb tx add --from=babayaga --to=caesar --value=1000
// hidden fee charge
✍ tbb tx add --from=babayaga --to=andrej --value=50
// new reward for another day of maintaining the DB
✍ tbb tx add --from=andrej --to=andrej --value=100 --data=reward

5. Зачем нам нужен блокчейн?

Баба Яга заходит в бар отмечать свой день рождения.

Баба Яга: Привет, Андрей! Сегодня мой день рождения! Давай свою самую дорогую бутылку!

Андрей: С днем рождения! Вот, прошу – водка Crystal Head. Но тебе нужно докупить еще один TBB токен. Бутылка стоит 950 TBB, а у тебя на балансе всего 949.

Баба Яга: В смысле?? У меня на балансе должно быть 999 TBB!

Андрей: Перевод денег Цезарю стоил тебе 50 токенов.

Баба Яга: Это недопустимо! Я бы никогда не согласился на такую комиссию. Так нельзя делать, Андрей. Я доверил твоей системе, а ты меня кинул. Так не пойдет.

Андрей: Ладно, послушай. Ты мой самый частый клиент, и я не хотел с тебя стягивать деньги, но меня заставили акционеры. Давай я перепишу систему и сделаю ее полностью прозрачной и децентрализованной. Если все смогут взаимодействовать с баром без моего посредничества, это должно повысить уровень доверия!

1. Заказ напитков будет занимать секунды, а не минуты

2. Пользователи, которые забыли кошельки дома, могут одалживать токены друг у друга.

3. Если у всех есть копия базы данных, владелец не может ее потерять.

4. База данных будет неизменна, никто не сможет внести правки в нее.

5. Если акционеры захотят поднять комиссии или представить новые механизмы, все участники будут в курсе и смогут согласиться или отказаться от изменений. 

Баба Яга: Звучит, конечно, хорошо. Ты уверен, что это выполнимо?

Андрей: Думаю да.

Баба Яга: Ну тогда иди и занимайся своими блокчейнами.

Как создать неизменную базу данных?

Если Андрей хочет выяснить как создать неизменную базу данных, сначала ему нужно узнать почему остальные базы данных изначально изменяемы. Он решил изучить базу данных MySQL:

В MySQL DB любой, у кого есть доступ, может внести изменение в таблицу:

UPDATE user_balance SET balance = balance + 100 WHERE id > 1

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

6. Неизменность при помощи функции хэш

Процесс хэширования – это преобразование данных произвольного размера в короткую строку определенного размера. Любое изменение изначальных данных приведет к созданию нового хэша.

package main
import (
	"crypto/sha256"
	"fmt"
)
func main() {
	balancesHash := sha256.Sum256([]byte("| 1 | Andrej | 99895 |"))
	fmt.Printf("%xn", balancesHash)
	// Output: 6a04bd8e2...f70a3902374f21e089ae7cc3b200751
	// Change balance from 99895 -> 99896
	balancesHashDiff := sha256.Sum256([]byte("| 1 | Andrej | 99896 |"))
fmt.Printf("%xn", balancesHashDiff)
	// Output: d04279207...ec6d280f6c7b3e2285758030292d5e1
}

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

1. Детерминированная – одинаковое сообщение всегда будет иметь одинаковый хэш

2. Небольшое изменение в сообщении полностью изменяет хэш

3. Имея в наличии хэш невозможно сгенерировать изначальное сообщение, только перепробовав все возможные варианты

4. Невозможно найти два разных сообщения с одинаковым хэшем.

Андрей модифицирует функцию Persist(), что бы она делала Snapshot хэша каждый раз, когда сохраняется новая транзакция.

type Snapshot [32]byte

Snapshot производится новой функцией sha256 secure hashing

func (s *State) doSnapshot() error {
   // Re-read the whole file from the first byte
   _, err := s.dbFile.Seek(0, 0)
   if err != nil {
      return err
   }
   txsData, err := ioutil.ReadAll(s.dbFile)
   if err != nil {
      return err
   }
   s.snapshot = sha256.Sum256(txsData)
   return nil

Когда новая транзакция записывается в файл tx.db , Persist() хэширует весь файл и возвращает 32-байтный хэш-отпечаток.

С этого момента каждый клиент может 100% конфиденциально и безопасно получить нужный набор данных при помощи нужного снимка.

Время попрактиковаться

1. Запустите команду tbb balances list и проверьте совпадают ли балансы.

2. Уберите две последние строчки из ./database/tx.db и проверьте балансы заново.

3. Выплатим награду Андрею за два дня работы:

Транзакция 1

✍ tbb tx add --from=andrej --to=andrej --value=100 --data=reward
Persisting new TX to disk:
       {"from":"andrej","to":"andrej","value":100,"data":"reward"}
New DB Snapshot: ff2470c7043f5a34169b5dd38921ba6825b03b3facb83e426
TX successfully persisted to the ledger.

Транзакция 2

✍ tbb tx add --from=andrej --to=andrej --value=100 --data=reward
Persisting new TX to disk:
       {"from":"andrej","to":"andrej","value":100,"data":"reward"}       
New DB Snapshot: 7d4a360f468b837b662816bcdc52c1869f99327d53ab4a9ca
TX successfully persisted to the ledger.

4. Запустите команду tbb balances list и убедитесь, что все снимки хэшей совпадают с изначальными.

✍ tbb balances list
Account balances at 7d4a360f465d...

| id | name     | balance |
| -- | -------- | ------- |
| 1  | Andrej   | 999251  |
| 2  | BabaYaga | 949     | 
| 3  | Caesar   | 1000    |


Готово!

Так как криптографическая хэш функция sha256 производит одинаковую строку при одинаковых входных данных вы можете повторить эти шаги на своем компьютере и сгенерировать такую же базу данных и такие же хэши!

Заключение

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

Изменения в базе данных называются транзакциями. Транзакции – это события внутри системы, которые записываются на блокчейн.

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


Источник: forknews.io

Comments (0)
Add Comment