Развој блокчејна за индустрију користећи Го. Део 1

Већ четири месеца радим на пројекту под називом „Развој алата за заштиту података и управљање у државним и индустријским секторима заснованим на блокчејну“.
Сада бих желео да вам кажем како сам започео овај пројекат, а сада ћу детаљно описати програмски код.

Развој блокчејна за индустрију користећи Го. Део 1

Ово је први чланак у низу чланака. Овде описујем сервер и протокол. У ствари, читалац може чак и да напише сопствене верзије ових блокчејн елемената.

А ево и другог дела — о блокчејну и структурама података трансакција, као и о пакету који имплементира интеракцију са базом података.

Прошле године, на хакатону Дигитал Бреактхроугх, дошли су на идеју да направе користан систем за индустрију и дигиталну економију користећи технологију дистрибуиране књиге, а за развој је додељен и грант од стране Фонда за помоћ иновацијама (требало би да напишем посебно чланак о гранту, за оне који тек почињу да се баве стартаповима), а сада редом.

Развој се одвија у језику Го, а база података у којој се чувају блокови је ЛевелДБ.
Главни делови су протокол, сервер (који покреће ТЦП и ВебСоцкет - први за синхронизацију блокчејна, други за повезивање клијената, слање трансакција и команди из ЈаваСцрипт-а, на пример.

Као што је поменуто, овај блокчејн је првенствено потребан за аутоматизацију и заштиту размене производа између добављача и купаца, или обоје у једној особи. Ови људи не журе да верују једни другима. Али задатак није само да се направи „чековна књижица“ са уграђеним калкулатором, већ и систем који аутоматизује већину рутинских задатака који се јављају при раду са животним циклусом производа. Бајткод који је одговоран за ово питање, као што је уобичајено код блок ланца, чува се на улазима и излазима трансакција (сама трансакције се чувају у блоковима, блокови у ЛевелДБ-у су унапред кодирани у ГОБ формату). Прво, хајде да причамо о протоколу и серверу (ака чвор).

Протокол није компликован, цела његова поента је да се пређе на режим учитавања неких података, обично блока или трансакције, као одговор на посебну командну линију, а потребан је и за размену инвентара, тако да чвор зна ко је је повезан са и како имају посла (чворови повезани за сесију синхронизације се такође називају „суседни“ јер је њихова ИП адреса позната и подаци о њиховом стању се чувају у меморији).

Фасцикле (директоријуми како их Линук назива) у схватању Го програмера називају се пакети, тако да на почетку сваке датотеке са Го кодом из овог директоријума пишу назив фолдера_пакета_где се_ова_датотека налази. У супротном, нећете моћи да унесете пакет у компајлер. Па, ово није тајна за оне који знају овај језик. Ово су пакети:

  • Мрежна комуникација (сервер, клијент, протокол)
  • Структуре ускладиштених и пренетих података (блок, трансакција)
  • База података (блокчејн)
  • Консензус
  • Наслагана виртуелна машина (квм)
  • Помоћни (крипто, типови) то је све за сада.

Ево везе до гитхуб-а

Ово је образовна верзија, недостаје јој међупроцесна интеракција и неколико експерименталних компоненти, али структура одговара оној на којој се одвија развој. Ако имате нешто да предложите у коментарима, радо ћу то узети у обзир у даљем развоју. А сада за објашњење сервера и протокол.

Хајде да прво погледамо сервер.

Подрутина сервера делује као сервер података који ради на врху ТЦП протокола користећи структуре података из пакета протокола.

Рутина користи следеће пакете: сервер, протокол, типови. У самом пакету тцп_сервер.го садржи структуру података Послужити.

type Serve struct {
	Port string
	BufSize int
	ST *types.Settings
}

Може да прихвати следеће параметре:

  • Мрежни порт преко којег ће се размењивати подаци
  • Конфигурациони фајл сервера у ЈСОН формату
  • Означите за рад у режиму за отклањање грешака (приватни блок ланац)

Напредак:

  • Чита конфигурацију из ЈСОН датотеке
  • Ознака режима за отклањање грешака је означена: ако је постављена, планер мрежне синхронизације се не покреће и блок ланац се не учитава
  • Иницијализација структуре података о конфигурацији и покретање сервера

сервер

  • Врши покретање ТЦП сервера и мрежну интеракцију у складу са протоколом.
  • Има структуру података Серве која се састоји од броја порта, величине бафера и показивача на структуру врсте.Подешавања
  • Метода Рун покреће мрежну интеракцију (ослушкујући долазне везе на датом порту, када се прими нова веза, њена обрада се преноси на метод приватног руковања у новој нити)
  • В руковати подаци из везе се читају у бафер, претварају у стринг репрезентацију и прослеђују у протокол.Избор
  • протокол.Избор враћа резултат или изазива грешку. резултат затим пребачен у протокол.Интерпретекоји се враћа интрпр - објекат типа ИнтерпретеДата, или узрокује грешку у обради резултата избора
  • Затим се прекидач извршава интрпр.Цоммандс[0] који проверава једно од: резултат, инв, грешка и постоји одељак Уобичајено
  • У одељку резултат прекидач се налази по вредности интрпр.Цоммандс[1] који проверава вредности дужина пуфера и верзија (у сваком случају се позива одговарајућа функција)

Функције ГетВерсион и БуфферЛенгтх налазе се у фајлу срвлиб.го серверски пакет

GetVersion(conn net.Conn, version string)

једноставно се штампа на конзоли и клијенту шаље верзију која је предата у параметру:

conn.Write([]byte("result:" + version))

.
Функција

BufferLength(conn net.Conn, intrpr *protocol.InterpreteData)

учитава блок, трансакцију или друге специфичне податке на следећи начин:

  • Штампа на конзоли тип података наведен у протоколу који треба да се прихвати:
    fmt.Println("DataType:", intrpr.Commands[2])
  • Чита вредност интрпр.Боди на нумеричку променљиву буф_лен
  • Креира бафер невбуф наведена величина:
    make([]byte, buf_len)
  • Шаље у реду одговор:
    conn.Write([]byte("result:ok"))
  • Потпуно попуњава бафер из тока читања:
    io.ReadFull(conn, newbuf)

    .

  • Штампа садржај бафера на конзолу
    fmt.Println(string(newbuf))

    и број прочитаних бајтова

    fmt.Println("Bytes length:", n)
  • Шаље у реду одговор:
    conn.Write([]byte("result:ok"))

Методе из серверског пакета су конфигурисане за обраду примљених података коришћењем функција из пакета протокол.

Протокол

Протокол служи као средство које представља податке у мрежној размени.

Избор (стринг) (стринг, грешка) врши примарну обраду података примљених од сервера, прима стринг репрезентацију података као улаз и враћа стринг припремљен за Тумач:

  • Улазни низ се дели на главу и тело помоћу РекПарсеН2(стр)
  • глава је подељена на елементе и смештена у командни исечак помоћу РекПарсеХеад(хеад)
  • В прекидач(команде[0]) изаберите примљену команду (цмд, кључ, адреса или се одељак активира Уобичајено)
  • 2 команде су проверене у цмд-у свитцх(цоммандс[1]) — дужина и гетверсион.
  • дужина проверава тип података команде[2] и чува га у тип података
  • Проверава то тело садржи вредност низа
    len(body) < 1
  • Враћа низ одговора:
    "result:bufferlength:" + datatype + "/" + body
  • гетверсион враћа стринг
    return "result:version/auto"

Тумач

Садржи структуру ИнтерпретеДата и врши секундарну обраду података враћених из Избор струне и формирање објеката ИнтерпретеДата.

type InterpreteData struct {
	Head string
	Commands []string
	Body string
	IsErr bool
	ErrCode int 
	ErrMessage string
}

Функција

Interprete(str string) (*InterpreteData, error)

прихвата низ резултат и креира и враћа референцу на објекат ИнтерпретеДата.

Напредак:

  • Слично томе Избор глава и тело се извлаче помоћу РекПарсеН2(стр)
  • глава се дели на елементе помоћу РекПарсеХеад(глава)
  • Објекат је иницијализован ИнтерпретеДата и показивач на њега се враћа:

res := &InterpreteData{
	Head: head,
	Commands: commands,
	Body: body,
}
return res, nil

Овај објекат се користи у сервер.го пакет главни.

Купац

Клијентски пакет садржи функције ТЦПЦоннецт и ТЦПРеспонсеДата.

Функција

TCPConnect(s *types.Settings, data []byte, payload []byte)

функционише на следећи начин:

  • Успоставља се веза са везом наведеном у пренесеном објекту подешавања
    net.Dial("tcp", s.Host + ":" + s.Port)
  • Подаци прослеђени у параметру података се преносе:
    conn.Write(data)
  • Одговор је прочитан
    resp, n, _ := TCPResponseData(conn, s.BufSize)

    и одштампан на конзоли

    fmt.Println(string(resp[:n]))
  • Ако се пренесе корисна носивост затим га преноси даље
    conn.Write(payload)

    и такође чита одговор сервера, штампајући га на конзоли

Функција

 TCPResponseData(conn net.Conn, bufsiz int) ([]byte, int, error)

креира бафер одређене величине, тамо чита одговор сервера и враћа овај бафер и број прочитаних бајтова, као и објекат грешке.

Подпрограм клијента

Служи за слање команди серверима чворова, као и за добијање кратке статистике и тестирања.

Може да прихвати следеће параметре: конфигурациону датотеку у ЈСОН формату, податке који се шаљу на сервер као стринг, путању до датотеке која се шаље у корисни терет, заставицу емулације планера чворова, тип података који се преноси као нумеричка вредност.

  • Добијање конфигурације
    st := types.ParseConfig(*config)
  • Ако је ему застава прослеђена, она почиње схедулер
  • Ако је дата ознака ф која означава путању до датотеке, онда учитавамо њене податке фдб а садржај се шаље на сервер
    client.TCPConnect(st, []byte(CMD_BUFFER_LENGTH + ":" + strconv.Itoa(*t) + "/" + strconv.Itoa(fdblen)), fdb)
  • Ако датотека није наведена, онда се подаци из заставице једноставно шаљу -d:
    client.TCPConnect(st, []byte(*data), nil)

Све ово је поједностављен приказ који показује структуру протокола. Током развоја, његовој структури се додаје неопходна функционалност.

У другом делу ћу говорити о структурама података за блокове и трансакције, у 3 о ВебСоцкет серверу за повезивање са ЈаваСцрипт-а, у 4 ћу погледати планер синхронизације, затим стек машину која обрађује бајт код са улаза и излаза, криптографију и базени за излазе.

Извор: ввв.хабр.цом

Додај коментар