Hyperledger FabricïŒHLFïŒã¯ã忣åå°åž³æè¡ïŒDLTïŒã䜿çšãããªãŒãã³ãœãŒã¹ãã©ãããã©ãŒã ã§ãããèš±å¯ã«ãŒã«ã䜿çšããŠçµç¹ã®ã³ã³ãœãŒã·ã¢ã ã«ãã£ãŠäœæããã³å¶åŸ¡ãããããžãã¹ãããã¯ãŒã¯ç°å¢ã§å®è¡ãããã¢ããªã±ãŒã·ã§ã³ãéçºããããã«èšèšãããŠããŸãã
ãã©ãããã©ãŒã ã¯ãHLFã®èгç¹ããã¹ããŒãã³ã³ãã©ã¯ãããµããŒãããŸããããšãã°ãå¥çŽæåã®éå®çãªæ©èœã®Solidityèšèªã䜿çšããã€ãŒãµãªã¢ã ãšã¯ç°ãªããGolangãJavaScriptãJavaãªã©ã®äžè¬èšèªã§äœæããããã§ãŒã³ã³ãŒãïŒLLLãViperãªã©ïŒã

ãããã¯ãã§ãŒã³ãããã¯ãŒã¯ã®å€æ°ã®ã³ã³ããŒãã³ããå±éããå¿
èŠãããããããã§ãŒã³ã³ãŒãã®éçºãšãã¹ãã¯ã倿Žã®ãã¹ãã«æéããããããªãé·ãããã»ã¹ã«ãªãå¯èœæ§ããããŸãã ãã®èšäºã§ã¯ã CCKitã©ã€ãã©ãªã䜿çšããGolangã§ã®HLFã¹ããŒãã³ã³ãã©ã¯ãã®è¿
éãªéçºãšãã¹ããžã®ã¢ãããŒãã«ã€ããŠèª¬æããŸãã
HLFããŒã¹ã®ã¢ããªã±ãŒã·ã§ã³
éçºè
ã®èгç¹ããèŠããšããããã¯ãã§ãŒã³ã¢ããªã±ãŒã·ã§ã³ã¯2ã€ã®äž»èŠéšåã§æ§æãããŠããŸãã
- ãªã³ãã§ãŒã³ -ãããã¯ãã§ãŒã³ãããã¯ãŒã¯ã®éé¢ãããç°å¢ã§åäœããã¹ããŒãã³ã³ãã©ã¯ãïŒããã°ã©ã ïŒã¯ããã©ã³ã¶ã¯ã·ã§ã³å±æ§ã®äœæãšæ§æã®ã«ãŒã«ã決å®ããŸãã ã¹ããŒãã³ã³ãã©ã¯ãã®äž»ãªã¢ã¯ã·ã§ã³ã¯ããããã¯ãã§ãŒã³ãããã¯ãŒã¯ã®ç¶æ
ããããŒã¿ãèªã¿åããæŽæ°ãåé€ããããšã§ãã ç¶æ
ããããŒã¿ãåé€ãããšããã®ããŒã¿ãååšãããšããæ
å ±ãæ®ãããšã匷調ããå¿
èŠããããŸãã
- ãªããã§ãŒã³ã¯ãSDKãä»ããŠãããã¯ãã§ãŒã³ç°å¢ãšããåãããã¢ããªã±ãŒã·ã§ã³ïŒAPIãªã©ïŒã§ãã ã€ã³ã¿ã©ã¯ã·ã§ã³ã¯ãã¹ããŒãã³ã³ãã©ã¯ã颿°ã®åŒã³åºããšã¹ããŒãã³ã³ãã©ã¯ãã€ãã³ãã®ç£èŠãšããŠçè§£ãããŸããå€éšã€ãã³ãã¯ã¹ããŒãã³ã³ãã©ã¯ãã®ããŒã¿ã倿Žããã¹ããŒãã³ã³ãã©ã¯ãã®ã€ãã³ãã¯å€éšã·ã¹ãã ã®ã¢ã¯ã·ã§ã³ãããªã¬ãŒã§ããŸãã
éåžžãããŒã¿ã¯ãããŒã ããããã¯ãã§ãŒã³ãããã¯ãŒã¯ããŒããä»ããŠèªã¿åãããŸãã ããŒã¿ãèšé²ããããã«ãã¢ããªã±ãŒã·ã§ã³ã¯ç¹å®ã®ã¹ããŒãã³ã³ãã©ã¯ãã®ãæ¿èªããªã·ãŒãã«åå ããŠããçµç¹ã®ããŒãã«ãªã¯ãšã¹ããéä¿¡ããŸãã
ãªããã§ãŒã³ã³ãŒãïŒAPIãªã©ïŒãéçºããã«ã¯ããããã¯ãã§ãŒã³ããŒããšã®çžäºäœçšãã«ãã»ã«åããå¿çãåéãããªã©ãå°çšã®SDKã䜿çšããŸãã HLFã«ã¯ãGoïŒ 1ã2 ïŒã Node.Js ãããã³Javaã® SDKå®è£
ããããŸã
ãã€ããŒã¬ãžã£ãŒãã¡ããªãã¯ã³ã³ããŒãã³ã
ãã£ã³ãã«
ãã£ãã«ã¯ãå€ç«ãããããã¯ãã§ãŒã³ïŒå
åž³ïŒããµããŒãããããŒãã®åå¥ã®ãµããããã§ãããã¹ããŒãã³ã³ãã©ã¯ããæäœããããã«äœ¿çšããããããã¯ãã§ãŒã³ã®çŸåšã®ç¶æ
ïŒããŒå€ïŒïŒ world state ïŒã§ãã ãã¹ãã¯ãä»»æã®æ°ã®ãã£ãã«ã«ã¢ã¯ã»ã¹ã§ããŸãã
ååŒ
Hyperledger Fabricã®ãã©ã³ã¶ã¯ã·ã§ã³ã¯ããã§ãŒã³ãã§ãŒã³ã¡ãœããã®å®è¡çµæã§ãããããã¯ãã§ãŒã³ã®ç¶æ
ã®ã¢ãããã¯æŽæ°ã§ãã ãã©ã³ã¶ã¯ã·ã§ã³ã¯ãåŒã³åºãå
ããŒãã«ãã£ãŠçœ²åãããããã€ãã®åŒæ°ïŒãã©ã³ã¶ã¯ã·ã§ã³ææ¡ïŒãšããã©ã³ã¶ã¯ã·ã§ã³ãã確èªããããããŒãããã®äžé£ã®å¿çïŒãã©ã³ã¶ã¯ã·ã§ã³ææ¡å¿çïŒã§ãã§ãŒã³ã³ãŒãã¡ãœãããåŒã³åºãèŠæ±ã§æ§æãããŸãã å¿çã«ã¯ã Read-Write Setãããã¯ãã§ãŒã³ã®ç¶æ
ãšãµãŒãã¹æ
å ±ïŒãã©ã³ã¶ã¯ã·ã§ã³ã確èªããããŒãã®çœ²åãšèšŒææžïŒã®å€åããããŒãšå€ã®ãã¢ã«é¢ããæ
å ±ãå«ãŸããŸãã ãªããªã åã
ã®ãã£ãã«ã®ãããã¯ãã§ãŒã³ã¯ç©ççã«åé¢ãããŠããããã©ã³ã¶ã¯ã·ã§ã³ã¯1ã€ã®ãã£ãã«ã®ã³ã³ããã¹ãã§ã®ã¿å®è¡ã§ããŸãã
BitcoinãEthereumãªã©ã®ãã¯ã©ã·ãã¯ããããã¯ãã§ãŒã³ãã©ãããã©ãŒã ã¯ããã¹ãŠã®ããŒãã§å®è¡ãããOrdering-Executionãã©ã³ã¶ã¯ã·ã§ã³ãµã€ã¯ã«ã䜿çšããŸããããã«ããããããã¯ãã§ãŒã³ãããã¯ãŒã¯ã®ã¹ã±ãŒã©ããªãã£ãå¶éãããŸãã

Hyperledger Fabricã¯ã3ã€ã®äž»ãªæäœããããã©ã³ã¶ã¯ã·ã§ã³å®è¡ããã³é
åžã¢ãŒããã¯ãã£ã䜿çšããŸãã
å®è¡ïŒ execute ïŒ-1ã€ãŸãã¯è€æ°ã®ãããã¯ãŒã¯ããŒãã§å®è¡ãããã¹ããŒãã³ã³ãã©ã¯ãã«ããäœæããã©ã³ã¶ã¯ã·ã§ã³-忣ã¬ãžã¹ããªã®ç¶æ
ã®ã¢ãããã¯ãªå€æŽïŒ æ¿èª ïŒ
é åºä»ã-ãã©ã°å¯èœãªã³ã³ã»ã³ãµã¹ã¢ã«ãŽãªãºã ã䜿çšããŠãå°éã®é åºä»ããµãŒãã¹ã«ãã£ãŠãã©ã³ã¶ã¯ã·ã§ã³ããããã¯ã«é åºä»ãããã°ã«ãŒãåããŸãã
æ€èšŒ-忣ã¬ãžã¹ããªã®ã³ããŒã«æ³šæè
ããã®æ
å ±ãé
眮ããåã«ã 泚æè
ããã®ãã©ã³ã¶ã¯ã·ã§ã³ã®ãããã¯ãŒã¯ããŒãã«ããæ€èšŒ

ãã®ã¢ãããŒãã«ããããããã¯ãã§ãŒã³ãããã¯ãŒã¯ã«å
¥ãåã«ãã©ã³ã¶ã¯ã·ã§ã³å®è¡ãã§ãŒãºãå®è¡ã§ãããããã¯ãŒã¯ããŒãã®åäœãæ°Žå¹³æ¹åã«ã¹ã±ãŒãªã³ã°ã§ããŸãã
ãã§ãŒã³ã³ãŒã
ã¹ããŒãã³ã³ãã©ã¯ããšãåŒã°ãããã§ãŒã³ã³ãŒãã¯ãGolangãJavaScriptïŒHLF 1.1+ïŒãŸãã¯JavaïŒHLF 1.3+ïŒã§èšè¿°ãããããã°ã©ã ã§ããããã¯ãã§ãŒã³ã®ç¶æ
ã倿Žãããã©ã³ã¶ã¯ã·ã§ã³ãäœæããããã®ã«ãŒã«ãå®çŸ©ããŸãã ããã°ã©ã ã¯ããããã¯ãã§ãŒã³ããŒãã®åæ£ãããã¯ãŒã¯ã®è€æ°ã®ç¬ç«ããããŒãã§åæã«å®è¡ããããã©ã³ã¶ã¯ã·ã§ã³ã®ã確èªãã«å¿
èŠãªãã¹ãŠã®ããŒãã§ã®ããã°ã©ã å®è¡ã®çµæã調æŽããããšã«ãããã¹ããŒãã³ã³ãã©ã¯ãã®å®è¡ã«äžç«ãªç°å¢ãäœæããŸãã
ã³ãŒãã¯ãã¡ãœããã§æ§æãããã€ã³ã¿ãŒãã§ã€ã¹ãå®è£
ããå¿
èŠããããŸãã
type Chaincode interface {
- Initã¡ãœããã¯ãã³ãŒãã³ãŒãã®ã€ã³ã¹ã¿ã³ã¹åãŸãã¯ã¢ããã°ã¬ãŒãæã«åŒã³åºãããŸãã ãã®ã¡ãœããã¯ãã³ãŒãã³ãŒãã®ç¶æ
ã®å¿
èŠãªåæåãå®è¡ããŸãã åŒã³åºããã€ã³ã¹ã¿ã³ã¹åãã¢ããã°ã¬ãŒãããã¡ãœããã³ãŒãã§åºå¥ããããšãéèŠã§ããããã«ãããã³ãŒãã³ãŒãã®æäœäžã«ãã§ã«ãŒã以å€ã®ç¶æ
ãåãåã£ãããŒã¿ã誀ã£ãŠåæåïŒãªã»ããïŒããªãããã«ã§ããŸãã
- Invokeã¡ãœããã¯ãã³ãŒãã³ãŒãã®æ©èœã«ã¢ã¯ã»ã¹ãããšãã«åŒã³åºãããŸãã ãã®ã¡ãœããã¯ãã¹ããŒãã³ã³ãã©ã¯ãã®ã¹ããŒã¿ã¹ã§æ©èœããŸãã
ãã§ãŒã³ã³ãŒãã¯ããããã¯ãã§ãŒã³ãããã¯ãŒã¯ã®ãã¢ã«ã€ã³ã¹ããŒã«ãããŸãã ã·ã¹ãã ã¬ãã«ã§ã¯ãã³ãŒãã®åã€ã³ã¹ã¿ã³ã¹ã¯ãç¹å®ã®ãããã¯ãŒã¯ããŒãã«æ¥ç¶ãããåå¥ã®docker-containerã«å¯Ÿå¿ããã³ãŒãã®å®è¡ãžã®åŒã³åºãããã£ã¹ãããããŸãã
Ethereumã¹ããŒãã³ã³ãã©ã¯ããšã¯ç°ãªããé£éããžãã¯ã¯æŽæ°ã§ããŸãããããã«ã¯ã³ãŒãã³ãŒãããã¹ããããã¹ãŠã®ããŒãã«æŽæ°ããŒãžã§ã³ãã€ã³ã¹ããŒã«ãããŠããå¿
èŠããããŸãã
SDKãä»ããå€éšããã®ãã§ãŒã³ã³ãŒã颿°ã®åŒã³åºãã«å¿ããŠããã§ãŒã³ã³ãŒãã¯ããããã¯ãã§ãŒã³ã®ç¶æ
ïŒ Read-Write Set ïŒããã³ã€ãã³ãã®å€æŽãäœæããŸãã ãã§ãŒã³ã³ãŒãã¯ç¹å®ã®ãã£ãã«ãåç
§ãã1ã€ã®ãã£ãã«ã®ããŒã¿ã®ã¿ã倿Žã§ããŸãã åæã«ãã³ãŒããã€ã³ã¹ããŒã«ãããŠãããã¹ããä»ã®ãã£ãã«ã«ãã¢ã¯ã»ã¹ã§ããå Žåãã³ãŒãã®ããžãã¯ã§ã¯ããããã®ãã£ãã«ããããŒã¿ãèªã¿åãããšãã§ããŸãã
ãããã¯ãã§ãŒã³ãããã¯ãŒã¯ã®ããŸããŸãªåŽé¢ã管çããããã®ç¹å¥ãªãã§ãŒã³ã³ãŒãã¯ãã·ã¹ãã ãã§ãŒã³ã³ãŒããšåŒã°ããŸãã
æšå¥šããªã·ãŒ
æ¿èªããªã·ãŒã¯ãç¹å®ã®ãã§ãŒã³ã³ãŒãã«ãã£ãŠçæããããã©ã³ã¶ã¯ã·ã§ã³ã®ã¬ãã«ã§ã³ã³ã»ã³ãµã¹ã«ãŒã«ãå®çŸ©ããŸãã ãã®ããªã·ãŒã¯ãã©ã®ãã£ãã«ããŒãããã©ã³ã¶ã¯ã·ã§ã³ãäœæããããæ±ºå®ããã«ãŒã«ãèšå®ããŸãã ãããè¡ãã«ã¯ãæ¿èªããªã·ãŒã§æå®ãããåããŒãããã§ãŒã³ã³ãŒãã¡ãœããïŒãå®è¡ãã¹ãããïŒãå®è¡ãããã·ãã¥ã¬ãŒã·ã§ã³ããå®è¡ããŸãããã®åŸã眲åãããçµæãåéããããã©ã³ã¶ã¯ã·ã§ã³ãéå§ããSDKã«ãã£ãŠæ€èšŒãããŸãïŒãã¹ãŠã®ã·ãã¥ã¬ãŒã·ã§ã³çµæã¯åäžã§ããå¿
èŠããããŸããããªã·ãŒã«å¿
èŠãªãã¹ãŠã®ããŒãã®çœ²åãååšããå¿
èŠããããŸãïŒã 次ã«ãSDKã¯ãã©ã³ã¶ã¯ã·ã§ã³ãordererã«éä¿¡ããŸãããã®åŸããã£ãã«ã«ã¢ã¯ã»ã¹ã§ãããã¹ãŠã®ããŒãã¯ã ordererãä»ããŠãã©ã³ã¶ã¯ã·ã§ã³ãåä¿¡ãããæ€èšŒãã¹ããããå®è¡ããŸãã ãã¹ãŠã®ãã£ãã«ããŒãããå®è¡ãã¹ãããã«åå ããå¿
èŠãããããã§ã¯ãªãããšã匷調ããããšãéèŠã§ãã
æ¿èªããªã·ãŒã¯ãã³ãŒãã®ã€ã³ã¹ã¿ã³ã¹åãŸãã¯ã¢ããã°ã¬ãŒãæã«æ±ºå®ãããŸãã ããŒãžã§ã³1.3ã§ã¯ããã§ãŒã³ã³ãŒãã®ã¬ãã«ã ãã§ãªããåã
ã®ç¶æ
ããŒã¹ã®æ¿èªããŒã®ã¬ãã«ã§ãããªã·ãŒãèšå®ã§ããããã«ãªããŸããã æ¿èªããªã·ãŒã®äŸïŒ
- ããŒãAãBãCãD
- ã»ãšãã©ã®ãã£ãã«ããŒã
- AãBãCãDãEãFããå°ãªããšã3ã€ã®ããŒã
ã€ãã³ã
ã€ãã³ãã¯ããããã¯ãã§ãŒã³ãã§ãŒã³ã®ç¶æ
ã®ãæŽæ°ãã£ãŒãããå
¬éã§ããååä»ãããŒã¿ã»ããã§ãã ã€ãã³ã屿§ã®ã»ããã¯ããã§ãŒã³ã³ãŒããå®çŸ©ããŸãã
ãããã¯ãŒã¯ã€ã³ãã©
ãã¹ãïŒãã¢ïŒ
ãã¹ãã¯ãã¢ã¯ã»ã¹æš©ãæã€ä»»æã®æ°ã®ãã£ãã«ã«æ¥ç¶ãããŸãã ãã¹ãã¯ããããã¯ãã§ãŒã³ã®ããŒãžã§ã³ãšãããã¯ãã§ãŒã³ã®ç¶æ
ãç¶æãããã§ãŒã³ã³ãŒããå®è¡ããããã®ç°å¢ãæäŸããŸãã ãã¹ããæ¿èªããªã·ãŒã«å«ãŸããŠããªãå Žåããã§ãŒã³ã³ãŒããèšå®ããå¿
èŠã¯ãããŸããã
ãã¹ããœãããŠã§ã¢ã¬ãã«ã§ã¯ããããã¯ãã§ãŒã³ã®çŸåšã®ç¶æ
ïŒã¯ãŒã«ãç¶æ
ïŒãLevelDBãŸãã¯CouchDBã«ä¿åã§ããŸãã CouchDBã®å©ç¹ã¯ãMongoDBæ§æã䜿çšããè±å¯ãªã¯ãšãªã®ãµããŒãã§ãã
泚æè
ãã©ã³ã¶ã¯ã·ã§ã³ç®¡çãµãŒãã¹ã¯ã眲åä»ããã©ã³ã¶ã¯ã·ã§ã³ãå
¥åãšããŠåãå
¥ãããã©ã³ã¶ã¯ã·ã§ã³ããããã¯ãŒã¯ããŒãå
šäœã«æ£ããé åºã§åæ£ãããããã«ããŸãã
泚æè
ã¯ã¹ããŒãã³ã³ãã©ã¯ããå®è¡ããããããã¯ãã§ãŒã³ãšãããã¯ãã§ãŒã³ç¶æ
ãå«ã¿ãŸããã çŸåšïŒ1.3ïŒã ordererã«ã¯2ã€ã®å®è£
ããããŸã-éçºãœããšãã¯ã©ãã·ã¥ãã©ãŒã«ããã¬ã©ã³ã¹ãæäŸããKafkaããŒã¹ã®ããŒãžã§ã³ã§ãã ç¹å®ã®å²åã®åå è
ã®äžæ£ãªåäœïŒãã¶ã³ãã³ãã©ãŒã«ããã¬ã©ã³ã¹ïŒã«å¯Ÿããèæ§ããµããŒãããæ³šæè
ã®å®è£
ã¯ã2018幎æ«ã«äºå®ãããŠããŸãã
ã¢ã€ãã³ãã£ãã£ãµãŒãã¹
Hyperledger Fabricãããã¯ãŒã¯ã§ã¯ããã¹ãŠã®ã¡ã³ããŒãä»ã®ã¡ã³ããŒã«ç¥ãããŠããIDïŒââIDïŒãæã£ãŠããŸãã èå¥ã«ã¯ãå
¬ééµã€ã³ãã©ã¹ãã©ã¯ãã£ïŒPKIïŒã䜿çšãããŸããããã«ãããçµç¹ãã€ã³ãã©ã¹ãã©ã¯ãã£èŠçŽ ïŒããŒããçºæ³šè
ïŒãã¢ããªã±ãŒã·ã§ã³ãããã³ãšã³ããŠãŒã¶ãŒçšã®X.509èšŒææžãäœæãããŸãã ãã®çµæãããŒã¿ã®èªã¿åãããã³å€æŽãžã®ã¢ã¯ã»ã¹ã¯ããããã¯ãŒã¯ã¬ãã«ãåäžãã£ãã«ããŸãã¯ã¹ããŒãã³ã³ãã©ã¯ãã®ããžãã¯ã§ã¢ã¯ã»ã¹ã«ãŒã«ãä»ããŠå¶åŸ¡ã§ããŸãã åããããã¯ãã§ãŒã³ãããã¯ãŒã¯ã§ã¯ãããŸããŸãªã¿ã€ãã®è€æ°ã®èå¥ãµãŒãã¹ãåæã«æ©èœããŸãã
ãã§ãŒã³ã³ãŒãã®å®è£
ãã§ãŒã³ã³ãŒãã¯ãç¹å®ã®ããžãã¹ããžãã¯ãå®è£
ããã¡ãœãããæã€ãªããžã§ã¯ããšèŠãªãããšãã§ããŸãã åŸæ¥ã®OOPãšã¯ç°ãªãããã§ãŒã³ã³ãŒãã«å±æ§ãã£ãŒã«ããå«ããããšã¯ã§ããŸããã ã¹ãã¬ãŒãžãHLFãããã¯ãã§ãŒã³ãã©ãããã©ãŒã ã«ãã£ãŠæäŸãããç¶æ
ãæäœããã«ã¯ã Initããã³Invokeã¡ãœãããåŒã³åºããããšãã«æž¡ãããChaincodeStubInterfaceã¬ã€ã€ãŒã䜿çšãããŸãã 颿°åŒã³åºãã®åŒæ°ãåãåãããããã¯ãã§ãŒã³ã®ç¶æ
ã倿Žããæ©èœãæäŸããŸãã
type ChaincodeStubInterface interface {
Solidityã§éçºãããEthereumã¹ããŒãã³ã³ãã©ã¯ãã§ã¯ãåã¡ãœããã¯ãããªãã¯é¢æ°ã«å¯Ÿå¿ããŠããŸãã ChaincodeStubInterface颿°ã䜿çšããŠã Initããã³Invokeã¡ãœããã®Hyperledger Fabricãã§ãŒã³ã³ãŒãã§ã GetArgsïŒïŒããã€ãé
åã®é
åã®åœ¢åŒã§é¢æ°åŒã³åºãã®åŒæ°ãååŸã§ããŸããã InvokeãåŒã³åºããšãã®é
åã®æåã®èŠçŽ ã«ã¯ãã§ãŒã³ã³ãŒã颿°ã®ååãå«ãŸããŸãã ãªããªã ãã§ãŒã³ã³ãŒãã¡ãœããã®åŒã³åºãã¯ãInvokeã¡ãœãããééããŸã;ããã¯ãããã³ãã³ã³ãããŒã©ãŒãã¿ãŒã³ã®å®è£
ã§ãããšèšããŸãã
ããšãã°ã ERC-20ããŒã¯ã³ã®æšæºEthereumã€ã³ã¿ãŒãã§ã€ã¹ã®å®è£
ãæ€èšããå Žåãã¹ããŒãã³ã³ãã©ã¯ãã¯ã¡ãœãããå®è£
ããå¿
èŠããããŸãã
- totalSupplyïŒïŒ
- balanceOfïŒaddress _ownerïŒ
- 転éïŒã¢ãã¬ã¹_toãuint256 _valueïŒ
HLFãå®è£
ããå Žåã Invoke颿°ã³ãŒãã¯ã Invokeã®æåã®åŒæ°ãæåŸ
ãããã¡ãœããã®ååãåŒã³åºãå ŽåïŒããšãã°ããtotalSupplyããŸãã¯ãbalanceOfãïŒãåŠçã§ããå¿
èŠããããŸãã ERC-20æšæºã®å®è£
ã®äŸã¯ããã§èŠãããŸã ã
ãã§ãŒã³ã³ãŒãã®äŸ
Hyperledger Fabricã®ããã¥ã¡ã³ãã«å ããŠããã§ãŒã³ã³ãŒãã®äŸãããã€ããããŸãã
ãããã®äŸã®ãã§ãŒã³ã³ãŒãã®å®è£
ã¯ããªãåé·ã§ãããåŒã³åºãããã«ãŒãã£ã³ã°é¢æ°ãéžæããããã®å€ãã®ç¹°ãè¿ãããžãã¯ãå«ã¿ãŸãïŒãåŒæ°ã®æ°ããã§ãã¯ããjsonããŒã·ã£ãªã³ã°/ã¢ã³ããŒã·ã£ãªã³ã°ããŸãïŒ
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response { function, args := stub.GetFunctionAndParameters() fmt.Println("invoke is running " + function)
ãã®ãããªã³ãŒãã®ç·šæã¯ãã³ãŒãã®å¯èªæ§ã®äœäžãšãå
¥åããŒã¿ã®éæŽååãå¿ããå Žåã«çºçããå¯èœæ§ã®ãããšã©ãŒãªã©ã«ã€ãªãããŸãã HLFéçºèšç»ã«é¢ãããã¬ãŒã³ããŒã·ã§ã³ã§ã¯ããã§ãŒã³ã³ãŒãã®éçºãžã®ã¢ãããŒãã®æ¹èšãç¹ã«Javaãã§ãŒã³ã³ãŒããžã®æ³šéã®å°å
¥ãªã©ã«ã€ããŠèšåããŠããŸãããèšç»ã¯2019幎ã«ã®ã¿äºæ³ãããããŒãžã§ã³ã«é¢é£ããŠããŸãã ã¹ããŒãã³ã³ãã©ã¯ãã®éçºçµéšãããå¥ã®ã©ã€ãã©ãªã§åºæ¬æ©èœãéžæãããšããã§ãŒã³ã³ãŒãã®éçºãšãã¹ãã容æã«ãªããšããçµè«ã«è³ããŸããã
CCKit-ãã§ãŒã³ã³ãŒããéçºããã³ãã¹ãããããã®ã©ã€ãã©ãª
CCKitã©ã€ãã©ãªã¯ããã§ãŒã³ã³ãŒãã®éçºãšãã¹ãã®å®è·µãèŠçŽããŠããŸãã ãã§ãŒã³ã³ãŒãæ¡åŒµæ©èœã®éçºã®äžç°ãšããŠãEthereumã¹ããŒãã³ã³ãã©ã¯ãã®æ¡åŒµæ©èœã® OpenZeppelinã©ã€ãã©ãªãäŸãšããŠäœ¿çšãããŸããã CCKitã¯æ¬¡ã®ã¢ãŒããã¯ãã£ãœãªã¥ãŒã·ã§ã³ã䜿çšããŸãã
ã¹ããŒãã³ã³ãã©ã¯ãæ©èœãžã®é話ã®ã«ãŒãã£ã³ã°
ã«ãŒãã£ã³ã°ãšã¯ãã¢ããªã±ãŒã·ã§ã³ãã¯ã©ã€ã¢ã³ãèŠæ±ã«å¿çããã¢ã«ãŽãªãºã ãæããŸãã ãã®ã¢ãããŒãã¯ãããšãã°ãã»ãŒãã¹ãŠã®httpãã¬ãŒã ã¯ãŒã¯ã§äœ¿çšãããŸãã ã«ãŒã¿ãŒã¯ç¹å®ã®ã«ãŒã«ã䜿çšããŠãèŠæ±ãšèŠæ±ãã³ãã©ãŒããã€ã³ãããŸãã ãã§ãŒã³ã³ãŒãã®å Žåãããã¯ãã§ãŒã³ã³ãŒã颿°ã®ååããã³ãã©ãŒé¢æ°ã«é¢é£ä»ããããã§ãã
Insurance Appãªã©ã®ã¹ããŒãã³ã³ãã©ã¯ãã®ææ°ã®äŸã§ã¯ããã§ãŒã³ã³ãŒã颿°ã®ååãšããã©ãŒã ã®Golangã³ãŒãã®é¢æ°ã®éã®ãããã³ã°ã䜿çšããŸãã
var bcFunctions = map[string]func(shim.ChaincodeStubInterface, []string) pb.Response{
CCKitã«ãŒã¿ãŒã¯ãhttpã«ãŒã¿ãŒã«äŒŒãã¢ãããŒããšããã§ãŒã³ã³ãŒãæ©èœãšããã«ãŠã§ã¢æ©èœã«ãªã¯ãšã¹ãã³ã³ããã¹ãã䜿çšããæ©èœã䜿çšããŸãã
ã³ãŒãã®é¢æ°ã®åŒã³åºãã®ã³ã³ããã¹ã
éåžžhttpèŠæ±ã®ãã©ã¡ãŒã¿ãŒã«ã¢ã¯ã»ã¹ããhttpèŠæ±ã³ã³ããã¹ããšåæ§ã«ãCCKitã«ãŒã¿ãŒã¯ã ã¹ããŒãã³ã³ãã©ã¯ã颿°ã®åŒã³åºãã®ã³ã³ããã¹ãã䜿çšããŸããããã¯ã shim.ChaincodeStubInterfaceã®æœè±¡åã§ã ã ã³ã³ããã¹ãã¯ããã§ãŒã³é¢æ°ã®ãã³ãã©ãŒãžã®å¯äžã®åŒæ°ã«ããããšãã§ããŸãããã³ãã©ãŒã¯ããããä»ããŠã颿°åŒã³åºãã®åŒæ°ãååŸã§ããã ãã§ãªããã¹ããŒãã³ã³ãã©ã¯ãïŒç¶æ
ïŒã®ç¶æ
ãæäœããããåçïŒå¿çïŒãäœæãããããããã®è£å©æ©èœã«ã¢ã¯ã»ã¹ã§ããŸã
Context interface { Stub() shim.ChaincodeStubInterface Client() (cid.ClientIdentity, error) Response() Response Logger() *shim.ChaincodeLogger Path() string State() State Time() (time.Time, error) Args() InterfaceMap Arg(string) interface{} ArgString(string) string ArgBytes(string) []byte SetArg(string, interface{}) Get(string) interface{} Set(string, interface{}) SetEvent(string, interface{}) error }
ãªããªã ã³ã³ããã¹ãã¯ã€ã³ã¿ãŒãã§ã€ã¹ã§ãããç¹å®ã®ãã§ãŒã³ã³ãŒãã§ã¯å±éã§ããŸãã
ããã«ãŠã§ã¢æ©èœ
äžéåŠçã®æ©èœïŒããã«ãŠã§ã¢ïŒã¯ãã³ãŒãã®ã¡ãœããã®ãã³ãã©ãŒã®åŒã³åºãã®åã«åŒã³åºãããã³ãŒãã®ã¡ãœãããšæ¬¡ã®äžé颿°ã®åŒã³åºãã®ã³ã³ããã¹ãã«ã¢ã¯ã»ã¹ããããæ¬¡ã®ã¡ãœããã®ãã³ãã©ãŒïŒçŽæ¥ïŒã«çŽæ¥ã¢ã¯ã»ã¹ããŸãã ããã«ãŠã§ã¢ã¯æ¬¡ã®çšéã«äœ¿çšã§ããŸãã
- å
¥åããŒã¿ã®å€æïŒä»¥äžã®äŸã§ã¯ã p.Stringãšp.Structã¯ããã«ãŠã§ã¢ã§ãïŒ
- 颿°ã®ã¢ã¯ã»ã¹å¶éïŒäŸïŒ owner.Only ïŒ
- èŠæ±åŠçãµã€ã¯ã«ã®å®äº
- ã¹ã¿ãã¯ããæ¬¡ã®äžéåŠç颿°ãåŒã³åºã
ããŒã¿æ§é 倿
ãã§ãŒã³ã³ãŒãã€ã³ã¿ãŒãã§ã€ã¹ã¯ããã€ãé
åã®é
åãå
¥åã«æäŸãããåèŠçŽ ããã§ãŒã³ã³ãŒã颿°ã®å±æ§ã§ããããšãåæãšããŠããŸãã ãã§ãŒã³é¢æ°ã®åãã³ãã©ãŒã®é¢æ°åŒã³åºãåŒæ°ãããã€ãé
åããgolangããŒã¿åïŒintãstringãstructureãarrayïŒãžã®æåããŒã¿ããŒã·ã£ãªã³ã°ãé²ããããã«ãŒãã£ã³ã°ã«ãŒã«ãäœæãããåãèªåçã«å€æããããšãã«ãCCKitã«ãŒã¿ãŒã§äºæãããããŒã¿åãèšå®ãããŸãã æ¬¡ã®äŸã§ã¯ ã carGet颿°ã¯æåååã®åŒæ°ãæ³å®ãã carRegister颿°ã¯CarPayloadæ§é äœãæ³å®ããŠããŸãã åŒæ°ã«ãååãä»ããããŸããããã«ããããã³ãã©ãŒã¯ååã§ã³ã³ããã¹ãããå€ãååŸã§ããŸãã ãã³ãã©ãŒã®äŸã以äžã«ç€ºããŸãã Protobufã䜿çšããŠãé£éããŒã¿ã¹ããŒã ãèšè¿°ããããšãã§ããŸãã
r.Group(`car`). Query(`List`, cars).
ãŸããã¹ããŒãã³ã³ãã©ã¯ãã®ç¶æ
ã«ããŒã¿ãæžã蟌ããšããããã³ã€ãã³ããäœæãããšãã«èªå倿ïŒããŒã·ã£ãªã³ã°ïŒã䜿çšãããŸãïŒgolangåã¯ãã€ãã®é
åã«ã·ãªã¢ã«åãããŸãïŒ
ãã§ãŒã³ã³ãŒãã®ãããã°ãšãã°èšé²ã®ããã®ããŒã«
ã³ãŒãããããã°ããã«ã¯ã ãããã°æ¡åŒµæ©èœã䜿çšã§ããŸãã ãããã°æ¡åŒµæ©èœã¯ãã¹ããŒãã³ã³ãã©ã¯ãã®ç¶æ
ã§ããŒã®ååšãæ€æ»ããããŒããšã®å€ãçŽæ¥èªã¿åã/倿Ž/åé€ã§ããã¹ããŒãã³ã³ãã©ã¯ãã¡ãœãããå®è£
ããŸãã
ãã§ãŒã³ã³ãŒã颿°ã®åŒã³åºãã®ã³ã³ããã¹ãã§ãã°ãèšé²ããã«ã¯ãLogïŒïŒã¡ãœããã䜿çšã§ããŸããããã¯ãHLFã§äœ¿çšããããã¬ãŒã®ã€ã³ã¹ã¿ã³ã¹ãè¿ããŸãã
ã¹ããŒãã³ã³ãã©ã¯ãã¡ãœããã¢ã¯ã»ã¹å¶åŸ¡ã¡ãœãã
ææè
æ¡åŒµã®äžéšãšããŠãã€ã³ã¹ã¿ã³ã¹åããããã§ãŒã³ã³ãŒãã®ææè
ã«é¢ããæ
å ±ãæ ŒçŽããããã®åºæ¬çãªããªããã£ããšãã¹ããŒãã³ã³ãã©ã¯ãã®ã¡ãœãããžã®ã¢ã¯ã»ã¹ä¿®é£ŸåïŒããã«ãŠã§ã¢ïŒãå®è£
ãããŸãã
ã¹ããŒãã³ã³ãã©ã¯ããã¹ãããŒã«
ãããã¯ãã§ãŒã³ãããã¯ãŒã¯ã®å±éããã§ãŒã³ã³ãŒãã®ã€ã³ã¹ããŒã«ãšåæåã¯ãããªãè€éãªã»ããã¢ãããšé·ãæé ã§ãã ã¹ããŒãã³ã³ãã©ã¯ãã®DEVã¢ãŒãã䜿çšãããšãã¹ããŒãã³ã³ãã©ã¯ãã³ãŒããåã€ã³ã¹ããŒã«/ã¢ããã°ã¬ãŒãããæéãççž®ã§ããŸãããã³ãŒãã®æŽæ°ããã»ã¹ã¯äŸç¶ãšããŠé
ããªããŸãã
shimããã±ãŒãžã«ã¯ããã§ãŒã³ã³ãŒãã®ã³ãŒããžã®åŒã³åºããã©ããããMockStubã®å®è£
ãå«ãŸããHLFãããã¯ãã§ãŒã³ç°å¢ã§ã®åäœãã·ãã¥ã¬ãŒãããŸãã MockStubã䜿çšãããšããã¹ãçµæãã»ãŒç¬æã«ååŸã§ããéçºæéãççž®ã§ããŸãã HLFã§ã®ã³ãŒãæäœã®äžè¬çãªã¹ããŒã ãèæ
®ãããšãMockStubã¯æ¬è³ªçã«SDKã眮ãæããã³ãŒãã®æ©èœãåŒã³åºãããšãã§ãããã¹ãäžã§ã³ãŒããéå§ããããã®ç°å¢ãæš¡å£ããŸãã

HLFé
ä¿¡ã®MockStubã«ã¯ã shim.ChaincodeStubInterfaceã€ã³ã¿ãŒãã§ã€ã¹ã®ã»ãŒãã¹ãŠã®ã¡ãœããã®å®è£
ãå«ãŸããŠããŸãããçŸåšã®ããŒãžã§ã³ïŒ1.3ïŒã§ã¯ãGetCreatorãªã©ã®éèŠãªã¡ãœããã®å®è£
ãæ¬ ããŠããŸãã ãªããªã ãã§ãŒã³ã³ãŒãã¯ãã®ã¡ãœããã䜿çšããŠãã¢ã¯ã»ã¹å¶åŸ¡çšã®ãã©ã³ã¶ã¯ã·ã§ã³äœæè
ã®èšŒææžãååŸã§ããŸãããã¹ãã§æå€§éã®ã«ãã¬ããžãåŸãã«ã¯ããã®ã¡ãœããã®ã¹ã¿ããæã€èœåãéèŠã§ãã
CCKitã©ã€ãã©ãªã«ã¯ãMockStubã®æ¡åŒµããŒãžã§ã³ãå«ãŸããŠããŸããããã«ã¯ãæ¬ èœããŠããã¡ãœããã®å®è£
ããã€ãã³ããã£ãã«ãªã©ãæäœããããã®ã¡ãœãããå«ãŸããŠããŸãã
ãã§ãŒã³ã³ãŒãã®äŸ
ããšãã°ãç»é²æžã¿ã®è»ã«é¢ããæ
å ±ãä¿åããããã®ç°¡åãªãã§ãŒã³ã³ãŒããäœæããŸã
ããŒã¿ã¢ãã«
ã³ãŒãã³ãŒãã®ç¶æ
ã¯ããŒãšå€ã®ã¹ãã¬ãŒãžã§ããããŒã¯æååã§ãå€ã¯ãã€ãã®é
åã§ãã åºæ¬çãªæ¹æ³ã¯ãããŒã¿æ§é ã®gonalized golangã€ã³ã¹ã¿ã³ã¹ãå€ãšããŠä¿åããããšã§ãã ãããã£ãŠããã§ãŒã³ã³ãŒãå
ã®ããŒã¿ãæäœããã«ã¯ãç¶æ
ããèªã¿åã£ãåŸããã€ãé
åãéæŽååããå¿
èŠããããŸãã
è»ã«ã€ããŠèšé²ããããã«ã次ã®å±æ§ã»ããã䜿çšããŸãã
- èå¥åïŒè»ã®çªå·ïŒ
- è»çš®
- è»äž¡ææè
æ
å ±
- ããŒã¿å€æŽæéã«é¢ããæ
å ±
ããŒã¿ããã§ãŒã³ã³ãŒãã«è»¢éããã«ã¯ããã§ãŒã³ã³ãŒãã®å€éšããã®ãã£ãŒã«ãã®ã¿ãå«ãå¥ã®æ§é ãäœæããŸãã
ããŒãæäœãã
ã¹ããŒãã³ã³ãã©ã¯ãç¶æ
ã®ã¬ã³ãŒãããŒã¯æååã§ãã ãŸããããŒã®äžéšããŒããã€ãïŒ U + 0000 ïŒã§åºåãããŠããè€åããŒãäœæããæ©èœããµããŒãããŠããŸã
func CreateCompositeKey(objectType string, attributes []string) (string, error)
CCKitã§ã¯ ã転éãããæ§é ãããŒã€ãŒã€ã³ã¿ãŒãã§ã€ã¹ããµããŒãããŠããå Žåãã¹ããŒãã³ã³ãã©ã¯ãã¹ããŒã¿ã¹é¢æ°ãã¬ã³ãŒãã®ããŒãèªåçã«äœæã§ããŸã
è»ãèšé²ããããã®ããŒçææ©èœã¯æ¬¡ã®ãšããã§ãã
const CarEntity = `CAR`
ã¹ããŒãã³ã³ãã©ã¯ãæ©èœã®å®£èšïŒã«ãŒãã£ã³ã°ïŒ
ãã§ãŒã³ã³ãŒãã®ã³ã³ã¹ãã©ã¯ã¿ãŒã¡ãœããã§ã¯ããã§ãŒã³ã³ãŒãã®é¢æ°ãšãã®åŒæ°ãå®çŸ©ã§ããŸãã è»ã®ç»é²ã³ãŒãã«ã¯3ã€ã®æ©èœããããŸã
- carListãCaræ§é ã®é
åãè¿ããŸã
- carGetãè»ã®èå¥åãåãå
¥ããè»ã®æ§é ãè¿ããŸã
- carRegisterãCarPayloadæ§é ã®ã·ãªã¢ã«åãããã€ã³ã¹ã¿ã³ã¹ãåãå
¥ããç»é²çµæãè¿ããŸãã ãã®ã¡ãœãããžã®ã¢ã¯ã»ã¹ã¯ãã§ãŒã³ã³ãŒãã®ææè
ã®ã¿ãå¯èœã§ãããã§ãŒã³ã³ãŒãã¯ææè
ããã±ãŒãžã®ããã«ãŠã§ã¢ã䜿çšããŠä¿åãããŸã
func New() *router.Chaincode { r := router.New(`cars`)
äžèšã®äŸã§ã¯ã Initã¡ãœãããšInvokeã¡ãœããã®åŠçãã«ãŒã¿ãŒã«å§ä»»ããããã§ãŒã³ã³ãŒãæ§é ã䜿çšããŠããŸãã
package router import ( "github.com/hyperledger/fabric/core/chaincode/shim" "github.com/hyperledger/fabric/protos/peer" )
ã«ãŒã¿ãŒãšåºæ¬çãªãã§ãŒã³ã³ãŒãæ§é ã䜿çšãããšããã³ãã©ãŒé¢æ°ãåå©çšã§ããŸãã ããšãã°ã carRegister
颿°ãžã®ã¢ã¯ã»ã¹ããã§ãã¯ããã«ãã§ãŒã³ã³ãŒããå®è£
ããã«ã¯ãæ°ããã³ã³ã¹ãã©ã¯ã¿ãŒã¡ãœãããäœæããã ãã§ååã§ãã
ã¹ããŒãã³ã³ãã©ã¯ãã®æ©èœã®å®è£
Golang颿°-CCKitã«ãŒã¿ãŒã®ã¹ããŒãã³ã³ãã©ã¯ã颿°ãã³ãã©ãŒã«ã¯ã 次ã®3ã€ã®ã¿ã€ãããããŸãã
- StubHandlerFunc - shim.ChaincodeStubInterfaceãåãå
¥ããæšæºå¿çpeer.Responseãè¿ãæšæºãã³ãã©ãŒã€ã³ã¿ãŒãã§ãŒã¹
- ContextHandlerFunc-ã³ã³ããã¹ããååŸããpeer.Responseãè¿ããŸã
- HandlerFunc-ã³ã³ããã¹ããåãåããã€ã³ã¿ãŒãã§ãŒã¹ãšãšã©ãŒãè¿ããŸãã ãã€ãé
åãè¿ãããpeer.Responseã®äœæã«åºã¥ããŠèªåçã«ãã€ãé
åã«å€æãããgolangåãè¿ãããšãã§ããŸãã å¿çã¹ããŒã¿ã¹ã¯ãæž¡ããããšã©ãŒã«å¿ããŠshim.OkãŸãã¯shim.Errorã«ãªããŸãã
, , ( CarPayload)
State , ( )
-
- â , . BDD â Behavior Driven Development, .
, , - Ethereum ganache-cli truffle . golang - Mockstub.
, . .
Ginkgo , Go, go test
. gomega expect , , .
import ( "testing" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" examplecert "github.com/s7techlab/cckit/examples/cert" "github.com/s7techlab/cckit/extensions/owner" "github.com/s7techlab/cckit/identity" "github.com/s7techlab/cckit/state" testcc "github.com/s7techlab/cckit/testing" expectcc "github.com/s7techlab/cckit/testing/expect" ) func TestCars(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "Cars Suite") }
, CarPayload :
var Payloads = []*Car{{ Id: `A777MP77`, Title: `VAZ`, Owner: `victor`, }, { Id: `O888OO77`, Title: `YOMOBIL`, Owner: `alexander`, }, { Id: `O222OO177`, Title: `Lambo`, Owner: `hodl`, }}
MockStub Cars.
ãªããªã cars , .
BeforeSuite Car authority Init . , Cars Init Init , .
BeforeSuite(func() {
. , CarRegister , .
It("Allow authority to add information about car", func() {
:
It("Disallow authority to add duplicate information about car", func() { expectcc.ResponseError( cc.From(actors[`authority`]).Invoke(`carRegister`, Payloads[0]), state.ErrKeyAlreadyExists)
ãããã«
- HLF Go, Java, JavaScript, , , - (Solidity) / -. / .
HLFã®ãã§ãŒã³ã³ãŒãã®ã¢ãŒããã¯ãã£ã¯ç©æ¥µçã«å®æãããŠããã以åã¯æããã«ååã§ã¯ãªãã£ãæ©èœããããŸãïŒã¬ã³ãŒãã®ãªã¹ãã®ããŒãžããšã®ã¯ãšãªãªã©ïŒãHypeledger Fabricã®è²¢ç®è
ã¯ãèå³ã®ããéçºè
ãããââãžã§ã¯ãã®éçºã«åå ããããç©æ¥µçã«å¥šå±ããŠããŸããéçºã®åéã¯ååã«åºãã