Olen nyt neljä kuukautta työskennellyt projektissa nimeltä ”Lohkoketjupohjaisten tietosuoja- ja hallintatyökalujen kehittäminen julkishallinnossa ja teollisuudessa”.
Haluaisin nyt kertoa teille, miten aloitin tämän projektin, ja kuvailen nyt ohjelmakoodia yksityiskohtaisesti.

Tämä on ensimmäinen artikkeli sarjassani. Tässä kuvailen palvelinta ja protokollaa. Lukija voi itse asiassa kirjoittaa omia versioitaan näistä lohkoketjun elementeistä.
— lohkoketjun tietorakenteista ja tapahtumista sekä tietokannan kanssa vuorovaikutuksen toteuttavasta paketista.
Viime vuonna Digital Breakthrough -hackathonissa esitimme ajatuksen hyödyllisen järjestelmän luomisesta hajautetun tilikirjan teknologiaa hyödyntäen teollisuutta ja digitaalitaloutta varten. Myös Foundation for Assistance to Small Innovative Enterprises (FASIE) myönsi apurahan kehitystyöhön (minun pitäisi kirjoittaa erillinen artikkeli avustuksesta niille, jotka vasta aloittavat). Nyt edetään askel askeleelta.
Kehitys tehdään Go-kielellä ja lohkot tallennetaan LevelDB-tietokantaan.
Pääosat ovat protokolla, palvelin (joka suorittaa TCP:tä) ja WebSocket – ensimmäinen lohkoketjun synkronointiin, toinen asiakkaiden yhdistämiseen, tapahtumien ja komentojen lähettämiseen esimerkiksi JavaScriptistä.
Kuten mainittiin, tätä lohkoketjua tarvitaan ensisijaisesti toimittajien ja asiakkaiden tai molempien välisen tuotevaihdon automatisointiin ja turvaamiseen. Nämä yritykset ovat haluttomia luottamaan toisiinsa. Tavoitteena ei kuitenkaan ole luoda vain laskurilla varustettua laskurikirjaa, vaan järjestelmä, joka automatisoi suurimman osan tuotteen elinkaaren aikana ilmenevistä rutiinitehtävistä. Tästä vastaava tavukoodi, kuten lohkoketjuille on tyypillistä, tallennetaan tapahtumien syötteisiin ja lähtöihin (itse tapahtumat tallennetaan lohkoihin, jotka LevelDB:ssä on esikoodattu GOB-muotoon). Ensin puhutaan protokollasta ja palvelimesta (tunnetaan myös solmuna).
Protokolla toimii melko yksinkertaisesti. Sen koko tarkoitus on vaihtaa lataustilaan tietylle datalle, yleensä lohkolle tai tapahtumalle, vastauksena erityiseen komentojonoon. Sitä tarvitaan myös varastonvaihtoon, jotta solmu tietää, kehen se on yhteydessä ja miten heillä menee (synkronointi-istuntoa varten yhteydessä olevia solmuja kutsutaan myös "naapureiksi", koska niiden IP-osoitteet tunnetaan ja niiden tilatiedot tallennetaan muistiin).
Kansiot (hakemistot, kuten niitä kutsutaan) Linux) kutsutaan Go-kielellä paketeiksi, joten jokaisen tässä hakemistossa olevan Go-koodia sisältävän tiedoston alkuun kirjoitetaan paketti [kansion_nimi_jossa_tämä_tiedosto_on]. Muuten pakettia ei voida syöttää kääntäjälle. No, se ei ole mikään salaisuus kieltä osaaville. Tässä ovat nämä paketit:
- Verkkovuorovaikutus (palvelin, asiakas, protokolla)
- Tallennetun ja lähetetyn datan rakenteet (lohko, tapahtuma)
- Tietokanta (lohkoketju)
- Konsensus
- Pinottu virtuaalikone (xvm)
- Apuohjelmat (krypto, tyypit) siinä kaikki tällä erää.
Tämä on harjoitusversio; siitä puuttuu prosessien välinen kommunikaatio ja useita kokeellisia komponentteja, mutta rakenne vastaa parhaillaan kehitteillä olevaa. Jos sinulla on ehdotuksia kommenteissa, otan ne mielelläni huomioon jatkokehitystä varten. Seuraavaksi muutamia selvennyksiä palvelimesta ja paketeista. protokolla.
Katsotaanpa ensin palvelinta.
Palvelinaliohjelma toimii TCP-protokollaa käyttävänä datapalvelimena käyttäen protokollapaketin datarakenteita.
Aliohjelma käyttää seuraavia paketteja: palvelin, protokolla, tyypitItse paketissa tcp_palvelin.go sisältää tietorakenteen Palvella.
type Serve struct {
Port string
BufSize int
ST *types.Settings
}Se voi ottaa seuraavat parametrit:
- Verkkoportti, jonka kautta tiedonvaihto tapahtuu
- Palvelimen määritystiedosto JSON-muodossa
- Merkitse, että se toimii virheenkorjaustilassa (yksityinen lohkoketju)
Edistyminen:
- Konfiguraatio luetaan JSON-tiedostosta.
- Virheenjäljitystilan lippu on valittuna: jos se on asetettu, verkon synkronoinnin ajoitusohjelmaa ei käynnistetä eikä lohkoketjua ladata.
- Konfiguraatiotietorakenteen alustaminen ja palvelimen käynnistäminen
Server
- Suorittaa TCP-palvelimen käynnistyksen ja verkon vuorovaikutuksen protokollan mukaisesti.
- Se sisältää Serve-tietorakenteen, joka koostuu porttinumerosta, puskurin koosta ja osoittimesta rakenteeseen. tyypit.Asetukset
- Run-metodi käynnistää verkkoyhteyden (kuuntelee saapuvia yhteyksiä tietyssä portissa; kun uusi yhteys vastaanotetaan, sen käsittely siirretään uudessa säikeessä olevalle private handle -metodille).
- В kahva Yhteydeltä tulevat tiedot luetaan puskuriin, muunnetaan merkkijonomuotoon ja välitetään protokolla.Valinta
- protokolla.Valinta palaa johtua tai aiheuttaa virheen. johtua sitten siirrettiin protokolla.Tulkitse, joka palauttaa sisäinen — tyyppinen objekti Tulkitse tietojatai aiheuttaa virheen valintatuloksen käsittelyssä
- Sitten vaihto suoritetaan seuraavasti: intrpr.komennot[0] jossa yksi seuraavista on valittuna: tulos, inv, virhe ja siellä on osio oletusarvo
- osiossa johtua kytkin löytyy arvon perusteella intrpr.komennot[1] joka tarkistaa arvot puskurin pituus и versio (jokaisessa tapauksessa kutsutaan vastaavaa funktiota)
Tehtävät HaeVersio и Puskurin pituus ovat tiedostossa srvlib.go palvelinpaketti.
GetVersion(conn net.Conn, version string)yksinkertaisesti tulostaa konsoliin ja lähettää parametrissa annetun version asiakkaalle:
conn.Write([]byte("result:" + version)).
Toiminto
BufferLength(conn net.Conn, intrpr *protocol.InterpreteData)suorittaa lohkon, tapahtuman tai muun määritetyn tiedon lataamisen seuraavasti:
- Tulostaa konsoliin protokollassa määritetyn datatyypin, joka on hyväksyttävä:
fmt.Println("DataType:", intrpr.Commands[2]) - Lukee arvon sisäinen.runko numeeriseen muuttujaan buf_len
- Luo puskurin newbuf määritetty koko:
make([]byte, buf_len) - Lähettää ok-vastauksen:
conn.Write([]byte("result:ok")) - Täyttää puskurin kokonaan lukuvirrasta:
io.ReadFull(conn, newbuf).
- Tulostaa puskurin sisällön konsolille.
fmt.Println(string(newbuf))ja luettujen tavujen määrä
fmt.Println("Bytes length:", n) - Lähettää ok-vastauksen:
conn.Write([]byte("result:ok"))
Palvelinpaketin metodit konfiguroidaan käsittelemään vastaanotettua dataa paketin funktioiden avulla. protokolla.
Protokolla
Protokolla toimii keinona, jolla data esitetään verkkovaihdossa.
Valinta(merkkijono) (merkkijono, virhe) suorittaa palvelimen vastaanottaman datan ensisijaisen käsittelyn, vastaanottaa syötteenä datan merkkijonoesityksen ja palauttaa sitä varten valmistellun merkkijonon Tulkki:
- Syötemerkkijono jaetaan pää- ja runko-osiin käyttämällä ReqParseN2(merkkijono)
- head jaetaan elementteihin ja sijoitetaan komentosektioon käyttämällä ReqParseHead(head)-funktiota
- В kytkin(komennot[0]) valitsemme vastaanotetun komennon (cmd, avain, osoite tai osio laukeaa oletusarvo)
- Cmd:ssä tarkistetaan kaksi komentoa switch(komennot[1]) — pituus и getversion.
- pituus tarkistaa tietotyypin kohdassa komennot[2] ja tallentaa sen tietotyyppi
- Tarkistaa, että elin sisältää merkkijonoarvon
len(body) < 1 - Palauttaa vastausmerkkijonon:
"result:bufferlength:" + datatype + "/" + body - getversion palauttaa merkkijonon
return "result:version/auto"
Tulkki
Sisältää InterpreteData-rakenteen ja suorittaa palautettujen tietojen toissijaisen käsittelyn. Valinta merkkijonot ja objektien muodostuminen Tulkitse tietoja.
type InterpreteData struct {
Head string
Commands []string
Body string
IsErr bool
ErrCode int
ErrMessage string
}Toiminto
Interprete(str string) (*InterpreteData, error)ottaa narun johtua ja luo palauttaa viittauksen objektiin Tulkitse tietoja.
Edistyminen:
- samoin Valinta Pää ja vartalo irrotetaan käyttämällä ReqParseN2(merkkijono)
- pää jaetaan elementteihin käyttämällä ReqParseHead(pää)
- Objekti on alustettu Tulkitse tietoja ja palautetaan osoitin siihen:
res := &InterpreteData{
Head: head,
Commands: commands,
Body: body,
}
return res, nilTätä objektia käytetään palvelin.go pääpaketti.
Asiakas
Asiakaspaketti sisältää funktioita TCPConnect и TCP-vastaustiedot.
Toiminto
TCPConnect(s *types.Settings, data []byte, payload []byte)toimii näin:
- Yhteys muodostetaan välitetyssä asetusobjektissa määritettyyn yhteyteen.
net.Dial("tcp", s.Host + ":" + s.Port) - Data-parametrissa välitetyt tiedot siirretään:
conn.Write(data) - Vastaus on luettavana
resp, n, _ := TCPResponseData(conn, s.BufSize)ja se on painettu konsoliin
fmt.Println(string(resp[:n])) - Jos siirretään hyötykuorma sitten välittää sen eteenpäin
conn.Write(payload)ja lukee myös palvelimen vastauksen ja tulostaa sen konsoliin
Toiminto
TCPResponseData(conn net.Conn, bufsiz int) ([]byte, int, error)luo määritetyn kokoisen puskurin, lukee palvelimen vastauksen siihen ja palauttaa tämän puskurin ja luettujen tavujen määrän sekä virheobjektin.
Asiakasaliohjelma
Palvelee komentojen lähettämiseen solmupalvelimille sekä lyhyiden tilastojen ja testauksen hankkimiseen.
Voi hyväksyä seuraavat parametrit: JSON-muodossa oleva määritystiedosto, palvelimelle merkkijonona siirrettävä data, hyötykuormaan siirrettävän tiedoston polku, solmun ajoituksen emulointilippu ja siirrettävän datan tyyppi numeerisena arvona.
- Määrityksen hakeminen
st := types.ParseConfig(*config) - Jos emu-lippu hyväksytään, se alkaa sheduler
- Jos f-lippu annetaan tiedostopolun kanssa, lataamme sen tiedot tiedostoon fdb ja sisältö lähetetään palvelimelle
client.TCPConnect(st, []byte(CMD_BUFFER_LENGTH + ":" + strconv.Itoa(*t) + "/" + strconv.Itoa(fdblen)), fdb) - Jos tiedostoa ei ole määritetty, lähetetään vain lipun tiedot. -d:
client.TCPConnect(st, []byte(*data), nil)
Tämä on yksinkertaistettu esitys protokollan rakenteesta. Kehityksen aikana sen rakenteeseen lisätään tarvittavat toiminnot.
Osassa 2 käsittelen lohkojen ja tapahtumien tietorakenteita, osassa 3 käsittelen WebSocket-palvelinta JavaScript-yhteyksien muodostamiseen ja osassa 4 käsittelen synkronoinnin ajoittajan sekä pinoamismoottorin, joka käsittelee syötteistä ja lähdöistä tulevaa tavukoodia, kryptografian ja lähtöpooleja.
Lähde: will.com
