Blockchain þróun fyrir iðnað með Go. 1. hluti

Núna í fjóra mánuði hef ég unnið að verkefni sem kallast „Þróun gagnaverndar og stjórnunartækja í stjórnvöldum og iðnaði byggt á blockchain.
Nú langar mig að segja ykkur frá því hvernig ég byrjaði á þessu verkefni og nú mun ég lýsa forritskóðanum í smáatriðum.

Blockchain þróun fyrir iðnað með Go. 1. hluti

Þetta er fyrsta greinin í röð greina. Hér lýsi ég þjóninum og samskiptareglum. Reyndar getur lesandinn jafnvel skrifað sínar eigin útgáfur af þessum blockchain þáttum.

Og hér er seinni hlutinn — um blockchain og viðskiptagagnaskipulag, svo og um pakkann sem útfærir samskipti við gagnagrunninn.

Á síðasta ári, á Digital Breakthrough hakkaþoninu, komu þeir með hugmynd um að búa til gagnlegt kerfi fyrir iðnað og stafrænt hagkerfi með dreifðri fjárhagstækni; einnig var veittur styrkur til þróunar frá Nýsköpunaraðstoðarsjóðnum (ég ætti að skrifa sérstaka grein um styrkinn, fyrir þá sem eru nýbyrjaðir ), og núna í röð.

Þróun fer fram á Go tungumálinu og gagnagrunnurinn sem kubbarnir eru geymdir í er LevelDB.
Helstu hlutar eru samskiptareglur, þjónninn (sem keyrir TCP og WebSocket - sá fyrsti til að samstilla blockchain, hinn til að tengja viðskiptavini, senda færslur og skipanir frá JavaScript, til dæmis.

Eins og fram hefur komið er þessi blockchain fyrst og fremst nauðsynleg til að gera sjálfvirkan og vernda vöruskipti milli birgja og viðskiptavina, eða hvort tveggja í einum einstaklingi. Þetta fólk er ekkert að flýta sér að treysta hvert öðru. En verkefnið er ekki aðeins að búa til „ávísanahefti“ með innbyggðri reiknivél, heldur kerfi sem gerir sjálfvirkan flest þau venjubundnu verkefni sem koma upp þegar unnið er með lífsferil vörunnar. Bætiskóðinn sem er ábyrgur fyrir þessu máli, eins og tíðkast með blockchains, er geymdur í inn- og úttakum viðskipta (færslurnar sjálfar eru geymdar í blokkum, blokkirnar í LevelDB eru forkóðar á GOB sniði). Í fyrsta lagi skulum við tala um samskiptareglur og netþjóninn (aka hnútur).

Samskiptareglur eru ekki flóknar, allt tilgangurinn með henni er að skipta yfir í þann hátt að hlaða sumum gögnum, venjulega blokk eða færslu, sem svar við sérstakri skipanalínu, og það er líka nauðsynlegt til að skiptast á birgðum, svo að hnúturinn viti hver hann er tengdur við og hvernig þeir hafa viðskipti að gera (hnútarnir sem tengdir eru fyrir samstillingarlotuna eru einnig kallaðir "nálægir" vegna þess að IP þeirra er þekkt og ástandsgögn þeirra eru geymd í minni).

Möppur (möppur eins og Linux kallar þær) í skilningi Go forritara eru kallaðar pakkar, þannig að í upphafi hverrar skráar með Go kóða úr þessari möppu skrifa þeir pakkann mappa_nafn_þar sem_þessi_skrá er staðsett. Annars muntu ekki geta fóðrað pakkann í þýðandann. Jæja, þetta er ekkert leyndarmál fyrir þá sem kunna þetta tungumál. Þetta eru pakkarnir:

  • Netsamskipti (þjónn, viðskiptavinur, samskiptareglur)
  • Uppbygging geymdra og sendra gagna (blokk, viðskipti)
  • Gagnagrunnur (blockchain)
  • Samstaða
  • Staflað sýndarvél (xvm)
  • Aukabúnaður (dulkóðun, tegundir) það er allt í bili.

Hér er hlekkurinn á github

Þetta er fræðsluútgáfa, það vantar víxlverkun milli ferla og nokkra tilraunaþætti, en uppbyggingin samsvarar þeirri sem þróun er á. Ef þú hefur eitthvað fram að færa í athugasemdunum mun ég gjarnan taka tillit til þess í frekari þróun. Og nú til útskýringar á þjóninum og siðareglur.

Við skulum líta á netþjóninn fyrst.

Undiráætlun netþjónsins virkar sem gagnaþjónn sem keyrir ofan á TCP samskiptareglur með því að nota gagnauppbyggingu úr samskiptareglunum.

Rútínan notar eftirfarandi pakka: miðlara, siðareglur, tegundir. Í pakkanum sjálfum tcp_server.go inniheldur gagnaskipulag Þjóna.

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

Það getur samþykkt eftirfarandi breytur:

  • Netgátt þar sem gögnum verður skipt um
  • Stillingarskrá miðlara á JSON sniði
  • Fáni til að keyra í villuleitarham (einka blockchain)

Framfarir:

  • Les stillingar úr JSON skrá
  • Villuleitarfáninn er merktur: ef hann er stilltur er samstillingaráætlun netkerfisins ekki ræst og blockchain er ekki hlaðið
  • Frumstillir uppsetningu gagnauppbyggingar og ræsir netþjóninn

Server

  • Framkvæmir ræsingu TCP netþjónsins og netsamskipta í samræmi við samskiptareglur.
  • Það hefur Serve gagnaskipulag sem samanstendur af gáttarnúmeri, biðminni og bendili á uppbygginguna tegundir.Stillingar
  • Run aðferðin byrjar netsamskipti (hlustað er á komandi tengingar á tilteknu tengi, þegar ný tenging er móttekin, er vinnsla hennar flutt yfir í einkaafgreiðsluaðferðina í nýjum þræði)
  • В annast gögn úr tengingunni eru lesin í biðminni, breytt í strengjaframsetningu og send til siðareglur.Val
  • siðareglur.Val skilar leitt eða veldur villu. leitt síðan flutt til siðareglur.Túlkasem skilar sér innrpr - hlutur af gerð Túlka gögn, eða veldur villu í vinnslu valniðurstöðu
  • Þá er skiptingin framkvæmd intrpr.Commands[0] sem athugar eitt af: afleiðing, inv, villa og það er kafli sjálfgefið
  • Í kaflanum leitt rofi finnst eftir gildi intrpr.Commands[1] sem athugar gildin biðminni lengd и útgáfa (í hverju tilviki er samsvarandi fall kallað)

Aðgerðir GetVersion и Stuðpúðalengd eru í skránni srvlib.go miðlara pakka

GetVersion(conn net.Conn, version string)

það prentar einfaldlega á stjórnborðið og sendir útgáfuna sem er send í færibreytunni til viðskiptavinarins:

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

.
Virka

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

hleður blokk, færslu eða önnur sérstök gögn sem hér segir:

  • Prentar á stjórnborðið þá gerð gagna sem tilgreind eru í samskiptareglunum sem þarf að samþykkja:
    fmt.Println("DataType:", intrpr.Commands[2])
  • Les gildið intrpr.Body í tölulega breytu buff_len
  • Býr til biðminni newbuf tilgreind stærð:
    make([]byte, buf_len)
  • Sendir allt í lagi svar:
    conn.Write([]byte("result:ok"))
  • Fyllir algjörlega biðminni úr lesstraumnum:
    io.ReadFull(conn, newbuf)

    .

  • Prentar innihald biðminni á stjórnborðið
    fmt.Println(string(newbuf))

    og fjöldi lesinna bæta

    fmt.Println("Bytes length:", n)
  • Sendir allt í lagi svar:
    conn.Write([]byte("result:ok"))

Aðferðir frá netþjónapakkanum eru stilltar til að vinna úr mótteknum gögnum með því að nota aðgerðir úr pakkanum siðareglur.

Siðareglur

Samskiptareglur þjónar sem leið sem táknar gögn í netskiptum.

Val (str strengur) (strengur, villa) framkvæmir frumvinnslu á gögnum sem þjónninn tekur á móti, fær strengmynd af gögnunum sem inntak og skilar streng sem er útbúinn fyrir Túlkur:

  • Inntaksstrengurinn er skipt í höfuð og líkama með því að nota ReqParseN2(str)
  • höfuð er skipt í þætti og sett í skipanasneið með því að nota ReqParseHead(head)
  • В switch(skipanir[0]) veldu móttekna skipun (cmd, lykill, heimilisfang eða hlutanum er ræst sjálfgefið)
  • 2 skipanir eru hakaðar í cmd switch(skipanir[1]) — lengd и getversion.
  • lengd athugar gagnategundina skipanir[2] og vistar það inn datategund
  • Athugar það líkami inniheldur strengsgildi
    len(body) < 1
  • Skilar svarstrengnum:
    "result:bufferlength:" + datatype + "/" + body
  • getversion skilar streng
    return "result:version/auto"

Túlkur

Inniheldur InterpreteData uppbyggingu og framkvæmir aukavinnslu gagna sem skilað er frá Val strengir og myndun hluta Túlka gögn.

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

Virka

Interprete(str string) (*InterpreteData, error)

tekur við streng leitt og býr til og skilar tilvísun í hlutinn Túlka gögn.

Framfarir:

  • Á sama hátt Val höfuð og líkami eru dregin út með því að nota ReqParseN2(str)
  • höfuð er skipt í þætti með því að nota ReqParseHead(haus)
  • Hluturinn er frumstilltur Túlka gögn og bendi á það er skilað:

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

Þessi hlutur er notaður í server.go aðalpakki.

viðskiptavinur

Biðlarapakkinn inniheldur aðgerðirnar TCPConnect и TCPResponseData.

Virka

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

virkar svona:

  • Tenging er gerð við tenginguna sem tilgreind er í samþykktum stillingahlutnum
    net.Dial("tcp", s.Host + ":" + s.Port)
  • Gögnin sem send eru í gagnabreytu eru send:
    conn.Write(data)
  • Svarið er lesið
    resp, n, _ := TCPResponseData(conn, s.BufSize)

    og prentað á stjórnborðið

    fmt.Println(string(resp[:n]))
  • Ef flutt farmur ber það svo áfram
    conn.Write(payload)

    og les einnig svar þjónsins, prentar það á stjórnborðið

Virka

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

býr til biðminni af tilgreindri stærð, les svar þjónsins þar og skilar þessum biðminni og fjölda lesinna bæta, auk villuhluts.

Undirrútína viðskiptavinar

Þjónar til að senda skipanir til hnútaþjóna, auk þess að fá stutta tölfræði og prófanir.

Getur samþykkt eftirfarandi færibreytur: stillingarskrá á JSON sniði, gögn sem á að senda á netþjóninn sem streng, slóð að skránni sem á að senda á hleðslu, hnútaáætlunargerðarfána, tegund gagna sem flutt eru sem tölugildi.

  • Að sækja stillingar
    st := types.ParseConfig(*config)
  • Ef emu fáninn er samþykktur byrjar hann skúrara
  • Ef f fáninn sem gefur til kynna slóðina að skránni er til staðar, þá hleðum við gögnum hennar inn fdb og efnið er sent á netþjóninn
    client.TCPConnect(st, []byte(CMD_BUFFER_LENGTH + ":" + strconv.Itoa(*t) + "/" + strconv.Itoa(fdblen)), fdb)
  • Ef skráin er ekki tilgreind, þá eru gögnin frá fánanum einfaldlega send -d:
    client.TCPConnect(st, []byte(*data), nil)

Allt er þetta einfölduð framsetning sem sýnir uppbyggingu samskiptareglunnar. Við þróun er nauðsynlegri virkni bætt við uppbyggingu þess.

Í seinni hlutanum mun ég tala um gagnastrúktúr fyrir blokkir og viðskipti, í 3 um WebSocket þjóninn til að tengjast frá JavaScript, í 4 mun ég skoða samstillingaráætlunina, síðan staflavél sem vinnur bætikóða frá inntak og úttak, dulmál og laugar fyrir úttak.

Heimild: www.habr.com

Bæta við athugasemd