Żvilupp ta 'blockchain għall-industrija bl-użu ta' Go. Parti 1

Ilni erba’ xhur naħdem fuq proġett imsejjaħ “Żvilupp ta’ għodod ta’ protezzjoni u ġestjoni tad-data fis-setturi tal-gvern u industrijali bbażati fuq blockchain.”
Issa nixtieq ngħidlek dwar kif bdejt dan il-proġett, u issa se niddeskrivi l-kodiċi tal-programm fid-dettall.

Żvilupp ta 'blockchain għall-industrija bl-użu ta' Go. Parti 1

Dan huwa l-ewwel artiklu minn sensiela ta’ artikli. Hawnhekk niddeskrivi s-server u l-protokoll. Fil-fatt, il-qarrej jista 'saħansitra jikteb il-verżjonijiet tiegħu stess ta' dawn l-elementi blockchain.

U hawn it-tieni parti — dwar blockchain u strutturi tad-dejta tat-tranżazzjonijiet, kif ukoll dwar il-pakkett li jimplimenta l-interazzjoni mad-database.

Is-sena l-oħra, waqt l-hackathon Digital Breakthrough, ħarġu b’idea li jagħmlu sistema utli għall-industrija u l-ekonomija diġitali bl-użu tat-teknoloġija tal-kotba distribwiti; ħarġet ukoll għotja għall-iżvilupp mill-Fond ta’ Assistenza għall-Innovazzjoni (għandi nikteb separata). artiklu dwar l-għotja, għal dawk li għadhom qed jibdew startups ), u issa fl-ordni.

L-iżvilupp iseħħ fil-lingwa Go, u d-database li fiha huma maħżuna l-blokki hija LevelDB.
Il-partijiet ewlenin huma l-protokoll, is-server (li jmexxi TCP u WebSocket - l-ewwel għas-sinkronizzazzjoni tal-blockchain, it-tieni għall-konnessjoni tal-klijenti, tibgħat tranżazzjonijiet u kmandi minn JavaScript, pereżempju.

Kif issemma, din il-blockchain hija meħtieġa primarjament biex awtomat u jipproteġi l-iskambju ta 'prodotti bejn fornituri u klijenti, jew it-tnejn f'persuna waħda. Dawn in-nies m’għandhomx għaġla biex jafdaw lil xulxin. Iżda l-kompitu mhuwiex biss li toħloq "ktieb taċ-ċekkijiet" b'kalkolatur inkorporat, iżda sistema li awtomatizza ħafna mill-kompiti ta 'rutina li jinqalgħu meta taħdem maċ-ċiklu tal-ħajja tal-prodott. Il-bytecode li huwa responsabbli għal din il-kwistjoni, kif soltu ma 'blockchains, huwa maħżun fl-inputs u l-outputs tat-tranżazzjonijiet (it-tranżazzjonijiet infushom huma maħżuna fi blokki, il-blokki f'LevelDB huma kodifikati minn qabel fil-format GOB). L-ewwel, ejja nitkellmu dwar il-protokoll u s-server (magħruf ukoll bħala node).

Il-protokoll mhuwiex ikkumplikat, il-punt kollu tiegħu huwa li taqleb għall-mod ta 'tagħbija ta' xi data, ġeneralment blokka jew transazzjoni, bi tweġiba għal linja ta 'kmand speċjali, u hija meħtieġa wkoll għall-iskambju ta' inventarju, sabiex in-nodu jkun jaf min hu huwa konness ma 'u kif għandhom in-negozju x'jagħmlu (in-nodi konnessi għas-sessjoni ta' sinkronizzazzjoni jissejħu wkoll "ġirien" minħabba li l-IP tagħhom huwa magħruf u d-dejta tal-istat tagħhom hija maħżuna fil-memorja).

Folders (direttorji kif isejħilhom Linux) fil-fehma tal-programmaturi Go jissejħu pakketti, għalhekk fil-bidu ta 'kull fajl b'kodiċi Go minn dan id-direttorju jiktbu pakkett folder_name_where_this_file jinsab. Inkella, ma tkunx tista' tgħaddi l-pakkett lill-kompilatur. Ukoll, dan mhux sigriet għal dawk li jafu din il-lingwa. Dawn huma l-pakketti:

  • Komunikazzjoni tan-netwerk (server, klijent, protokoll)
  • Strutturi ta' data maħżuna u trażmessa (blokk, transazzjoni)
  • Database (blockchain)
  • Kunsens
  • Magna virtwali f'munzelli (xvm)
  • Awżiljarju (kripto, tipi) dak kollu għalissa.

Hawn hu l-link għal github

Din hija verżjoni edukattiva, m'għandhiex interazzjoni bejn il-proċessi u diversi komponenti sperimentali, iżda l-istruttura tikkorrispondi għal dik li fuqha qed jitwettaq l-iżvilupp. Jekk għandek xi ħaġa li tissuġġerixxi fil-kummenti, inkun kuntent li nikkunsidraha fi żvilupp ulterjuri. U issa għal spjegazzjoni tas-server u protokoll.

Ejja nħarsu lejn is-server l-ewwel.

Is-subrutina tas-server taġixxi bħala server tad-dejta li jaħdem fuq il-protokoll TCP billi juża strutturi tad-dejta mill-pakkett tal-protokoll.

Ir-rutina tuża l-pakketti li ġejjin: servers, protokoll, tipi. Fil-pakkett innifsu tcp_server.go fih struttura tad-data Iservu.

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

Jista 'jaċċetta l-parametri li ġejjin:

  • Port tan-netwerk li minnu ser tiġi skambjata d-dejta
  • Fajl tal-konfigurazzjoni tas-server fil-format JSON
  • Bandiera biex taħdem fil-modalità debug (blockchain privata)

Progress:

  • Jaqra l-konfigurazzjoni mill-fajl JSON
  • Il-bandiera tal-modalità tad-debug hija ċċekkjata: jekk tkun issettjata, l-iskedar tas-sinkronizzazzjoni tan-netwerk ma jiġix imniedi u l-blockchain mhix mgħobbija
  • L-inizjalizzazzjoni tal-istruttura tad-dejta tal-konfigurazzjoni u l-bidu tas-server

server

  • Twettaq it-tnedija tas-server TCP u l-interazzjoni tan-netwerk skont il-protokoll.
  • Għandha struttura tad-dejta Serve li tikkonsisti f'numru tal-port, daqs tal-buffer u pointer għall-istruttura tipi.Settings
  • Il-metodu Run jibda l-interazzjoni tan-netwerk (sma 'għal konnessjonijiet deħlin fuq port partikolari, meta tiġi riċevuta konnessjoni ġdida, l-ipproċessar tiegħu jiġi trasferit għall-metodu tal-manku privat f'ħajt ġdid)
  • В jimmaniġġaw id-dejta mill-konnessjoni tinqara f'buffer, tiġi kkonvertita f'rappreżentazzjoni ta' string u mgħoddija lil protokoll.Għażla
  • protokoll.Għażla prospetti tirriżulta jew tikkawża żball. tirriżulta imbagħad trasferiti għal protokoll.Interpretili jirritorna intrpr - oġġett tat-tip InterpreteData, jew tikkawża żball fl-ipproċessar tar-riżultat tal-għażla
  • Imbagħad is-swiċċ jiġi esegwit intrpr.Kmandi[0] li jiċċekkja waħda minn: riżultat, inv, żball u hemm sezzjoni inadempjenza
  • Fit-taqsima tirriżulta swiċċ jinstab bil-valur intrpr.Kmandi[1] li jiċċekkja l-valuri bufferlength и verżjoni (f'kull każ tissejjaħ il-funzjoni korrispondenti)

Funzjonijiet GetVersion и BufferLength jinsabu fil-fajl srvlib.go pakkett tas-server

GetVersion(conn net.Conn, version string)

sempliċiment jistampa fuq il-console u jibgħat il-verżjoni mgħoddija fil-parametru lill-klijent:

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

.
Funzjoni

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

jgħabbi blokka, tranżazzjoni, jew data speċifika oħra kif ġej:

  • Tipprintja fuq il-console it-tip ta' dejta speċifikata fil-protokoll li jeħtieġ li tiġi aċċettata:
    fmt.Println("DataType:", intrpr.Commands[2])
  • Jaqra l-valur intrpr.Korp għal varjabbli numeriku buf_len
  • Joħloq buffer newbuf daqs speċifikat:
    make([]byte, buf_len)
  • Tibgħat tweġiba ok:
    conn.Write([]byte("result:ok"))
  • Imla kompletament il-buffer mill-fluss tal-qari:
    io.ReadFull(conn, newbuf)

    .

  • Tipprintja l-kontenut tal-buffer fuq il-console
    fmt.Println(string(newbuf))

    u n-numru ta' bytes li jinqraw

    fmt.Println("Bytes length:", n)
  • Tibgħat tweġiba ok:
    conn.Write([]byte("result:ok"))

Il-metodi mill-pakkett tas-server huma kkonfigurati biex jipproċessaw id-dejta riċevuta billi jużaw funzjonijiet mill-pakkett protokoll.

Protokoll

Protokoll iservi bħala mezz li jirrappreżenta data fl-iskambju tan-netwerk.

Għażla (string string) (string, żball) iwettaq l-ipproċessar primarju tad-dejta riċevuta mis-server, jirċievi string rappreżentazzjoni tad-dejta bħala input u jirritorna string ippreparat għal Interpretu:

  • Is-sekwenza tad-dħul hija maqsuma f'ras u ġisem bl-użu ReqParseN2(str)
  • ir-ras tinqasam f'elementi u titqiegħed f'porzjon ta' kmandi bl-użu ta' ReqParseHead(ras)
  • В swiċċ(kmandi[0]) agħżel il-kmand riċevut (cmd, ċavetta, indirizz jew is-sezzjoni hija attivata inadempjenza)
  • 2 kmandi huma kkontrollati f'cmd swiċċ(kmandi[1]) — tul и getversion.
  • tul jiċċekkja t-tip tad-data in jikkmanda[2] u jsalvaha Datatype
  • Kontrolli li korp fih valur ta' string
    len(body) < 1
  • Jirritorna s-sekwenza tar-rispons:
    "result:bufferlength:" + datatype + "/" + body
  • getversion jirritorna string
    return "result:version/auto"

Interpretu

Fih l-istruttura InterpreteData u jwettaq ipproċessar sekondarju tad-dejta rritornata minnha għażla kordi u formazzjoni ta’ oġġetti InterpreteData.

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

Funzjoni

Interprete(str string) (*InterpreteData, error)

jaċċetta string tirriżulta u joħloq u jirritorna referenza għall-oġġett InterpreteData.

Progress:

  • Bl-istess mod għażla ras u korp huma estratti bl-użu ReqParseN2(str)
  • ras huwa maqsum elementi bl-użu ReqParseHead(ras)
  • L-oġġett huwa inizjalizzat InterpreteData u jiġi rritornat pointer għalih:

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

Dan l-oġġett huwa użat fi server.go pakkett prinċipali.

klijent

Il-pakkett tal-klijent fih il-funzjonijiet TCPConnect и TCPResponseData.

Funzjoni

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

jaħdem bħal dan:

  • Issir konnessjoni mal-konnessjoni speċifikata fl-oġġett tas-settings mgħoddi
    net.Dial("tcp", s.Host + ":" + s.Port)
  • Id-dejta mgħoddija fil-parametru tad-dejta tiġi trażmessa:
    conn.Write(data)
  • It-tweġiba tinqara
    resp, n, _ := TCPResponseData(conn, s.BufSize)

    u stampat fuq il-console

    fmt.Println(string(resp[:n]))
  • Jekk jiġi trasferit payload imbagħad jgħaddiha
    conn.Write(payload)

    u jaqra wkoll ir-rispons tas-server, jistampah fuq il-console

Funzjoni

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

joħloq buffer tad-daqs speċifikat, jaqra r-rispons tas-server hemmhekk u jirritorna dan il-buffer u n-numru ta 'bytes moqrija, kif ukoll oġġett ta' żball.

Subrutina tal-klijent

Iservi biex tibgħat kmandi lil servers node, kif ukoll tikseb statistika qasira u ttestjar.

Jista 'jaċċetta l-parametri li ġejjin: fajl ta' konfigurazzjoni f'format JSON, dejta li għandha tintbagħat lis-server bħala string, mogħdija għall-fajl li għandha tintbagħat għal payload, bandiera ta 'emulazzjoni ta' node scheduler, tip ta 'dejta trasferita bħala valur numeriku.

  • Jkollna l-konfigurazzjoni
    st := types.ParseConfig(*config)
  • Jekk il-bandiera emu tgħaddi, din tibda sheduler
  • Jekk il-bandiera f li tindika l-mogħdija għall-fajl hija fornuta, allura aħna tagħbija d-data tagħha fiha fdb u l-kontenut jintbagħat lis-server
    client.TCPConnect(st, []byte(CMD_BUFFER_LENGTH + ":" + strconv.Itoa(*t) + "/" + strconv.Itoa(fdblen)), fdb)
  • Jekk il-fajl ma jkunx speċifikat, allura d-dejta mill-bandiera tintbagħat sempliċement -d:
    client.TCPConnect(st, []byte(*data), nil)

Dan kollu huwa rappreżentazzjoni simplifikata li turi l-istruttura tal-protokoll. Matul l-iżvilupp, il-funzjonalità meħtieġa hija miżjuda mal-istruttura tagħha.

Fit-tieni parti se nitkellem dwar l-istrutturi tad-dejta għal blokki u tranżazzjonijiet, fi 3 dwar is-server WebSocket għall-konnessjoni minn JavaScript, f'4 se nħares lejn l-iskedar tas-sinkronizzazzjoni, imbagħad magna tal-munzell li tipproċessa bytecode minn inputs u outputs, kriptografija u pools għall-outputs.

Sors: www.habr.com

Żid kumment