Pangembangan Blockchain kanggo industri nggunakake Go. Bagean 1

Patang sasi saiki aku wis nggarap proyek sing diarani "Pengembangan alat proteksi lan manajemen data ing sektor pemerintah lan industri adhedhasar blockchain."
Saiki aku arep ngomong babagan carane miwiti proyek iki, lan saiki aku bakal njlèntrèhaké kode program kanthi rinci.

Pangembangan Blockchain kanggo industri nggunakake Go. Bagean 1

Iki minangka artikel pisanan ing seri artikel. Ing kene aku njlèntrèhaké server lan protokol. Nyatane, sing maca malah bisa nulis versi dhewe saka unsur pamblokiran kasebut.

Lan iki bagean kapindho - babagan struktur pamblokiran lan data transaksi, uga babagan paket sing ngetrapake interaksi karo database.

Pungkasan taun, ing hackathon Terobosan Digital, dheweke duwe ide kanggo nggawe sistem sing migunani kanggo industri lan ekonomi digital nggunakake teknologi buku besar sing disebarake; hibah uga ditanggepi kanggo pangembangan dening Yayasan Bantuan Inovasi (aku kudu nulis sing kapisah. artikel bab hibah, kanggo wong-wong sing mung miwiti kanggo nindakake startups ), lan saiki supaya.

Pangembangan ditindakake ing basa Go, lan basis data ing ngendi blok kasebut disimpen yaiku LevelDB.
Bagéan utama yaiku protokol, server (sing nganggo TCP lan WebSocket - sing pisanan kanggo nyinkronake pamblokiran, sing kapindho kanggo nyambungake klien, ngirim transaksi lan printah saka JavaScript, contone.

Kaya sing wis kasebut, pamblokiran iki dibutuhake utamane kanggo ngotomatisasi lan nglindhungi ijol-ijolan produk antarane pemasok lan pelanggan, utawa loro-lorone ing siji wong. Wong-wong iki ora cepet-cepet percaya marang saben liyane. Nanging tugas kasebut ora mung nggawe "buku cek" kanthi kalkulator sing dibangun, nanging sistem sing ngotomatisasi sebagian besar tugas rutin sing muncul nalika nggarap siklus urip produk. Bytecode sing tanggung jawab kanggo perkara iki, kaya biasane karo blockchains, disimpen ing input lan output transaksi (transaksi kasebut disimpen ing blok, blok ing LevelDB wis dienkode ing format GOB). Pisanan, ayo ngomong babagan protokol lan server (alias simpul).

Protokol ora rumit, kabeh titik iku kanggo ngalih menyang mode loading sawetara data, biasane pemblokiran utawa transaksi, nanggepi baris printah khusus, lan iku uga perlu kanggo ijol-ijolan persediaan, supaya simpul ngerti sapa iku. disambungake lan carane duwe bisnis kanggo nindakake (node ​​sing disambungake kanggo sesi sinkronisasi uga disebut "tangga" amarga IP dikenal lan data negara disimpen ing memori).

Folder (direktori minangka jeneng Linux) ing pangerten programer Go disebut paket, supaya ing awal saben file karo kode Go saka direktori iki padha nulis paket folder_name_where_this_file dumunung. Yen ora, sampeyan ora bakal bisa Feed paket kanggo compiler. Nah, iki dudu rahasia kanggo sing ngerti basa iki. Iki minangka paket:

  • Komunikasi jaringan (server, klien, protokol)
  • Struktur data sing disimpen lan dikirim (blok, transaksi)
  • Database (blockchain)
  • Konsensus
  • Mesin virtual sing ditumpuk (xvm)
  • Auxiliary (crypto, jinis) iku kabeh kanggo saiki.

Punika link kanggo github

Iki minangka versi pendidikan, ora ana interaksi antar-proses lan sawetara komponen eksperimen, nanging struktur kasebut cocog karo sing ditindakake pangembangan. Yen sampeyan duwe apa-apa kanggo menehi saran ing komentar, aku bakal seneng njupuk menyang akun ing pembangunan luwih. Lan saiki kanggo panjelasan saka server lan protokol.

Ayo ndeleng server dhisik.

Subrutin server tumindak minangka server data sing mlaku ing ndhuwur protokol TCP nggunakake struktur data saka paket protokol.

Rutin nggunakake paket ing ngisor iki: server, protokol, jinis. Ing paket dhewe tcp_server.go ngemot struktur data Ngawula.

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

Bisa nampa paramèter ing ngisor iki:

  • Port jaringan ing ngendi data bakal diijolke
  • File konfigurasi server ing format JSON
  • Flag kanggo mlaku ing mode debug (blockchain pribadi)

kemajuan:

  • Maca konfigurasi saka file JSON
  • Gendéra mode debug dicenthang: yen wis disetel, panjadwal sinkronisasi jaringan ora diluncurake lan pamblokiran ora dimuat
  • Miwiti struktur data konfigurasi lan miwiti server

server

  • Nindakake peluncuran server TCP lan interaksi jaringan sesuai karo protokol.
  • Wis struktur data Ngawula dumadi saka nomer port, ukuran buffer lan pointer kanggo struktur jinis.Setelan
  • Cara Run miwiti interaksi jaringan (ngrungokake sambungan sing mlebu ing port tartamtu, nalika sambungan anyar ditampa, pangolahan kasebut ditransfer menyang cara nangani pribadi ing benang anyar)
  • В nangani data saka sambungan diwaca menyang buffer, diowahi kanggo perwakilan senar lan liwati menyang protokol.Pilihan
  • protokol.Pilihan bali asil utawa nyebabake kesalahan. asil banjur ditransfer menyang protokol. Interpretekang bali intrpr - jinis obyek InterpreteData, utawa nyebabake kesalahan nalika ngolah asil pilihan
  • Banjur saklar dieksekusi intrpr.Prentah[0] kang mriksa salah siji saka: asil, inv, kesalahan lan ana bagean standar
  • Ing bagean asil ngalih ditemokake dening Nilai intrpr.Prentah[1] kang mriksa nilai dawa buffer и versi (ing saben kasus, fungsi sing cocog diarani)

Fungsi GetVersion и BufferLength ana ing file srvlib.go paket server

GetVersion(conn net.Conn, version string)

iku mung prints menyang console lan ngirim versi liwati parameter kanggo klien:

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

.
fungsi

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

mbukak blok, transaksi, utawa data spesifik liyane kaya ing ngisor iki:

  • Nyetak menyang console jinis data sing ditemtokake ing protokol sing kudu ditampa:
    fmt.Println("DataType:", intrpr.Commands[2])
  • Maca nilai intrpr.Badan menyang variabel numerik buf_len
  • Nggawe buffer newbuf ukuran sing ditemtokake:
    make([]byte, buf_len)
  • Ngirim respon ok:
    conn.Write([]byte("result:ok"))
  • Rampung ngisi buffer saka stream maca:
    io.ReadFull(conn, newbuf)

    .

  • Prints isi buffer kanggo console
    fmt.Println(string(newbuf))

    lan jumlah bita sing diwaca

    fmt.Println("Bytes length:", n)
  • Ngirim respon ok:
    conn.Write([]byte("result:ok"))

Cara saka paket server dikonfigurasi kanggo ngolah data sing ditampa nggunakake fungsi saka paket kasebut protokol.

Protokol

Protokol minangka sarana sing makili data ing ijol-ijolan jaringan.

Pilihan(str string) (string, kesalahan) nindakake pangolahan utami data sing ditampa dening server, nampa perwakilan senar data minangka input lan ngasilake senar sing disiapake kanggo Juru basa:

  • String input dipérang dadi sirah lan awak nggunakake ReqParseN2(str)
  • sirah dipérang dadi unsur lan diselehake menyang irisan perintah nggunakake ReqParseHead (kepala)
  • В ngalih (perintah[0]) pilih perintah sing ditampa (cmd, kunci, alamat utawa bagean micu standar)
  • 2 printah dicenthang ing cmd ngalih (prentah [1]) - dawa и getversion.
  • dawa mriksa jinis data ing dhawuh [2] lan nyimpen ing jinis data
  • Priksa sing awak ngandhut nilai string
    len(body) < 1
  • Ngasilake string respon:
    "result:bufferlength:" + datatype + "/" + body
  • getversion ngasilake senar
    return "result:version/auto"

Juru basa

Ngandhut struktur InterpreteData lan nindakake pangolahan sekunder saka data sing bali saka Choice strings lan tatanan obyek InterpreteData.

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

fungsi

Interprete(str string) (*InterpreteData, error)

nampa senar asil lan nggawe lan ngasilake referensi kanggo obyek InterpreteData.

kemajuan:

  • Kajaba iku Choice sirah lan awak dijupuk nggunakake ReqParseN2(str)
  • sirah dipérang dadi unsur nggunakake ReqParseHead(kepala)
  • Objek diinisialisasi InterpreteData lan pointer kanggo bali:

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

Objek iki digunakake ing server.go paket utama.

Klien

Paket klien ngemot fungsi TCPConnect и TCPResponseData.

fungsi

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

dianggo kaya iki:

  • Sambungan digawe menyang sambungan sing ditemtokake ing obyek setelan liwati
    net.Dial("tcp", s.Host + ":" + s.Port)
  • Data sing dikirimake ing parameter data dikirim:
    conn.Write(data)
  • Jawaban diwaca
    resp, n, _ := TCPResponseData(conn, s.BufSize)

    lan dicithak ing console

    fmt.Println(string(resp[:n]))
  • Yen ditransfer payload banjur liwati
    conn.Write(payload)

    lan uga maca respon server, printing menyang console

fungsi

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

nggawe buffer saka ukuran kasebut, maca respon server ana lan ngasilake buffer iki lan nomer bita diwaca, uga obyek kesalahan.

Subrutin klien

Serves kanggo ngirim printah kanggo server simpul, uga njupuk statistik singkat lan testing.

Bisa nampa parameter ing ngisor iki: file konfigurasi ing format JSON, data sing bakal dikirim menyang server minangka senar, path menyang file sing bakal dikirim menyang payload, flag emulasi panjadwal simpul, jinis data sing ditransfer minangka nilai numerik.

  • Njupuk konfigurasi
    st := types.ParseConfig(*config)
  • Yen gendéra emu dilewati, bakal diwiwiti tukang gawe
  • Yen flag f nuduhake path menyang file diwenehake, banjur kita mbukak data menyang fdb lan isi dikirim menyang server
    client.TCPConnect(st, []byte(CMD_BUFFER_LENGTH + ":" + strconv.Itoa(*t) + "/" + strconv.Itoa(fdblen)), fdb)
  • Yen file ora ditemtokake, banjur data saka gendera mung dikirim -d:
    client.TCPConnect(st, []byte(*data), nil)

Kabeh iki minangka perwakilan sing disederhanakake sing nuduhake struktur protokol. Sajrone pangembangan, fungsi sing dibutuhake ditambahake ing struktur kasebut.

Ing bagean kapindho aku bakal ngomong babagan struktur data kanggo pamblokiran lan transaksi, ing 3 babagan server WebSocket kanggo nyambungake saka JavaScript, ing 4 aku bakal ndeleng jadwal sinkronisasi, banjur mesin tumpukan sing ngolah bytecode saka input lan output, kriptografi lan pools kanggo output.

Source: www.habr.com

Add a comment