8か月間GoでDcoinを曞き盎した方法...䞀般的にKatyaに぀いお



この郚分では、SMSが「もう電話しないで、私に手玙を曞かないでください!!!!」



最初の郚分はここに、2番目はここにありたす 。

4.5幎前、私はこのビゞネスに完党に䞍適切な蚀語、぀たりPHPで暗号通貚を曞き始めるのは無謀でした。 結局、私は曞きたした私は頑固ですが、束葉杖で束葉杖を手に入れたした。それが䞀般的に機胜するずいう事実は、ある皮の魔法でした。

私はすぐにあなたに譊告したいず思いたす、私は独孊のプログラマヌで、半孊歎のあるプログラマヌです、そしお、それを穏やかに蚀えば、コヌドを曞くこずは理想的ではありたせん。



それはすべお、私がカティアずいう名前の女の子ず別れ、同じ日に2015幎4月4日Goを勉匷しお暗号通貚を曞き換えるこずにしたずいう事実から始たりたした。 ネタバレの䞋でカティアに぀いお曞くこずはできたせん。 それにもかかわらず、Habrは、恋愛物語ではなくIT蚘事のために、そしおGoテヌマに興味のある厳しいITの人々のために、単に「カティアに぀いお」ネタバレに泚意を払わないかもしれたせん。



8か月の結果アプリケヌションは、Win 64/32 、OSX64/32、Linux64/32、FreeBSD64/32、 Android 、 IOS 誰かがApp Storeにドロップするずクヌルになりたすで実行されたす

合蚈コヌドは玄73k行で、異なるOSのコヌドは数癟行皋床です。

40k-凊理/ブロック生成/ tr-17、17.5k-むンタヌフェヌス甚コントロヌラヌ、15.5k-テンプレヌト

PostgreSQL、SQLite、MySQLがサポヌトされおいたす。



私の䜜品をテストする人に譊告したす-バグがあるかもしれたせん。時間があれば、 darwin @ dcoin.clubたたはハブのPMでそれらに぀いお曞いおください。 提案やアドバむスも歓迎したす。



最初の2぀のパヌトでは、Webサヌバヌがdcoinでどのように機胜するか、およびhtml / templateに぀いお説明したした。



この蚘事では、デヌタベヌス、アプリケヌションのスムヌズなシャットダりン、ブロックの暗号化ず解析に぀いお説明したす



Katyaに぀いお
䞀晩䞭、私も圌女も眠るこずができず、圌らはただ静かに暪たわりたした。 私の頭の䞭には、「圌女を芋お、私は別のものを芋぀けるだろう、圌女は䞍十分だ」ずいう考えがありたした。 圌女が考えおいたこずは、私にはわかりたせん。

朝、なんらかの理由で、私は再び圌女ぞの愛を感じたした。 圌は朝食を食べ、スヌプを容噚に詰めおカティアが仕事で食べるようにした。



デヌタベヌス



dcoinでは、sqlite、postgres、mysqlをサポヌトしたした。 通垞のデスクトップアプリケヌションでは、デフォルトでsqliteが遞択されたす。 䜙分なものを远加する必芁はありたせん。 dcoinプヌルを䞊げる人は、postgresずmysqlのどちらかを遞ぶ方が良いでしょう。

golangでSQLデヌタベヌスを操䜜するには、パッケヌゞデヌタベヌス/ sqlが責任を負いたす。 sqlite 、 postgresql 、 mysqlデヌタベヌスドラむバヌを接続する必芁がありたす。



最初はsqliteのみを䜿甚しおから、postgresqlずmysqlを接続するこずにしたした。 それほど難しくないこずが刀明したした。 sql.Openでデヌタベヌスに接続するためのパラメヌタヌのみを倉曎し、SQLク゚リの構文の違いを考慮する必芁がありたした。

これがデヌタベヌスぞの接続の実装です。

デヌタベヌスの操䜜にラッパヌを䜿甚しなかったのは、 叀いバヌゞョンのDcoinからベアsqlク゚リを転送する方が䟿利でした。同じ理由で、デヌタベヌスから受け取ったデヌタ型の倉換を䌎うコヌドの構成がかなり貧匱です。



私が螏んだ熊手

1. db.Query "sql"の埌にrows.Closeを呌び出すこずを忘れた堎合、閉じられおいない接続がたくさんありたす。

2.゚ラヌ凊理の前にdeferを呌び出すこずはできたせん。 ゚ラヌがある堎合、rowはnilになり、rows.Closeを呌び出すずパニックが発生したす。 これはできたせん



rows, err := db.Query("SELECT * FROM table") defer rows.Close() if err != nil { return err }
      
      





それは本圓です

 rows, err := db.Query("SELECT * FROM table") if err != nil { return err } defer rows.Close()
      
      





Katyaに぀いお
その埌、圌女は䜕床も䌚議のスケゞュヌルを倉曎したした。 理由はわかりたせんが、毎日圌女に恋をするようになりたした。 私は圌女だけが欲しかった、私は圌女だけを考えた。 ある時点で、私は圌女ず結婚したいず思うようになりたした。 私は偶然stiehi.ruでケむティの詩を芋぀けたした。私が叫んだ䞀節の埌で、それは圌女の元ボヌむフレンドが圌女をひどく扱った方法に぀いおでした。 私は倢䞭になりたした、圌女のために私が感じた気持ちは奇劙で、私にははっきりしおいたせんでした、私はそのような状態を持っおいたこずがありたせん。



ゞョン゜ン



 type minersDataType struct { hosts string `json:"hosts"` } func main() { result_ := minersDataType{hosts: "pool.dcoin.club"} result, _ := json.Marshal(result_) }
      
      





結果には「{}」が含たれたす

ホストをホストに眮き換えるず、すべおが機胜し、結果に{"hosts" "111111"}が衚瀺されたす。

 type minersDataType struct { Hosts string `json:"hosts"` } func main() { result_ := minersDataType{Hosts: "pool.dcoin.club"} result, _ := json.Marshal(result_) }
      
      





私はこれに長い間銬鹿だったので、誰かが同じ熊手を螏たないように情報を䜜っおいたす



Katyaに぀いお
圌はカティアに私が圌女を愛しおいるず曞いた、私は圌女ず䞀緒にいたい。 ずにかく圌女はデヌトに耐え続けた。 疲れお、私は圌女の奜きな花を買っお、䌚いに圌女に行きたした。 䜕らかの理由で、私は圌女の詩の1぀を孊びさえしたした。 到着しお、誰も家にいたせん。 電話が応答しおいたせん。



信号



ブロックの解析プロセスでプログラムを終了するず、デヌタが完党に入力されず、非同期化が発生する堎合がありたす。 たずえば、芋越トランザクションは凊理されおいたすが、償华トランザクションは凊理されおいたせん。 したがっお、アプリケヌションを閉じるための信号がある堎合は、スムヌズに終了するこずが重芁です

 SigChan = make(chan os.Signal, 1) C.waitSig() //     go func() { signal.Notify(SigChan, os.Interrupt, os.Kill, syscall.SIGTERM) // ,    <-SigChan //  ,      for i := 0; i < countDaemons; i++ { daemons.DaemonCh <- true answer := <-daemons.AnswerDaemonCh } //   ,       DB.Close() }()
      
      





C.waitSig-これはりィンドりに必芁です。 Windows Goの信号は衚瀺されたせん。

 /* #include <stdio.h> #include <signal.h> extern void go_callback_int(); static inline void SigBreak_Handler(int n_signal){ go_callback_int(); } static inline void waitSig() { #if (WIN32 || WIN64) signal(SIGBREAK, &SigBreak_Handler); signal(SIGINT, &SigBreak_Handler); #endif } */ import ( "C" ) //export go_callback_int func go_callback_int() { SigChan <- syscall.Signal(1) }
      
      





SIGBREAKたたはSIGINTが到着するず、SigBreak_Handlerが呌び出され、go_callback_intが呌び出され、完了のシグナルがあったこずがSigChanチャネルに送信されたす。

Dcoinでは、信号凊理がここに実装されおいたす。



Katyaに぀いお
私はVKで圌女に手玙を曞き、圌女は家で遺䜓を忘れおいたず蚀いたした、そしお今、圌女には友人がいたした。 私は圌女を埅぀ず曞いた。 その埌、圌は「再び私に電話したり曞いたりしないでください!!!!」を受け取りたした。 質問はしたせんでした。隣のアパヌトに電話し、カティアが家にいるずきに花を莈るように頌みたした。 圌は数時間埌にDcoin on Goを曞き換えるこずを決めた埌、家に着きたした。



暗号化



GoでAESを䜿甚しおキヌを暗号化し、JSで埩号化する必芁がありたした。 私は玄2日間苊しめられたした。 暗号化されたテキスト自䜓ずずもにIVを送信する必芁があるこずがわかりたす。 ここにこの機胜がありたす



 func Encrypt(password, text []byte) ([]byte, error) { iv := []byte(RandSeq(aes.BlockSize)) c, err := aes.NewCipher(password) if err != nil { return nil, ErrInfo(err) } plaintext := PKCS5Padding([]byte(text), c.BlockSize()) cfbdec := cipher.NewCBCEncrypter(c, iv) EncPrivateKeyBin := make([]byte, len(plaintext)) cfbdec.CryptBlocks(EncPrivateKeyBin, plaintext) EncPrivateKeyBin = append(iv, EncPrivateKeyBin...) return EncPrivateKeyBin, nil }
      
      





およびJSでの埩号化

  ivAndText = atob(text); iv = ivAndText.substr(0, 16); encText = ivAndText.substr(16); cipherParams = CryptoJS.lib.CipherParams.create({ ciphertext: CryptoJS.enc.Base64.parse(btoa(encText)) }); password = CryptoJS.enc.Latin1.parse(hex_md5(password)); var decrypted = CryptoJS.AES.decrypt(cipherParams, password, {mode: CryptoJS.mode.CBC, iv: CryptoJS.enc.Utf8.parse(iv), padding: CryptoJS.pad.Iso10126 }); var decryptedText = hex2a(decrypted.toString());
      
      





workerで埩号化を行いたす。そうしないず、同期のためにブラりザヌが䞀時的にハングしたす。



解析ブロック



dcparserパッケヌゞは、ブロックを盎接解析し、テヌブルにデヌタを入力したす

たずえば、新しいナヌザヌキヌ、基本的には新しいDcoinナヌザヌ-new_user.goを登録するトランザクションを考えたす。

NewUserInitは、このトランザクションのデヌタを含む倉数を蚭定したす。 それらは2぀だけです-public_keyずsign

NewUserFrontは、デヌタのチェックを担圓したす。 特に、このトランザクションを生成したナヌザヌがマむナヌであるかどうかを確認したす。 制限を超えおいるかどうかを確認したす。

NewUserはデヌタベヌスにデヌタを曞き蟌みたす

NewUserRollbackFrontは、NewUserFrontメ゜ッドによっお行われた倉曎をロヌルバックしたす

NewUserRollbackは、NewUserメ゜ッドによっお入力されたデヌタをロヌルバックしたす

70皮類のトランザクションのそれぞれに察しお、同様の4぀の方法がありたす。

270,000ブロックがどのように解析されるかをちょっず想像しおみおください。 70個のメ゜ッドが180個のテヌブルず1100個の異なる列にデヌタを入力したす。 そしお、私を最も魅了しおいるのは、RollbackずRollbackFrontを介しお、逆の順序で1぀のブロックのすべおのデヌタをロヌルバックするこずです。 このような完党なロヌルバックは、dcparserの正しい動䜜をテストするために行われたす。 どこかでデヌタが誀っお入力された堎合、これはすぐに衚瀺されたす。



Katyaに぀いお
数日埌、私は圌女に、数ヶ月間、自分のプロゞェクトに向かっおいるず曞いお、䜕もしおくれないようにず頌みたした。 1週間埌、カティアからテキストメッセヌゞが届きたした。



おわりに



次の蚘事では、gomobileを少し倉曎し、通知を远加し、iOSおよびAndroidアプリケヌションのバックグラりンドで䜜業する方法に぀いお説明したす。



All Articles