Go аркылуу өнөр жай үчүн блокчейн иштеп чыгуу. 1-бөлүк

Төрт айдан бери мен “Блокчейндин негизинде мамлекеттик жана өнөр жай секторлорунда маалыматтарды коргоо жана башкаруу куралдарын иштеп чыгуу” аттуу долбоордун үстүндө иштеп жатам.
Эми мен бул долбоорду кантип баштаганым тууралуу айтып бергим келет, эми мен программалык кодду кеңири сүрөттөп берем.

Go аркылуу өнөр жай үчүн блокчейн иштеп чыгуу. 1-бөлүк

Бул макалалардын сериясындагы биринчи макала. Бул жерде мен серверди жана протоколду сүрөттөп берем. Чынында, окурман бул блокчейн элементтеринин өз версияларын да жаза алат.

Ал эми бул жерде экинчи бөлүгү болуп саналат — блокчейн жана транзакция маалыматтарынын структуралары жөнүндө, ошондой эле маалымат базасы менен өз ара аракеттенүүнү ишке ашырган пакет жөнүндө.

Өткөн жылы Digital Breakthrough хакатонунда алар бөлүштүрүлгөн бухгалтердик технологияларды колдонуу менен өнөр жай жана санариптик экономика үчүн пайдалуу система түзүү идеясын ойлоп табышты; Инновацияларга көмөк көрсөтүү фонду тарабынан өнүктүрүүгө грант да берилген (мен өзүнчө жазуу керек). грант жөнүндө макала, стартаптарды жаңыдан баштагандар үчүн ) жана азыр тартипте.

Иштеп чыгуу Go тилинде ишке ашат жана блоктор сакталган маалымат базасы LevelDB болуп саналат.
Негизги бөлүктөр протокол, сервер (TCP жана WebSocket иштетет - биринчиси блокчейнди синхрондоштуруу үчүн, экинчиси кардарларды туташтыруу, JavaScript'тен транзакцияларды жана буйруктарды жөнөтүү үчүн, мисалы.

Белгиленгендей, бул блокчейн биринчи кезекте жеткирүүчүлөр менен кардарлардын же экөөнүн тең бир адамда өнүмдөрдү алмашуусун автоматташтыруу жана коргоо үчүн керек. Бул адамдар бири-бирине ишенүүгө ашыкпайт. Бирок милдет - бул орнотулган калькулятор менен "чек китепчесин" түзүү гана эмес, бирок продукттун жашоо цикли менен иштөөдө пайда болгон күнүмдүк иштердин көпчүлүгүн автоматташтырган система. Бул маселе үчүн жооптуу байт-код, адаттагыдай эле, блокчейндерде, транзакциялардын киришинде жана чыгышында сакталат (транзакциялардын өзү блоктордо сакталат, LevelDBдеги блоктор GOB форматында алдын ала коддолгон). Биринчиден, протокол жана сервер (ака түйүн) жөнүндө сүйлөшөлү.

Протокол татаал эмес, анын бүт мааниси атайын буйрук сабына жооп катары кээ бир маалыматтарды, адатта блокту же транзакцияны жүктөө режимине өтүү болуп саналат, ошондой эле түйүн ким экенин билиши үчүн инвентаризацияны алмашуу үчүн керек. менен туташкан жана алардын кандайча бизнеси бар (синхрондоштуруу сеансы үчүн туташкан түйүндөр “коңшу” деп да аталат, анткени алардын IP дареги белгилүү жана алардын абалы маалыматтары эстутумда сакталат).

Папкалар (Linux аларды атаган каталогдор) Go программасын түшүнгөндө пакеттер деп аталат, андыктан бул каталогдон Go коду бар ар бир файлдын башында алар папканын_аты_кайда_бул_файл жайгашкандыгын жазышат. Болбосо, топтомду компиляторго бере албай каласыз. Ооба, бул тилди билгендер үчүн бул сыр эмес. Бул пакеттер:

  • Тармактык байланыш (сервер, кардар, протокол)
  • Сакталган жана берилүүчү маалыматтардын структуралары (блок, транзакция)
  • Маалыматтар базасы (блокчейн)
  • Консенсус
  • Үйүлгөн виртуалдык машина (xvm)
  • Көмөкчү (крипто, түрлөрү) азырынча бардыгы.

Бул жерде github шилтемеси

Бул билим берүү версиясы, анда процесстер аралык өз ара аракеттенүү жана бир нече эксперименталдык компоненттер жок, бирок түзүлүшү иштеп чыгуу жүрүп жаткан версияга туура келет. Эгерде сизде комментарийлерде сунуш кыла турган нерсе болсо, мен аны андан ары өнүктүрүүдө эске алууга кубанычта болом. Эми серверди түшүндүрүү үчүн жана протокол.

Адегенде серверди карап көрөлү.

Сервердин подпрограммасы TCP протоколунун үстүндө иштеген маалымат серверинин ролун аткарат, ал протокол пакетинен маалымат структураларын колдонот.

Режим төмөнкү пакеттерди колдонот: Server, протокол, түрлөрү. Пакеттин өзүндө tcp_server.go маалымат структурасын камтыйт кызмат кылуу.

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

Ал төмөнкү параметрлерди кабыл алат:

  • Маалыматтар алмаша турган тармак порту
  • JSON форматындагы сервер конфигурация файлы
  • Мүчүлүштүктөрдү оңдоо режиминде иштөө үчүн белги (жеке блокчейн)

Прогресс:

  • JSON файлынан конфигурацияны окуйт
  • Мүчүлүштүктөрдү оңдоо режиминин желеги текшерилди: эгер ал коюлган болсо, тармактын синхрондоштуруу пландоочусу иштетилбейт жана блокчейн жүктөлбөйт
  • Конфигурация маалымат структурасын инициализациялоо жана серверди ишке киргизүү

Server

  • TCP серверин ишке киргизүүнү жана протоколго ылайык тармактын өз ара аракеттенүүсүн ишке ашырат.
  • Анын порт номеринен, буфер өлчөмүнөн жана структурага көрсөткүчтөн турган Серв маалымат структурасы бар түрлөрү.Жөндөөлөр
  • Run методу тармактын өз ара аракеттенүүсүн баштайт (берилген портто кирүүчү байланыштарды угуу, жаңы туташуу алынганда, аны иштетүү жаңы жиптеги жеке тутка ыкмасына өткөрүлөт)
  • В туура туташуудан алынган маалыматтар буферге окулуп, сап көрсөтүүгө айландырылат жана ага өткөрүлөт протокол. Тандоо
  • протокол. Тандоо кайтып келет жыйынтык же ката кетирет. жыйынтык анан которулду протокол. интерпретациялоокайсы кайтып келет intrpr - типтеги объект InterpreteData, же тандоонун жыйынтыгын иштетүүдө ката кетирет
  • Андан кийин которуу ишке ашырылат intrpr.Commands[0] кайсы бирин текшерет: натыйжа, инв, ката жана бөлүм бар жарыяланбаган
  • Бөлүмдө жыйынтык которуштуруу мааниси боюнча табылат intrpr.Commands[1] баалуулуктарды текшерет буфер узундугу и версия (ар бир учурда тиешелүү функция чакырылат)

милдеттери GetVersion и BufferLength файлда бар srvlib.go сервер пакети

GetVersion(conn net.Conn, version string)

ал жөн гана консолго басып чыгарат жана параметрде берилген версияны кардарга жөнөтөт:

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

.
милдети

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

блокту, транзакцияны же башка конкреттүү маалыматтарды төмөнкүдөй жүктөйт:

  • Протоколдо көрсөтүлгөн, кабыл алынышы керек болгон маалыматтардын түрүн консолго басып чыгарат:
    fmt.Println("DataType:", intrpr.Commands[2])
  • Баасын окуйт intrpr.Body сандык өзгөрмөгө buf_len
  • Буферди түзөт newbuf белгиленген өлчөмү:
    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"))

Сервер пакетинин ыкмалары пакеттеги функцияларды колдонуу менен алынган маалыматтарды иштетүү үчүн конфигурацияланган протокол.

протоколу

Протокол тармак алмашууда маалыматтарды көрсөтүүчү каражат катары кызмат кылат.

Тандоо(str сап) (сап, ката) сервер тарабынан кабыл алынган маалыматтарды алгачкы иштетүүнү жүзөгө ашырат, киргизүү катары маалыматтардын сап көрсөтүүсүн алат жана даярдалган сапты кайтарат. Котормочу:

  • Киргизүү сап жардамы менен баш жана денеге бөлүнөт ReqParseN2(str)
  • баш элементтерге бөлүнөт жана ReqParseHead (баш) аркылуу буйруктар кесимине жайгаштырылат
  • В switch(буйруктар[0]) кабыл алынган буйрукту тандоо (cmd, ачкыч, дарек же бөлүм ишке киргизилет жарыяланбаган)
  • 2 буйрук cmd менен текшерилет switch(commands[1]) — узундук и алуу.
  • узундук маалымат түрүн текшерет буйруктар[2] жана аны сактайт берилиштер типи
  • Ошону текшерет дене сап маанисин камтыйт
    len(body) < 1
  • Жооп сабын кайтарат:
    "result:bufferlength:" + datatype + "/" + body
  • алуу сапты кайтарат
    return "result:version/auto"

Котормочу

InterpreteData структурасын камтыйт жана кайтарылган маалыматтарды экинчилик иштетүүнү жүзөгө ашырат тандоо саптар жана объект түзүү InterpreteData.

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

милдети

Interprete(str string) (*InterpreteData, error)

сапты кабыл алат жыйынтык жана объектке шилтеме жаратат жана кайтарат InterpreteData.

Прогресс:

  • Ошо сыяктуу эле, тандоо башы жана денеси алынып салынат ReqParseN2(str)
  • башы элементтерге бөлүнөт ReqParseHead(баш)
  • Объект инициализацияланган InterpreteData жана ага көрсөткүч кайтарылат:

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

Бул объект колдонулат server.go негизги пакет.

керектөөчү

Кардар пакети функцияларды камтыйт TCPConnect и TCPResponseData.

милдети

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)

көрсөтүлгөн өлчөмдөгү буферди түзөт, ал жерде сервердин жообун окуйт жана бул буферди жана окулган байттардын санын, ошондой эле ката объектисин кайтарат.

Кардардын подпрограммасы

Түйүн серверлерине буйруктарды жөнөтүү үчүн, ошондой эле кыска статистиканы жана тестирлөөлөрдү алуу үчүн кызмат кылат.

Төмөнкү параметрлерди кабыл ала алат: JSON форматындагы конфигурация файлы, сап катары серверге жөнөтүлө турган маалыматтар, пайдалуу жүккө жөнөтүлө турган файлга жол, түйүн пландоочу эмуляция желеги, сандык маани катары өткөрүлүп берилген маалыматтардын түрү.

  • Конфигурация алынууда
    st := types.ParseConfig(*config)
  • Эму желеги өтсө, ал башталат шедулер
  • Эгерде файлдын жолун көрсөткөн ф желек берилсе, анда биз анын маалыматтарын жүктөйбүз fdb жана мазмун серверге жөнөтүлөт
    client.TCPConnect(st, []byte(CMD_BUFFER_LENGTH + ":" + strconv.Itoa(*t) + "/" + strconv.Itoa(fdblen)), fdb)
  • Эгерде файл көрсөтүлбөсө, анда желектеги маалыматтар жөн гана жөнөтүлөт -d:
    client.TCPConnect(st, []byte(*data), nil)

Мунун баары протоколдун түзүмүн көрсөткөн жөнөкөйлөштүрүлгөн өкүлчүлүк. Иштеп чыгуу учурунда анын структурасына керектүү функциялар кошулат.

Экинчи бөлүктө мен блоктор жана транзакциялар үчүн маалымат структуралары жөнүндө, 3-бөлүмдө JavaScript-тен туташуу үчүн WebSocket сервери жөнүндө, 4-бөлүмдө синхрондоштуруу пландоочусун, андан кийин кириш жана чыгуулардан байт кодду иштеткен стек машинасын, криптографияны жана чыгаруу үчүн бассейндер.

Source: www.habr.com

Комментарий кошуу