Արդեն չորս ամիս է, ինչ ես աշխատում եմ նախագծի վրա, որը կոչվում է «Տվյալների պաշտպանության և կառավարման գործիքների մշակում պետական և արդյունաբերական հատվածներում՝ հիմնված բլոկչեյնի վրա»։
Այժմ ես կցանկանայի ձեզ պատմել, թե ինչպես սկսեցի այս նախագիծը, իսկ այժմ մանրամասն նկարագրեմ ծրագրի կոդը։
Սա հոդվածաշարի առաջին հոդվածն է։ Այստեղ ես նկարագրում եմ սերվերը և արձանագրությունը: Փաստորեն, ընթերցողը կարող է նույնիսկ գրել այս բլոկչեյն տարրերի իր տարբերակները:
Անցյալ տարի «Digital Breakthrough» հաքաթոնում նրանք հանդես եկան արդյունաբերության և թվային տնտեսության համար օգտակար համակարգ ստեղծելու գաղափարով՝ օգտագործելով բաշխված գրքույկ տեխնոլոգիա; զարգացման համար դրամաշնորհ է տրամադրվել նաև Innovation Assistance Fund-ի կողմից (ես պետք է առանձին գրեմ: հոդված դրամաշնորհի մասին, նրանց համար, ովքեր նոր են սկսում ստարտափներ ), և այժմ՝ ըստ կարգի:
Զարգացումը տեղի է ունենում Go լեզվով, և տվյալների բազան, որտեղ պահվում են բլոկները, LevelDB է:
Հիմնական մասերն են արձանագրությունը, սերվերը (որն աշխատում է TCP-ն և WebSocket-ը՝ առաջինը՝ բլոկչեյնը համաժամեցնելու համար, երկրորդը՝ հաճախորդներին միացնելու, գործարքներ և հրամաններ ուղարկելու համար, օրինակ՝ JavaScript-ից։
Ինչպես նշվեց, այս բլոկչեյնն առաջին հերթին անհրաժեշտ է մատակարարների և հաճախորդների միջև ապրանքների փոխանակումն ավտոմատացնելու և պաշտպանելու համար, կամ երկուսն էլ մեկ անձի մեջ: Այս մարդիկ չեն շտապում վստահել միմյանց։ Բայց խնդիրը միայն ներկառուցված հաշվիչով «ստուգագիր» ստեղծելը չէ, այլ համակարգ, որն ավտոմատացնում է սովորական առաջադրանքների մեծ մասը, որոնք առաջանում են արտադրանքի կյանքի ցիկլի հետ աշխատելիս: Բայթկոդը, որը պատասխանատու է այս հարցի համար, ինչպես ընդունված է բլոկչեյնների դեպքում, պահվում է գործարքների մուտքերում և ելքերում (գործարքներն իրենք պահվում են բլոկներում, LevelDB-ի բլոկները նախապես կոդավորված են GOB ձևաչափով): Նախ, եկեք խոսենք արձանագրության և սերվերի մասին (aka node):
Արձանագրությունը բարդ չէ, դրա ամբողջ իմաստը որոշ տվյալների բեռնման ռեժիմին անցնելն է, սովորաբար բլոկի կամ գործարքի, ի պատասխան հրամանի հատուկ տողի, և դա անհրաժեշտ է նաև գույքագրման փոխանակման համար, որպեսզի հանգույցն իմանա, թե ով է այն: կապված է և ինչպես են նրանք անելիքներ ունեն (համաժամացման նիստի համար միացված հանգույցները կոչվում են նաև «հարևան», քանի որ նրանց IP-ն հայտնի է, և նրանց վիճակի տվյալները պահվում են հիշողության մեջ):
Թղթապանակները (դիրեկտորիաները, ինչպես դրանք անվանում է Linux-ը) Go ծրագրավորողների հասկացության մեջ կոչվում են փաթեթներ, ուստի այս գրացուցակից Go կոդով յուրաքանչյուր ֆայլի սկզբում նրանք գրում են փաթեթ folder_name_where_this_file is located: Հակառակ դեպքում, դուք չեք կարողանա փաթեթը փոխանցել կոմպիլյատորին: Դե, սա գաղտնիք չէ նրանց համար, ովքեր գիտեն այս լեզուն։ Սրանք փաթեթներ են.
- Ցանցային հաղորդակցություն (սերվեր, հաճախորդ, արձանագրություն)
- Պահված և փոխանցված տվյալների կառուցվածքները (բլոկ, գործարք)
- Տվյալների բազա (բլոկչեյն)
- Համաձայնություն
- Խցանված վիրտուալ մեքենա (xvm)
- Օժանդակ (կրիպտո, տեսակներ) այսքանը առայժմ:
Սա կրթական տարբերակ է, զուրկ է միջգործընթացային փոխազդեցությունից և մի քանի փորձարարական բաղադրիչներից, սակայն կառուցվածքը համապատասխանում է նրան, որի վրա իրականացվում է մշակում։ Եթե դուք ինչ-որ բան ունեք առաջարկելու մեկնաբանություններում, ես ուրախ կլինեմ հաշվի առնել այն հետագա մշակման ժամանակ: Իսկ հիմա սերվերի բացատրության համար և արձանագրություն.
Եկեք նախ նայենք սերվերին:
Սերվերի ենթակարգը գործում է որպես տվյալների սերվեր, որն աշխատում է TCP արձանագրության վերևում՝ օգտագործելով արձանագրության փաթեթի տվյալների կառուցվածքները:
Առօրյան օգտագործում է հետևյալ փաթեթները. սերվեր, արձանագրություն, տեսակները. Ինքն փաթեթում tcp_server.go պարունակում է տվյալների կառուցվածք Ծառայել.
type Serve struct {
Port string
BufSize int
ST *types.Settings
}
Այն կարող է ընդունել հետևյալ պարամետրերը.
- Ցանցային նավահանգիստ, որի միջոցով կփոխանակվեն տվյալները
- Սերվերի կազմաձևման ֆայլ JSON ձևաչափով
- Դրոշ՝ վրիպազերծման ռեժիմում աշխատելու համար (մասնավոր բլոկչեյն)
Առաջընթաց:
- Կարդում է կազմաձևումը JSON ֆայլից
- Վրիպազերծման ռեժիմի դրոշակը ստուգված է. եթե այն սահմանված է, ցանցի համաժամացման ժամանակացույցը չի գործարկվում, և բլոկչեյնը չի բեռնվում:
- Կազմաձևման տվյալների կառուցվածքի սկզբնավորում և սերվերի գործարկում
Server
- Իրականացնում է TCP սերվերի և ցանցային փոխազդեցության գործարկումը՝ համաձայն արձանագրության:
- Այն ունի Serve տվյալների կառուցվածք, որը բաղկացած է պորտի համարից, բուֆերի չափից և կառուցվածքի ցուցիչից տեսակները.Կարգավորումներ
- Run մեթոդը սկսում է ցանցային փոխազդեցությունը (լսելով մուտքային կապերը տվյալ նավահանգստում, երբ նոր կապ է ստացվում, դրա մշակումը փոխանցվում է մասնավոր բռնակի մեթոդին նոր շղթայում)
- В բռնակ կապից ստացված տվյալները կարդացվում են բուֆերի մեջ, վերածվում լարային ներկայացման և փոխանցվում արձանագրություն.Ընտրություն
- արձանագրություն.Ընտրություն վերադարձ արդյունք կամ առաջացնում է սխալ: արդյունք այնուհետև փոխանցվել է արձանագրություն.Մեկնաբանելորը վերադառնում է intrpr - տիպի օբյեկտ InterpreteData, կամ սխալ է առաջացնում ընտրության արդյունքի մշակման ժամանակ
- Այնուհետև անջատիչը կատարվում է intrpr.Commands[0] որը ստուգում է. արդյունք, inv, սխալ և կա մի հատված անհոգություն
- Բաժնում արդյունք անջատիչը հայտնաբերվում է արժեքով intrpr.Commands[1] որը ստուգում է արժեքները բուֆերային երկարություն и տարբերակ (յուրաքանչյուր դեպքում կոչվում է համապատասխան ֆունկցիա)
Գործառույթներ GetVersion и Բուֆերի երկարություն գտնվում են ֆայլում srvlib.go սերվերի փաթեթ
GetVersion(conn net.Conn, version string)
այն պարզապես տպում է վահանակ և ուղարկում է պարամետրով փոխանցված տարբերակը հաճախորդին.
conn.Write([]byte("result:" + version))
.
Ֆունկցիա
BufferLength(conn net.Conn, intrpr *protocol.InterpreteData)
բեռնում է բլոկ, գործարք կամ այլ կոնկրետ տվյալներ հետևյալ կերպ.
- Վահանակին տպում է արձանագրության մեջ նշված տվյալների տեսակը, որոնք պետք է ընդունվեն.
fmt.Println("DataType:", intrpr.Commands[2])
- Կարդում է արժեքը intrpr.Body թվային փոփոխականին buf_len
- Ստեղծում է բուֆեր newbuf նշված չափը:
make([]byte, buf_len)
- Լավ պատասխան է ուղարկում.
conn.Write([]byte("result:ok"))
- Ամբողջությամբ լրացնում է բուֆերը ընթերցված հոսքից.
io.ReadFull(conn, newbuf)
.
- Տպում է բուֆերի բովանդակությունը վահանակի վրա
fmt.Println(string(newbuf))
և կարդացած բայթերի քանակը
fmt.Println("Bytes length:", n)
- Լավ պատասխան է ուղարկում.
conn.Write([]byte("result:ok"))
Սերվերի փաթեթի մեթոդները կազմաձևված են ստացված տվյալների մշակման համար՝ օգտագործելով փաթեթից ստացված գործառույթները արձանագրություն.
Արձանագրություն
Արձանագրությունը ծառայում է որպես միջոց, որը ներկայացնում է տվյալները ցանցային փոխանակման մեջ:
Ընտրություն (str string) (տող, սխալ) կատարում է սերվերի կողմից ստացված տվյալների առաջնային մշակումը, որպես մուտքագրում ստանում է տվյալների տողային ներկայացում և վերադարձնում է դրա համար պատրաստված տողը. Թարգմանիչ:
- Մուտքային տողը բաժանվում է գլխի և մարմնի՝ օգտագործելով ReqParseN2 (փող.)
- գլուխը բաժանվում է տարրերի և տեղադրվում հրամանների հատվածում՝ օգտագործելով ReqParseHead (գլուխ)
- В անջատիչ (հրամաններ[0]) ընտրեք ստացված հրամանը (cmd, բանալի, հասցե կամ հատվածը գործարկվում է անհոգություն)
- cmd-ում ստուգվում է 2 հրաման անջատիչ (հրամաններ[1]) - երկարություն и վերափոխում.
- երկարություն ստուգում է տվյալների տեսակը հրամաններ[2] և պահպանում է այն datatype
- Ստուգում է դա մարմին պարունակում է լարային արժեք
len(body) < 1
- Վերադարձնում է պատասխանի տողը.
"result:bufferlength:" + datatype + "/" + body
- վերափոխում վերադարձնում է տող
return "result:version/auto"
Թարգմանիչ
Պարունակում է InterpreteData կառուցվածքը և իրականացնում է վերադարձված տվյալների երկրորդական մշակում Ընտրություն լարերի և օբյեկտների ձևավորում InterpreteData.
type InterpreteData struct {
Head string
Commands []string
Body string
IsErr bool
ErrCode int
ErrMessage string
}
Ֆունկցիա
Interprete(str string) (*InterpreteData, error)
ընդունում է տող արդյունք և ստեղծում և վերադարձնում է հղում օբյեկտին InterpreteData.
Առաջընթաց:
- Նմանապես, Ընտրություն գլուխը և մարմինը արդյունահանվում են օգտագործելով ReqParseN2 (փող.)
- գլուխը բաժանվում է տարրերի, օգտագործելով ReqParseHead (գլուխ)
- Օբյեկտը սկզբնավորվում է InterpreteData և դրա ցուցիչը վերադարձվում է.
res := &InterpreteData{
Head: head,
Commands: commands,
Body: body,
}
return res, nil
Այս օբյեկտը օգտագործվում է server.go փաթեթի հիմնական.
հաճախորդ
Հաճախորդի փաթեթը պարունակում է գործառույթներ TCPConnect и TCPResponseData.
Ֆունկցիա
TCPConnect(s *types.Settings, data []byte, payload []byte)
աշխատում է հետևյալ կերպ.
- Միացում է կատարվում անցած կարգավորումների օբյեկտում նշված կապին
net.Dial("tcp", s.Host + ":" + s.Port)
- Տվյալների պարամետրում փոխանցված տվյալները փոխանցվում են.
conn.Write(data)
- Պատասխանը կարդացվում է
resp, n, _ := TCPResponseData(conn, s.BufSize)
և տպագրվել է վահանակի վրա
fmt.Println(string(resp[:n]))
- Եթե փոխանցվի payload ապա փոխանցում է այն
conn.Write(payload)
և նաև կարդում է սերվերի պատասխանը՝ այն տպելով վահանակի վրա
Ֆունկցիա
TCPResponseData(conn net.Conn, bufsiz int) ([]byte, int, error)
ստեղծում է նշված չափի բուֆեր, այնտեղ կարդում է սերվերի պատասխանը և վերադարձնում այս բուֆերը և կարդացված բայթերի քանակը, ինչպես նաև սխալի օբյեկտ:
Հաճախորդի ենթածրագր
Ծառայում է հանգույցների սերվերներին հրամաններ ուղարկելու, ինչպես նաև համառոտ վիճակագրություն և թեստավորում ստանալու համար:
Կարող է ընդունել հետևյալ պարամետրերը՝ կազմաձևման ֆայլ JSON ձևաչափով, տվյալներ սերվերին որպես տող ուղարկելու, ուղի դեպի ֆայլ, որը պետք է ուղարկվի ծանրաբեռնվածություն, հանգույցի ժամանակացույցի էմուլյացիայի դրոշակ, տվյալների տեսակը, որը փոխանցվում է որպես թվային արժեք:
- Ստանալով կոնֆիգուրացիա
st := types.ParseConfig(*config)
- Եթե էմուի դրոշը փոխանցվում է, այն սկսվում է աշտարակ
- Եթե ֆայլի ուղին ցույց տվող f դրոշը մատակարարված է, ապա մենք բեռնում ենք դրա տվյալները fdb և բովանդակությունը ուղարկվում է սերվեր
client.TCPConnect(st, []byte(CMD_BUFFER_LENGTH + ":" + strconv.Itoa(*t) + "/" + strconv.Itoa(fdblen)), fdb)
- Եթե ֆայլը նշված չէ, ապա դրոշի տվյալները պարզապես ուղարկվում են -d:
client.TCPConnect(st, []byte(*data), nil)
Այս ամենը պարզեցված ներկայացում է, որը ցույց է տալիս արձանագրության կառուցվածքը: Մշակման ընթացքում դրա կառուցվածքին ավելացվում է անհրաժեշտ ֆունկցիոնալությունը։
Երկրորդ մասում ես կխոսեմ բլոկների և գործարքների համար տվյալների կառուցվածքների մասին, 3-ում՝ JavaScript-ից միանալու WebSocket սերվերի մասին, 4-ում կանդրադառնամ համաժամացման ժամանակացույցին, այնուհետև ստեկ մեքենան, որը մշակում է բայթային ծածկագիրը մուտքերից և ելքերից, կրիպտոգրաֆիա և լողավազաններ ելքերի համար:
Source: www.habr.com