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

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

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

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


3. Создание интерфейса командной строки (CLI) 


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


Самый простой способ разработать CLI программу на GO - это использовать стороннюю библиотеку github.com/spf13/cobra.


Андрей подключает встроенного в Go менеджера go modules:

✍ cd $GOPATH/src/github.com/web3coach/the-blockchain-way-of-programming-newsletter-edition
✍ go mod init github.com/web3coach/the-blockchain-way-of-programming-newsletter-edition

Команда Go modules будет автоматически подтягивать любую библиотеку, которую вы выберите в файлах Go.


Андрей создает новый каталог под названием cmd с подкаталогом tbb:


✍mkdir -p ./cmd/tbb

Внутри каталога он создает файл main.go, служащий отправной точкой CLI программы.


package main
import (
    "github.com/spf13/cobra"
    "os"
    "fmt"
)
func main() {
    var tbbCmd = &cobra.Command{
        Use:   "tbb",
        Short: "The Blockchain Bar CLI",
        Run: func(cmd *cobra.Command, args []string) {
        },
    }
    err := tbbCmd.Execute()
    if err != nil {
        fmt.Fprintln(os.Stderr, err)
        os.Exit(1)
    }
}

Программы GO компилируются при помощи команды install :


✍ go install ./cmd/tbb/...
go: finding github.com/spf13/cobra v1.0.0
go: downloading github.com/spf13/cobra v1.0.0
go: extracting github.com/spf13/cobra v1.0.0

Go будет находить недостающие библиотеки и автоматически подтягивать их перед тем как компилировать программу. В зависимости от $GOPATH результат будет сохраняться в папку $GOPATH/bin.


✍echo $GOPATH
/home/web3coach/go
✍which tbb
/home/web3coach/go/bin/tbb

Вы можете запустить tbb из своего терминала хоть сейчас, но ничего не произойдет, так как функция Run внутри файла main.go пуста. 


Для начала Андрею нужно управлять версиями (versioning support) для tbb. Рядом с файлом main.go он создает команду version.go:

 package main
import (
    "fmt"
    "github.com/spf13/cobra"
)
const Major = "0"
const Minor = "1"
const Fix = "0"
const Verbal = "TX Add && Balances List"
var versionCmd = &cobra.Command{
    Use:   "version",
    Short: "Describes version.",
    Run: func(cmd *cobra.Command, args []string) {
        fmt.Printf("Version: %s.%s.%s-beta %s", Major, Minor, Fix, Verbal)
    },
}

Компилирует ее и запускает:

✍ go install ./cmd/tbb/...
✍ tbb version
Version: 0.1.0-beta TX Add && Balances List

Готово.


Идентично с файлом version.go он создает файл balances.go


func balancesCmd() *cobra.Command {
    var balancesCmd = &cobra.Command{
        Use:   "balances",
        Short: "Interact with balances (list...).",
        PreRunE: func(cmd *cobra.Command, args []string) error {
            return incorrectUsageErr()
        },
        Run: func(cmd *cobra.Command, args []string) {
        },
    }
    balancesCmd.AddCommand(balancesListCmd)
   return balancesCmd
}

Команда balances будет ответственна за загрузку последнего State базы данных и отображение информации:


var balancesListCmd = &cobra.Command{
    Use:   "list",
    Short: "Lists all balances.",
    Run: func(cmd *cobra.Command, args []string) {
        state, err := database.NewStateFromDisk()
        if err != nil {
            fmt.Fprintln(os.Stderr, err)
            os.Exit(1)
        }
        defer state.Close()
        fmt.Println("Accounts balances:")
        fmt.Println("__________________")
        fmt.Println("")
        for account, balance := range state.Balances {
            fmt.Println(fmt.Sprintf("%s: %d", account, balance))
        }
    },
}

Теперь команда должна выдавать те же балансы, которые указаны в файле Genesis, так как tx.db все еще пуста.


✍ go install ./cmd/tbb/...
✍ tbb balances list
Accounts balances:
__________________
andrej: 1000000

Все работает как надо. Теперь ему нужна команда для записи деятельности бара. Андрей создает команду ./cmd/tbb/tx.go


func txCmd() *cobra.Command {
    var txsCmd = &cobra.Command{
        Use:   "tx",
        Short: "Interact with txs (add...).",
        PreRunE: func(cmd *cobra.Command, args []string) error {
            return incorrectUsageErr()
        },
        Run: func(cmd *cobra.Command, args []string) {
        },
    }
    txsCmd.AddCommand(txAddCmd())
    return txsCmd
}

Команда tbb tx add использует функцию State.Add(tx) для того, чтобы вносить события в баре в систему:


func txAddCmd() *cobra.Command {
    var cmd = &cobra.Command{
        Use:   "add",
        Short: "Adds new TX to database.",
        Run: func(cmd *cobra.Command, args []string) {
            from, _ := cmd.Flags().GetString(flagFrom)
            to, _ := cmd.Flags().GetString(flagTo)
            value, _ := cmd.Flags().GetUint(flagValue)
            fromAcc := database.NewAccount(from)
            toAcc := database.NewAccount(to)
            tx := database.NewTx(fromAcc, toAcc, value, "")
            state, err := database.NewStateFromDisk()
            if err != nil {
                fmt.Fprintln(os.Stderr, err)
                os.Exit(1)
            }  
            // defer means, at the end of this function execution,
            // execute the following statement (close DB file with all TXs)
            defer state.Close()
            // Add the TX to an in-memory array (pool)
            err = state.Add(tx)
            if err != nil {
                fmt.Fprintln(os.Stderr, err)
                os.Exit(1)
            }
            // Flush the mempool TXs to disk
            err = state.Persist()
            if err != nil {
                fmt.Fprintln(os.Stderr, err)
                os.Exit(1)
            }
            fmt.Println("TX successfully added to the ledger.")
        },
    }

Команда tbb tx add содержит три необходимых элемента: --from, --to , --value.


cmd.Flags().String(flagFrom, "", "From what account to send tokens")
cmd.MarkFlagRequired(flagFrom)
cmd.Flags().String(flagTo, "", "To what account to send tokens")
cmd.MarkFlagRequired(flagTo)
cmd.Flags().Uint(flagValue, 0, "How many tokens to send")
cmd.MarkFlagRequired(flagValue)
return cmd


Интерфейс командной строки готов!


Андрей переносит все записи со своей бумажной базы данных в электронную:

✍ tbb tx add --from=andrej --to=andrej --value=3
✍tbb tx add --from=andrej --to=andrej --value=700
✍tbb tx add --from=babayaga --to=andrej --value=2000
✍tbb tx add --from=andrej --to=andrej --value=100 --data=reward
✍tbb tx add --from=babayaga --to=andrej --value=1

Теперь он рассчитывает конечные балансы клиентов:

✍ tbb balances list

Accounts balances:

__________________

andrej: 998801

babayaga: 1999

Данные бара успешно восстановлены! 

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

Подписывайтесь на ForkNews в Telegram, чтобы быть в курсе новостей из мира криптовалют


По материалам www.freecodecamp.org

Читайте также

34052021-11-28

ТОП-10 крипто кошельков в 2021 году


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

Кошельки, Обучение
47192020-11-11

Что такое сжигание токенов?

Разберем что такое сжигание токенов и зачем криптовалютные проекты сжигают собственные токены.

Обучение

Последние статьи из раздела Обучение

Свежее видео на канале

Выбор редакции

212982024-07-25

LendPal.io объявляет о начале бета-тестирования

LendPal.io с объявляет о начале бета-тестирования своей инновационной платформы для криптовалютного P2P-кредитования.

Новости, Стабильные коины, Трейдинг, Инвестиции, Это интересно
688452020-10-30

Топ 10 крипто кошельков в 2020 году

По мере роста популярности криптовалют растет и спрос на качественные и безопасные криптовалютные кошельки.

Кошельки
607562017-12-10

Bitcoin: пирамида или нет?

С января 2009 года, когда был сгенерирован первый генезиз-блок bitcoin-сети, прошло уже девять лет, но до сих пор всякого рода "эксперты" ломают копья в спорах: являются ли криптовалюты финансовой пирамидой или нет. Быстрый рост доходности bitcoin и прибыли тех, кто раньше стал участником этой системы, пугает схожестью с пирамидами 90-х.

Bitcoin
582222018-04-28

on-chain и off-chain управление: за и против

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

Blockchain
456952021-05-08

Какие альткоины принесут своим держателям доход в 2021 году?

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

Альткоины
422942018-05-12

Эволюция человека и денег

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

Это интересно