Go ን በመጠቀም ለኢንዱስትሪ የብሎክቼይን ልማት። ክፍል 1

አሁን ለአራት ወራት ያህል በብሎክቼይን ላይ የተመሰረተ "በመንግስት እና በኢንዱስትሪ ዘርፎች የመረጃ ጥበቃ እና አስተዳደር መሳሪያዎችን ማዘጋጀት" የተባለ ፕሮጀክት እየሰራሁ ነው.
አሁን ይህንን ፕሮጀክት እንዴት እንደጀመርኩ ልነግርዎ እፈልጋለሁ, እና አሁን የፕሮግራሙን ኮድ በዝርዝር እገልጻለሁ.

Go ን በመጠቀም ለኢንዱስትሪ የብሎክቼይን ልማት። ክፍል 1

ይህ በተከታታይ መጣጥፎች ውስጥ የመጀመሪያው ጽሑፍ ነው። እዚህ አገልጋዩን እና ፕሮቶኮሉን እገልጻለሁ. እንዲያውም አንባቢው የእነዚህን የብሎክቼይን አካላት የራሱን ስሪቶች እንኳን መጻፍ ይችላል።

እና ሁለተኛው ክፍል እነሆ - ስለ blockchain እና የግብይት ውሂብ አወቃቀሮች, እንዲሁም ከመረጃ ቋቱ ጋር መስተጋብርን ስለሚተገበር ጥቅል.

ባለፈው ዓመት በዲጂታል Breakthrough hackathon ላይ የተከፋፈለ የሂሳብ መዝገብ ቴክኖሎጂን በመጠቀም ለኢንዱስትሪ እና ለዲጂታል ኢኮኖሚ ጠቃሚ አሰራርን ለመፍጠር የሚያስችል ሀሳብ አቅርበው ነበር፤ ለልማቱ የሚሆን ስጦታም በኢኖቬሽን እርዳታ ፈንድ ተሰጥቷል (የተለየ መጻፍ አለብኝ) ስለ ስጦታው ጽሑፍ ፣ ገና ጅምር ለሚጀምሩ) እና አሁን በቅደም ተከተል።

ልማት የሚካሄደው በ Go ቋንቋ ነው፣ እና ብሎኮች የተቀመጡበት ዳታቤዝ LevelDB ነው።
ዋናዎቹ ክፍሎች ፕሮቶኮል ፣ አገልጋዩ (TCP እና WebSocket ን ያካሂዳል - የመጀመሪያው blockchainን ለማመሳሰል ፣ ሁለተኛው ደንበኞችን ለማገናኘት ፣ ግብይቶችን እና ትዕዛዞችን ከጃቫስክሪፕት መላክ ፣ ለምሳሌ ።

እንደተጠቀሰው፣ ይህ blockchain በዋነኛነት በአቅራቢዎች እና በደንበኞች መካከል ወይም ሁለቱንም በአንድ ሰው ውስጥ ያለውን የምርት ልውውጥ በራስ ሰር ለመስራት እና ለመጠበቅ ያስፈልጋል። እነዚህ ሰዎች እርስ በርስ ለመተማመን አይቸኩሉም. ነገር ግን ስራው አብሮ የተሰራ ካልኩሌተር ያለው "ቼክ ደብተር" መፍጠር ብቻ ሳይሆን ከምርቱ የህይወት ኡደት ጋር ሲሰራ የሚነሱትን አብዛኛዎቹን መደበኛ ስራዎች በራስ ሰር የሚሰራ ስርዓት ነው። ለዚህ ጉዳይ ተጠያቂ የሆነው ባይትኮድ፣ ከብሎክቼይን ጋር እንደተለመደው፣ በግብይቶች እና ግብይቶች ውስጥ ይከማቻል (ግብይቶቹ እራሳቸው በብሎኮች ውስጥ ይቀመጣሉ፣ በ LevelDB ውስጥ ያሉ ብሎኮች በ GOB ቅርጸት ቀድመው ተቀምጠዋል)። በመጀመሪያ፣ ስለ ፕሮቶኮሉ እና ስለ አገልጋዩ (aka node) እንነጋገር።

ፕሮቶኮሉ ውስብስብ አይደለም፣ ዋናው ነጥቡ ወደ ልዩ የትዕዛዝ መስመር ምላሽ ለመስጠት ወደ አንዳንድ ዳታ የመጫኛ ዘዴ መቀየር ነው፣ አብዛኛውን ጊዜ ብሎክ ወይም ግብይት፣ እና ኢንቬንቶሪን ለመለዋወጥም ያስፈልጋል፣ በዚህም መስቀለኛ መንገድ ማን እንደሆነ እንዲያውቅ። ጋር የተገናኘ እና እንዴት ሥራ እንደሚኖራቸው (ለማመሳሰል ክፍለ ጊዜ የተገናኙት አንጓዎች "ጎረቤት" ይባላሉ ምክንያቱም የእነሱ አይፒ ስለሚታወቅ እና የግዛታቸው ውሂብ በማህደረ ትውስታ ውስጥ ስለሚከማች)።

በ Go programmers ግንዛቤ ውስጥ አቃፊዎች (ዳይሬክተሮች ሊኑክስ እንደሚጠራቸው) ፓኬጆች ይባላሉ፣ ስለዚህ በእያንዳንዱ ፋይል መጀመሪያ ላይ Go code ያለው ከዚህ ዳይሬክቶሪ ላይ የጥቅል ፎልደር_name_where_this_file የሚገኝበትን ይጽፋሉ። አለበለዚያ ጥቅሉን ወደ ማጠናከሪያው መመገብ አይችሉም. ደህና, ይህን ቋንቋ ለሚያውቁ ይህ ሚስጥር አይደለም. እነዚህ ፓኬጆች ናቸው፡-

  • የአውታረ መረብ ግንኙነት (አገልጋይ ፣ ደንበኛ ፣ ፕሮቶኮል)
  • የተከማቸ እና የሚተላለፍ ውሂብ አወቃቀሮች (ማገድ፣ ግብይት)
  • የውሂብ ጎታ (ብሎክቼይን)
  • መግባባት
  • የተቆለለ ምናባዊ ማሽን (xvm)
  • ረዳት (crypto, አይነቶች) ለአሁን ብቻ ነው.

የ github ማገናኛ ይኸውና።

ይህ ትምህርታዊ እትም ነው, በሂደት መካከል ያለውን መስተጋብር እና በርካታ የሙከራ አካላት የሉትም, ነገር ግን አወቃቀሩ ልማት እየተካሄደ ካለው ጋር ይዛመዳል. በአስተያየቶቹ ውስጥ የሚጠቁሙት ነገር ካለ, ለተጨማሪ እድገት ግምት ውስጥ በማስገባት ደስተኛ ነኝ. እና አሁን ለአገልጋዩ ማብራሪያ እና ፕሮቶኮል.

አስቀድመን አገልጋይን እንይ።

የአገልጋዩ ንዑስ ክፍል በTCP ፕሮቶኮል ላይ ከፕሮቶኮል እሽግ ውስጥ የውሂብ አወቃቀሮችን በመጠቀም የሚሰራ የውሂብ አገልጋይ ሆኖ ይሰራል።

መደበኛው የሚከተሉትን ፓኬጆች ይጠቀማል። አገልጋይ, ፕሮቶኮል, አይነቶች. በጥቅሉ ውስጥ እራሱ tcp_server.go የውሂብ መዋቅር ይዟል አገልግሉ.

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

የሚከተሉትን መለኪያዎች መቀበል ይችላል:

  • ውሂብ የሚለዋወጥበት የአውታረ መረብ ወደብ
  • የአገልጋይ ውቅር ፋይል በJSON ቅርጸት
  • በአራሚ ሁነታ ለመሮጥ ጠቁም (የግል ብሎክቼይን)

እድገት፡-

  • ከJSON ፋይል ውቅረትን ያነባል።
  • የማረም ሁነታ ባንዲራ ተረጋግጧል፡ ከተዋቀረ የአውታረ መረብ ማመሳሰል መርሐግብር አልተጀመረም እና እገዳው አልተጫነም
  • የውቅረት ዳታ አወቃቀሩን ማስጀመር እና አገልጋዩን ማስጀመር

አገልጋይ

  • በፕሮቶኮሉ መሰረት የTCP አገልጋይ እና የአውታረ መረብ መስተጋብር ማስጀመርን ያከናውናል።
  • የወደብ ቁጥር፣ የመያዣ መጠን እና የመዋቅሩ ጠቋሚን የያዘ የሰርቭ ዳታ መዋቅር አለው። አይነቶች.ቅንጅቶች
  • የሩጫ ዘዴው የአውታረ መረብ መስተጋብር ይጀምራል (በተወሰነ ወደብ ላይ ለሚመጡ ግንኙነቶች ማዳመጥ ፣ አዲስ ግንኙነት ከተቀበለ ፣ አሰራሩ በአዲስ ክር ውስጥ ወደ የግል መያዣ ዘዴ ይተላለፋል)
  • В መያዣ ከግንኙነቱ የተገኘው መረጃ ወደ ቋት ይነበባል፣ ወደ የሕብረቁምፊ ውክልና ይቀየራል እና ወደ ይተላለፋል ፕሮቶኮል.ምርጫ
  • ፕሮቶኮል.ምርጫ ይመለሳል ውጤት ወይም ስህተትን ያስከትላል. ውጤት ከዚያም ተላልፏል ፕሮቶኮል. መተርጎምየሚመለሰው intrpr - አይነት ነገር ዳታ መተርጎምወይም የምርጫውን ውጤት በማስኬድ ላይ ስህተት ይፈጥራል
  • ከዚያ ማብሪያው ይከናወናል intrpr.Commands[0] አንዱን የሚያረጋግጥ፡ ውጤት፣ ኢንቪ፣ ስህተት እና ክፍል አለ ነባሪ
  • በክፍል ውስጥ ውጤት መቀየሪያ የሚገኘው በዋጋ ነው። 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.አካል ወደ የቁጥር ተለዋዋጭ 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 string) (ሕብረቁምፊ፣ ስህተት) በአገልጋዩ የተቀበለውን ውሂብ ዋና ሂደት ያከናውናል ፣ እንደ ግብዓት የውሂቡን የሕብረቁምፊ ውክልና ይቀበላል እና ለእሱ የተዘጋጀውን ሕብረቁምፊ ይመልሳል አስተርጓሚ:

  • የግቤት ሕብረቁምፊው በመጠቀም ወደ ጭንቅላት እና አካል ተከፍሏል። ReqParseN2(str)
  • ጭንቅላት ወደ ንጥረ ነገሮች የተከፈለ እና ReqParseHead (ጭንቅላት) በመጠቀም ወደ የትዕዛዝ ቁራጭ ይቀመጣል።
  • В መቀየሪያ (ትዕዛዞች[0]) የተቀበለውን ትዕዛዝ ይምረጡ (cmd ፣ ቁልፍ ፣ አድራሻ ወይም ክፍሉ ተቀስቅሷል ነባሪ)
  • 2 ትዕዛዞች በ cmd ውስጥ ምልክት ይደረግባቸዋል መቀየር (ትዕዛዞች[1]) - ርዝመት и ግትርነት.
  • ርዝመት ውስጥ ያለውን የውሂብ አይነት ይፈትሻል ትዕዛዞች[2] እና ውስጥ ያስቀምጣል። የውሂብ አይነት
  • ያንን ያረጋግጣል አካል የሕብረቁምፊ እሴት ይዟል
    len(body) < 1
  • የምላሽ ሕብረቁምፊውን ይመልሳል፡-
    "result:bufferlength:" + datatype + "/" + body
  • ግትርነት ሕብረቁምፊ ይመልሳል
    return "result:version/auto"

አስተርጓሚ

የትርጓሜ ዳታ አወቃቀሩን ይይዛል እና የተመለሰውን ውሂብ ሁለተኛ ደረጃ ሂደትን ያከናውናል። ምርጫ ሕብረቁምፊዎች እና ነገሮች መፈጠር ዳታ መተርጎም.

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

ይህ ነገር በ ውስጥ ጥቅም ላይ ይውላል አገልጋይ.ሂድ ጥቅል ዋና.

ደምበኛ

የደንበኛ ጥቅል ተግባራቶቹን ይዟል TCPConnect и TCPRsponseData.

ሥራ

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)

የተወሰነ መጠን ያለው ቋት ይፈጥራል፣ የአገልጋዩን ምላሽ እዚያ ያነባል እና ይህንን ቋት እና የተነበበው ባይት ብዛት እንዲሁም የስህተት ነገር ይመልሳል።

የደንበኛ subbroutine

ወደ መስቀለኛ መንገድ አገልጋዮች ትዕዛዞችን ለመላክ፣ እንዲሁም አጭር ስታቲስቲክስን እና ሙከራዎችን ለማግኘት ያገለግላል።

የሚከተሉትን መመዘኛዎች መቀበል ይችላል፡ የውቅረት ፋይል በJSON ቅርጸት፣ ወደ አገልጋዩ እንደ ሕብረቁምፊ የሚላክ ውሂብ፣ ወደ ፋይሉ የሚላክበት መንገድ፣ የመስቀለኛ መርሐግብር አስማሚ ጥቆማ፣ የውሂብ አይነት እንደ ቁጥራዊ እሴት የተላለፈ።

  • አወቃቀሩን በማግኘት ላይ
    st := types.ParseConfig(*config)
  • የኢምዩ ባንዲራ ከተላለፈ ይጀምራል sheduler
  • ወደ ፋይሉ የሚወስደውን መንገድ የሚያመለክተው የ f ባንዲራ ከቀረበ ውሂቡን ወደ ውስጥ እንጭነዋለን ኤፍዲቢ እና ይዘቱ ወደ አገልጋዩ ይላካል
    client.TCPConnect(st, []byte(CMD_BUFFER_LENGTH + ":" + strconv.Itoa(*t) + "/" + strconv.Itoa(fdblen)), fdb)
  • ፋይሉ ካልተገለጸ ከባንዲራ የሚገኘው መረጃ በቀላሉ ይላካል -d:
    client.TCPConnect(st, []byte(*data), nil)

ይህ ሁሉ የፕሮቶኮሉን መዋቅር የሚያሳይ ቀለል ያለ ውክልና ነው. በእድገቱ ወቅት አስፈላጊው ተግባር ወደ መዋቅሩ ይታከላል.

በሁለተኛው ክፍል ስለ ብሎኮች እና ግብይቶች ስለ ዳታ አወቃቀሮች እናገራለሁ ፣ በ 3 ውስጥ ስለ ዌብሶኬት አገልጋይ ከጃቫ ስክሪፕት ፣ በ 4 ውስጥ የማመሳሰል መርሐግብርን እመለከታለሁ ፣ ከዚያ ከግብአት እና ውፅዓት ባይትኮድ የሚያስኬድ ቁልል ማሽን ፣ ክሪፕቶግራፊ እና የውጤቶች ገንዳዎች.

ምንጭ: hab.com

አስተያየት ያክሉ