Maendeleo ya blockchain kwa tasnia inayotumia Go. Sehemu 1

Kwa miezi minne sasa nimekuwa nikifanya kazi kwenye mradi unaoitwa "Maendeleo ya zana za ulinzi na usimamizi wa data katika sekta za serikali na viwanda kulingana na blockchain."
Sasa ningependa kukuambia kuhusu jinsi nilivyoanza mradi huu, na sasa nitaelezea msimbo wa programu kwa undani.

Maendeleo ya blockchain kwa tasnia inayotumia Go. Sehemu 1

Hii ni makala ya kwanza katika mfululizo wa makala. Hapa ninaelezea seva na itifaki. Kwa kweli, msomaji anaweza hata kuandika matoleo yake ya vipengele hivi vya blockchain.

Na hapa ni sehemu ya pili - kuhusu blockchain na miundo ya data ya shughuli, na pia kuhusu kifurushi kinachotumia mwingiliano na hifadhidata.

Mwaka jana, kwenye Digital Breakthrough hackathon, walikuja na wazo la kutengeneza mfumo muhimu kwa tasnia na uchumi wa kidijitali kwa kutumia teknolojia ya leja iliyosambazwa; ruzuku pia ilitolewa kwa maendeleo na Mfuko wa Usaidizi wa Innovation (ninapaswa kuandika tofauti. makala kuhusu ruzuku, kwa wale ambao wanaanza tu kuanza), na sasa kwa utaratibu.

Maendeleo hufanyika katika lugha ya Go, na hifadhidata ambayo vizuizi vimehifadhiwa ni LevelDB.
Sehemu kuu ni itifaki, seva (ambayo inaendesha TCP na WebSocket - ya kwanza kwa kusawazisha blockchain, ya pili kwa kuunganisha wateja, kutuma shughuli na amri kutoka kwa JavaScript, kwa mfano.

Kama ilivyotajwa, blockchain hii inahitajika kimsingi kugeuza na kulinda ubadilishanaji wa bidhaa kati ya wauzaji na wateja, au zote mbili kwa mtu mmoja. Watu hawa hawana haraka ya kuaminiana. Lakini kazi sio tu kuunda "kitabu cha hundi" na kihesabu kilichojengwa, lakini mfumo unaoendesha kazi nyingi za kawaida zinazotokea wakati wa kufanya kazi na mzunguko wa maisha ya bidhaa. Bytecode ambayo inawajibika kwa suala hili, kama kawaida na blockchains, imehifadhiwa katika pembejeo na matokeo ya shughuli (shughuli zenyewe zimehifadhiwa kwenye vizuizi, vizuizi kwenye LevelDB vimesimbwa mapema katika fomati ya GOB). Kwanza, hebu tuzungumze juu ya itifaki na seva (aka node).

Itifaki sio ngumu, hatua yake yote ni kubadili kwenye hali ya kupakia data fulani, kwa kawaida kizuizi au shughuli, kwa kukabiliana na mstari maalum wa amri, na pia inahitajika kwa kubadilishana hesabu, ili nodi ijue ni nani. imeunganishwa na jinsi wana biashara ya kufanya (nodi zilizounganishwa kwa kipindi cha ulandanishi pia huitwa "jirani" kwa sababu IP yao inajulikana na data ya hali yao imehifadhiwa kwenye kumbukumbu).

Folda (saraka kama Linux inaziita) katika uelewa wa waandaaji wa programu za Go huitwa vifurushi, kwa hivyo mwanzoni mwa kila faili iliyo na nambari ya Go kutoka kwa saraka hii huandika folda ya kifurushi_name_ambapo_faili_hili iko. Vinginevyo, hutaweza kulisha kifurushi kwa mkusanyaji. Kweli, hii sio siri kwa wanaojua lugha hii. Hivi ndivyo vifurushi:

  • Mawasiliano ya mtandao (seva, mteja, itifaki)
  • Muundo wa data iliyohifadhiwa na kupitishwa (kizuizi, shughuli)
  • Hifadhidata (blockchain)
  • Makubaliano
  • Mashine pepe iliyopangwa kwa rafu (xvm)
  • Msaidizi (crypto, aina) ndiyo yote kwa sasa.

Hapa kuna kiunga cha github

Hili ni toleo la kielimu, halina mwingiliano kati ya mchakato na vifaa kadhaa vya majaribio, lakini muundo unalingana na ule ambao maendeleo yanafanywa. Ikiwa una chochote cha kupendekeza katika maoni, nitafurahi kuzingatia katika maendeleo zaidi. Na sasa kwa maelezo ya seva na itifaki.

Hebu tuangalie seva kwanza.

Utaratibu mdogo wa seva hufanya kama seva ya data inayoendesha juu ya itifaki ya TCP kwa kutumia miundo ya data kutoka kwa kifurushi cha itifaki.

Ratiba hutumia vifurushi vifuatavyo: server, itifaki, aina. Katika mfuko yenyewe tcp_server.go ina muundo wa data Kutumikia.

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

Inaweza kukubali vigezo vifuatavyo:

  • Mlango wa mtandao ambao data itabadilishwa
  • Faili ya usanidi wa seva katika umbizo la JSON
  • Alamisha kwa kukimbia katika hali ya utatuzi (kizuizi cha faragha)

Maendeleo:

  • Husoma usanidi kutoka kwa faili ya JSON
  • Bendera ya hali ya utatuzi imeangaliwa: ikiwa imewekwa, kipanga ratiba cha ulandanishi wa mtandao hakijazinduliwa na blockchain haijapakiwa.
  • Kuanzisha muundo wa data ya usanidi na kuanzisha seva

server

  • Hufanya uzinduzi wa seva ya TCP na mwingiliano wa mtandao kwa mujibu wa itifaki.
  • Ina muundo wa data ya Serve inayojumuisha nambari ya mlango, saizi ya bafa na kielekezi cha muundo aina.Mipangilio
  • Mbinu ya Run huanza mwingiliano wa mtandao (kusikiliza miunganisho inayoingia kwenye lango fulani, muunganisho mpya unapopokelewa, usindikaji wake huhamishiwa kwa njia ya kushughulikia ya kibinafsi kwenye uzi mpya)
  • Π’ kushughulikia data kutoka kwa muunganisho inasomwa kuwa buffer, inabadilishwa kuwa uwakilishi wa kamba na kupitishwa kwa itifaki.Chaguo
  • itifaki.Chaguo anarudi kusababisha au husababisha kosa. kusababisha kisha kuhamishiwa itifaki.Tafsiriambayo inarudi intrpr - kitu cha aina TafsiriData, au husababisha hitilafu katika kuchakata matokeo ya uteuzi
  • Kisha swichi inatekelezwa intrpr.Commands[0] ambayo hukagua moja ya: matokeo, inv, makosa na kuna sehemu default
  • Katika sehemu kusababisha swichi hupatikana kwa thamani intrpr.Commands[1] ambayo hukagua maadili urefu wa buffer ΠΈ version (katika kila kesi kazi inayolingana inaitwa)

Kazi GetVersion ΠΈ Urefu wa Buffer ziko kwenye faili srvlib.go kifurushi cha seva

GetVersion(conn net.Conn, version string)

inachapisha kwa koni na kutuma toleo lililopitishwa kwa paramu kwa mteja:

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

.
Kazi

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

hupakia kizuizi, shughuli, au data nyingine maalum kama ifuatavyo:

  • Huchapisha kwenye kiweko aina ya data iliyobainishwa katika itifaki ambayo inahitaji kukubaliwa:
    fmt.Println("DataType:", intrpr.Commands[2])
  • Inasoma thamani Mwili wa intrpr kwa kutofautiana kwa nambari buf_len
  • Huunda bafa newbuf ukubwa maalum:
    make([]byte, buf_len)
  • Inatuma jibu sawa:
    conn.Write([]byte("result:ok"))
  • Inajaza kikamilifu buffer kutoka kwa mtiririko uliosomwa:
    io.ReadFull(conn, newbuf)

    .

  • Huchapisha yaliyomo kwenye bafa kwenye kiweko
    fmt.Println(string(newbuf))

    na idadi ya baiti zilizosomwa

    fmt.Println("Bytes length:", n)
  • Inatuma jibu sawa:
    conn.Write([]byte("result:ok"))

Mbinu kutoka kwa kifurushi cha seva zimesanidiwa ili kuchakata data iliyopokelewa kwa kutumia vitendaji kutoka kwa kifurushi itifaki.

Itifaki ya

Itifaki hutumika kama njia inayowakilisha data katika ubadilishanaji wa mtandao.

Chaguo(str string) (kamba, kosa) hufanya usindikaji wa msingi wa data iliyopokelewa na seva, hupokea uwakilishi wa kamba ya data kama ingizo na kurudisha kamba iliyotayarishwa kwa Mkalimani:

  • Kamba ya kuingiza imegawanywa katika kichwa na mwili kwa kutumia ReqParseN2(str)
  • kichwa kimegawanywa katika vitu na kuwekwa kwenye kipande cha amri kwa kutumia ReqParseHead(kichwa)
  • Π’ kubadili(amri[0]) chagua amri iliyopokelewa (cmd, ufunguo, anwani au sehemu imeanzishwa default)
  • Amri 2 zimetiwa alama kwenye cmd kubadili(amri[1]) - urefu ΠΈ kupata toleo.
  • urefu huangalia aina ya data amri [2] na kuihifadhi ndani Datatype
  • Hukagua hiyo mwili ina thamani ya mfuatano
    len(body) < 1
  • Hurejesha mfuatano wa majibu:
    "result:bufferlength:" + datatype + "/" + body
  • kupata toleo inarudisha kamba
    return "result:version/auto"

Mkalimani

Ina muundo wa InterpreteData na hufanya uchakataji wa pili wa data iliyorejeshwa kutoka Uchaguzi masharti na uundaji wa kitu TafsiriData.

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

Kazi

Interprete(str string) (*InterpreteData, error)

inakubali kamba kusababisha na huunda na kurudisha kumbukumbu kwa kitu TafsiriData.

Maendeleo:

  • Vile vile Uchaguzi kichwa na mwili hutolewa kwa kutumia ReqParseN2(str)
  • kichwa imegawanywa katika vipengele kwa kutumia ReqParseHead(kichwa)
  • Kipengee kimeanzishwa TafsiriData na kiashiria kinarudishwa:

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

Kitu hiki kinatumika katika seva.go kifurushi kikuu.

mteja

Kifurushi cha mteja kina vitendaji TCPConnect ΠΈ TCPResponseData.

Kazi

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

inafanya kazi kama hii:

  • Uunganisho unafanywa kwa uunganisho uliowekwa kwenye kitu cha mipangilio iliyopitishwa
    net.Dial("tcp", s.Host + ":" + s.Port)
  • Data iliyopitishwa katika parameta ya data inapitishwa:
    conn.Write(data)
  • Jibu linasomwa
    resp, n, _ := TCPResponseData(conn, s.BufSize)

    na kuchapishwa kwenye console

    fmt.Println(string(resp[:n]))
  • Ikihamishwa payload kisha huipitisha
    conn.Write(payload)

    na pia husoma majibu ya seva, na kuichapisha kwa koni

Kazi

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

huunda bafa ya ukubwa uliobainishwa, husoma jibu la seva hapo na kurudisha bafa hii na idadi ya baiti zilizosomwa, pamoja na kitu cha hitilafu.

Utaratibu mdogo wa mteja

Hutumika kutuma amri kwa seva za nodi, na pia kupata takwimu fupi na majaribio.

Inaweza kukubali vigezo vifuatavyo: faili ya usanidi katika umbizo la JSON, data ya kutumwa kwa seva kama mfuatano, njia ya faili itakayotumwa kwa upakiaji, bendera ya uigaji wa kipanga ratiba, aina ya data inayohamishwa kama thamani ya nambari.

  • Kupata usanidi
    st := types.ParseConfig(*config)
  • Ikiwa bendera ya emu itapitishwa, inaanza mchungaji
  • Ikiwa bendera ya f inayoonyesha njia ya faili imetolewa, basi tunapakia data yake ndani fdb na yaliyomo hutumwa kwa seva
    client.TCPConnect(st, []byte(CMD_BUFFER_LENGTH + ":" + strconv.Itoa(*t) + "/" + strconv.Itoa(fdblen)), fdb)
  • Ikiwa faili haijainishwa, basi data kutoka kwa bendera inatumwa tu -d:
    client.TCPConnect(st, []byte(*data), nil)

Yote hii ni uwakilishi rahisi unaoonyesha muundo wa itifaki. Wakati wa maendeleo, utendaji muhimu huongezwa kwa muundo wake.

Katika sehemu ya pili nitazungumza juu ya muundo wa data kwa vizuizi na shughuli, katika 3 kuhusu seva ya WebSocket ya kuunganishwa kutoka kwa JavaScript, katika 4 nitaangalia mpangilio wa maingiliano, kisha mashine ya stack ambayo husindika bytecode kutoka kwa pembejeo na matokeo, cryptography na. mabwawa kwa ajili ya matokeo.

Chanzo: mapenzi.com

Kuongeza maoni