Go yordamida sanoat uchun blokcheyn ishlab chiqish. 1-qism

To‘rt oydan beri men “Blokcheyn asosida davlat va sanoat sektorlarida ma’lumotlarni himoya qilish va boshqarish vositalarini ishlab chiqish” loyihasi ustida ishlayapman.
Endi men sizga ushbu loyihani qanday boshlaganim haqida gapirib bermoqchiman va endi men dastur kodini batafsil tasvirlab beraman.

Go yordamida sanoat uchun blokcheyn ishlab chiqish. 1-qism

Bu maqolalar turkumidagi birinchi maqola bo’lgan maqola yangiliklar.net saytiga kiritilgan. Bu erda men server va protokolni tasvirlayman. Aslida, o'quvchi hatto ushbu blokcheyn elementlarining o'z versiyalarini yozishi mumkin.

Va bu erda ikkinchi qism — blokcheyn va tranzaksiya maʼlumotlari tuzilmalari, shuningdek, maʼlumotlar bazasi bilan oʻzaro aloqani amalga oshiradigan paket haqida.

O'tgan yili Digital Breakthrough hakathonida ular taqsimlangan daftar texnologiyasidan foydalangan holda sanoat va raqamli iqtisodiyot uchun foydali tizim yaratish g'oyasi bilan chiqdilar; Innovatsiyalarga ko'maklashish jamg'armasi tomonidan ham grant ajratildi (men alohida yozishim kerak) grant haqida maqola, endi boshlayotganlar uchun ) va endi tartibda.

Rivojlanish Go tilida amalga oshiriladi va bloklar saqlanadigan ma'lumotlar bazasi LevelDB hisoblanadi.
Asosiy qismlar protokol, server (TCP va WebSocket bilan ishlaydi - birinchisi blokcheynni sinxronlashtirish uchun, ikkinchisi mijozlarni ulash, JavaScript-dan tranzaksiyalar va buyruqlarni yuborish uchun).

Yuqorida aytib o'tilganidek, ushbu blokcheyn birinchi navbatda etkazib beruvchilar va mijozlar o'rtasida yoki ikkalasi ham bir odamda mahsulot almashinuvini avtomatlashtirish va himoya qilish uchun kerak. Bu odamlar bir-biriga ishonishga shoshilishmaydi. Ammo vazifa nafaqat o'rnatilgan kalkulyator bilan "chek kitobi" ni yaratish, balki mahsulotning hayot aylanishi bilan ishlashda yuzaga keladigan odatiy vazifalarning ko'pini avtomatlashtiradigan tizimdir. Ushbu masala uchun mas'ul bo'lgan bayt-kod, odatdagidek, blokcheynlarda bo'lgani kabi, tranzaktsiyalarning kirish va chiqishlarida saqlanadi (tranzaktsiyalarning o'zi bloklarda saqlanadi, LevelDB-dagi bloklar GOB formatida oldindan kodlangan). Birinchidan, protokol va server (aka tugun) haqida gapiraylik.

Protokol murakkab emas, uning butun maqsadi maxsus buyruq qatoriga javoban ba'zi ma'lumotlarni, odatda blok yoki tranzaktsiyani yuklash rejimiga o'tishdir, shuningdek, tugun kimligini bilishi uchun inventar almashish uchun kerak bo'ladi. ga ulanganligi va ular qanday biznes qilishlari kerak (sinxronizatsiya seansi uchun ulangan tugunlar "qo'shni" deb ham ataladi, chunki ularning IP-si ma'lum va ularning holati ma'lumotlari xotirada saqlanadi).

Go dasturini tushunishda papkalar (Linux deb ataydigan kataloglar) paketlar deb ataladi, shuning uchun har bir faylning boshida ushbu katalogdan Go kodi bo'lgan papkalar papkasi_name_qaerda_ushbu_fayl joylashganligini yozadilar. Aks holda, siz paketni kompilyatorga bera olmaysiz. Xo'sh, bu tilni biladiganlar uchun sir emas. Bular paketlar:

  • Tarmoq aloqasi (server, mijoz, protokol)
  • Saqlangan va uzatiladigan ma'lumotlarning tuzilmalari (blok, tranzaksiya)
  • Ma'lumotlar bazasi (blokcheyn)
  • Kelishuv
  • Yigʻilgan virtual mashina (xvm)
  • Yordamchi (kripto, turlar) hozircha hammasi.

Mana github ga havola

Bu ta'lim versiyasi bo'lib, unda jarayonlararo o'zaro ta'sir va bir nechta eksperimental komponentlar mavjud emas, ammo tuzilma ishlab chiqilayotganiga mos keladi. Agar sharhlarda taklif qiladigan biror narsangiz bo'lsa, men uni keyingi rivojlanishda hisobga olishdan xursand bo'laman. Va endi serverni tushuntirish uchun va Protokol.

Keling, avval serverni ko'rib chiqaylik.

Server pastki dasturi protokol paketidagi ma'lumotlar tuzilmalaridan foydalangan holda TCP protokoli ustida ishlaydigan ma'lumotlar serveri vazifasini bajaradi.

Muntazam quyidagi paketlardan foydalanadi: server, Protokol, turlari. Paketning o'zida tcp_server.go ma'lumotlar strukturasini o'z ichiga oladi Xizmat qilish.

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

U quyidagi parametrlarni qabul qilishi mumkin:

  • Ma'lumotlar almashinadigan tarmoq porti
  • JSON formatidagi server konfiguratsiya fayli
  • Nosozliklarni tuzatish rejimida ishlash uchun belgi (xususiy blokcheyn)

Jarayon:

  • JSON faylidan konfiguratsiyani o'qiydi
  • Nosozliklarni tuzatish rejimi bayrog'i tekshiriladi: agar u o'rnatilgan bo'lsa, tarmoq sinxronlash rejalashtiruvchisi ishga tushmaydi va blokcheyn yuklanmagan.
  • Konfiguratsiya ma'lumotlar strukturasini ishga tushirish va serverni ishga tushirish

Server

  • TCP serverini ishga tushirish va protokolga muvofiq tarmoq o'zaro ta'sirini amalga oshiradi.
  • U port raqami, bufer o'lchami va strukturaga ko'rsatgichdan iborat Xizmat ko'rsatish ma'lumotlar strukturasiga ega turlari.Sozlamalar
  • Run usuli tarmoq o'zaro ta'sirini boshlaydi (ma'lum portda kiruvchi ulanishlarni tinglash, yangi ulanish qabul qilinganda, uni qayta ishlash yangi oqimdagi shaxsiy ishlov berish usuliga o'tkaziladi)
  • В Ushlab turing ulanishdan olingan ma'lumotlar buferga o'qiladi, satr tasviriga aylantiriladi va unga uzatiladi protokol. Tanlov
  • protokol. Tanlov qaytadi Natijalar yoki xatoga sabab bo'ladi. Natijalar keyin ga o'tkaziladi protokol. Interpreteqaysi qaytaradi intrpr - turdagi ob'ekt Interprete Data, yoki tanlov natijasini qayta ishlashda xatolikka olib keladi
  • Keyin kommutator bajariladi intrpr.Buyruqlar[0] qaysi birini tekshiradi: natija, inv, xato va bo'lim mavjud default
  • Bo'limda Natijalar kalit qiymati bo'yicha topiladi intrpr.Buyruqlar[1] qiymatlarni tekshiradi bufer uzunligi и versiya (har bir holatda tegishli funktsiya chaqiriladi)

Vazifalar GetVersion и Bufer uzunligi faylda mavjud srvlib.go server paketi

GetVersion(conn net.Conn, version string)

u shunchaki konsolga chop etadi va parametrda berilgan versiyani mijozga yuboradi:

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

.
vazifa

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

blok, tranzaksiya yoki boshqa maxsus ma'lumotlarni quyidagi tarzda yuklaydi:

  • Qabul qilinishi kerak bo'lgan protokolda ko'rsatilgan ma'lumotlar turini konsolga chop etadi:
    fmt.Println("DataType:", intrpr.Commands[2])
  • Qiymatni o'qiydi intrpr.Body raqamli o'zgaruvchiga buf_len
  • Bufer yaratadi yangi buf belgilangan o'lcham:
    make([]byte, buf_len)
  • Yaxshi javob yuboradi:
    conn.Write([]byte("result:ok"))
  • O'qish oqimidan buferni to'liq to'ldiradi:
    io.ReadFull(conn, newbuf)

    .

  • Bufer tarkibini konsolga chop etadi
    fmt.Println(string(newbuf))

    va o'qilgan baytlar soni

    fmt.Println("Bytes length:", n)
  • Yaxshi javob yuboradi:
    conn.Write([]byte("result:ok"))

Server paketidagi usullar paketdagi funksiyalar yordamida qabul qilingan ma'lumotlarni qayta ishlash uchun tuzilgan Protokol.

Protokol

Protokol tarmoq almashinuvida ma'lumotlarni ifodalovchi vosita bo'lib xizmat qiladi.

Choice(str string) (string, xato) server tomonidan qabul qilingan ma'lumotlarni birlamchi qayta ishlashni amalga oshiradi, kirish sifatida ma'lumotlarning satrli tasvirini oladi va tayyorlangan satrni qaytaradi. Tarjimon:

  • Kirish satri yordamida bosh va tanaga bo'linadi ReqParseN2(str)
  • bosh elementlarga bo'linadi va ReqParseHead (head) yordamida buyruqlar bo'limiga joylashtiriladi.
  • В switch(buyruqlar[0]) qabul qilingan buyruqni tanlang (cmd, kalit, manzil yoki bo'lim ishga tushiriladi default)
  • 2 ta buyruq cmd da tekshiriladi switch(buyruqlar[1]) — uzunlik и olish.
  • Uzunligi ma'lumotlar turini tekshiradi buyruqlar[2] va uni saqlaydi ma'lumotlar turi
  • Buni tekshiradi badan qator qiymatini o'z ichiga oladi
    len(body) < 1
  • Javoblar qatorini qaytaradi:
    "result:bufferlength:" + datatype + "/" + body
  • olish qatorni qaytaradi
    return "result:version/auto"

Tarjimon

InterpreteData strukturasini o'z ichiga oladi va qaytarilgan ma'lumotlarni ikkilamchi qayta ishlashni amalga oshiradi tanlash satrlar va ob'ektni shakllantirish Interprete Data.

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

vazifa

Interprete(str string) (*InterpreteData, error)

qatorni qabul qiladi Natijalar va ob'ektga havolani yaratadi va qaytaradi Interprete Data.

Jarayon:

  • Xuddi shunday tanlash yordamida bosh va tana ajratib olinadi ReqParseN2(str)
  • yordamida bosh elementlarga bo'linadi ReqParseHead(bosh)
  • Ob'ekt ishga tushirildi Interprete Data va unga ko'rsatgich qaytariladi:

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

Bu ob'ektda ishlatiladi server.go asosiy paket.

mijoz

Mijoz paketi funktsiyalarni o'z ichiga oladi TCPConnect и TCPResponseData.

vazifa

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

quyidagicha ishlaydi:

  • O'tkazilgan sozlamalar ob'ektida ko'rsatilgan ulanishga ulanish amalga oshiriladi
    net.Dial("tcp", s.Host + ":" + s.Port)
  • Ma'lumotlar parametrida uzatilgan ma'lumotlar uzatiladi:
    conn.Write(data)
  • Javob o'qiladi
    resp, n, _ := TCPResponseData(conn, s.BufSize)

    va konsolda chop etilgan

    fmt.Println(string(resp[:n]))
  • Agar o'tkazilsa Foydali yuk keyin uzatadi
    conn.Write(payload)

    va shuningdek, server javobini o'qiydi va uni konsolga chop etadi

vazifa

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

belgilangan o'lchamdagi buferni yaratadi, u erda server javobini o'qiydi va bu buferni va o'qilgan baytlar sonini, shuningdek, xato ob'ektini qaytaradi.

Mijoz subprogrammasi

Tugun serverlariga buyruqlar yuborish, shuningdek, qisqacha statistika va testlarni olish uchun xizmat qiladi.

Quyidagi parametrlarni qabul qilishi mumkin: JSON formatidagi konfiguratsiya fayli, serverga qator sifatida yuboriladigan maʼlumotlar, foydali yukga yuboriladigan faylga yoʻl, tugunni rejalashtiruvchi emulyatsiya bayrogʻi, raqamli qiymat sifatida uzatiladigan maʼlumotlar turi.

  • Konfiguratsiyani olish
    st := types.ParseConfig(*config)
  • Agar emu bayrog'i topshirilsa, u boshlanadi sheduler
  • Agar faylga yo'lni ko'rsatadigan f bayrog'i berilgan bo'lsa, biz uning ma'lumotlarini yuklaymiz fdb va kontent serverga yuboriladi
    client.TCPConnect(st, []byte(CMD_BUFFER_LENGTH + ":" + strconv.Itoa(*t) + "/" + strconv.Itoa(fdblen)), fdb)
  • Agar fayl ko'rsatilmagan bo'lsa, u holda bayroqdagi ma'lumotlar oddiygina yuboriladi -d:
    client.TCPConnect(st, []byte(*data), nil)

Bularning barchasi protokol tuzilishini ko'rsatadigan soddalashtirilgan tasvirdir. Rivojlanish jarayonida uning tuzilishiga kerakli funksionallik qo'shiladi.

Ikkinchi qismda men bloklar va tranzaktsiyalar uchun ma'lumotlar tuzilmalari haqida gapiraman, 3-da JavaScript-dan ulanish uchun WebSocket serveri haqida, 4-da sinxronizatsiya rejalashtiruvchisini, keyin kirish va chiqishlardan bayt-kodni qayta ishlaydigan stek mashinasini ko'rib chiqaman, kriptografiya va chiqish uchun hovuzlar.

Manba: www.habr.com

a Izoh qo'shish