Go භාවිතා කරන කර්මාන්තය සඳහා Blockchain සංවර්ධනය. 1 කොටස

දැන් මාස හතරක් තිස්සේ මම "බ්ලොක්චේන් මත පදනම් වූ රාජ්‍ය සහ කාර්මික අංශවල දත්ත ආරක්ෂණ සහ කළමනාකරණ මෙවලම් සංවර්ධනය කිරීම" නම් ව්‍යාපෘතියක වැඩ කරමින් සිටිමි.
දැන් මම මෙම ව්යාපෘතිය ආරම්භ කළ ආකාරය ගැන ඔබට කියන්නට කැමැත්තෙමි, දැන් මම වැඩසටහන් කේතය විස්තරාත්මකව විස්තර කරමි.

Go භාවිතා කරන කර්මාන්තය සඳහා Blockchain සංවර්ධනය. 1 කොටස

මේ ලිපි පෙළක පළමු ලිපියයි. මෙන්න මම සේවාදායකය සහ ප්රොටෝකෝලය විස්තර කරමි. ඇත්ත වශයෙන්ම, පාඨකයාට මෙම බ්ලොක්චේන් මූලද්රව්යවල ඔහුගේම අනුවාද පවා ලිවිය හැකිය.

ඒ වගේම මෙන්න දෙවන කොටස — blockchain සහ ගණුදෙණු දත්ත ව්‍යුහයන් ගැන මෙන්ම දත්ත සමුදාය සමඟ අන්තර්ක්‍රියා කරන පැකේජය ගැන.

පසුගිය වසරේ Digital Breakthrough hackathon හිදී ඔවුන් බෙදා හරින ලද ලෙජර් තාක්‍ෂණය භාවිතයෙන් කර්මාන්තයට සහ ඩිජිටල් ආර්ථිකයට ප්‍රයෝජනවත් පද්ධතියක් සෑදීමට අදහසක් ඉදිරිපත් කළහ; නවෝත්පාදන ආධාර අරමුදල මගින් සංවර්ධනය සඳහා ප්‍රදානයක් ද නිකුත් කරන ලදී (මම වෙනම ලිවිය යුතුයි. ප්‍රදානය පිළිබඳ ලිපිය, අලුතින් ආරම්භ කරන අය සඳහා ), සහ දැන් පිළිවෙලට.

සංවර්ධනය Go භාෂාවෙන් සිදු වන අතර, කුට්ටි ගබඩා කර ඇති දත්ත සමුදාය LevelDB වේ.
ප්‍රධාන කොටස් වන්නේ ප්‍රොටෝකෝලය, සේවාදායකය (TCP සහ WebSocket ක්‍රියාත්මක වන - බ්ලොක්චේන් සමමුහුර්ත කිරීම සඳහා පළමුවැන්න, සේවාදායකයින් සම්බන්ධ කිරීම, ජාවාස්ක්‍රිප්ට් වෙතින් ගනුදෙනු සහ විධාන යැවීම, උදාහරණයක් ලෙස.

සඳහන් කළ පරිදි, මෙම blockchain මූලික වශයෙන් අවශ්‍ය වන්නේ සැපයුම්කරුවන් සහ පාරිභෝගිකයින් අතර නිෂ්පාදන හුවමාරුව ස්වයංක්‍රීය කිරීමට සහ ආරක්ෂා කිරීමට හෝ දෙකම එක් පුද්ගලයෙකු තුළ ය. මෙම පුද්ගලයින් එකිනෙකා විශ්වාස කිරීමට ඉක්මන් නොවේ. නමුත් කාර්යය වන්නේ බිල්ට් කැල්කියුලේටරය සමඟ "චෙක්බුක්" නිර්මාණය කිරීම පමණක් නොව, නිෂ්පාදන ජීවන චක්රය සමඟ වැඩ කරන විට පැන නගින බොහෝ සාමාන්ය කාර්යයන් ස්වයංක්රීය කරන පද්ධතියකි. බ්ලොක්චේන් වල සිරිතක් ලෙස මෙම කාරණයට වගකිව යුතු බයිට්කේතය ගනුදෙනු වල යෙදවුම් සහ ප්‍රතිදානයන්හි ගබඩා කර ඇත (ගනුදෙනු බ්ලොක් වල ගබඩා කර ඇත, LevelDB හි කුට්ටි GOB ආකෘතියෙන් පූර්ව කේතනය කර ඇත). පළමුව, අපි ප්‍රොටෝකෝලය සහ සේවාදායකය (එනම් නෝඩය) ගැන කතා කරමු.

ප්‍රොටෝකෝලය සංකීර්ණ නොවේ, එහි සම්පූර්ණ කරුණ වන්නේ විශේෂ විධාන රේඛාවකට ප්‍රතිචාර වශයෙන් සමහර දත්ත පැටවීමේ ක්‍රමයට, සාමාන්‍යයෙන් වාරණ හෝ ගනුදෙනුවකට මාරුවීම වන අතර, ඉන්වෙන්ටරි හුවමාරු කර ගැනීම සඳහා ද එය අවශ්‍ය වේ, එවිට නෝඩය එය කවුදැයි දැන ගනී. සම්බන්ධ වී ඇති අතර ඔවුන්ට ව්‍යාපාර කිරීමට ඇත්තේ කෙසේද (සමමුහුර්ත කිරීමේ සැසිය සඳහා සම්බන්ධ කර ඇති නෝඩ් ඔවුන්ගේ IP දන්නා අතර ඒවායේ රාජ්‍ය දත්ත මතකයේ ගබඩා කර ඇති නිසා "අසල්වැසි" ලෙසද හැඳින්වේ).

Go ක්‍රමලේඛකයින් පිළිබඳ අවබෝධයේ ඇති ෆෝල්ඩර (ලිනක්ස් ලෙස හඳුන්වන නාමාවලි) පැකේජ ලෙස හැඳින්වේ, එබැවින් මෙම නාමාවලියෙන් Go කේතය සහිත සෑම ගොනුවකම ආරම්භයේදීම ඔවුන් විසින් folder_name_where_this_file පිහිටා ඇති පැකේජය ලියයි. එසේ නොමැතිනම්, ඔබට පැකේජය සම්පාදකයට පෝෂණය කිරීමට නොහැකි වනු ඇත. හොඳයි, මෙම භාෂාව දන්නා අයට මෙය රහසක් නොවේ. මේවා පැකේජ වේ:

  • ජාල සන්නිවේදනය (සේවාදායකය, සේවාදායකයා, ප්‍රොටෝකෝලය)
  • ගබඩා කරන ලද සහ සම්ප්‍රේෂණය කරන ලද දත්තවල ව්‍යුහයන් (අවහිර කිරීම, ගනුදෙනුව)
  • දත්ත සමුදාය (බ්ලොක්චේන්)
  • සම්මුතිය
  • ගොඩගැසූ අතථ්‍ය යන්ත්‍රය (xvm)
  • සහායක (ක්‍රිප්ටෝ, වර්ග) දැනට එපමණයි.

මෙන්න github එකට ලින්ක් එක

මෙය අධ්‍යාපනික අනුවාදයකි, එයට අන්තර් ක්‍රියාවලි අන්තර්ක්‍රියා සහ පර්යේෂණාත්මක සංරචක කිහිපයක් නොමැත, නමුත් ව්‍යුහය සංවර්ධනය සිදු කරන එකට අනුරූප වේ. අදහස් දැක්වීමේදී ඔබට යෝජනා කිරීමට යමක් ඇත්නම්, වැඩිදුර සංවර්ධනයේදී එය සැලකිල්ලට ගැනීමට මම සතුටු වෙමි. දැන් සේවාදායකයේ පැහැදිලි කිරීමක් සඳහා සහ ප්රොටොකෝලය.

අපි මුලින්ම server එක බලමු.

ප්‍රොටෝකෝල පැකේජයේ දත්ත ව්‍යුහයන් භාවිතා කරමින් TCP ප්‍රොටෝකෝලය මත ක්‍රියාත්මක වන දත්ත සේවාදායකයක් ලෙස සේවාදායක උපසිරැසි ක්‍රියා කරයි.

චර්යාව පහත පැකේජ භාවිතා කරයි: සේවාදායකය, ප්රොටොකෝලය, වර්ග. පැකේජයේම tcp_server.go දත්ත ව්යුහය අඩංගු වේ සේවය කරන්න.

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

එය පහත පරාමිතීන් පිළිගත හැකිය:

  • දත්ත හුවමාරු වන ජාල වරාය
  • සේවාදායක වින්‍යාස ගොනුව JSON ආකෘතියෙන්
  • නිදොස් කිරීමේ මාදිලියේ ධාවනය සඳහා ධජය (පුද්ගලික බ්ලොක්චේන්)

ප්රගතිය:

  • JSON ගොනුවෙන් වින්‍යාසය කියවයි
  • දෝශ නිරාකරණ ප්‍රකාර ධජය පරීක්ෂා කර ඇත: එය සකසා ඇත්නම්, ජාල සමමුහුර්ත කිරීමේ උපලේඛනය දියත් නොකරන අතර බ්ලොක්චේන් පූරණය නොවේ
  • වින්‍යාස දත්ත ව්‍යුහය ආරම්භ කිරීම සහ සේවාදායකය ආරම්භ කිරීම

සේවාදායකය

  • ප්‍රොටෝකෝලයට අනුකූලව TCP සේවාදායකය දියත් කිරීම සහ ජාල අන්තර්ක්‍රියා සිදු කරයි.
  • එහි පෝට් අංකයකින්, බෆර ප්‍රමාණයකින් සහ ව්‍යුහයට පොයින්ටරයකින් සමන්විත සර්ව් දත්ත ව්‍යුහයක් ඇත වර්ග.සැකසීම්
  • ධාවන ක්‍රමය ජාල අන්තර්ක්‍රියා ආරම්භ කරයි (දී ඇති පෝට් එකක එන සම්බන්ධතා සඳහා සවන් දීම, නව සම්බන්ධතාවයක් ලැබුණු විට, එහි සැකසීම නව නූල් එකක පුද්ගලික හැසිරවීමේ ක්‍රමයට මාරු කරනු ලැබේ)
  • В හැසිරවීම සම්බන්ධතාවයේ දත්ත බෆරයක් බවට කියවා, තන්තු නිරූපණයක් බවට පරිවර්තනය කර යවනු ලැබේ protocol.Choice
  • protocol.Choice ආපසු පැමිණේ ප්රතිඵලය නැතහොත් දෝෂයක් ඇති කරයි. ප්රතිඵලය පසුව මාරු කළා ප්රොටෝකෝලය.අර්ථකථනය කරන්නආපසු එන intrpr - වර්ගයේ වස්තුව පරිවර්ථන දත්ත, හෝ තේරීමේ ප්‍රතිඵලය සැකසීමේදී දෝෂයක් ඇති කරයි
  • එවිට ස්විචය ක්රියාත්මක වේ intrpr.Commands[0] මෙයින් එකක් පරීක්ෂා කරන්නේ: ප්රතිඵලය, inv, දෝෂය සහ කොටසක් ඇත පැහැර හැරීමකි
  • කොටසේ ප්රතිඵලය ස්විචය අගයෙන් සොයා ගනී intrpr.Commands[1] අගයන් පරීක්ෂා කරන බෆර දිග и පිටපත (සෑම අවස්ථාවකම අදාළ කාර්යය ලෙස හැඳින්වේ)

කාර්යයන් GetVersion и BufferLength ගොනුවේ ඇත 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.ශරීරය සංඛ්‍යාත්මක විචල්‍යයකට 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"))

සේවාදායක පැකේජයෙන් ක්‍රම වින්‍යාස කර ඇත්තේ පැකේජයේ ඇති කාර්යයන් භාවිතයෙන් ලැබුණු දත්ත සැකසීමටය ප්රොටොකෝලය.

ප්රොටොකෝලය

ප්‍රොටෝකෝලයක් ජාල හුවමාරුවේ දත්ත නියෝජනය කරන මාධ්‍යයක් ලෙස ක්‍රියා කරයි.

තේරීම (string) (තන්තුව, දෝෂය) සේවාදායකයට ලැබෙන දත්තවල ප්‍රාථමික සැකසුම් සිදු කරයි, දත්තවල තන්තු නිරූපණයක් ආදානය ලෙස ලබා ගනී සහ ඒ සඳහා සකස් කළ තන්තුවක් ආපසු ලබා දෙයි පරිවර්තක:

  • ආදාන තන්තුව භාවිතා කරමින් හිස සහ ශරීරයට බෙදී ඇත ReqParseN2(str)
  • හිස මූලද්‍රව්‍යවලට බෙදී ReqParseHead(හිස) භාවිතයෙන් විධාන පෙත්තකට තබා ඇත
  • В මාරු (විධාන[0]) ලැබුණු විධානය තෝරන්න (cmd, යතුර, ලිපිනය හෝ කොටස අවුලුවනු ලැබේ පැහැර හැරීමකි)
  • විධාන 2 ක් cmd හි පරීක්ෂා කර ඇත මාරු (විධාන[1]) - දිග и ලබා ගැනීම.
  • දිග දත්ත වර්ගය පරීක්ෂා කරයි විධාන[2] සහ එය සුරකියි දත්ත සමුදාය
  • එය පරීක්ෂා කරයි සිරුර තන්තු අගයක් අඩංගු වේ
    len(body) < 1
  • ප්‍රතිචාර තන්තුව ආපසු ලබා දෙයි:
    "result:bufferlength:" + datatype + "/" + body
  • ලබා ගැනීම තන්තුවක් ආපසු ලබා දෙයි
    return "result:version/auto"

පරිවර්තක

InterpreteData ව්‍යුහය අඩංගු වන අතර ආපසු ලැබෙන දත්තවල ද්විතියික සැකසුම් සිදු කරයි තේරීම නූල් සහ වස්තුව ගොඩනැගීම පරිවර්ථන දත්ත.

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

උත්සවය

Interprete(str string) (*InterpreteData, error)

තන්තුවක් පිළිගනී ප්රතිඵලය සහ වස්තුවට සඳහනක් නිර්මාණය කර ආපසු ලබා දෙයි පරිවර්ථන දත්ත.

ප්රගතිය:

  • ඒ හා සමානවම තේරීම හිස සහ ශරීරය භාවිතයෙන් නිස්සාරණය කරනු ලැබේ ReqParseN2(str)
  • හිස භාවිතා කරමින් මූලද්රව්ය වලට බෙදී ඇත ReqParseHead(හිස)
  • වස්තුව ආරම්භ කර ඇත පරිවර්ථන දත්ත සහ එය වෙත දර්ශකයක් ආපසු එවනු ලැබේ:

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]))
  • මාරු කළොත් බරයි පසුව එය සම්මත කරයි
    conn.Write(payload)

    තවද එය කොන්සෝලයට මුද්‍රණය කරමින් සේවාදායක ප්‍රතිචාරය කියවයි

උත්සවය

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

නිශ්චිත ප්‍රමාණයේ බෆරයක් නිර්මාණය කරයි, එහි සේවාදායක ප්‍රතිචාරය කියවා මෙම බෆරය සහ කියවූ බයිට් ගණන මෙන්ම දෝෂ වස්තුවක් ද ලබා දෙයි.

සේවාලාභී උපසිරැසි

නෝඩ් සේවාදායකයන්ට විධාන යැවීමට මෙන්ම කෙටි සංඛ්‍යාලේඛන සහ පරීක්ෂණ ලබා ගැනීමටද සේවය කරයි.

පහත පරාමිති පිළිගත හැක: JSON ආකෘතියෙන් වින්‍යාස ගොනුව, තන්තුවක් ලෙස සේවාදායකයට යැවිය යුතු දත්ත, ගෙවීමට යැවිය යුතු ගොනුව වෙත මාර්ගය, නෝඩ් උපලේඛන අනුකරණ ධජය, සංඛ්‍යාත්මක අගයක් ලෙස මාරු කළ දත්ත වර්ගය.

  • වින්‍යාසය ලබා ගැනීම
    st := types.ParseConfig(*config)
  • emu ධජය සම්මත කළහොත් එය ආරම්භ වේ ෂෙඩුලර්
  • ගොනුව වෙත යන මාර්ගය දැක්වෙන f ධජය සපයා තිබේ නම්, අපි එහි දත්ත පූරණය කරමු fdb සහ අන්තර්ගතය සේවාදායකය වෙත යවනු ලැබේ
    client.TCPConnect(st, []byte(CMD_BUFFER_LENGTH + ":" + strconv.Itoa(*t) + "/" + strconv.Itoa(fdblen)), fdb)
  • ගොනුව නිශ්චිතව දක්වා නොමැති නම්, ධජයෙන් දත්ත සරලව යවනු ලැබේ -d:
    client.TCPConnect(st, []byte(*data), nil)

මේ සියල්ල ප්‍රොටෝකෝලයේ ව්‍යුහය පෙන්වන සරල නිරූපණයකි. සංවර්ධනය අතරතුර, අවශ්ය ක්රියාකාරිත්වය එහි ව්යුහයට එකතු වේ.

දෙවන කොටසේදී මම බ්ලොක් සහ ගනුදෙනු සඳහා දත්ත ව්‍යුහයන් ගැන කතා කරමි, 3 හි ජාවාස්ක්‍රිප්ට් වෙතින් සම්බන්ධ වීමට ඇති වෙබ්සොකට් සේවාදායකය ගැන, 4 හි මම සමමුහුර්ත කාලසටහන දෙස බලමි, පසුව ආදාන සහ ප්‍රතිදාන වලින් බයිට්කෝඩ් සකසන ස්ටැක් යන්ත්‍රයක්, ගුප්ත ලේඛන සහ නිමැවුම් සඳහා තටාක.

මූලාශ්රය: www.habr.com

අදහස් එක් කරන්න