é»éåœéæ
å ±ãµãŒãã¹ ãã¯ãã¹ ã€ãããŒã·ã§ã³ æ¬éšããªãŒãã³ ã€ãããŒã·ã§ã³ ã©ãã® æ¯å康é ã§ãã ããã§ã¯ã ãããã¯ãã§ãŒã³ é±å ±4/12ãã£ãŠã¿ãããã ãšã³ã¿ã¡ã®ææ°ã¢ã€ãã ã¯NFT ãã®ä»ã®ãã¥ãŒã¹ ãšã³ã¿ã¡ã®ææ°ã¢ã€ãã ã¯NFT å
é±ã NFTã身è¿ã« ãšããèšäºãæžãããã§ãããããã«ãããé²ãã§ãšã³ã¿ã¡åãããŠããŸããã ãã¹ã§éãããNFTã€ãã³ããã«ãªã¹ã ã£ãçç±ïŒçŸå°ã¬ããŒã ããªãŠããã»ã¬ãã®ç»å Žã§ããããã¯ãNFTããã«ãç¶ãããšãæåŸ
ããŠãã人ãã¡ãããªãããããšã瀺ããŠãããšæããŸãã ã°ã©ããŒè³ãšNFTã®å€ïŒçŸå°ã¬ããŒã 鳿¥œã¢ãŒãã£ã¹ããNFTãã¢ãŒãã£ã¹ãã¯NFTããã«ã«æµ®ãããŠãã人ãã¡ã ãã§ãªãããŸããã«NFTã«åãçµãã§ãã人ããããªãã«ãããšæã£ãŠãŸããã ã°ã©ããŒè³ ã®å€ã ãšæŽŸæãªæãã«ã¯ã©ãããŠããªã£ã¡ãããŸããã ãšã³ã¿ã¡æ¥çã¯ãã¿ã¬ã³ãã®äººæ°ããéã«å€ããããžãã¹ã ãšæã£ãŠããã®ã§ãäžé£ã®åãã¯å
šãéåæãªãã®ã§ãããNFTãããã¯ãœã«èšãããæ¥ãæ¥ãªããã°ãããªãšå人çã«ã¯æã£ãŠããŸããNFTã¯ã㯠ãã ãžãŒ ã®äžã€ã§ãè¯ã/æªããšããååšã§ã¯ãªãã®ã§ã ãã®ä»ã®ãã¥ãŒã¹ ãã€ã¯ããœããããWeb3ãæè³ãå éããããã¯ãã§ãŒã³äŒæ¥ãžã®æè³ãäººææ¡å
ãž ã¹ã¿ãŒããã¯ã¹ã幎å
ã«NFTããžãã¹åå
¥ ã¢ãã¢ã«ãšéåœCUBEååŒäŒç€ŸãK-POPã¢ãŒãã£ã¹ãåç»NFTããšã¢ãããããž ãã³ã¯ãNFTã§ã¢ãŒãã£ã¹ãã®çµæžçèªç«ãå¯èœã«ãããã³ã©ã ã 人æ°ã¡ã¿ããŒã¹ããŠãŒã¶ãŒæ°ã䌞ã³ãââåžå Žã®æåŸ
ãäžåã 100åãã«ã®ãããã³ã€ã³è³Œå
¥ãé²ããLFGã鱿«ã«1å7000äžãã«çžåœã賌å
¥ââTerraUSDã®è£ä»ãè³ç£ãšã㊠å·çïŒ @higa ïŒ Shodo ã§å·çãããŸãã ïŒ
é»éåœéæ
å ±ãµãŒãã¹ ãã¯ãã¹ ã€ãããŒã·ã§ã³ æ¬éšããªãŒãã³ ã€ãããŒã·ã§ã³ ã©ãã® æ¯å康é ã§ãã ããã§ã¯ã ãããã¯ãã§ãŒã³ é±å ±4/12ãã£ãŠã¿ãããã ãšã³ã¿ã¡ã®ææ°ã¢ã€ãã ã¯NFT ãã®ä»ã®ãã¥ãŒã¹ ãšã³ã¿ã¡ã®ææ°ã¢ã€ãã ã¯NFT å
é±ã NFTã身è¿ã« ãšããèšäºãæžãããã§ãããããã«ãããé²ãã§ãšã³ã¿ã¡åãããŠããŸããã ãã¹ã§éãããNFTã€ãã³ããã«ãªã¹ã ã£ãçç±ïŒçŸå°ã¬ããŒã ããªãŠããã»ã¬ãã®ç»å Žã§ããããã¯ãNFTããã«ãç¶ãããšãæåŸ
ããŠãã人ãã¡ãããªãããããšã瀺ããŠãããšæããŸãã ã°ã©ããŒè³ãšNFTã®å€ïŒçŸå°ã¬ããŒã 鳿¥œã¢ãŒãã£ã¹ããNFTãã¢ãŒãã£ã¹ãã¯NFTããã«ã«æµ®ãããŠãã人ãã¡ã ãã§ãªãããŸããã«NFTã«åãçµãã§ãã人ããããªãã«ãããšæã£ãŠãŸããã ã°ã©ããŒè³ ã®å€ã ãšæŽŸæãªæãã«ã¯ã©ãããŠããªã£ã¡ãããŸããã ãšã³ã¿ã¡æ¥çã¯ãã¿ã¬ã³ãã®äººæ°ããéã«å€ããããžãã¹ã ãšæã£ãŠããã®ã§ãäžé£ã®åãã¯å
šãéåæãªãã®ã§ãããNFTãããã¯ãœã«èšãããæ¥ãæ¥ãªããã°ãããªãšå人çã«ã¯æã£ãŠããŸããNFTã¯ã㯠ãã ãžãŒ ã®äžã€ã§ãè¯ã/æªããšããååšã§ã¯ãªãã®ã§ã ãã®ä»ã®ãã¥ãŒã¹ ãã€ã¯ããœããããWeb3ãæè³ãå éããããã¯ãã§ãŒã³äŒæ¥ãžã®æè³ãäººææ¡å
ãž ã¹ã¿ãŒããã¯ã¹ã幎å
ã«NFTããžãã¹åå
¥ ã¢ãã¢ã«ãšéåœCUBEååŒäŒç€ŸãK-POPã¢ãŒãã£ã¹ãåç»NFTããšã¢ãããããž ãã³ã¯ãNFTã§ã¢ãŒãã£ã¹ãã®çµæžçèªç«ãå¯èœã«ãããã³ã©ã ã 人æ°ã¡ã¿ããŒã¹ããŠãŒã¶ãŒæ°ã䌞ã³ãââåžå Žã®æåŸ
ãäžåã 100åãã«ã®ãããã³ã€ã³è³Œå
¥ãé²ããLFGã鱿«ã«1å7000äžãã«çžåœã賌å
¥ââTerraUSDã®è£ä»ãè³ç£ãšã㊠å·çïŒ @higa ïŒ Shodo ã§å·çãããŸãã ïŒ
ã¯ãã©ãŒããŒïŒ X ã€ãããŒã·ã§ã³ æ¬éšã®å®®æŸ€é¿ã§ãïŒ æ¬èšäºã§ã¯ãæ ªåŒäŒç€Ÿ é»éåœéæ
å ±ãµãŒãã¹ ïŒä»¥äžãISIDïŒã®ç€Ÿå
ã©ãžãªã§ããTecHuman.fmãšãããã§ã®ã³ã³ãã³ãå¶äœã«å©çšããŠãããµãŒãã¹ã«ã€ããŠãç°¡åã«ã玹ä»ããŸãïŒ TecHuman.fmã£ãŠäœïŒ ã³ã³ãã³ãå¶äœã«å©çšããŠãããµãŒãã¹ Miro Zoom Audacity Figma AviUtil Microsoft Stream Microsoft SharePoint ãŸãšã TecHuman.fmã£ãŠäœïŒ TecHuman.fmãšã¯ãISIDã®ããžã§ã³ã§ãããHUMANOLOGY for the futureãã«ç
§ãããISIDã®æå€§ã®åŒ·ã¿ã§ãã人ïŒHumanïŒãšæè¡ïŒTechnologyïŒã®äž¡èгç¹ããã£ãŠãã€ã³ããããåŸãããšãåŠã³åãããšãããŒãã«å¶äœããŠãã瀟å
ã©ãžãªã§ãã å¿ããæ¹ã§ãæ¥åã®ééæéãªã©ã«æ°è»œã«åå ããŠã»ããããšããæããããè³ã ãã§åå ã§ããé³å£°åœ¢åŒã®ã³ã³ãã³ããå±éãã圢ã§ã¹ã¿ãŒãããŸããã ã§ãããæè¿ã§ã¯çŽèå±
ïŒé³å£°ïŒéæ¢ç»ïŒåœ¢åŒã®ã³ã³ãã³ããåç»åœ¢åŒã®ã³ã³ãã³ããå±éãããŠããŠããŸãã ã³ã³ãã³ãã®å¶äœã¯ç€Ÿå
å
¬åã«ããéãŸã£ãæå¿ã¡ã³ããŒãè¡ã£ãŠããã2021幎3ææ«æç¹ã§50æ¬ä»¥äžã®ã³ã³ãã³ããå
¬éãããŠããŸãã æè¿ã§ã¯ããã®ISIDããã¯ããã°ã®ç޹ä»ã³ã³ãã³ããå
¬éãããŸããã ã³ã³ãã³ãå¶äœã«å©çšããŠãããµãŒãã¹ Miro ã¡ã³ããŒãä»äºã®åéã«äœæ¥ãé²ããããäŒç»ããããã§ããããã«ã Miro ãå
±åäœæ¥ã® ã¯ãŒã¯ã¹ããŒã¹ ã«ããŠããŸãã ã³ã³ãã³ãã®ã³ã³ã»ããã¡ã€ãã³ã°ãããããå°æ¬ã®äžæžããããããåºæŒè
ãšã®èª¿æŽã«å©çšãããããŠããŸãã miro.com Zoom åé²ã«ã¯ãçãããåç¥ã® Zoom ã®ææãã©ã³ãå©çšããŠããŸãã ææãã©ã³ã«ããããšã§ã3å以äžã§ã®40å以äžã®åé²ã«ã察å¿ã§ããŸãã ååºæŒè
ããšã®é³å£°ãã©ãã¯ãåå¥ã«é²é³ã§ãããããåŸç¶ã®é³å£°ç·šéããããããšããã¡ãªããããããŸãã Audacity é³å£°ç·šéã«ã¯ã ãªãŒãã³ãœãŒã¹ ã®é³å£°ç·šéã»é²é³ãœãããŠã§ã¢ã§ãã Audacity ãå©çšããŠããŸãã åé²ããé³å£°ã®é³éã調æŽããããBGMãSEã远å ããããèšãçŽãéšåãã«ãããããããŸãã ãªããBGMãSEã«é¢ããŠã¯ãISIDã®å奜äŒã®äžã€ã§ãã JAZZéš ã®çããã«å¶äœããã ãããã®ãå©çšããããšãå€ãã§ãã Figma ãµã ãã€ã«ç»åã®äœæã«ã¯ããã©ãŠã¶äžã§åäœãããããã¿ã€ãã³ã°ããŒã«ã§ãã Figma ã®ç¡æãã©ã³ãå©çšããŠããŸãã æäœæãšããŠã¯ Adobe XDã«è¿ããUIãã¶ã€ããŒã«ãªã£ããããªæèŠã§ç»åãäœæã§ããŸãã çŽèå±
圢åŒã®ã³ã³ãã³ãã®å Žåã«ã¯ãã³ã³ãã³ãå
ã§è¡šç€ºããç»åã Figma ã§äœæããŠããŸãã AviUtil åç»ç·šéã«ã¯ãåç»ç·šéãœãããŠã§ã¢ã§ãã AviUtil ãå©çšããŠããŸãã åºæ¬çã«ã¯ç·šéæžã¿ã®é³å£°ãã¡ã€ã«ãšãµã ãã€ã«ç»åãåãããã ãã§ãããåç»åœ¢åŒã®ã³ã³ãã³ãã®å Žåã«ã¯ãããè€éãªåŠçãããããšã«ãªããŸãã Microsoft Stream 宿ããã³ã³ãã³ãã¯ãåç»å
±æãµãŒãã¹ã§ãã Microsoft Stream ã«ã¢ããããŒãããå
šç€Ÿã«å
¬éããŸãã åçæ°ããããã®æ°ã¯éå¶ã¡ã³ããŒããã³ãã³ç¢ºèªããŸããããã¯ãåé¿ããããšå¬ãããã®ã§ãã Microsoft SharePoint ã³ã©ãã¬ãŒã·ã§ã³ã»ãã¡ã€ã«å
±æãµãŒãã¹ã§ãã Microsoft SharePoint ã«TecHuman.fmå°çšã®åºå ±ããŒãžããã£ãŠããŸãã éå»ã«é
ä¿¡ããã³ã³ãã³ããäžãæã«éããŠã瀟å¡ãæ°è»œã«ããã€ã§ã奜ããªã³ã³ãã³ããèŠèŽã§ããããã«ããŠããŸãã ãŸãšã æ¬èšäºã§ã¯ãISIDã®ç€Ÿå
ã©ãžãªã§ããTecHuman.fmãšãããã§ã®ã³ã³ãã³ãå¶äœã«å©çšããŠãããµãŒãã¹ã«ã€ããŠãç°¡åã«ã玹ä»ããŸããïŒ TecHuman.fmã«é¢ããŠã¯ãISIDã®æ¡çšããŒãžã®äžã§ã玹ä»ãããŠããïŒ ãã¡ã ïŒã®ã§ããã²ç®ãéããŠããã ããã°ãšæããŸãã æåŸãŸã§ãèªã¿ããã ããæ¬åœã«ããããšãããããŸããïŒ å·çïŒ @miyazawa.hibiki ãã¬ãã¥ãŒïŒ @sato.taichi ïŒ Shodo ã§å·çãããŸãã ïŒ
ã¯ãã©ãŒããŒïŒ X ã€ãããŒã·ã§ã³ æ¬éšã®å®®æŸ€é¿ã§ãïŒ æ¬èšäºã§ã¯ãæ ªåŒäŒç€Ÿ é»éåœéæ
å ±ãµãŒãã¹ ïŒä»¥äžãISIDïŒã®ç€Ÿå
ã©ãžãªã§ããTecHuman.fmãšãããã§ã®ã³ã³ãã³ãå¶äœã«å©çšããŠãããµãŒãã¹ã«ã€ããŠãç°¡åã«ã玹ä»ããŸãïŒ TecHuman.fmã£ãŠäœïŒ ã³ã³ãã³ãå¶äœã«å©çšããŠãããµãŒãã¹ Miro Zoom Audacity Figma AviUtil Microsoft Stream Microsoft SharePoint ãããã« TecHuman.fmã£ãŠäœïŒ TecHuman.fmãšã¯ãISIDã®ããžã§ã³ã§ãããHUMANOLOGY for the futureãã«ç
§ãããISIDã®æå€§ã®åŒ·ã¿ã§ãã人ïŒHumanïŒãšæè¡ïŒTechnologyïŒã®äž¡èгç¹ããã£ãŠãã€ã³ããããåŸãããšãåŠã³åãããšãããŒãã«å¶äœããŠãã瀟å
ã©ãžãªã§ãã å¿ããæ¹ã§ãæ¥åã®ééæéãªã©ã«æ°è»œã«åå ããŠã»ããããšããæããããè³ã ãã§åå ã§ããé³å£°åœ¢åŒã®ã³ã³ãã³ããå±éãã圢ã§ã¹ã¿ãŒãããŸããã ã§ãããæè¿ã§ã¯çŽèå±
ïŒé³å£°ïŒéæ¢ç»ïŒåœ¢åŒã®ã³ã³ãã³ããåç»åœ¢åŒã®ã³ã³ãã³ããå±éãããŠããŠããŸãã ã³ã³ãã³ãã®å¶äœã¯ç€Ÿå
å
¬åã«ããéãŸã£ãæå¿ã¡ã³ããŒãè¡ã£ãŠããã2021幎3ææ«æç¹ã§50æ¬ä»¥äžã®ã³ã³ãã³ããå
¬éãããŠããŸãã æè¿ã§ã¯ããã®ISIDããã¯ããã°ã®ç޹ä»ã³ã³ãã³ããå
¬éãããŸããã ã³ã³ãã³ãå¶äœã«å©çšããŠãããµãŒãã¹ Miro ã¡ã³ããŒãä»äºã®åéã«äœæ¥ãé²ããããäŒç»ããããã§ããããã«ã Miro ãå
±åäœæ¥ã® ã¯ãŒã¯ã¹ããŒã¹ ã«ããŠããŸãã ã³ã³ãã³ãã®ã³ã³ã»ããã¡ã€ãã³ã°ãããããå°æ¬ã®äžæžããããããåºæŒè
ãšã®èª¿æŽã«å©çšãããããŠããŸãã miro.com Zoom åé²ã«ã¯ãçãããåç¥ã® Zoom ã®ææãã©ã³ãå©çšããŠããŸãã ææãã©ã³ã«ããããšã§ã3å以äžã§ã®40å以äžã®åé²ã«ã察å¿ã§ããŸãã ååºæŒè
ããšã®é³å£°ãã©ãã¯ãåå¥ã«é²é³ã§ãããããåŸç¶ã®é³å£°ç·šéããããããšããã¡ãªããããããŸãã Audacity é³å£°ç·šéã«ã¯ã ãªãŒãã³ãœãŒã¹ ã®é³å£°ç·šéã»é²é³ãœãããŠã§ã¢ã§ãã Audacity ãå©çšããŠããŸãã åé²ããé³å£°ã®é³éã調æŽããããBGMãSEã远å ããããèšãçŽãéšåãã«ãããããããŸãã ãªããBGMãSEã«é¢ããŠã¯ãISIDã®å奜äŒã®äžã€ã§ãã JAZZéš ã®çããã«å¶äœããã ãããã®ãå©çšããããšãå€ãã§ãã Figma ãµã ãã€ã«ç»åã®äœæã«ã¯ããã©ãŠã¶äžã§åäœãããããã¿ã€ãã³ã°ããŒã«ã§ãã Figma ã®ç¡æãã©ã³ãå©çšããŠããŸãã æäœæãšããŠã¯ Adobe XDã«è¿ããUIãã¶ã€ããŒã«ãªã£ããããªæèŠã§ç»åãäœæã§ããŸãã çŽèå±
圢åŒã®ã³ã³ãã³ãã®å Žåã«ã¯ãã³ã³ãã³ãå
ã§è¡šç€ºããç»åã Figma ã§äœæããŠããŸãã AviUtil åç»ç·šéã«ã¯ãåç»ç·šéãœãããŠã§ã¢ã§ãã AviUtil ãå©çšããŠããŸãã åºæ¬çã«ã¯ç·šéæžã¿ã®é³å£°ãã¡ã€ã«ãšãµã ãã€ã«ç»åãåãããã ãã§ãããåç»åœ¢åŒã®ã³ã³ãã³ãã®å Žåã«ã¯ãããè€éãªåŠçãããããšã«ãªããŸãã Microsoft Stream 宿ããã³ã³ãã³ãã¯ãåç»å
±æãµãŒãã¹ã§ãã Microsoft Stream ã«ã¢ããããŒãããå
šç€Ÿã«å
¬éããŸãã åçæ°ããããã®æ°ã¯éå¶ã¡ã³ããŒããã³ãã³ç¢ºèªããŸããããã¯ãåé¿ããããšå¬ãããã®ã§ãã Microsoft SharePoint ã³ã©ãã¬ãŒã·ã§ã³ã»ãã¡ã€ã«å
±æãµãŒãã¹ã§ãã Microsoft SharePoint ã«TecHuman.fmå°çšã®åºå ±ããŒãžããã£ãŠããŸãã éå»ã«é
ä¿¡ããã³ã³ãã³ããäžãæã«éããŠã瀟å¡ãæ°è»œã«ããã€ã§ã奜ããªã³ã³ãã³ããèŠèŽã§ããããã«ããŠããŸãã ãããã« æ¬èšäºã§ã¯ãISIDã®ç€Ÿå
ã©ãžãªã§ããTecHuman.fmãšãããã§ã®ã³ã³ãã³ãå¶äœã«å©çšããŠãããµãŒãã¹ã«ã€ããŠãç°¡åã«ã玹ä»ããŸããïŒ TecHuman.fmã«é¢ããŠã¯ãISIDã®æ¡çšããŒãžã®äžã§ã玹ä»ãããŠããïŒ ãã¡ã ïŒã®ã§ããã²ç®ãéããŠããã ããã°ãšæããŸãã æåŸãŸã§ãèªã¿ããã ããæ¬åœã«ããããšãããããŸããïŒ ç§ãã¡ã¯åãäºæ¥éšã§å
±ã«åããŠããã ãã仲éãåéããŠããŸãïŒ ã¿ãªããŸã®ãå¿åããåŸ
ã¡ããŠããŸãïŒ ãã«ãµã€ã¯ã«ãšã³ãžã㢠å·çïŒ @miyazawa.hibiki ãã¬ãã¥ãŒïŒ @sato.taichi ïŒ Shodo ã§å·çãããŸãã ïŒ
é»éåœéæ
å ±ãµãŒãã¹ ãã¯ãã¹ ã€ãããŒã·ã§ã³ æ¬éšããªãŒãã³ ã€ãããŒã·ã§ã³ ã©ãã® æ¯å康é ã§ãã ããã§ã¯ã ãããã¯ãã§ãŒã³ é±å ±4/5ãã£ãŠã¿ãããã NFTã身è¿ã« ããžã¿ã«ã§ãâæ¬ç©ä¿èšŒâ LINEåå
¥ã§NFTã身è¿ã«ïŒãWBSã ãLINE Blockchainã®å±æãšæªæ¥ã®çµæžåãLVCã€ã³ã¿ãã¥ãŒ ãïŒæã«ïŒ®ïŒŠïŒŽé»åååŒåžå Žéå§ïŒãã€ãã€æ±ºæžæ€èš ãLINE NFTã ã¯ãœãããã³ã¯çµæžåã®ç¢ºç«ããCEOã«èããçã®çã ãåæãå è€ããªã€ãæŸäºç§åãNFT掻çšãžããããžãã¯ã¬ã«ç¹å
žã®å®èšŒå®æœ ã€ã³ã¹ã¿ã°ã©ã ãNFTã®ã¡ã€ã³ã¹ããªãŒã åãå éïŒãã€ãéè¡ ãã®ä»ã®ãã¥ãŒã¹ OpenSeaããœã©ãNFTã®åãæ±ãéå§ãž æ¥çžŸçµ¶å¥œèª¿ã®æå·é貚ååŒæã瀟å¡ã«é«é¡ããŒãã¹ãæ¯çµŠ ã²ãŒã ãããã ãã§ãéã皌ãã!?ãããžãã¹ç³»YouTuberãæããWeb3.0æä»£ã®å¯æ¥ã®ãã³ã NFTã身è¿ã« LINEãNFTã«åå
¥ããããšã§ãNFTããã身è¿ã«ãªãããšãæåŸ
ãããŠããŸããLINEã®IDãæã£ãŠããŠãLINE BITMAXã«å£åº§ãéãã°ã䜿ããããã«ãªãã®ã§ããããŸã§ãã身è¿ã«ãªã£ãã®ã¯ééããªããšæããŸãã ããžã¿ã«ã§ãâæ¬ç©ä¿èšŒâ LINEåå
¥ã§NFTã身è¿ã«ïŒãWBSã ãLINE Blockchainã®å±æãšæªæ¥ã®çµæžåãLVCã€ã³ã¿ãã¥ãŒ ãïŒæã«ïŒ®ïŒŠïŒŽé»åååŒåžå Žéå§ïŒãã€ãã€æ±ºæžæ€èš ãLINE NFTã ã¯ãœãããã³ã¯çµæžåã®ç¢ºç«ããCEOã«èããçã®çã æå人ãNFTãçºè¡ããäŸãå¢ããŠããŸããã ãåæãå è€ããªã€ãæŸäºç§åãNFT掻çšãžããããžãã¯ã¬ã«ç¹å
žã®å®èšŒå®æœ Instagram ãNFTããµããŒãããããšã§ãNFTã®ã¡ã€ã³ã¹ããªãŒã åãé²ãããšãæåŸ
ãããŠããŸãã ã€ã³ã¹ã¿ã°ã©ã ãNFTã®ã¡ã€ã³ã¹ããªãŒã åãå éïŒãã€ãéè¡ ãã®ä»ã®ãã¥ãŒã¹ OpenSeaããœã©ãNFTã®åãæ±ãéå§ãž æ¥çžŸçµ¶å¥œèª¿ã®æå·é貚ååŒæã瀟å¡ã«é«é¡ããŒãã¹ãæ¯çµŠ ã²ãŒã ãããã ãã§ãéã皌ãã!?ãããžãã¹ç³»YouTuberãæããWeb3.0æä»£ã®å¯æ¥ã®ãã³ã èªæ°å
ãWeb3æä»£ã®NFTæŠç¥ã§ãã¯ã€ãããŒããŒæ¡ãå
¬è¡šââã«ãŒã«æŽåãšèŠå¶ç·©åæ¥ã å·çïŒ @higa ïŒ Shodo ã§å·çãããŸãã ïŒ
é»éåœéæ
å ±ãµãŒãã¹ ãã¯ãã¹ ã€ãããŒã·ã§ã³ æ¬éšããªãŒãã³ ã€ãããŒã·ã§ã³ ã©ãã® æ¯å康é ã§ãã ããã§ã¯ã ãããã¯ãã§ãŒã³ é±å ±4/5ãã£ãŠã¿ãããã NFTã身è¿ã« ããžã¿ã«ã§ãâæ¬ç©ä¿èšŒâ LINEåå
¥ã§NFTã身è¿ã«ïŒãWBSã ãLINE Blockchainã®å±æãšæªæ¥ã®çµæžåãLVCã€ã³ã¿ãã¥ãŒ ãïŒæã«ïŒ®ïŒŠïŒŽé»åååŒåžå Žéå§ïŒãã€ãã€æ±ºæžæ€èš ãLINE NFTã ã¯ãœãããã³ã¯çµæžåã®ç¢ºç«ããCEOã«èããçã®çã ãåæãå è€ããªã€ãæŸäºç§åãNFT掻çšãžããããžãã¯ã¬ã«ç¹å
žã®å®èšŒå®æœ ã€ã³ã¹ã¿ã°ã©ã ãNFTã®ã¡ã€ã³ã¹ããªãŒã åãå éïŒãã€ãéè¡ ãã®ä»ã®ãã¥ãŒã¹ OpenSeaããœã©ãNFTã®åãæ±ãéå§ãž æ¥çžŸçµ¶å¥œèª¿ã®æå·é貚ååŒæã瀟å¡ã«é«é¡ããŒãã¹ãæ¯çµŠ ã²ãŒã ãããã ãã§ãéã皌ãã!?ãããžãã¹ç³»YouTuberãæããWeb3.0æä»£ã®å¯æ¥ã®ãã³ã NFTã身è¿ã« LINEãNFTã«åå
¥ããããšã§ãNFTããã身è¿ã«ãªãããšãæåŸ
ãããŠããŸããLINEã®IDãæã£ãŠããŠãLINE BITMAXã«å£åº§ãéãã°ã䜿ããããã«ãªãã®ã§ããããŸã§ãã身è¿ã«ãªã£ãã®ã¯ééããªããšæããŸãã ããžã¿ã«ã§ãâæ¬ç©ä¿èšŒâ LINEåå
¥ã§NFTã身è¿ã«ïŒãWBSã ãLINE Blockchainã®å±æãšæªæ¥ã®çµæžåãLVCã€ã³ã¿ãã¥ãŒ ãïŒæã«ïŒ®ïŒŠïŒŽé»åååŒåžå Žéå§ïŒãã€ãã€æ±ºæžæ€èš ãLINE NFTã ã¯ãœãããã³ã¯çµæžåã®ç¢ºç«ããCEOã«èããçã®çã æå人ãNFTãçºè¡ããäŸãå¢ããŠããŸããã ãåæãå è€ããªã€ãæŸäºç§åãNFT掻çšãžããããžãã¯ã¬ã«ç¹å
žã®å®èšŒå®æœ Instagram ãNFTããµããŒãããããšã§ãNFTã®ã¡ã€ã³ã¹ããªãŒã åãé²ãããšãæåŸ
ãããŠããŸãã ã€ã³ã¹ã¿ã°ã©ã ãNFTã®ã¡ã€ã³ã¹ããªãŒã åãå éïŒãã€ãéè¡ ãã®ä»ã®ãã¥ãŒã¹ OpenSeaããœã©ãNFTã®åãæ±ãéå§ãž æ¥çžŸçµ¶å¥œèª¿ã®æå·é貚ååŒæã瀟å¡ã«é«é¡ããŒãã¹ãæ¯çµŠ ã²ãŒã ãããã ãã§ãéã皌ãã!?ãããžãã¹ç³»YouTuberãæããWeb3.0æä»£ã®å¯æ¥ã®ãã³ã èªæ°å
ãWeb3æä»£ã®NFTæŠç¥ã§ãã¯ã€ãããŒããŒæ¡ãå
¬è¡šââã«ãŒã«æŽåãšèŠå¶ç·©åæ¥ã å·çïŒ @higa ïŒ Shodo ã§å·çãããŸãã ïŒ
ã¿ãªããããã«ã¡ã¯ãISIDããã¯ããã°ç·šééšã® é»éåœéæ
å ±ãµãŒãã¹ (ISID) éèãœãªã¥ãŒã·ã§ã³äºæ¥éšã®ç³æ²¢ã§ããISIDã¯2021幎11æã«ISIDããã¯ããã°ãéå§ããçŸæç¹ã§50èšäºãå
¬éããŸããïŒ ãããŸã§ISIDããã¯ããã°ã¯ç€Ÿå
çã«ããã©ã€ã¢ã«ãã®äœçœ®ä»ãã§ãããã仿ããæ£åŒéçšãžç§»è¡ããããšã«ããªããŸãããæ¬èšäºã§ã¯ãISIDããã¯ããã°ãã¯ãããããšæã£ãçç±ããããããã£ãŠã¿ãŠããã£ãããšã«ã€ããŠããµãããã£ãŠã¿ãããšæããŸãã ISIDãããã¯ããã°ãã¯ãããçç± çŸåšãããŸããŸãªäŒæ¥ãããããã®ç®çã§ããã¯ããã°ãéçšããŠããŸãã ããŒã±ãã£ã³ã° ãäººäºæœçãªã©ã® ãããããŠã³ ãªã¢ãããŒãã§ããã¯ããã°ãéçšããŠããäŒæ¥ãå€ããšæããŸãããããšã¯éã«ããšã³ãžãã¢ç€Ÿå¡ã®ããã£ãŠã¿ããããšããæ°æã¡ãäžå¿ãšã㊠ããã ã¢ãã ã«éå§ããå Žåãããã§ããããISIDããã¯ããã°ã¯ããŸãã«ãšã³ãžãã¢ç€Ÿå¡ã®ããã£ãŠã¿ãããããçãŸããŠããŸããããæ£ç¢ºã«èšããšããã£ãŠã¿ãããšãããšããã§ãã ISIDã¯ã ããã ã¢ãã ã®æ¹å掻åãå®ã¯æŽ»çºã§ããéšéãæšªæããããŸããŸãªçµç¹æ¹åã®ããã°ã©ã ãåžžæå®è¡ãããŠããŸããå°éã®æ¬éšéšçœ²ãäœããæ€èšãããšããããã¯ã顧客ãããžãã¹åœ¢æ
ãç°ãªãéšéã®ã¡ã³ããŒãéçµããŠã瀟ã®èª²é¡ã«ã€ããŠè°è«ãè¡ãã解決çãçµç¹ãããžã¡ã³ãã«æèšããå®è¡ããããšãèš±ããããããªæåã§ãã ã¶ã£ã¡ããããã£ãŠã¿ããããšèšãã°ããã£ãŠã¿ãã°ããšèšãããé°å²æ°ããããŸãïŒæ¬èšäºã§ã¯æ·±ãåæ±ããŸããããèªç€Ÿã®è¡åæéã AHEAD ãšããã¯ãŒããæ¡çšããŠããŸãïŒã 2020幎ã«çºè¶³ãããISIDã°ã«ãŒãã®é·ææé·ãæ¯ããäºæ¥åºç€ã®æ§ç¯ãç®æããæ°ããªæ¥åããã»ã¹ãåãæ¹ãæ€èšãã瀟å
ãããžã§ã¯ãã®äžã€ã§ãããã¯ãŒã¯ãã©ã³ã¹ãã©ãŒã¡ãŒã·ã§ã³ãããžã§ã¯ãããšãããã®ããããŸããããããæŽŸçããæè¡åç§äŒã®2021幎床掻åããåºãŠãã㢠ã€ã㢠ã®äžã€ããããã¯ããã°ã®éèšãã§ããã ãããã瀟å
ã§ããããããªäºã«ãã£ã¬ã³ãžããŠãããšã³ãžãã¢ããããããããã©ãæ
å ±ãããŸãå
±æã§ããŠããªã 瀟äŒããèŠããšISIDã®ãšã³ãžãã¢åããŸã£ããèŠããŠããªãïŒèŠããŠããªãïŒ ããããISIDã«ãšã³ãžãã¢ããããšæãããŠããªãããïŒåºåäŒç€Ÿã®ã·ã¹ãã éšãšãã誀解ãããããïŒ ISIDã®ãšã³ãžãã¢åãç¥ã£ãŠããããå
±æãã人ã«ãžã§ã€ã³ããŠããããã ããã°ãæžãã®ã¯ãšã³ãžãã¢ãšããŠã®æé·æ©äŒã§ããããã å®éãå人ããã°ããã£ãŠãã人ããããã©ãç¶ããã®ã¯å€§å€ ããäŒç€Ÿã§æžãããã³ãããã°ãæžãäºã¯ãã£ã±ããã ããã瀟ãšããŠã®ããã¯ããã°ããã£ãŠã¿ãã°ããã®ã§ã¯âŠâŠ ããŸããæºåå§ããã°ãä»å¹ŽïŒ2021幎ïŒã® ã¢ããã³ãã«ã¬ã³ã㌠ã«åæŠã§ããããããªãã®ïŒ å€ããã«äžèšã®ãããªè©±ãããŠãããããšã¯å¢ãã§ããã¯ããã°ã®éèšãžïŒ ISIDããã¯ããã°ã®ãã©ã€ã¢ã«ãã¯ãããã«ããã£ãŠ ããã¯ããã°ãå®çŸããæè¡ã¹ã¿ãã¯ã®éžå®ã«ã€ããŠã¯ãæ¬ããã¯ããã°ã®ä»¥äžèšäºã§ç޹ä»ããŠããã®ã§æ¬èšäºã§ã¯çç¥ããŸããããã¯ããã°ã®éçšã¯ãã©ã€ã¢ã«ã§ãã£ãŠãæ¥åãšããŠæ±ããããéçšã³ã¹ããæããããšãéèŠãªããŒãã§ãããããã§æç« æ ¡æ£ãã§ããå·ç管ç SaaS ã®Shodoã®æ¡çšã¯éèŠã§ããã ããã¯ããã°å§ããŸããã ISIDããã¯ããã°ã¯ç€ŸãšããŠã®æ
å ±çºä¿¡ã«åœããããšããåºå ±éšéãšã®èª¿æŽãçµç¹ãæããŠãã ãœãŒã·ã£ã«ã¡ãã£ã¢ å©çšã«é¢ãã ã¬ã€ãã©ã€ã³ ãã¬ãã¥ãŒããã»ã¹ãç°¡åã«åºããŠãããŸããããã©ã€ã¢ã«ãšããããšããããåé¡ãçºçãããèŠçŽãã°è¯ãã®ã§éªšåçšåºŠã®ç°¡åãªãã®ã§æžãŸããŠããŸãã ã ãããã®æ¹åæ§ãåºããšããã§ãããŒã«é¡ã®è«žè²»çšããã³ããã°å·çè
ãšã¬ãã¥ã¢ãŒã®äººä»¶è²»ããã£ããèŠç©ã£ãŠã³ã¹ããåããŸãšããŠãMakrdownã§1ããŒãžãããã®äŒç»æžãæžããŠãããžã¡ã³ããšé¢ä¿è
ã«èª¬æã»æ¿è«ŸãåŸãŠã¹ã¿ãŒãã§ãã瀟å
ã§å·çè
ãå
¬åãããšãããããŸãèŠåŽãã倿§ãªå·çè
ãéããããšãã§ããŸããïŒã¡ãã£ãšå¿é
ã ã£ãã®ã§ããææã§ããïŒã çµæãšããŠã2021幎㮠ã¢ããã³ãã«ã¬ã³ã㌠ã§ã¯äžæ¥ãæ¬ ããããšãªã25èšäºãæçš¿ããããšãã§ããŸãããèšäºã®äžèЧã¯ä»¥äžã®ãšããã§ãã é»éåœéæ
å ±ãµãŒãã¹ Advent Calendar 2021 - Adventar ãã©ã€ã¢ã«ã§ããã£ãããš çã£ãŠããªãã£ãã®ã§ããã®ã§ãããããã¯ããã°ã¯çäžãããºããããã«ããããããšç¶ããŠããŸããäžæ¹ã§ããããããšãã£ãŠã¿ãŠããã£ãããšããããŸãããã®ããã€ããã玹ä»ããŸãã ISIDããã¯ããã°ãå§ããããšããã©ãããã ããçšåºŠäºæ³ããŠããããšã§ã¯ãããŸããã SNS ãªã©ã®åå¿ãèŠãŠãããšISIDãããã¯ããã°å§ããããšèªäœã«ããã€ãåå¿ãããã ããŠããŸãããããããISIDãäœããã£ãŠããäŒæ¥ããããã«ããããšããããšæããŸãã倿§ãªãšã³ãžãã¢ãåšåžããŠããããšã瀺ããã®ã¯è¯ãã£ããšæããŸãã 瀟å
ã³ãã¥ãã±ãŒã·ã§ã³æŽ»æ§åã®å¹æããã£ã 瀟å
ã®æ
å ±å
±æã®ä»çµã¿ã¯åçš®ãšãããããŠããã®ã§ãããããã§ããªãã瀟å
ã³ãã¥ãã±ãŒã·ã§ã³æŽ»æ§åã®å¹æããã£ããšæããŸããISIDããã¯ããã°ã¯å人ã®èŠç¹ã§çèº«å€§ã®æè¡æ
å ±ãçºä¿¡ããããšãç¹åŸŽã§ãã瀟å
ã®æ
å ±å
±æãšãããšããããžã§ã¯ããä»äºããã客æ§ããæŽ»èºãã人ããäžå¿ãšããããšãå€ããå²ãšïŒãããããªæå³ã§ïŒãã«ã話ã°ããã«ãªããã¡ã§ããããã¯ããã°ã«èç©ããããããªãå°ããªæ
å ±ã倧äºãªãã ãšæ¹ããŠæ°ã¥ãããããããªæ°ãããŸãã ãŸããæ®æ®µä»äºã§é¢ãããªãäººã®æŽ»åãèãæ¹ããä»éšéãä»éšçœ²ã®æè¡çãªããšãããããããšã倧ããªã¡ãªããã ãšæããŸããä»éšéã®åäžä»£ã»åæã®æžããèšäºã«åºæ¿ãåããŠãã人ããããšãã»ã»ã» åäººã®æé·æ©äŒã«ãªãããšãããã£ã ã¢ãŠãããããéããŠåŠã³ãæ·±ãŸããèªå·±æé·ãããšãã話ã¯ããèããŸããããã¯ããã°ã«èšäºãæžãäºãèªå·±ç éœã®æ©äŒã¥ãããšããŠæå¹ã ã£ããšãã声ã¯ç€Ÿå
ãããäžãããŸãããå
å®¹ãæŽçãææžåãããšããæŽ»åãææçŸ©ãªããšã«å ããŠãå
容ã«ãã£ãŠã¯ã·ãã¢ãšã³ãžãã¢ãåºå ±éšéã®ã¬ãã¥ãŒãå
¥ããŸããæ®æ®µã®ç ç©¶éçºãã¯ã©ã€ã¢ã³ãã¯ãŒã¯ããããžã§ã¯ã掻åã§ã¯çµéšãã«ããæŽ»åãè¯ãåºæ¿ãšãªã£ãŠããããã§ãã ãããŠæ£åŒéçšãž çŸæç¹ã§ãISIDããã¯ããã°ãå§ããããšã«ã¯ã¡ãªãããããªãããã¡ãªããã¯ã»ãšãã©ãªãããšãããããŸãããããã§ïŒå¥ã«ãªã«ãå€ãããªãã®ã§ããïŒæ¹ããŠãISIDããã¯ããã°ã¯ãã©ã€ã¢ã«ãããæ£åŒéçšããžç§»è¡ããããšã«ãªããŸããã ãã㯠ããã°ç ã«ã¯ä»¥äžã®ãããªèšäºããããåœç¶åèãšãããŠããã ããŠããŸãã ããã¯ããã°ã¯ç¶ããªã - äœãµã€ããæœ°ããåŸã«ããã°ãæåãªäŒæ¥ã«è»¢è·ããŠã®æ°ã¥ããšåçïœä¹
æŸåïŒITçŸç©èªã®èéå®¶ïœnote ISIDããã¯ããã°ã¯åœé¢ä»¥äžã®æ¹éã§ç¶ç¶ããäºå®ã§ãã ç·šéé·ã¯é
眮ããªãïŒæå¿ã«ããç·šééšã§éçšïŒ æ°å€ç®æšãªã©ã¯èšå®ããªãïŒç®å®ãšããŠé±1çšåºŠã®æŽæ°é »åºŠã¯ç¶æããããã©ããããèããïŒ å¿ååã¯ããªããã¬ãã¥ãŒã¯ãããèšäºã®å·çã¯æ¥åã æ»ãªãªããšãããªã»ã»ã»ïŒäžèšããã°èšäºã«æžãããŠãããããã¯ããã°ãæ»ã¬æ¡ä»¶ããæèããŠããŸãïŒ ããã¯ããã°ã®ãããããããã æ¹ããŠãISIDããã¯ããã°ã®ããããç§ãã¡ã¯ãã®ããã«å®çŸ©ããŠããŸãã ç身倧ã®ISID瀟å¡ã®å§¿ããªãŒãã³ã«äŒããŠãã ISID瀟å¡ãæè¡çãªåçµã¿ãå
¬éããŠãã èªãã®ã¢ãŠãããããããæ©äŒãéããŠèªåãã¡èªèº«ã®èœåãé«ãã å®ã¯ISIDããã¯ããã°ãäŒç»æšé²ããŠããã«ããã£ãŠãããã£ãæèŠã®äžã€ã«ããã£ãšãã¬ã£ãäººãæžãã¹ãã§ã¯ãªããã»å
é²çãªå
å®¹ã§æè¡ãã¢ããŒã«ããã»ããè¯ãã®ã§ã¯ããšãããã®ããããŸãããäžã®äžã«ã¯ãããã£ãæ¹éã®ã¢ããŒã«ã¡ãã£ã¢ãšããŠã®ããã°ãããããããããšã¯çè§£ããŠããŸãããè°è«ã®çµæããããããããããããšã¯éãããšçµè«ã¥ããŠããŸããããããã¡ã¯ãç身倧ã®èªåãã¡ãå
±æããŠããæ¹åã§ããããããISIDããã¯ããã°ãç¶ç¶ããŠããããšèããŠããŸãã æåŸãŸã§ãèªã¿ããã ãããããšãããããŸããISIDããã¯ããã°ãåŒç¶ããããããé¡ãããŸãã å·çïŒ Ishizawa Kento (@kent) ãã¬ãã¥ãŒïŒ @higa ïŒ Shodo ã§å·çãããŸãã ïŒ
ã¿ãªããããã«ã¡ã¯ãISIDããã¯ããã°ç·šééšã® é»éåœéæ
å ±ãµãŒãã¹ (ISID) éèãœãªã¥ãŒã·ã§ã³äºæ¥éšã®ç³æ²¢ã§ããISIDã¯2021幎11æã«ISIDããã¯ããã°ãéå§ããçŸæç¹ã§50èšäºãå
¬éããŸããïŒ ãããŸã§ISIDããã¯ããã°ã¯ç€Ÿå
çã«ããã©ã€ã¢ã«ãã®äœçœ®ä»ãã§ãããã仿ããæ£åŒéçšãžç§»è¡ããããšã«ããªããŸãããæ¬èšäºã§ã¯ãISIDããã¯ããã°ãã¯ãããããšæã£ãçç±ããããããã£ãŠã¿ãŠããã£ãããšã«ã€ããŠããµãããã£ãŠã¿ãããšæããŸãã ISIDãããã¯ããã°ãã¯ãããçç± çŸåšãããŸããŸãªäŒæ¥ãããããã®ç®çã§ããã¯ããã°ãéçšããŠããŸãã ããŒã±ãã£ã³ã° ãäººäºæœçãªã©ã® ãããããŠã³ ãªã¢ãããŒãã§ããã¯ããã°ãéçšããŠããäŒæ¥ãå€ããšæããŸãããããšã¯éã«ããšã³ãžãã¢ç€Ÿå¡ã®ããã£ãŠã¿ããããšããæ°æã¡ãäžå¿ãšã㊠ããã ã¢ãã ã«éå§ããå Žåãããã§ããããISIDããã¯ããã°ã¯ããŸãã«ãšã³ãžãã¢ç€Ÿå¡ã®ããã£ãŠã¿ãããããçãŸããŠããŸããããæ£ç¢ºã«èšããšããã£ãŠã¿ãããšãããšããã§ãã ISIDã¯ã ããã ã¢ãã ã®æ¹å掻åãå®ã¯æŽ»çºã§ããéšéãæšªæããããŸããŸãªçµç¹æ¹åã®ããã°ã©ã ãåžžæå®è¡ãããŠããŸããå°éã®æ¬éšéšçœ²ãäœããæ€èšãããšããããã¯ã顧客ãããžãã¹åœ¢æ
ãç°ãªãéšéã®ã¡ã³ããŒãéçµããŠã瀟ã®èª²é¡ã«ã€ããŠè°è«ãè¡ãã解決çãçµç¹ãããžã¡ã³ãã«æèšããå®è¡ããããšãèš±ããããããªæåã§ãã ã¶ã£ã¡ããããã£ãŠã¿ããããšèšãã°ããã£ãŠã¿ãã°ããšèšãããé°å²æ°ããããŸãïŒæ¬èšäºã§ã¯æ·±ãåæ±ããŸããããèªç€Ÿã®è¡åæéã AHEAD ãšããã¯ãŒããæ¡çšããŠããŸãïŒã 2020幎ã«çºè¶³ãããISIDã°ã«ãŒãã®é·ææé·ãæ¯ããäºæ¥åºç€ã®æ§ç¯ãç®æããæ°ããªæ¥åããã»ã¹ãåãæ¹ãæ€èšãã瀟å
ãããžã§ã¯ãã®äžã€ã§ãããã¯ãŒã¯ãã©ã³ã¹ãã©ãŒã¡ãŒã·ã§ã³ãããžã§ã¯ãããšãããã®ããããŸããããããæŽŸçããæè¡åç§äŒã®2021幎床掻åããåºãŠãã㢠ã€ã㢠ã®äžã€ããããã¯ããã°ã®éèšãã§ããã ãããã瀟å
ã§ããããããªäºã«ãã£ã¬ã³ãžããŠãããšã³ãžãã¢ããããããããã©ãæ
å ±ãããŸãå
±æã§ããŠããªã 瀟äŒããèŠããšISIDã®ãšã³ãžãã¢åããŸã£ããèŠããŠããªãïŒèŠããŠããªãïŒ ããããISIDã«ãšã³ãžãã¢ããããšæãããŠããªãããïŒåºåäŒç€Ÿã®ã·ã¹ãã éšãšãã誀解ãããããïŒ ISIDã®ãšã³ãžãã¢åãç¥ã£ãŠããããå
±æãã人ã«ãžã§ã€ã³ããŠããããã ããã°ãæžãã®ã¯ãšã³ãžãã¢ãšããŠã®æé·æ©äŒã§ããããã å®éãå人ããã°ããã£ãŠãã人ããããã©ãç¶ããã®ã¯å€§å€ ããäŒç€Ÿã§æžãããã³ãããã°ãæžãäºã¯ãã£ã±ããã ããã瀟ãšããŠã®ããã¯ããã°ããã£ãŠã¿ãã°ããã®ã§ã¯âŠâŠ ããŸããæºåå§ããã°ãä»å¹ŽïŒ2021幎ïŒã® ã¢ããã³ãã«ã¬ã³ã㌠ã«åæŠã§ããããããªãã®ïŒ å€ããã«äžèšã®ãããªè©±ãããŠãããããšã¯å¢ãã§ããã¯ããã°ã®éèšãžïŒ ISIDããã¯ããã°ã®ãã©ã€ã¢ã«ãã¯ãããã«ããã£ãŠ ããã¯ããã°ãå®çŸããæè¡ã¹ã¿ãã¯ã®éžå®ã«ã€ããŠã¯ãæ¬ããã¯ããã°ã®ä»¥äžèšäºã§ç޹ä»ããŠããã®ã§æ¬èšäºã§ã¯çç¥ããŸããããã¯ããã°ã®éçšã¯ãã©ã€ã¢ã«ã§ãã£ãŠãæ¥åãšããŠæ±ããããéçšã³ã¹ããæããããšãéèŠãªããŒãã§ãããããã§æç« æ ¡æ£ãã§ããå·ç管ç SaaS ã®Shodoã®æ¡çšã¯éèŠã§ããã ããã¯ããã°å§ããŸããã ISIDããã¯ããã°ã¯ç€ŸãšããŠã®æ
å ±çºä¿¡ã«åœããããšããåºå ±éšéãšã®èª¿æŽãçµç¹ãæããŠãã ãœãŒã·ã£ã«ã¡ãã£ã¢ å©çšã«é¢ãã ã¬ã€ãã©ã€ã³ ãã¬ãã¥ãŒããã»ã¹ãç°¡åã«åºããŠãããŸããããã©ã€ã¢ã«ãšããããšããããåé¡ãçºçãããèŠçŽãã°è¯ãã®ã§éªšåçšåºŠã®ç°¡åãªãã®ã§æžãŸããŠããŸãã ã ãããã®æ¹åæ§ãåºããšããã§ãããŒã«é¡ã®è«žè²»çšããã³ããã°å·çè
ãšã¬ãã¥ã¢ãŒã®äººä»¶è²»ããã£ããèŠç©ã£ãŠã³ã¹ããåããŸãšããŠãMakrdownã§1ããŒãžãããã®äŒç»æžãæžããŠãããžã¡ã³ããšé¢ä¿è
ã«èª¬æã»æ¿è«ŸãåŸãŠã¹ã¿ãŒãã§ãã瀟å
ã§å·çè
ãå
¬åãããšãããããŸãèŠåŽãã倿§ãªå·çè
ãéããããšãã§ããŸããïŒã¡ãã£ãšå¿é
ã ã£ãã®ã§ããææã§ããïŒã çµæãšããŠã2021幎㮠ã¢ããã³ãã«ã¬ã³ã㌠ã§ã¯äžæ¥ãæ¬ ããããšãªã25èšäºãæçš¿ããããšãã§ããŸãããèšäºã®äžèЧã¯ä»¥äžã®ãšããã§ãã é»éåœéæ
å ±ãµãŒãã¹ Advent Calendar 2021 - Adventar ãã©ã€ã¢ã«ã§ããã£ãããš çã£ãŠããªãã£ãã®ã§ããã®ã§ãããããã¯ããã°ã¯çäžãããºããããã«ããããããšç¶ããŠããŸããäžæ¹ã§ããããããšãã£ãŠã¿ãŠããã£ãããšããããŸãããã®ããã€ããã玹ä»ããŸãã ISIDããã¯ããã°ãå§ããããšããã©ãããã ããçšåºŠäºæ³ããŠããããšã§ã¯ãããŸããã SNS ãªã©ã®åå¿ãèŠãŠãããšISIDãããã¯ããã°å§ããããšèªäœã«ããã€ãåå¿ãããã ããŠããŸãããããããISIDãäœããã£ãŠããäŒæ¥ããããã«ããããšããããšæããŸãã倿§ãªãšã³ãžãã¢ãåšåžããŠããããšã瀺ããã®ã¯è¯ãã£ããšæããŸãã 瀟å
ã³ãã¥ãã±ãŒã·ã§ã³æŽ»æ§åã®å¹æããã£ã 瀟å
ã®æ
å ±å
±æã®ä»çµã¿ã¯åçš®ãšãããããŠããã®ã§ãããããã§ããªãã瀟å
ã³ãã¥ãã±ãŒã·ã§ã³æŽ»æ§åã®å¹æããã£ããšæããŸããISIDããã¯ããã°ã¯å人ã®èŠç¹ã§çèº«å€§ã®æè¡æ
å ±ãçºä¿¡ããããšãç¹åŸŽã§ãã瀟å
ã®æ
å ±å
±æãšãããšããããžã§ã¯ããä»äºããã客æ§ããæŽ»èºãã人ããäžå¿ãšããããšãå€ããå²ãšïŒãããããªæå³ã§ïŒãã«ã話ã°ããã«ãªããã¡ã§ããããã¯ããã°ã«èç©ããããããªãå°ããªæ
å ±ã倧äºãªãã ãšæ¹ããŠæ°ã¥ãããããããªæ°ãããŸãã ãŸããæ®æ®µä»äºã§é¢ãããªãäººã®æŽ»åãèãæ¹ããä»éšéãä»éšçœ²ã®æè¡çãªããšãããããããšã倧ããªã¡ãªããã ãšæããŸããä»éšéã®åäžä»£ã»åæã®æžããèšäºã«åºæ¿ãåããŠãã人ããããšãã»ã»ã» åäººã®æé·æ©äŒã«ãªãããšãããã£ã ã¢ãŠãããããéããŠåŠã³ãæ·±ãŸããèªå·±æé·ãããšãã話ã¯ããèããŸããããã¯ããã°ã«èšäºãæžãäºãèªå·±ç éœã®æ©äŒã¥ãããšããŠæå¹ã ã£ããšãã声ã¯ç€Ÿå
ãããäžãããŸãããå
å®¹ãæŽçãææžåãããšããæŽ»åãææçŸ©ãªããšã«å ããŠãå
容ã«ãã£ãŠã¯ã·ãã¢ãšã³ãžãã¢ãåºå ±éšéã®ã¬ãã¥ãŒãå
¥ããŸããæ®æ®µã®ç ç©¶éçºãã¯ã©ã€ã¢ã³ãã¯ãŒã¯ããããžã§ã¯ã掻åã§ã¯çµéšãã«ããæŽ»åãè¯ãåºæ¿ãšãªã£ãŠããããã§ãã ãããŠæ£åŒéçšãž çŸæç¹ã§ãISIDããã¯ããã°ãå§ããããšã«ã¯ã¡ãªãããããªãããã¡ãªããã¯ã»ãšãã©ãªãããšãããããŸãããããã§ïŒå¥ã«ãªã«ãå€ãããªãã®ã§ããïŒæ¹ããŠãISIDããã¯ããã°ã¯ãã©ã€ã¢ã«ãããæ£åŒéçšããžç§»è¡ããããšã«ãªããŸããã ãã㯠ããã°ç ã«ã¯ä»¥äžã®ãããªèšäºããããåœç¶åèãšãããŠããã ããŠããŸãã ããã¯ããã°ã¯ç¶ããªã - äœãµã€ããæœ°ããåŸã«ããã°ãæåãªäŒæ¥ã«è»¢è·ããŠã®æ°ã¥ããšåçïœä¹
æŸåïŒITçŸç©èªã®èéå®¶ïœnote ISIDããã¯ããã°ã¯åœé¢ä»¥äžã®æ¹éã§ç¶ç¶ããäºå®ã§ãã ç·šéé·ã¯é
眮ããªãïŒæå¿ã«ããç·šééšã§éçšïŒ æ°å€ç®æšãªã©ã¯èšå®ããªãïŒç®å®ãšããŠé±1çšåºŠã®æŽæ°é »åºŠã¯ç¶æããããã©ããããèããïŒ å¿ååã¯ããªããã¬ãã¥ãŒã¯ãããèšäºã®å·çã¯æ¥åã æ»ãªãªããšãããªã»ã»ã»ïŒäžèšããã°èšäºã«æžãããŠãããããã¯ããã°ãæ»ã¬æ¡ä»¶ããæèããŠããŸãïŒ ããã¯ããã°ã®ãããããããã æ¹ããŠãISIDããã¯ããã°ã®ããããç§ãã¡ã¯ãã®ããã«å®çŸ©ããŠããŸãã ç身倧ã®ISID瀟å¡ã®å§¿ããªãŒãã³ã«äŒããŠãã ISID瀟å¡ãæè¡çãªåçµã¿ãå
¬éããŠãã èªãã®ã¢ãŠãããããããæ©äŒãéããŠèªåãã¡èªèº«ã®èœåãé«ãã å®ã¯ISIDããã¯ããã°ãäŒç»æšé²ããŠããã«ããã£ãŠãããã£ãæèŠã®äžã€ã«ããã£ãšãã¬ã£ãäººãæžãã¹ãã§ã¯ãªããã»å
é²çãªå
å®¹ã§æè¡ãã¢ããŒã«ããã»ããè¯ãã®ã§ã¯ããšãããã®ããããŸãããäžã®äžã«ã¯ãããã£ãæ¹éã®ã¢ããŒã«ã¡ãã£ã¢ãšããŠã®ããã°ãããããããããšã¯çè§£ããŠããŸãããè°è«ã®çµæããããããããããããšã¯éãããšçµè«ã¥ããŠããŸããããããã¡ã¯ãç身倧ã®èªåãã¡ãå
±æããŠããæ¹åã§ããããããISIDããã¯ããã°ãç¶ç¶ããŠããããšèããŠããŸãã æåŸãŸã§ãèªã¿ããã ãããããšãããããŸããISIDããã¯ããã°ãåŒç¶ããããããé¡ãããŸãã å·çïŒ Ishizawa Kento (@kent) ãã¬ãã¥ãŒïŒ @higa ïŒ Shodo ã§å·çãããŸãã ïŒ
é»éåœéæ
å ±ãµãŒãã¹ ãã¯ãã¹ ã€ãããŒã·ã§ã³ æ¬éšããªãŒãã³ ã€ãããŒã·ã§ã³ ã©ãã® æ¯å康é ã§ããä»ååãäžããã®ã¯Tailwind CSS ã Tailwind CSS ã¯ãæè¿äººæ°æ¥äžæã® CSS ãã¬ãŒã ã¯ãŒã¯ ã§ãã ã¡ãžã£ãŒãªBootstrapãªã©ã® ãã¬ãŒã ã¯ãŒã¯ ã¯ããããããèŠæ ãã®è¯ã ã³ã³ããŒãã³ã ãçšæãããŠããŠããããã«ã¹ã¿ãã€ãºããŸããããã«å¯ŸããTailwind CSS ã¯ã CSS ã®äŸ¿å©ãªclassã倧éã«çšæãããŠããã ãã§ããããã§ã¯ãªãTailwind CSS ã®äººæ°ãäžæããŠããã®ã§ããããã äžçªã®åå ã¯Bootstrapãªã©ã® ã³ã³ããŒãã³ã ã䜿ããšãèŠãç®ãåãæ§ã«ãªã£ãŠããŸãã®ã§ãµã€ãã®åæ§ãåºããªããªãããšã§ãã ãµã€ãã®åæ§ãåºãããã«ãåºæ¥åãã® ã³ã³ããŒãã³ã ã¯äœ¿ããèªåã§ãã¶ã€ã³ãçµã¿ç«ãŠãŠãããšã³ã¹ããæãããŸãããã®ã³ã¹ããã§ããã ãäžããããã«ãTailwind CSS ã§ã¯äŸ¿å©ãªã¯ã©ã¹ãããããçšæãããŠããŸãã æè¿ã¯ã Adobe XDã䜿ã£ãŠãããã¿ã€ããäœãããšãå€ããªã£ãŠããŠãããšæããŸããXDã§äœã£ããã®ãHTMLã«èœãšã蟌ããšãã«ãåºæ¥åãã® ã³ã³ããŒãã³ã ããã£ãŠãããŸã圹ã«ç«ã¡ãŸãããèªåã§ãã€ããŒã³ã¹ãã§ãã¶ã€ã³ããã®ã«Tailwind CSS ã¯åããŠããã®ã§ãã Clubhouse ã Netflix Top 10 ãTailwind CSS ã䜿ã£ãŠããããã§ãã åæºå first.html rectangles.html responsive_design.html ãŸãšã åæºå ä»å䜿ãHTMLãåãã£ãŠçšæããŠãããã®ã§ãããŠã³ããŒãããŠãã ããã tailwindcss_samples.zip ããªããã VS Code ã䜿ã£ãŠãããªãããšãŠã䟿å©ãªTailwind CSS ã®æ©èœæ¡åŒµãçšæãããŠããã®ã§ã€ã³ã¹ããŒã«ããŸãããã ã¡ãã¥ãŒã®æ©èœæ¡åŒµïŒExtensionsïŒãéããŠãtainwindã§æ€çŽ¢ããŠãã ãããTailwind CSS IntelliSenseãšããæ©èœæ¡åŒµãããã®ã§ããããã€ã³ã¹ããŒã«ããŠãã ããã æ¬¡ã®ããã«classã®è£å®ãã§ããŸãã Tailwind CSS ã«ã¯ããããã®classãçšæãããŠããã®ã§ããããå
šéšèŠããã®ã¯å€§å€ã§ããããããããçšåºŠãªããŠãããšããã¹ãã«é¢ããclassã¯textã§å§ãŸããšããããšãèªç¶ã«èŠããããã®ã§ãtextãšå
¥åãè£å®ããã°classãã©ããªã«ããããããããšå¯Ÿå¿ã§ããŸãã Tailwind CSS ã䜿ãããã®æ¹æ³ã¯ããã€ããããŸããã CDN ã䜿ãã®ãæãç°¡åã§ãããã®èšäºã§ã¯ CDN ã䜿ããŸããheadã¿ã°ã®åèŠçŽ ã«æ¬¡ã®linkã¿ã°ã远å ããŠãã ããã < link href = "https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel = "stylesheet" /> first.html ããã§ã¯ãfirst.htmlã Chrome ã§éããŸãããã Mac ã䜿ã£ãŠããå Žåã¯ãfirst.htmlãå³ã¯ãªã㯠-> ãã®ã¢ããªã±ãŒã·ã§ã³ã§éã -> Google Chrome .appãéžãã§ãã ããã Windows ã䜿ã£ãŠããå Žåã¯ãfirst.htmlãå³ã¯ãªã㯠-> æ
å ±ãèŠã -> ãã®ã¢ããªã±ãŒã·ã§ã³ã§éãã§ã Chrome ãéžãã§ãã ããã <!DOCTYPE html> < html lang = "ja" > < head > < meta charset = "UTF-8" /> < meta http-equiv = "X-UA-Compatible" content = "IE=edge" /> < meta name = "viewport" content = "width=device-width, initial-scale=1.0" /> < title > Document </ title > < link href = "https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel = "stylesheet" /> </ head > < body > < span class = "text-red-500" > ããã </ span > </ body > </ html > text-red-500ãtext-blue-500ã«å€ããŠHTMLãä¿åãããã©ãŠã¶ããªããŒãããŸããããæåã®è²ãéããªã£ãã¯ãã§ãã text-blue-500ã®500ã¯äœã衚ããŠããã®ã§ãããããããã¯æåã®è²ã®æ¿ãã§ãã500ãæ¶ããŠè£å®ããããšæ¬¡ã®ãããªéžæè¢ãããããšãããããŸãã æ°åã倧ãããªãã»ã©è²ãæ¿ããªããŸããããã§ã¯ãtext-blue-100ã«å€æŽããŠHTMLãä¿åãããã©ãŠã¶ããªããŒãããŸããããæåã®è²ãèããªããŸãããã rectangles.html ããã§ã¯ããããããªclassã詊ããŠã¿ãŸããããrectangles.htmlã Chrome ã§éããŸãããã <!DOCTYPE html> < html lang = "ja" > < head > < meta charset = "UTF-8" /> < meta http-equiv = "X-UA-Compatible" content = "IE=edge" /> < meta name = "viewport" content = "width=device-width, initial-scale=1.0" /> < title > Rectabgles </ title > < link href = "https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel = "stylesheet" /> </ head > < body class = "pl-4" > < div > w-4 = 1 rem = 16px </ div > < div class = "text-white bg-blue-500 w-4" > ããã </ div > < div class = "mt-4" > w-12 </ div > < div class = "text-white bg-blue-500 w-12" > ããã </ div > < div class = "mt-4" > w-20 </ div > < div class = "text-white bg-blue-500 w-20" > ããã </ div > < div class = "mt-4" > w-20 text-center </ div > < div class = "text-white bg-blue-500 w-20 text-center" > ããã </ div > < div class = "mt-4" > w-20 text-center py-2 </ div > < div class = "text-white bg-blue-500 w-20 text-center py-2" > ããã </ div > < div class = "mt-4" > w-20 text-center py-2 rounded-xl </ div > < div class = "text-white bg-blue-500 w-20 text-center py-2 rounded-xl" > ããã </ div > < div class = "mt-4" > w-20 text-center py-2 bg-opacity-80 </ div > < div class = "text-white bg-blue-500 w-20 text-center py-2 bg-opacity-80" > ããã </ div > < div class = "mt-4" > w-20 text-center py-2 font-bold </ div > < div class = "text-white bg-blue-500 w-20 text-center py-2 font-bold" > ããã </ div > < div class = "mt-4" > w-20 text-center py-2 border-8 border-red-500 </ div > < div class = "w-20 text-center py-2 border-8 border-red-500" > ããã </ div > </ body > </ html > å·ŠåŽã16px空ããŠããŸãã ããã¯ãbodyã¿ã°ã®classã«æå®ããpl-4ã®å¹æã§ããpl-4ãšã¯ãpadding left 16pxã®ããšã§ãã1ã4pxã«ãªããŸãã < body class = "pl-4" > äžã®ã¿ã°ãšè·é¢ãéããã«ã¯ãmt-xxã䜿ããŸããmtã¯margin topã®ç¥ã§ãã < div class = "mt-4" > w-12 </ div > èæ¯è²ãæå®ããã«ã¯ãbg-è²-æ¿ãã§æå®ããŸããæ¿ãã¯500ãçãäžã®å€ã§ãæ¿ããªããšæ°å€ã倧ãããªããŸãã900ãæã倧ããå€ã§ãã å¹
ãæå®ããã«ã¯ãw-æ°å€ã§æå®ããŸããæ°å€ã¯å
çšãšåæ§1ã4pxã«ãªããŸããTailwind CSS ã§ã¯ãæ°å€ã®4ã16px = 1 rem = 1æååã®å¹
ã«ãªããŸãã < div class = "text-white bg-blue-500 w-4" > ããã </ div > ã¡ããã©ã1æåã®å¹
ã§æ¹è¡ãããŠããŸããã æ¬¡ã¯ãw-12 = 3 remã«ããŠã¿ãŸãããã < div class = "text-white bg-blue-500 w-12" > ããã </ div > ã¡ããã©æåå¹
ãšåãã«ãªã£ãŠããŸãã w-20ã«ãããšã©ããªãã§ããããã < div class = "text-white bg-blue-500 w-20" > ããã </ div > å·Šå¯ãã«ãªããŸããã äžå€®å¯ãã«ããŠã¿ãŸããããtext-centerã䜿ããŸãã < div class = "text-white bg-blue-500 w-20 text-center" > ããã </ div > æåã®äžäžã«ã¹ããŒã¹ãå
¥ããŠã¿ãŸããããpyïŒpadding yæ¹åïŒã䜿ããŸãã < div class = "text-white bg-blue-500 w-20 text-center py-2" > ããã </ div > è§äžžã«ããŠã¿ãŸããããroundedã䜿ããŸãã < div class = "text-white bg-blue-500 w-20 text-center py-2 rounded-xl" > ããã </ div > roundedã§ã©ã®ãããªå€ã䜿ãããã¯ãroundedãšå
¥åããè£å®ã§ç¢ºãããŸãããã èæ¯ã®äžéæåºŠãèšå®ããŸããããbg-opacity-xxã䜿ããŸããxxã¯0ãã100ãŸã§ã®æ°åãå
¥ããŸããæ°åã倧ããã»ã©äžéæåºŠã¯é«ãã100ã®å Žåã¯éæåºŠãªãïŒäœãæå®ããªãã®ãšäžç·ïŒã§ããxxã§ãã©ã®å€ã䜿ãããã¯è£å®ã§ç¢ºãããŸãããã < div class = "text-white bg-blue-500 w-20 text-center py-2 bg-opacity-80" > ããã </ div > ãã©ã³ãã倪ãããŠã¿ãŸããããfont-boldã䜿ããŸãã < div class = "text-white bg-blue-500 w-20 text-center py-2 font-bold" > ããã </ div > æ ç·ãèšå®ããŸããããborder-倪ããšborder-è²-æ¿ãã§æå®ããŸãã < div class = "w-20 text-center py-2 border-8 border-red-500" > ããã </ div > ããã§ã¯ãå¹
ïŒwidthïŒã4ã®åæ°ä»¥å€ã®23pxã«ãããå Žåã¯ã©ãããã®ã§ãããããw-[23px]ã®ããã«[]ã®äžã«ãµã€ãºãæå®ããŸãããã ãã CDN çã§ã¯ã§ããŸãããnpmã§tailwindcssãã€ã³ã¹ããŒã«ããå¿
èŠããããŸãã詳ããã¯äžèšãã芧ãã ããã Installation: Tailwind CLI using-arbitrary-values responsive_design.html Tailwind CSS ã䜿ããšç°¡åã«ã¬ã¹ãã³ã·ããã¶ã€ã³ã«ã§ããŸããresponsive_design.htmlã Chrome ã§éããŠãã ããã <!DOCTYPE html> < html lang = "ja" > < head > < meta charset = "UTF-8" /> < meta http-equiv = "X-UA-Compatible" content = "IE=edge" /> < meta name = "viewport" content = "width=device-width, initial-scale=1.0" /> < title > Responsive Design </ title > < link href = "https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel = "stylesheet" /> </ head > < body class = "pl-4 pt-4" > < div class = "bg-blue-500 w-16 md:w-32 lg:w-48 xl:w-60 h-8" ></ div > < div class = "mt-4 md:flex" > < div class = "w-72 h-8 bg-indigo-500" ></ div > < div class = "mt-1 md:mt-0 md:ml-1 w-72 h-8 bg-pink-500" ></ div > </ div > </ body > </ html > Chrome ã®Windowã®å¹
ãã§ããã ãå°ããããŠãã ãããæ¬¡ã®ãããªéãåè§ã衚瀺ãããŸãããã å°ãã¥ã€Windowã®å¹
ã倧ããããŠãã ããã768px以äžã§åè§ã®å¹
ã16pxå¢ããŸããããåæ§ã«ã1024pxã1280px以äžã§åè§ã®å¹
ãå¢ããã¯ãã§ãã ã¿ã°ã®å®çŸ©ãèŠãŠã¿ãŸãããã < div class = "bg-blue-500 w-16 md:w-32 lg:w-48 xl:w-60 h-8" ></ div > w-xxã® ãã¬ãã£ãã¯ã¹ ãšããŠmd:, lg:, xl:ãæå®ãããŠããŸãããããè§£éãããšæ¬¡ã®ããã«ãªããŸãã 768pxæªæºã¯ãw-16ã md: 768px以äž1024pxæªæºã¯ãw-32ã lg: 1024px以äž1280pxæªæºã¯ãw-48ã xl: 1280px以äžã¯ãw-60ã ã¬ã¹ãã³ã·ããã¶ã€ã³ã§ããããã®ã ã¹ãã ã§ã¯ã¹ããŒã¹ããªãã®ã§çžŠã«è¡šç€ºãã ã¿ãã¬ãã 以äžã®ã¹ããŒã¹ãããå Žåã¯ã暪ã«è¡šç€ºããããæ¹ã§ãã ãŸãã ã¹ãã ã§çžŠã«è¡šç€ºããã«ã¯ãæ®éã«divã䜿ããŸãã < div > < div > ã³ã³ãã³ã1 </ div > < div > ã³ã³ãã³ã2 </ div > </ div > å¹
ã768px以äžã®ãšãã«ã暪ã«è¡šç€ºããã«ã¯ãmd: flex ã䜿ããŸãã < div class = "md:flex" > < div > ã³ã³ãã³ã1 </ div > < div > ã³ã³ãã³ã2 </ div > </ div > ã€ãŸããmd: flex ã䜿ãã°ã ã¹ãã ã§ã¯çžŠã«è¡šç€ºããå¹
768px以äžãªã暪ã«è¡šç€ºãããšããããšãç°¡åã«ã§ããŸãã < div class = "mt-4 md:flex" > < div class = "w-72 h-8 bg-indigo-500" ></ div > < div class = "mt-1 md:mt-0 md:ml-1 w-72 h-8 bg-pink-500" ></ div > </ div > å¹
ã768pxæªæºã å¹
ã768pxä»¥äž mt-1 md:mt-0 md:ml-1ã説æããŠãããŸããããå¹
ã768pxæªæºã®ãšãã¯ã瞊ã«äžŠã¶ã®ã§ãmt-1ïŒmargin top 4pxïŒã§äžã®èŠçŽ ãš4pxãããŸãã å¹
ã768px以äžã®ãšãã¯ã暪ã«äžŠã¶ã®ã§ãmd:mt-0ïŒmargin top 0pxïŒã§äžã®èŠçŽ ãšã®ã¹ããŒã¹ã0pxã«ããmd:ml-1ã§å·Šã®èŠçŽ ãšã®ã¹ããŒã¹ã4pxãããŸãã ãŸãšã Tailwind CSS ãããã ã£ãã§ãããããHTMLãã¿ãã°ãclass屿§ã«å¿
èŠãªæ
å ±ããããããã©ããããã¶ã€ã³ã«ãªãã®ãäºæ³ã§ããŸããããã«ããããªãèŠéããè¯ããªããŸãã ã¹ãã¬ã¹ããªãŒãª CSS ã©ã€ãããéãããã ããã å·çïŒ @higa ïŒ Shodo ã§å·çãããŸãã ïŒ
é»éåœéæ
å ±ãµãŒãã¹ ãã¯ãã¹ ã€ãããŒã·ã§ã³ æ¬éšããªãŒãã³ ã€ãããŒã·ã§ã³ ã©ãã® æ¯å康é ã§ããä»ååãäžããã®ã¯Tailwind CSS ã Tailwind CSS ã¯ãæè¿äººæ°æ¥äžæã® CSS ãã¬ãŒã ã¯ãŒã¯ ã§ãã ã¡ãžã£ãŒãªBootstrapãªã©ã® ãã¬ãŒã ã¯ãŒã¯ ã¯ããããããèŠæ ãã®è¯ã ã³ã³ããŒãã³ã ãçšæãããŠããŠããããã«ã¹ã¿ãã€ãºããŸããããã«å¯ŸããTailwind CSS ã¯ã CSS ã®äŸ¿å©ãªclassã倧éã«çšæãããŠããã ãã§ããããã§ã¯ãªãTailwind CSS ã®äººæ°ãäžæããŠããã®ã§ããããã äžçªã®åå ã¯Bootstrapãªã©ã® ã³ã³ããŒãã³ã ã䜿ããšãèŠãç®ãåãæ§ã«ãªã£ãŠããŸãã®ã§ãµã€ãã®åæ§ãåºããªããªãããšã§ãã ãµã€ãã®åæ§ãåºãããã«ãåºæ¥åãã® ã³ã³ããŒãã³ã ã¯äœ¿ããèªåã§ãã¶ã€ã³ãçµã¿ç«ãŠãŠãããšã³ã¹ããæãããŸãããã®ã³ã¹ããã§ããã ãäžããããã«ãTailwind CSS ã§ã¯äŸ¿å©ãªã¯ã©ã¹ãããããçšæãããŠããŸãã æè¿ã¯ã Adobe XDã䜿ã£ãŠãããã¿ã€ããäœãããšãå€ããªã£ãŠããŠãããšæããŸããXDã§äœã£ããã®ãHTMLã«èœãšã蟌ããšãã«ãåºæ¥åãã® ã³ã³ããŒãã³ã ããã£ãŠãããŸã圹ã«ç«ã¡ãŸãããèªåã§ãã€ããŒã³ã¹ãã§ãã¶ã€ã³ããã®ã«Tailwind CSS ã¯åããŠããã®ã§ãã Clubhouse ã Netflix Top 10 ãTailwind CSS ã䜿ã£ãŠããããã§ãã åæºå first.html rectangles.html responsive_design.html ãŸãšã åæºå ä»å䜿ãHTMLãåãã£ãŠçšæããŠãããã®ã§ãããŠã³ããŒãããŠãã ããã tailwindcss_samples.zip ããªããã VS Code ã䜿ã£ãŠãããªãããšãŠã䟿å©ãªTailwind CSS ã®æ©èœæ¡åŒµãçšæãããŠããã®ã§ã€ã³ã¹ããŒã«ããŸãããã ã¡ãã¥ãŒã®æ©èœæ¡åŒµïŒExtensionsïŒãéããŠãtainwindã§æ€çŽ¢ããŠãã ãããTailwind CSS IntelliSenseãšããæ©èœæ¡åŒµãããã®ã§ããããã€ã³ã¹ããŒã«ããŠãã ããã æ¬¡ã®ããã«classã®è£å®ãã§ããŸãã Tailwind CSS ã«ã¯ããããã®classãçšæãããŠããã®ã§ããããå
šéšèŠããã®ã¯å€§å€ã§ããããããããçšåºŠãªããŠãããšããã¹ãã«é¢ããclassã¯textã§å§ãŸããšããããšãèªç¶ã«èŠããããã®ã§ãtextãšå
¥åãè£å®ããã°classãã©ããªã«ããããããããšå¯Ÿå¿ã§ããŸãã Tailwind CSS ã䜿ãããã®æ¹æ³ã¯ããã€ããããŸããã CDN ã䜿ãã®ãæãç°¡åã§ãããã®èšäºã§ã¯ CDN ã䜿ããŸããheadã¿ã°ã®åèŠçŽ ã«æ¬¡ã®linkã¿ã°ã远å ããŠãã ããã < link href = "https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel = "stylesheet" /> first.html ããã§ã¯ãfirst.htmlã Chrome ã§éããŸãããã Mac ã䜿ã£ãŠããå Žåã¯ãfirst.htmlãå³ã¯ãªã㯠-> ãã®ã¢ããªã±ãŒã·ã§ã³ã§éã -> Google Chrome .appãéžãã§ãã ããã Windows ã䜿ã£ãŠããå Žåã¯ãfirst.htmlãå³ã¯ãªã㯠-> æ
å ±ãèŠã -> ãã®ã¢ããªã±ãŒã·ã§ã³ã§éãã§ã Chrome ãéžãã§ãã ããã <!DOCTYPE html> < html lang = "ja" > < head > < meta charset = "UTF-8" /> < meta http-equiv = "X-UA-Compatible" content = "IE=edge" /> < meta name = "viewport" content = "width=device-width, initial-scale=1.0" /> < title > Document </ title > < link href = "https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel = "stylesheet" /> </ head > < body > < span class = "text-red-500" > ããã </ span > </ body > </ html > text-red-500ãtext-blue-500ã«å€ããŠHTMLãä¿åãããã©ãŠã¶ããªããŒãããŸããããæåã®è²ãéããªã£ãã¯ãã§ãã text-blue-500ã®500ã¯äœã衚ããŠããã®ã§ãããããããã¯æåã®è²ã®æ¿ãã§ãã500ãæ¶ããŠè£å®ããããšæ¬¡ã®ãããªéžæè¢ãããããšãããããŸãã æ°åã倧ãããªãã»ã©è²ãæ¿ããªããŸããããã§ã¯ãtext-blue-100ã«å€æŽããŠHTMLãä¿åãããã©ãŠã¶ããªããŒãããŸããããæåã®è²ãèããªããŸãããã rectangles.html ããã§ã¯ããããããªclassã詊ããŠã¿ãŸããããrectangles.htmlã Chrome ã§éããŸãããã <!DOCTYPE html> < html lang = "ja" > < head > < meta charset = "UTF-8" /> < meta http-equiv = "X-UA-Compatible" content = "IE=edge" /> < meta name = "viewport" content = "width=device-width, initial-scale=1.0" /> < title > Rectabgles </ title > < link href = "https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel = "stylesheet" /> </ head > < body class = "pl-4" > < div > w-4 = 1 rem = 16px </ div > < div class = "text-white bg-blue-500 w-4" > ããã </ div > < div class = "mt-4" > w-12 </ div > < div class = "text-white bg-blue-500 w-12" > ããã </ div > < div class = "mt-4" > w-20 </ div > < div class = "text-white bg-blue-500 w-20" > ããã </ div > < div class = "mt-4" > w-20 text-center </ div > < div class = "text-white bg-blue-500 w-20 text-center" > ããã </ div > < div class = "mt-4" > w-20 text-center py-2 </ div > < div class = "text-white bg-blue-500 w-20 text-center py-2" > ããã </ div > < div class = "mt-4" > w-20 text-center py-2 rounded-xl </ div > < div class = "text-white bg-blue-500 w-20 text-center py-2 rounded-xl" > ããã </ div > < div class = "mt-4" > w-20 text-center py-2 bg-opacity-80 </ div > < div class = "text-white bg-blue-500 w-20 text-center py-2 bg-opacity-80" > ããã </ div > < div class = "mt-4" > w-20 text-center py-2 font-bold </ div > < div class = "text-white bg-blue-500 w-20 text-center py-2 font-bold" > ããã </ div > < div class = "mt-4" > w-20 text-center py-2 border-8 border-red-500 </ div > < div class = "w-20 text-center py-2 border-8 border-red-500" > ããã </ div > </ body > </ html > å·ŠåŽã16px空ããŠããŸãã ããã¯ãbodyã¿ã°ã®classã«æå®ããpl-4ã®å¹æã§ããpl-4ãšã¯ãpadding left 16pxã®ããšã§ãã1ã4pxã«ãªããŸãã < body class = "pl-4" > äžã®ã¿ã°ãšè·é¢ãéããã«ã¯ãmt-xxã䜿ããŸããmtã¯margin topã®ç¥ã§ãã < div class = "mt-4" > w-12 </ div > èæ¯è²ãæå®ããã«ã¯ãbg-è²-æ¿ãã§æå®ããŸããæ¿ãã¯500ãçãäžã®å€ã§ãæ¿ããªããšæ°å€ã倧ãããªããŸãã900ãæã倧ããå€ã§ãã å¹
ãæå®ããã«ã¯ãw-æ°å€ã§æå®ããŸããæ°å€ã¯å
çšãšåæ§1ã4pxã«ãªããŸããTailwind CSS ã§ã¯ãæ°å€ã®4ã16px = 1 rem = 1æååã®å¹
ã«ãªããŸãã < div class = "text-white bg-blue-500 w-4" > ããã </ div > ã¡ããã©ã1æåã®å¹
ã§æ¹è¡ãããŠããŸããã æ¬¡ã¯ãw-12 = 3 remã«ããŠã¿ãŸãããã < div class = "text-white bg-blue-500 w-12" > ããã </ div > ã¡ããã©æåå¹
ãšåãã«ãªã£ãŠããŸãã w-20ã«ãããšã©ããªãã§ããããã < div class = "text-white bg-blue-500 w-20" > ããã </ div > å·Šå¯ãã«ãªããŸããã äžå€®å¯ãã«ããŠã¿ãŸããããtext-centerã䜿ããŸãã < div class = "text-white bg-blue-500 w-20 text-center" > ããã </ div > æåã®äžäžã«ã¹ããŒã¹ãå
¥ããŠã¿ãŸããããpyïŒpadding yæ¹åïŒã䜿ããŸãã < div class = "text-white bg-blue-500 w-20 text-center py-2" > ããã </ div > è§äžžã«ããŠã¿ãŸããããroundedã䜿ããŸãã < div class = "text-white bg-blue-500 w-20 text-center py-2 rounded-xl" > ããã </ div > roundedã§ã©ã®ãããªå€ã䜿ãããã¯ãroundedãšå
¥åããè£å®ã§ç¢ºãããŸãããã èæ¯ã®äžéæåºŠãèšå®ããŸããããbg-opacity-xxã䜿ããŸããxxã¯0ãã100ãŸã§ã®æ°åãå
¥ããŸããæ°åã倧ããã»ã©äžéæåºŠã¯é«ãã100ã®å Žåã¯éæåºŠãªãïŒäœãæå®ããªãã®ãšäžç·ïŒã§ããxxã§ãã©ã®å€ã䜿ãããã¯è£å®ã§ç¢ºãããŸãããã < div class = "text-white bg-blue-500 w-20 text-center py-2 bg-opacity-80" > ããã </ div > ãã©ã³ãã倪ãããŠã¿ãŸããããfont-boldã䜿ããŸãã < div class = "text-white bg-blue-500 w-20 text-center py-2 font-bold" > ããã </ div > æ ç·ãèšå®ããŸããããborder-倪ããšborder-è²-æ¿ãã§æå®ããŸãã < div class = "w-20 text-center py-2 border-8 border-red-500" > ããã </ div > ããã§ã¯ãå¹
ïŒwidthïŒã4ã®åæ°ä»¥å€ã®23pxã«ãããå Žåã¯ã©ãããã®ã§ãããããw-[23px]ã®ããã«[]ã®äžã«ãµã€ãºãæå®ããŸãããã ãã CDN çã§ã¯ã§ããŸãããnpmã§tailwindcssãã€ã³ã¹ããŒã«ããå¿
èŠããããŸãã詳ããã¯äžèšãã芧ãã ããã Installation: Tailwind CLI using-arbitrary-values responsive_design.html Tailwind CSS ã䜿ããšç°¡åã«ã¬ã¹ãã³ã·ããã¶ã€ã³ã«ã§ããŸããresponsive_design.htmlã Chrome ã§éããŠãã ããã <!DOCTYPE html> < html lang = "ja" > < head > < meta charset = "UTF-8" /> < meta http-equiv = "X-UA-Compatible" content = "IE=edge" /> < meta name = "viewport" content = "width=device-width, initial-scale=1.0" /> < title > Responsive Design </ title > < link href = "https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel = "stylesheet" /> </ head > < body class = "pl-4 pt-4" > < div class = "bg-blue-500 w-16 md:w-32 lg:w-48 xl:w-60 h-8" ></ div > < div class = "mt-4 md:flex" > < div class = "w-72 h-8 bg-indigo-500" ></ div > < div class = "mt-1 md:mt-0 md:ml-1 w-72 h-8 bg-pink-500" ></ div > </ div > </ body > </ html > Chrome ã®Windowã®å¹
ãã§ããã ãå°ããããŠãã ãããæ¬¡ã®ãããªéãåè§ã衚瀺ãããŸãããã å°ãã¥ã€Windowã®å¹
ã倧ããããŠãã ããã768px以äžã§åè§ã®å¹
ã16pxå¢ããŸããããåæ§ã«ã1024pxã1280px以äžã§åè§ã®å¹
ãå¢ããã¯ãã§ãã ã¿ã°ã®å®çŸ©ãèŠãŠã¿ãŸãããã < div class = "bg-blue-500 w-16 md:w-32 lg:w-48 xl:w-60 h-8" ></ div > w-xxã® ãã¬ãã£ãã¯ã¹ ãšããŠmd:, lg:, xl:ãæå®ãããŠããŸãããããè§£éãããšæ¬¡ã®ããã«ãªããŸãã 768pxæªæºã¯ãw-16ã md: 768px以äž1024pxæªæºã¯ãw-32ã lg: 1024px以äž1280pxæªæºã¯ãw-48ã xl: 1280px以äžã¯ãw-60ã ã¬ã¹ãã³ã·ããã¶ã€ã³ã§ããããã®ã ã¹ãã ã§ã¯ã¹ããŒã¹ããªãã®ã§çžŠã«è¡šç€ºãã ã¿ãã¬ãã 以äžã®ã¹ããŒã¹ãããå Žåã¯ã暪ã«è¡šç€ºããããæ¹ã§ãã ãŸãã ã¹ãã ã§çžŠã«è¡šç€ºããã«ã¯ãæ®éã«divã䜿ããŸãã < div > < div > ã³ã³ãã³ã1 </ div > < div > ã³ã³ãã³ã2 </ div > </ div > å¹
ã768px以äžã®ãšãã«ã暪ã«è¡šç€ºããã«ã¯ãmd: flex ã䜿ããŸãã < div class = "md:flex" > < div > ã³ã³ãã³ã1 </ div > < div > ã³ã³ãã³ã2 </ div > </ div > ã€ãŸããmd: flex ã䜿ãã°ã ã¹ãã ã§ã¯çžŠã«è¡šç€ºããå¹
768px以äžãªã暪ã«è¡šç€ºãããšããããšãç°¡åã«ã§ããŸãã < div class = "mt-4 md:flex" > < div class = "w-72 h-8 bg-indigo-500" ></ div > < div class = "mt-1 md:mt-0 md:ml-1 w-72 h-8 bg-pink-500" ></ div > </ div > å¹
ã768pxæªæºã å¹
ã768pxä»¥äž mt-1 md:mt-0 md:ml-1ã説æããŠãããŸããããå¹
ã768pxæªæºã®ãšãã¯ã瞊ã«äžŠã¶ã®ã§ãmt-1ïŒmargin top 4pxïŒã§äžã®èŠçŽ ãš4pxãããŸãã å¹
ã768px以äžã®ãšãã¯ã暪ã«äžŠã¶ã®ã§ãmd:mt-0ïŒmargin top 0pxïŒã§äžã®èŠçŽ ãšã®ã¹ããŒã¹ã0pxã«ããmd:ml-1ã§å·Šã®èŠçŽ ãšã®ã¹ããŒã¹ã4pxãããŸãã ãŸãšã Tailwind CSS ãããã ã£ãã§ãããããHTMLãã¿ãã°ãclass屿§ã«å¿
èŠãªæ
å ±ããããããã©ããããã¶ã€ã³ã«ãªãã®ãäºæ³ã§ããŸããããã«ããããªãèŠéããè¯ããªããŸãã ã¹ãã¬ã¹ããªãŒãª CSS ã©ã€ãããéãããã ããã å·çïŒ @higa ïŒ Shodo ã§å·çãããŸãã ïŒ
ããã«ã¡ã¯ãXIæ¬éšã AIãã©ã³ã¹ãã©ãŒã¡ãŒã·ã§ã³ã»ã³ã¿ãŒ ã®åŸ³å å
ã§ãã æ¥ããã®æ¥åã§ã¯ãã客æ§ããé ãã£ãããŒã¿ã®åæããAIã·ã¹ãã ã®éçºãæ
åœããŠããŸãã å®éã«ãã£ãŠããããšã¯ãããŒã¿çè§£ã®ããã« EDA ïŒæ¢çŽ¢çããŒã¿åæïŒã宿œããããåæãAIã¢ãã«éçºãè¡ãããã«ããŒã¿ã®ã¯ãªãŒãã³ã°ãè¡ã£ãããããããããŒã¿ãµã€ãšã³ã¹ã®ã©ããããéšåãã»ãšãã©ã«ãªããŸãã ãããã®äœæ¥ã¯åºæ¬çã«jupyter notebookäžã§è¡ã£ãŠããŸããjupyter notebookã¯AIãããŒã¿ãµã€ãšã³ã¹ã«é¢ãã£ãŠããæ¹ãªã誰ããè§Šã£ãããšã®ããã¡ãžã£ãŒãªããŒã«ã§ãããã£ãšããã®èšäºãèªãã§ãã ãã£ãŠããå€ãã®æ¹ãæ¥åžžçã«å©çšããŠããã®ã§ã¯ãªãã§ããããã jupyter notebookã¯ããããªããšä»äºã«ãªããªãããã匷åãªãã®ã§ããæ¬ ç¹ããã£ãŠãè€æ°äººã§åãnotebookãå
±æããŠäœæ¥ãé²ããŠããã«ã¯äžåã ã£ããããŸãã ãšããããšã§ããããªjupyter notebookãGitãçšããŠç®¡çããããšã§ãè€æ°äººã§åæã«åæãããžã§ã¯ããé²ããããšãå¯èœã«ãã䟿å©ãªããŒã«Jupytextã玹ä»ããããšæããŸãã ãªãJupytextãªã®ãïŒ Jupytextã®äœ¿ãæ¹ ã€ã³ã¹ããŒã«ã®ä»æ¹ Jupytextã®èšå® ãã¡ã€ã«ã®ä¿åæ¹æ³ pyãã¡ã€ã«ããnotebookã埩å
ãã Jupytextã䜿ã£ãŠã¿ãŠ ãã¡ãªããã¯å¯Ÿå¿ããŠããç°å¢ãéãããŠããããš ãªãJupytextãªã®ãïŒ çµéšã®ããæ¹ãããã£ããããšæããŸãããjupyter notebookãåºåããipynbãã¡ã€ã«ãGitã§ç®¡çããããšãããšã³ã³ããªã¯ããé »ç¹ã«èµ·ãããŸãã ipynbãã¡ã€ã«ã®äžèº«ã¯ json ã«ãªã£ãŠããŠãã³ãŒã以å€ã« ã¡ã¿ããŒã¿ ãå®è¡çµæãå«ãŸããŸãããããã®ããŒã¿ãå®è¡ãããåºŠã«æžãæããã®ã§ãåŠçå
容ãäžç·ã ãšããŠãè€æ°ç®æã§ç°ãªãéšåãçããŠããŸããŸãã ãŸããã³ã³ããªã¯ãã解決ããããšããŠãã json ãã¡ã€ã«ã®å·®ç°ãæ¯èŒããã®ã¯äžå¯èœãªã®ã§äººåã§ã¯ç¡çã§ãã Jupytextã䜿çšãããšãnotebookãä¿åãã床ã«ipynbãã¡ã€ã«ããã³ãŒãéšåãæœåºããpyãã¡ã€ã«ãèªåã§äœæããŠãããŸãããããŠäœæãããpyãã¡ã€ã«ã®ã¿ãGitäžã§ç®¡çããã°ç«¶åã®çºçãé²ãããšããããã§ãã ãã¡ãããããŒã«ã«ã«ã¯ipynbãã¡ã€ã«ãæ®ãããã®ã§ãå®è¡çµæã ã¡ã¿ããŒã¿ ã¯ããŒã«ã«ã«ãã£ãããšæ®ããŸãã ãã¡ã€ã«ã®åŸ©å
ãç°¡åã§pullããŠããpyãã¡ã€ã«ãJupyter Notebookã§èªã¿èŸŒãã°ãèªåã§ipynbãã¡ã€ã«ã«åŸ©å
ã§ããŸãã â»jupyterã VS code ã§å©çšããŠããå ŽåãJupytextã¯äœ¿çšã§ããŸããã VS code ã§Jupytextãé©çšããŠããnotebooã®ipynbãã¡ã€ã«ãéããŠããŸããšipynbãã¡ã€ã«ãç ŽæããŸãããŸããjupytextãé©çšãããŠããªãJupyter Notebookã§éããŠãipynbãã¡ã€ã«ãç Žæããã®ã§æ°ãã€ããŠãã ããã â»ãã®èšäºã§ã¯ãé æåã倧æåã®Jupyter Notebookã¯Jupyter ProjectçŽæ£ã®å®è¡ç°å¢ãæããŠããŸããJupytextã¯Jupyter Notebook以å€ã«Jupyter Labã§ã䜿çšã§ããããã§ãããæåã¯ç¢ºèªããŠããªãã§ãã Jupytextã®äœ¿ãæ¹ ã€ã³ã¹ããŒã«ã®ä»æ¹ ãŸãã¯å°å
¥ã®ä»æ¹ããã å
¬åŒã®ããã¥ã¡ã³ã ã«æžããŠããããã«Jupytextã®å°å
¥ã¯pipãããã¯condaãçšããŠè¡ããŸãã ãããžã§ã¯ãããšã«Jupytextã®äœ¿çšã®æç¡ãåãæ¿ãããå Žåã¯ãcondaãpyenvã䜿ã£ãŠä»®æ³ç°å¢ã«å°å
¥ããããšãããããããŸãã pip install jupytext --upgrade ãŸã㯠conda install jupytext -c conda-forge ããã ãã§ãã æ£åžžã«ã€ã³ã¹ããŒã«ã§ããŠããã°ã次åã®Jupyter Notebookã®èµ·åæã«ã [I 10:28:31.646 LabApp] [Jupytext Server Extension] Changing NotebookApp.contents_manager_class from LargeFileManager to jupytext.TextFileContentsManager ãšè¡šç€ºãããŸãã Jupytextã®èšå® ãããŸã§ã§ããã§ã«Jupytextã䜿çšããæºåã¯æŽã£ãŠããŸãããåŸã
ã®ããšãèããŠJupytextã®èšå®ãããŠãããŸãããã Jupytextã®èšå®æ¹æ³ã¯è€æ°ååšããŸããããããžã§ã¯ãçŽäžã®ãã©ã«ãïŒJupyter Notebookãç«ã¡äžãããã©ã«ãïŒã«jupytext.ymlãšãã yaml ãã¡ã€ã«ãäœæããŠããã®ãç°¡åãªæ¹æ³ã¿ããã§ã ãšããããã以äžãèšå®ãã¡ã€ã«ã«è¿œå ããŠãä¿åæã«ããã©ã«ãã§äœæããããã¡ã€ã«ã®ãã©ãŒããããæå®ããŸãããã default_jupytext_formats: "ipynb,py:percent" ipynb ã¯ipynbãã¡ã€ã«ã®ããšã§ãã py:percent ãæå®ãããšãããŒã»ã³ãèšå·2〠%% ã§ã»ã«éãåãã衚èšã§ã³ãŒããæœåºããpyãã¡ã€ã«ãäœæã§ããŸããããããŠããããšã§ããã®è¡šèšã§ä¿åããŠããã°ãã VS code ã§éããŠãã»ã«ããšã«åå²ããã圢ã§è¡šç€ºãå®è¡ã§ããŸãã ãã®ä»ã«ãéžæã§ãããã©ãŒããããè€æ°ååšããŸãããã¡ãã® å
¬åŒããã¥ã¡ã³ã ã«éžæã§ãããã©ãŒãããã®è©³çްãèŒã£ãŠããŸãã ä¿åãã¡ã€ã«ã®ãã©ãŒãããã2ã€ä»¥äžéžæããããšãå¯èœã§ãã èšå®ã¯Jupyter Notebookãåèµ·åããã°ããã®åŸäœæãããã¹ãŠã®notebookã«å¯ŸããŠãã®èšå®ãé©å¿ãããŸãããã§ã«äœææžã¿ã®notebookã«å¯ŸããŠã¯æåã§èšå®ããå¿
èŠãããã®ã§ã ããŒã«ã㌠ãããã¡ã€ã«âJupyterãéžæãã衚瀺ãããã¡ãã¥ãŒããä¿åãã¡ã€ã«ã®ãã©ãŒããããéžæããŠãã ããã ãã¡ã€ã«ã®ä¿åæ¹æ³ éåžžéãnotebookãä¿åããã°æå®ããã圢åŒã§ãã¡ã€ã«ãä¿åãããŸããç¹ã«ãªã«ãããå¿
èŠã¯ãªãã§ãã ipynb圢åŒä»¥å€ã«ã³ãŒãéšåãæœåºãããã¡ã€ã«ãä¿åãããããgitignoreãèšå®ããŠã³ãŒãéšåãæœåºãããã¡ã€ã«ã®ã¿ã管çãããããã«èšå®ããŸããããããããšã§ãGitã§jupyter notebookãå®å
šã«ç®¡çã§ããŸãã ã¡ãªã¿ã«ãnotebooksãšãããã©ã«ãäžã§jupyter notebookã管çããŠããå Žåãgitignoreãã¡ã€ã«ã以äžã®ããã«ç·šéãããšãipynb圢åŒã®ãã¡ã€ã«ãGitã®ç®¡ç察象ããå€ããŸãã /notebooks/*.ipynb pyãã¡ã€ã«ããnotebookã埩å
ãã ãã¡ããç¹ã«äœãããå¿
èŠæ§ã¯ãããŸãããJupytextãå°å
¥ãããJupyter Notebookã§ã³ãŒãéšåãæœåºãããpyãã¡ã€ã«ãéãã°ãnotebookã埩å
ã§ããŸãã Jupytextã䜿ã£ãŠã¿ãŠ äœ¿ãå§ããŠãŸã æ¥ãæµ
ãã§ããéåžžã«ããæãã«äœ¿ããŠããŸãã jupyter notebookã®çšéçã«ãè€æ°ã®äººã1ã€ã®notebookãåæ
ããŠç·šéãããšããäœ¿ãæ¹ã¯ããŸããªããšæããŸãããããå¥ã
ã®äººã1ã€ã®notebookãç·šéããŠããŸã£ãŠãç°¡åã«diffãåãããšãã§ããã®ã§ãgitã§ã®ããŒãžã§ã³ç®¡çã¯æ Œæ®µã«ããããããªããŸããã ããã«ãäžçªæ©æµãåããããã®ãç¹ã«ã³ãŒãã«å€æŽãå ããŠããªããã©notebookãå®è¡ããå Žåã§ããã³ãŒãã«å€æŽããªããªã倿Žãç Žæ£ããŠããŸãã°ããã§ãããJupytextã䜿ã£ãŠããã°ããããã³ã³ããªã¯ãããçããªãã®ã§ipynbãã¡ã€ã«ã®å·®ç°ãæèããå¿
èŠæ§ããªããªããŸãã ãã¡ãªããã¯å¯Ÿå¿ããŠããç°å¢ãéãããŠããããš Jupyter Notebook以å€ã«ãjupyter notebookãå®è¡ã§ããç°å¢ã¯å¢ããŠããŠããŸããããèªåã®åšãã§ã¯ VS code ã«jupyterçšã® æ¡åŒµæ©èœ ãå
¥ããŠå©çšããŠãã人ãå€ããæè¿ã¯ç§ã VS code ã§å®è¡ããããšãå¢ããŠããŠããŸãã ãã ãåé ã§ãäŒãããããã«Jupytext㯠VS code ã«ã¯å¯Ÿå¿ããŠãããããããžã§ã¯ãã«Jupytextãå°å
¥ããã«ã¯ã¡ã³ããŒå
šå¡ã«Jupyter NotebookãŸãã¯ãJupyter Labã䜿ã£ãŠãããå¿
èŠããããŸãã çŸç¶ãJupyter Notebookããã VS code ã®ã»ãã髿©èœãªã®ã§ãããã¯æ®å¿µãªãšããã§ããã»ã»ã»ã jupyter notebookãGitã§ç®¡çããããããŠãããããŒã«Jupytextã®ç޹ä»ã§ããããã¡ãªããããããŸããjupyter notebookãGitäžã§ç®¡çããŠãã人ã«ã¯mustãªããŒã«ã ãšæããŸãã ãã®èšäºãèªãã§èå³ãæ¹§ããæ¹ã¯è©Šãã«äœ¿ã£ãŠã¿ãŠãã ããã æåŸã«ãç§ãæå±ããŠãã AIãã©ã³ã¹ãã©ãŒã¡ãŒã·ã§ã³ã»ã³ã¿ãŒã®webãµã€ã ã§ã¯ãæ¯æ2ã3èšäºã®ããŒã¹ã§ã³ã©ã ãå
¬éããŠããŸãã Kaggle Masterã«ããKaggleã³ã³ãã®ã¯ããæ¹è§£èª¬ãææ°ã®è«æã«åºã¥ããAIã¢ãã«æ§ç¯ææ³ã®ææ¡ãããã«AIãœãããŠã§ã¢éçºã®ãªã¢ã«ãªçŸç¶ãªã©ãããŒã¿ãµã€ãšã³ã¹ãAIã«ãŸã€ããæ§ã
ãªæ
å ±ãçºä¿¡ããŠããŸãã®ã§ãã²é²èЧãã ããã ããã§ã¯ã å·çïŒ @tokuhara.hikaru ãã¬ãã¥ãŒïŒ @higa ïŒ Shodo ã§å·çãããŸãã ïŒ
ããã«ã¡ã¯ãXIæ¬éšã AIãã©ã³ã¹ãã©ãŒã¡ãŒã·ã§ã³ã»ã³ã¿ãŒ ã®åŸ³å å
ã§ãã æ¥ããã®æ¥åã§ã¯ãã客æ§ããé ãã£ãããŒã¿ã®åæããAIã·ã¹ãã ã®éçºãæ
åœããŠããŸãã å®éã«ãã£ãŠããããšã¯ãããŒã¿çè§£ã®ããã« EDA ïŒæ¢çŽ¢çããŒã¿åæïŒã宿œããããåæãAIã¢ãã«éçºãè¡ãããã«ããŒã¿ã®ã¯ãªãŒãã³ã°ãè¡ã£ãããããããããŒã¿ãµã€ãšã³ã¹ã®ã©ããããéšåãã»ãšãã©ã«ãªããŸãã ãããã®äœæ¥ã¯åºæ¬çã«jupyter notebookäžã§è¡ã£ãŠããŸããjupyter notebookã¯AIãããŒã¿ãµã€ãšã³ã¹ã«é¢ãã£ãŠããæ¹ãªã誰ããè§Šã£ãããšã®ããã¡ãžã£ãŒãªããŒã«ã§ãããã£ãšããã®èšäºãèªãã§ãã ãã£ãŠããå€ãã®æ¹ãæ¥åžžçã«å©çšããŠããã®ã§ã¯ãªãã§ããããã jupyter notebookã¯ããããªããšä»äºã«ãªããªãããã匷åãªãã®ã§ããæ¬ ç¹ããã£ãŠãè€æ°äººã§åãnotebookãå
±æããŠäœæ¥ãé²ããŠããã«ã¯äžåã ã£ããããŸãã ãšããããšã§ããããªjupyter notebookãGitãçšããŠç®¡çããããšã§ãè€æ°äººã§åæã«åæãããžã§ã¯ããé²ããããšãå¯èœã«ãã䟿å©ãªããŒã«Jupytextã玹ä»ããããšæããŸãã ãªãJupytextãªã®ãïŒ Jupytextã®äœ¿ãæ¹ ã€ã³ã¹ããŒã«ã®ä»æ¹ Jupytextã®èšå® ãã¡ã€ã«ã®ä¿åæ¹æ³ pyãã¡ã€ã«ããnotebookã埩å
ãã Jupytextã䜿ã£ãŠã¿ãŠ ãã¡ãªããã¯å¯Ÿå¿ããŠããç°å¢ãéãããŠããããš ãªãJupytextãªã®ãïŒ çµéšã®ããæ¹ãããã£ããããšæããŸãããjupyter notebookãåºåããipynbãã¡ã€ã«ãGitã§ç®¡çããããšãããšã³ã³ããªã¯ããé »ç¹ã«èµ·ãããŸãã ipynbãã¡ã€ã«ã®äžèº«ã¯ json ã«ãªã£ãŠããŠãã³ãŒã以å€ã« ã¡ã¿ããŒã¿ ãå®è¡çµæãå«ãŸããŸãããããã®ããŒã¿ãå®è¡ãããåºŠã«æžãæããã®ã§ãåŠçå
容ãäžç·ã ãšããŠãè€æ°ç®æã§ç°ãªãéšåãçããŠããŸããŸãã ãŸããã³ã³ããªã¯ãã解決ããããšããŠãã json ãã¡ã€ã«ã®å·®ç°ãæ¯èŒããã®ã¯äžå¯èœãªã®ã§äººåã§ã¯ç¡çã§ãã Jupytextã䜿çšãããšãnotebookãä¿åãã床ã«ipynbãã¡ã€ã«ããã³ãŒãéšåãæœåºããpyãã¡ã€ã«ãèªåã§äœæããŠãããŸãããããŠäœæãããpyãã¡ã€ã«ã®ã¿ãGitäžã§ç®¡çããã°ç«¶åã®çºçãé²ãããšããããã§ãã ãã¡ãããããŒã«ã«ã«ã¯ipynbãã¡ã€ã«ãæ®ãããã®ã§ãå®è¡çµæã ã¡ã¿ããŒã¿ ã¯ããŒã«ã«ã«ãã£ãããšæ®ããŸãã ãã¡ã€ã«ã®åŸ©å
ãç°¡åã§pullããŠããpyãã¡ã€ã«ãJupyter Notebookã§èªã¿èŸŒãã°ãèªåã§ipynbãã¡ã€ã«ã«åŸ©å
ã§ããŸãã â»jupyterã VS code ã§å©çšããŠããå ŽåãJupytextã¯äœ¿çšã§ããŸããã VS code ã§Jupytextãé©çšããŠããnotebooã®ipynbãã¡ã€ã«ãéããŠããŸããšipynbãã¡ã€ã«ãç ŽæããŸãããŸããjupytextãé©çšãããŠããªãJupyter Notebookã§éããŠãipynbãã¡ã€ã«ãç Žæããã®ã§æ°ãã€ããŠãã ããã â»ãã®èšäºã§ã¯ãé æåã倧æåã®Jupyter Notebookã¯Jupyter ProjectçŽæ£ã®å®è¡ç°å¢ãæããŠããŸããJupytextã¯Jupyter Notebook以å€ã«Jupyter Labã§ã䜿çšã§ããããã§ãããæåã¯ç¢ºèªããŠããªãã§ãã Jupytextã®äœ¿ãæ¹ ã€ã³ã¹ããŒã«ã®ä»æ¹ ãŸãã¯å°å
¥ã®ä»æ¹ããã å
¬åŒã®ããã¥ã¡ã³ã ã«æžããŠããããã«Jupytextã®å°å
¥ã¯pipãããã¯condaãçšããŠè¡ããŸãã ãããžã§ã¯ãããšã«Jupytextã®äœ¿çšã®æç¡ãåãæ¿ãããå Žåã¯ãcondaãpyenvã䜿ã£ãŠä»®æ³ç°å¢ã«å°å
¥ããããšãããããããŸãã pip install jupytext --upgrade ãŸã㯠conda install jupytext -c conda-forge ããã ãã§ãã æ£åžžã«ã€ã³ã¹ããŒã«ã§ããŠããã°ã次åã®Jupyter Notebookã®èµ·åæã«ã [I 10:28:31.646 LabApp] [Jupytext Server Extension] Changing NotebookApp.contents_manager_class from LargeFileManager to jupytext.TextFileContentsManager ãšè¡šç€ºãããŸãã Jupytextã®èšå® ãããŸã§ã§ããã§ã«Jupytextã䜿çšããæºåã¯æŽã£ãŠããŸãããåŸã
ã®ããšãèããŠJupytextã®èšå®ãããŠãããŸãããã Jupytextã®èšå®æ¹æ³ã¯è€æ°ååšããŸããããããžã§ã¯ãçŽäžã®ãã©ã«ãïŒJupyter Notebookãç«ã¡äžãããã©ã«ãïŒã«jupytext.ymlãšãã yaml ãã¡ã€ã«ãäœæããŠããã®ãç°¡åãªæ¹æ³ã¿ããã§ã ãšããããã以äžãèšå®ãã¡ã€ã«ã«è¿œå ããŠãä¿åæã«ããã©ã«ãã§äœæããããã¡ã€ã«ã®ãã©ãŒããããæå®ããŸãããã default_jupytext_formats: "ipynb,py:percent" ipynb ã¯ipynbãã¡ã€ã«ã®ããšã§ãã py:percent ãæå®ãããšãããŒã»ã³ãèšå·2〠%% ã§ã»ã«éãåãã衚èšã§ã³ãŒããæœåºããpyãã¡ã€ã«ãäœæã§ããŸããããããŠããããšã§ããã®è¡šèšã§ä¿åããŠããã°ãã VS code ã§éããŠãã»ã«ããšã«åå²ããã圢ã§è¡šç€ºãå®è¡ã§ããŸãã ãã®ä»ã«ãéžæã§ãããã©ãŒããããè€æ°ååšããŸãããã¡ãã® å
¬åŒããã¥ã¡ã³ã ã«éžæã§ãããã©ãŒãããã®è©³çްãèŒã£ãŠããŸãã ä¿åãã¡ã€ã«ã®ãã©ãŒãããã2ã€ä»¥äžéžæããããšãå¯èœã§ãã èšå®ã¯Jupyter Notebookãåèµ·åããã°ããã®åŸäœæãããã¹ãŠã®notebookã«å¯ŸããŠãã®èšå®ãé©å¿ãããŸãããã§ã«äœææžã¿ã®notebookã«å¯ŸããŠã¯æåã§èšå®ããå¿
èŠãããã®ã§ã ããŒã«ã㌠ãããã¡ã€ã«âJupyterãéžæãã衚瀺ãããã¡ãã¥ãŒããä¿åãã¡ã€ã«ã®ãã©ãŒããããéžæããŠãã ããã ãã¡ã€ã«ã®ä¿åæ¹æ³ éåžžéãnotebookãä¿åããã°æå®ããã圢åŒã§ãã¡ã€ã«ãä¿åãããŸããç¹ã«ãªã«ãããå¿
èŠã¯ãªãã§ãã ipynb圢åŒä»¥å€ã«ã³ãŒãéšåãæœåºãããã¡ã€ã«ãä¿åãããããgitignoreãèšå®ããŠã³ãŒãéšåãæœåºãããã¡ã€ã«ã®ã¿ã管çãããããã«èšå®ããŸããããããããšã§ãGitã§jupyter notebookãå®å
šã«ç®¡çã§ããŸãã ã¡ãªã¿ã«ãnotebooksãšãããã©ã«ãäžã§jupyter notebookã管çããŠããå Žåãgitignoreãã¡ã€ã«ã以äžã®ããã«ç·šéãããšãipynb圢åŒã®ãã¡ã€ã«ãGitã®ç®¡ç察象ããå€ããŸãã /notebooks/*.ipynb pyãã¡ã€ã«ããnotebookã埩å
ãã ãã¡ããç¹ã«äœãããå¿
èŠæ§ã¯ãããŸãããJupytextãå°å
¥ãããJupyter Notebookã§ã³ãŒãéšåãæœåºãããpyãã¡ã€ã«ãéãã°ãnotebookã埩å
ã§ããŸãã Jupytextã䜿ã£ãŠã¿ãŠ äœ¿ãå§ããŠãŸã æ¥ãæµ
ãã§ããéåžžã«ããæãã«äœ¿ããŠããŸãã jupyter notebookã®çšéçã«ãè€æ°ã®äººã1ã€ã®notebookãåæ
ããŠç·šéãããšããäœ¿ãæ¹ã¯ããŸããªããšæããŸãããããå¥ã
ã®äººã1ã€ã®notebookãç·šéããŠããŸã£ãŠãç°¡åã«diffãåãããšãã§ããã®ã§ãgitã§ã®ããŒãžã§ã³ç®¡çã¯æ Œæ®µã«ããããããªããŸããã ããã«ãäžçªæ©æµãåããããã®ãç¹ã«ã³ãŒãã«å€æŽãå ããŠããªããã©notebookãå®è¡ããå Žåã§ããã³ãŒãã«å€æŽããªããªã倿Žãç Žæ£ããŠããŸãã°ããã§ãããJupytextã䜿ã£ãŠããã°ããããã³ã³ããªã¯ãããçããªãã®ã§ipynbãã¡ã€ã«ã®å·®ç°ãæèããå¿
èŠæ§ããªããªããŸãã ãã¡ãªããã¯å¯Ÿå¿ããŠããç°å¢ãéãããŠããããš Jupyter Notebook以å€ã«ãjupyter notebookãå®è¡ã§ããç°å¢ã¯å¢ããŠããŠããŸããããèªåã®åšãã§ã¯ VS code ã«jupyterçšã® æ¡åŒµæ©èœ ãå
¥ããŠå©çšããŠãã人ãå€ããæè¿ã¯ç§ã VS code ã§å®è¡ããããšãå¢ããŠããŠããŸãã ãã ãåé ã§ãäŒãããããã«Jupytext㯠VS code ã«ã¯å¯Ÿå¿ããŠãããããããžã§ã¯ãã«Jupytextãå°å
¥ããã«ã¯ã¡ã³ããŒå
šå¡ã«Jupyter NotebookãŸãã¯ãJupyter Labã䜿ã£ãŠãããå¿
èŠããããŸãã çŸç¶ãJupyter Notebookããã VS code ã®ã»ãã髿©èœãªã®ã§ãããã¯æ®å¿µãªãšããã§ããã»ã»ã»ã jupyter notebookãGitã§ç®¡çããããããŠãããããŒã«Jupytextã®ç޹ä»ã§ããããã¡ãªããããããŸããjupyter notebookãGitäžã§ç®¡çããŠãã人ã«ã¯mustãªããŒã«ã ãšæããŸãã ãã®èšäºãèªãã§èå³ãæ¹§ããæ¹ã¯è©Šãã«äœ¿ã£ãŠã¿ãŠãã ããã æåŸã«ãç§ãæå±ããŠãã AIãã©ã³ã¹ãã©ãŒã¡ãŒã·ã§ã³ã»ã³ã¿ãŒã®webãµã€ã ã§ã¯ãæ¯æ2ã3èšäºã®ããŒã¹ã§ã³ã©ã ãå
¬éããŠããŸãã Kaggle Masterã«ããKaggleã³ã³ãã®ã¯ããæ¹è§£èª¬ãææ°ã®è«æã«åºã¥ããAIã¢ãã«æ§ç¯ææ³ã®ææ¡ãããã«AIãœãããŠã§ã¢éçºã®ãªã¢ã«ãªçŸç¶ãªã©ãããŒã¿ãµã€ãšã³ã¹ãAIã«ãŸã€ããæ§ã
ãªæ
å ±ãçºä¿¡ããŠããŸãã®ã§ãã²é²èЧãã ããã ããã§ã¯ã å·çïŒ @tokuhara.hikaru ãã¬ãã¥ãŒïŒ @higa ïŒ Shodo ã§å·çãããŸãã ïŒ
é»éåœéæ
å ±ãµãŒãã¹ ãã¯ãã¹ ã€ãããŒã·ã§ã³ æ¬éšããªãŒãã³ ã€ãããŒã·ã§ã³ ã©ãã®æ¯åã§ãã ããã§ã¯ãä»é±ã ãããã¯ãã§ãŒã³ é±å ±3/23ãã£ãŠã¿ãããã NFTããã« NFTããã«ã®ãã¥ãŒã¹ NFTã®çºè¡ãæŽ»çº NFTã®çºè¡ã掻çºã®ãã¥ãŒã¹ NFTã®åãæ±ããç°¡åã«ããããšãããœãªã¥ãŒã·ã§ã³ãåºãŠãã NFTã®åãæ±ããç°¡åã«ããããšãããœãªã¥ãŒã·ã§ã³ãåºãŠããã®ãã¥ãŒã¹ ãããã¯ãã§ãŒã³ã²ãŒã ãæŽ»çº ãããã¯ãã§ãŒã³ã²ãŒã ãæŽ»çºã®ãã¥ãŒã¹ NFTããã« NFTããã«ã®èŠªçãšãèšããYuga LabsãCryptoPunksã® ç¥çè²¡ç£æš© ãååŸããŸãããYuga Labsã¯ãBored Ape Yacht Clubãäœã£ããšããã§ããååŸéé¡ã¯æããã«ãªã£ãŠããŸããããBored ApesãšCryptoPunksãããããŠã4200åå以äžã®äŸ¡å€ããããšèšãããŠããã®ã§ããªãã®éé¡ãåãããšæãããŸãã ããã«ãããBored Apeã®æã¡äž»ã¯Bored Apeã®åçšå©çšæš©ãåŸãããããã«ãªããšæåŸ
ãããŠããŸãã ããã¯ã泚ç®ãã€ã³ãã§ããçŸåšã®Bored Apeã®æã¡äž»ã¯ãé«é¡ïŒæ°ååã®ãã®ãããïŒã§èœæããã«ãããããããåã« ä¿æ ããŠããã ãã§åçšå©çšæš©ã¯ãªãã®ã§ããããã¯ãã©ã®NFTã§ãåãã§ãã ä¿æ è
ã«åçšå©çšæš©ãã€ããŠããNFTã¯ããããŸãã§ãã ç±³ãã¥ãŒãžã·ã£ã³ã®ã¹ ãã£ãŒ ãã»ã¢ãªãæ°ããéå»ã«ãªãªãŒã¹ãã6æã®ã¢ã«ãã ããåŸãããå°çšãããã1åã®NFTããåŸãããåå
¥ã®ã»ããå€ãã£ããšããå ±åããããŸããã 10幎é鳿¥œããã£ãŠããŠããããŸã§6æã®ã¢ã«ãã ããªãªãŒã¹ãããã©ã ããããå
šéšåãããåå
¥ããã å»å¹Žã®ãããäžåã®NFTããããã«ããåå
¥ãäžåã£ããã ã NFTã®ååŒé«ã¯ã2021幎8æãããŒã¯ã«æžå°ãã12æã«å°ãçãè¿ããŸãããNFTã®ããŒã¯ã¯éãããšèšãããããšããããŸãããããã«æ¥ãŠããã«ãªè©±ãåºãŠããã®ã¯èŠæ³šç®ã§ãã æ¬åœã«ããã«ã忥ããŠããã®ãããããšãããäžåºŠããã«ãèµ·ããããšããŠèª°ãã仿ããŠããã®ãã NFTããã«ã®ãã¥ãŒã¹ Yuga LabsãCryptoPunksã®NFTã³ã¬ã¯ã·ã§ã³ã®æš©å©ãã¯ãªãšã€ã¿ãŒLarva LabsããååŸ Bored Apesã®NFTãããžã§ã¯ãã«å
¬åŒã®ãApeCoinãããŒã¯ã³ãã§ãã ãããã£ãŒã«ç»åNFTã¯æå·è³ç£ã¢ãŒããèŠãããŠãã ã¹ãã£ãŒãã»ã¢ãªãæ°ãNFTåå
¥ã鳿¥œåå
¥ãäžåã£ãã NFTã®çºè¡ãæŽ»çº æè¿ãæ¥æ¬ã§ãNFTãçºè¡ããäŸãå¢ããŠããŸããã 2021幎ã®NFTã®çãäžãããèŠãŠãèªåãã¡ãNFTã«åãçµãããšæã£ãäŒæ¥ããã¡ããã©ä»ããçºè¡ããŠããã®ãããããŸããã NFTã®çºè¡ã掻çºã®ãã¥ãŒã¹ æåçºã®ç¥ç€Ÿã§ âããžã¿ã«åŸ¡æ±å°â é
åž ãLAWSON TICKET NFTããçºè¡š--æãå
¥ãã®ããã€ãã³ããã±ãããNFTã« NFTã®åãæ±ããç°¡åã«ããããšãããœãªã¥ãŒã·ã§ã³ãåºãŠãã NFTã売買ããã«ã¯ãçŸç¶ã ãšæå·è³ç£ã®ç¥è/çµéšããããªãã«å¿
èŠã§ããäžè¬ã®äººã«ã¯æ·å±
ãé«ãã®ã§ãã§ããã ãç°¡åã«ããããšãããœãªã¥ãŒã·ã§ã³ãåºå§ããŠããŸããã ä»ã®ãšãããæ±ºå®çãªãœãªã¥ãŒã·ã§ã³ã¯ãããŸããããNFTãæ®åããã«ã¯è§£æ±ºããªããã°ãªããªãåé¡ãªã®ã§ãåŒãç¶ããŠã©ããããå¿
èŠããããŸãã NFTã®åãæ±ããç°¡åã«ããããšãããœãªã¥ãŒã·ã§ã³ãåºãŠããã®ãã¥ãŒã¹ NFTããŒã±ãããã¬ã€ã¹nanakusaããSBINFTããšããŠãªãã¥ãŒã¢ã«ãããŒãããŒã«ã¯ã¹ãããåïŒã PPRPãåœå
åã®NFT賌å
¥ä»£è¡ãµãŒãã¹ãéå§ ãããã¯ãã§ãŒã³ ã²ãŒã ãæŽ»çº ãããã¯ãã§ãŒã³ ã²ãŒã ãç¶ã
ãšåºãŠããŸãããã©ãããPlay to earnãåºæ¬ã³ã³ã»ããã§ããã皌ãããã«éã¶ããšããããšã§ãã²ãŒã å
ã§ã®æŽ»åã«å¿ã㊠ããŒã¯ ã³ããããããã® ããŒã¯ ã³ãçŸéã«å€ããããšãã§ããŸãã ãŸããã²ãŒã å
ã¢ã€ãã ãNFTã«ãªã£ãŠããŠã ããŒã±ãããã¬ã€ã¹ ã§å£²è²·ã§ããããã«ãªã£ãŠããŸãã RMT ãå¯èœã«ãªã£ããšããããšã§ãã ãããã¯ãã§ãŒã³ ã²ãŒã ãæŽ»çºã®ãã¥ãŒã¹ ãããããŒãã«ãç¬èªã®ãããã¯ãã§ãŒã³ãšã³ã·ã¹ãã ãMBXããMARBLEXãŠã©ã¬ãããã®ãµãŒãã¹éå§ HashPortãéãã§çšŒããããã¯ãã§ãŒã³ã²ãŒã ããšã«ããã¹ã¿ãŒãºãã6æäžæ¬ã«é
ä¿¡ãNFTã¯4æãªãªãŒã¹äºå®ã®ããŒã±ãããã¬ã€ã¹ãPLT Placeãã§è²©å£² XLGAMESïŒãããã¯ãã§ãŒã³é©çšã®MMORPGãArcheWorldããçºè¡šã7æã®ã°ããŒãã«ãµãŒãã¹éå§ãç®æã å·çïŒ @higa ïŒ Shodo ã§å·çãããŸãã ïŒ
é»éåœéæ
å ±ãµãŒãã¹ ãã¯ãã¹ ã€ãããŒã·ã§ã³ æ¬éšããªãŒãã³ ã€ãããŒã·ã§ã³ ã©ãã®æ¯åã§ãã ããã§ã¯ãä»é±ã ãããã¯ãã§ãŒã³ é±å ±3/23ãã£ãŠã¿ãããã NFTããã« NFTããã«ã®ãã¥ãŒã¹ NFTã®çºè¡ãæŽ»çº NFTã®çºè¡ã掻çºã®ãã¥ãŒã¹ NFTã®åãæ±ããç°¡åã«ããããšãããœãªã¥ãŒã·ã§ã³ãåºãŠãã NFTã®åãæ±ããç°¡åã«ããããšãããœãªã¥ãŒã·ã§ã³ãåºãŠããã®ãã¥ãŒã¹ ãããã¯ãã§ãŒã³ã²ãŒã ãæŽ»çº ãããã¯ãã§ãŒã³ã²ãŒã ãæŽ»çºã®ãã¥ãŒã¹ NFTããã« NFTããã«ã®èŠªçãšãèšããYuga LabsãCryptoPunksã® ç¥çè²¡ç£æš© ãååŸããŸãããYuga Labsã¯ãBored Ape Yacht Clubãäœã£ããšããã§ããååŸéé¡ã¯æããã«ãªã£ãŠããŸããããBored ApesãšCryptoPunksãããããŠã4200åå以äžã®äŸ¡å€ããããšèšãããŠããã®ã§ããªãã®éé¡ãåãããšæãããŸãã ããã«ãããBored Apeã®æã¡äž»ã¯Bored Apeã®åçšå©çšæš©ãåŸãããããã«ãªããšæåŸ
ãããŠããŸãã ããã¯ã泚ç®ãã€ã³ãã§ããçŸåšã®Bored Apeã®æã¡äž»ã¯ãé«é¡ïŒæ°ååã®ãã®ãããïŒã§èœæããã«ãããããããåã« ä¿æ ããŠããã ãã§åçšå©çšæš©ã¯ãªãã®ã§ããããã¯ãã©ã®NFTã§ãåãã§ãã ä¿æ è
ã«åçšå©çšæš©ãã€ããŠããNFTã¯ããããŸãã§ãã ç±³ãã¥ãŒãžã·ã£ã³ã®ã¹ ãã£ãŒ ãã»ã¢ãªãæ°ããéå»ã«ãªãªãŒã¹ãã6æã®ã¢ã«ãã ããåŸãããå°çšãããã1åã®NFTããåŸãããåå
¥ã®ã»ããå€ãã£ããšããå ±åããããŸããã 10幎é鳿¥œããã£ãŠããŠããããŸã§6æã®ã¢ã«ãã ããªãªãŒã¹ãããã©ã ããããå
šéšåãããåå
¥ããã å»å¹Žã®ãããäžåã®NFTããããã«ããåå
¥ãäžåã£ããã ã NFTã®ååŒé«ã¯ã2021幎8æãããŒã¯ã«æžå°ãã12æã«å°ãçãè¿ããŸãããNFTã®ããŒã¯ã¯éãããšèšãããããšããããŸãããããã«æ¥ãŠããã«ãªè©±ãåºãŠããã®ã¯èŠæ³šç®ã§ãã æ¬åœã«ããã«ã忥ããŠããã®ãããããšãããäžåºŠããã«ãèµ·ããããšããŠèª°ãã仿ããŠããã®ãã NFTããã«ã®ãã¥ãŒã¹ Yuga LabsãCryptoPunksã®NFTã³ã¬ã¯ã·ã§ã³ã®æš©å©ãã¯ãªãšã€ã¿ãŒLarva LabsããååŸ Bored Apesã®NFTãããžã§ã¯ãã«å
¬åŒã®ãApeCoinãããŒã¯ã³ãã§ãã ãããã£ãŒã«ç»åNFTã¯æå·è³ç£ã¢ãŒããèŠãããŠãã ã¹ãã£ãŒãã»ã¢ãªãæ°ãNFTåå
¥ã鳿¥œåå
¥ãäžåã£ãã NFTã®çºè¡ãæŽ»çº æè¿ãæ¥æ¬ã§ãNFTãçºè¡ããäŸãå¢ããŠããŸããã 2021幎ã®NFTã®çãäžãããèŠãŠãèªåãã¡ãNFTã«åãçµãããšæã£ãäŒæ¥ããã¡ããã©ä»ããçºè¡ããŠããã®ãããããŸããã NFTã®çºè¡ã掻çºã®ãã¥ãŒã¹ æåçºã®ç¥ç€Ÿã§ âããžã¿ã«åŸ¡æ±å°â é
åž ãLAWSON TICKET NFTããçºè¡š--æãå
¥ãã®ããã€ãã³ããã±ãããNFTã« NFTã®åãæ±ããç°¡åã«ããããšãããœãªã¥ãŒã·ã§ã³ãåºãŠãã NFTã売買ããã«ã¯ãçŸç¶ã ãšæå·è³ç£ã®ç¥è/çµéšããããªãã«å¿
èŠã§ããäžè¬ã®äººã«ã¯æ·å±
ãé«ãã®ã§ãã§ããã ãç°¡åã«ããããšãããœãªã¥ãŒã·ã§ã³ãåºå§ããŠããŸããã ä»ã®ãšãããæ±ºå®çãªãœãªã¥ãŒã·ã§ã³ã¯ãããŸããããNFTãæ®åããã«ã¯è§£æ±ºããªããã°ãªããªãåé¡ãªã®ã§ãåŒãç¶ããŠã©ããããå¿
èŠããããŸãã NFTã®åãæ±ããç°¡åã«ããããšãããœãªã¥ãŒã·ã§ã³ãåºãŠããã®ãã¥ãŒã¹ NFTããŒã±ãããã¬ã€ã¹nanakusaããSBINFTããšããŠãªãã¥ãŒã¢ã«ãããŒãããŒã«ã¯ã¹ãããåïŒã PPRPãåœå
åã®NFT賌å
¥ä»£è¡ãµãŒãã¹ãéå§ ãããã¯ãã§ãŒã³ ã²ãŒã ãæŽ»çº ãããã¯ãã§ãŒã³ ã²ãŒã ãç¶ã
ãšåºãŠããŸãããã©ãããPlay to earnãåºæ¬ã³ã³ã»ããã§ããã皌ãããã«éã¶ããšããããšã§ãã²ãŒã å
ã§ã®æŽ»åã«å¿ã㊠ããŒã¯ ã³ããããããã® ããŒã¯ ã³ãçŸéã«å€ããããšãã§ããŸãã ãŸããã²ãŒã å
ã¢ã€ãã ãNFTã«ãªã£ãŠããŠã ããŒã±ãããã¬ã€ã¹ ã§å£²è²·ã§ããããã«ãªã£ãŠããŸãã RMT ãå¯èœã«ãªã£ããšããããšã§ãã ãããã¯ãã§ãŒã³ ã²ãŒã ãæŽ»çºã®ãã¥ãŒã¹ ãããããŒãã«ãç¬èªã®ãããã¯ãã§ãŒã³ãšã³ã·ã¹ãã ãMBXããMARBLEXãŠã©ã¬ãããã®ãµãŒãã¹éå§ HashPortãéãã§çšŒããããã¯ãã§ãŒã³ã²ãŒã ããšã«ããã¹ã¿ãŒãºãã6æäžæ¬ã«é
ä¿¡ãNFTã¯4æãªãªãŒã¹äºå®ã®ããŒã±ãããã¬ã€ã¹ãPLT Placeãã§è²©å£² XLGAMESïŒãããã¯ãã§ãŒã³é©çšã®MMORPGãArcheWorldããçºè¡šã7æã®ã°ããŒãã«ãµãŒãã¹éå§ãç®æã å·çïŒ @higa ïŒ Shodo ã§å·çãããŸãã ïŒ
ããã«ã¡ã¯ã é»éåœéæ
å ±ãµãŒãã¹ (ISID) éèãœãªã¥ãŒã·ã§ã³äºæ¥éšã®æ°Žéã§ãã goèšèªã§éçºããŠãããããžã§ã¯ãã§ãDIãå°å
¥ããæ©äŒããã£ãã®ã§ç޹ä»ããŸãã éçºç°å¢ Visual Studio Code 1.64.2 go 1.17.8 ãªãDIãå¿
èŠãªã®ã goãšèšãã° go generateã«å
žåçãªèªåçæãã€ã¡ãŒãžãããæ¹ãå€ããä»ã®èšèªã§è¯ã䜿çšãããDIã³ã³ãããšã¯çžãèããšæãããæ¹ãå€ãã®ã§ã¯ãªãã§ããããã ç§ãå®ã¯ããèããŠããã¯ãã§ãããäŸåæ§ãåãé¢ããŠç¶æ³ã«å¿ããŠå¿
èŠãªå®è£
ãInjectionïŒæ³šå
¥ïŒãããšãã ã¢ãŒããã¯ã㣠ã¯ãèšèªãåããæçšã§ããã±ãŒã¹ã¯ãããŸãã 以äžã«äŸãæããŸãã ããŒã«ã«éçºç°å¢ã§ã¯DBã¢ã¯ã»ã¹ã䌎ããªãã¢ãã¯ã䜿ããããããã€ãããç°å¢ã§ã¯DBã¢ã¯ã»ã¹ã䌎ãã¢ãžã¥ãŒã«ã«å·®ãæ¿ããã åäœãã¹ã ã§ã¯åçš®éä¿¡ïŒ API ã³ãŒã«ãªã©ïŒãè¡ããªããããã以å€ã§ã¯å®éã«éä¿¡ãè¡ãã¢ãžã¥ãŒã«ã皌åããã ãã¡ã€ã«å
¥åºåãè¡ãæ©èœã§ãç¹å®ã®æ¡ä»¶äžã§ã¯ãã¡ã€ã«ãæ±ããã«ãšãã¥ã¬ãŒãããã¢ãŒãã«åãæ¿ããã ã€ã³ã¿ãã§ãŒã¹ã¯ç¢ºå®ãããå®è£
ãæªå®ã®å ŽåãäžæŠã¹ã¿ãå®è£
ãå
ãŠãŠããŒã«ã«ã§ã®éçºã¯æ»ããªãããã«ãããããããã€æã¯æ£åŒãªã¢ãžã¥ãŒã«ãçšãã å¥ã®è©±ã§ããããã®ã±ãŒã¹ã¯æ¬çªã¢ãžã¥ãŒã«ã®å®è£
ã宿ãããŸã§ã¯ãpanicããçã§æå³ãæç¢ºã«ããæ¹ãè¯ãã§ãããã ãªã©ãäžå®ã®èŠæš¡ãã€è€é床ã®ã·ã¹ãã ãæ§ç¯ããå ŽåãDIã³ã³ãããæ¬²ãããªãã±ãŒã¹ã¯å€ãã§ãã ãããã¯ãéžå® goã®DIã³ã³ãããšããŠã¯ã Google ããã® wire ã Uber ããã® fx ãæåã§ã 1 ã GitHub ã®Staræ°ã¯ wire ãäžçªå€ãã§ãããæã
ã¯fxãæ¡çšããŸããã éžå®ã«ã¯æ±ºå®çãšåŒã¹ãã»ã©ã®çç±ã¯ãªãã匷ããŠæãããš wire ã¯äŸåæ§ã解決ããã³ãŒããèªåçæããŸãããfxã¯æç€ºçã«äŸåæ§ã解決ããå®è£
ããããšããç¹ã§ãã wire ã®ã¡ãªãããšã㊠ã³ã³ãã€ã« æã«äŸåæ§ã®ç¢º ããã ããæ€èšŒåºæ¥ãŸãããå®éããŒã«ã«ã§äžåºŠã皌å確èªãããªãã±ãŒã¹ã¯æãåŸãªãã®ã§ãfxã§ç¹æ®µå°ãäºã¯ãªããšèããŸããã ãŸããçŽè¿ã®ã³ããããã°éããªãªãŒã¹é »åºŠïŒ wireã®ãªãªãŒã¹ ã fxã®ãªãªãŒã¹ ïŒãèŠããšã wire ã¯ããæè¿åæ»æ°å³ã§fxã®æ¹ã掻çºã«æŽ»åããŠããããšããã®ãçç±ã§ãã fxã®äœ¿ãæ¹ å°å
¥ã¯ä»ã®ã©ã€ãã©ãªåæ§ go get go.uber.org/fx ã§å®äºã§ããïŒãã ãgo modulesåæïŒ fxã®å
¬åŒããã¥ã¡ã³ã㯠ãã¡ã ã§ãããå©ç𿹿³ãšãµã³ãã«ã³ãŒãã瀺ããŸãã å©ç𿹿³ åæåçšã®fx.Appãæ§ç¯ãã fx.New ãåŒã³ãåæåçšã® App ãæ§ç¯ããŸãã ã¢ãžã¥ãŒã«ã®äŸåé¢ä¿ãå®çŸ©ãã fx.Newã®åŒæ°ã«ã¯ãæšç§»çãªäŸåãå«ããŠäŸåé¢ä¿ã®ã¢ãžã¥ãŒã«å®çŸ©ãæž¡ããŸãã ã¢ãžã¥ãŒã«å®çŸ©ãšã¯ãfx.Optionã€ã³ã¿ãã§ãŒã¹ãæºãããã®ã§ã ã·ã°ãã㣠ã¯ä»¥äžã§ãã type Option interface { fmt.Stringer apply(*module) } ã¢ãžã¥ãŒã«å®çŸ©ã«ã¯ã³ã³ã¹ã ã©ã¯ ã¿é¢æ°ãäžãã fx.Povide ãèµ·å颿°ãäžãã fx.Invoke çãå«ã¿ãŸã (fx.Optionãæºãããã)ã fx.Newã«ã¯ Invoke ã§åŸããã1ã€ä»¥äžã®èµ·å颿°ãšãäŸåé¢ä¿ã®è§£æ±ºã«å¿
èŠãªå
šãŠã®ã³ã³ã¹ã ã©ã¯ ã¿é¢æ°ãäžããŠåŸãããProviveã®æ»ãå€ãå¿
èŠ WithLogger( https://pkg.go.dev/go.uber.org/fx#WithLogger )ãªã©ããã®ä»Optionãè¿ã颿°ã¯ type Option åç
§ fx.Appãå®è¡ãã å®è¡ãããã£ãšãåçŽãªæ¹æ³ã¯App.RunãåŒã³ã ãäºã§ãããRunã§äºè¶³ããªãã±ãŒã¹ãå€ãã§ãããã ãã现ããå¶åŸ¡ãããå Žåã fx.App ã®App.Startã§èµ·åãéå§ããApp.Stopã§æç€ºçã«çµäºããŸãã fx.Appã®èµ·åã«ããã£ãŠã®ç¹åŸŽã¯ä»¥äžã§ãã App.Startã¯ãšã©ãŒãçºçããå Žåãé€ããApp.StopãåŒã°ãããŸã§åŠçãçµäºãããªã App.StartãApp.Stop㯠LifeCycle ã«ããèµ·åæãšçµäºæã®ããã¯ãå¯èœã§ãäœããã®åŠçãæã¿èŸŒãã App.Runã¯ãæç€ºçã«æå®ããªãéãããã©ã«ãã® ã¿ã€ã ã¢ãŠã å€ãçšããå
éšçã«ã¯ Done ïŒãããã¯ããã·ã°ãã«ã®ãã£ã³ãã«ïŒãšStartãçšããã·ã³ãã«ãªèµ·ååŠç Runã®å®è£
ã¯ä»¥äžã®3è¡ã®ã¿ if code := app.run(app.Done()); code != 0 { app.exit(code) } ãµã³ãã« fxãçšããããçšåºŠå®è·µçãªäŸåæ§ã解決ããã³ãŒããæžããŠã¿ãŸãã èµ·åãšçµäºã§ãã®ã³ã°ãããã㪠fx.Hook ãä»èŸŒãã§ã¿ãŸããã å©ç𿹿³ ã§ç€ºãã3ç¹ã¯ã ãœãŒã¹ã³ãŒã äžã®ãâ åæåçšã®fx.Appãæ§ç¯ãããããâ¡ã¢ãžã¥ãŒã«ã®äŸåé¢ä¿ãå®çŸ©ãããããâ¢fx.Appãå®è¡ãããã®ã³ã¡ã³ãã«å¯Ÿå¿ããŠããŸãã // ãŠãŒã¹ã±ãŒã¹ã®ã€ã³ã¿ãã§ãŒã¹ã§ãã // 䟿å®äž1ãã¡ã€ã«ã§æžããŠããŸãããæ¬äœã®å®è£
ãçµããåã¯æ«å®å®è£
ãDIãããªã©ãå¯èœã§ãã // ä»åã¯ãæ°è¡äžã®paymentUsecaseãæ¬ã€ã³ã¿ãã§ãŒã¹ã®å®è£
ããŠDIããŸãã type PaymentUsecase interface { Pay() } type paymentUsecase struct { repo AccountRepository } func (paymentUsecase) Pay() { // ãéã調éããŠæ¯æããŠãŒã¹ã±ãŒã¹å®è£
fmt.Println( "Paid!!" ) } // ãŠãŒã¹ã±ãŒã¹ã®ãã¡ã¯ããªé¢æ°ã§ãfxãPaymentUsecaseã®å®è£
ãåŸãããã«å¿
èŠã§ãã // fx.Newã®éã«ãã®ãã¡ã¯ããªé¢æ°ãäžããŠããªããšãäŸåæ§ã解決ã§ããã«å®è¡æãšã©ãŒã«ãªããŸãã func NewPaymentUsecase(repo AccountRepository) PaymentUsecase { return &paymentUsecase{repo: repo} //Usecaseã€ã³ã¿ãã§ãŒã¹ã®å®è£
ãè¿ã } // ãªããžããªã€ã³ã¿ãã§ãŒã¹ã§ãã // ã¢ãžã¥ãŒã«ãå®éã«DBã¢ã¯ã»ã¹ãããã©ãããªã©ããDIãããªããžã§ã¯ãã§åãæ¿ããå¯èœã§ãã type AccountRepository interface { GetByNo(AccountNo) Account } // ãªããžããªã®å®è£
ã§ããåŸè¿°ããŸãããã¢ãã¯ãªããžããªã«å·®ãæ¿ããŠDIãããªã©ãå¯èœã§ãã type accountRepository struct {} func (repo accountRepository) GetByNo(acntNo AccountNo) Account { return Account{ 1 } // å®è£
ã¯é©åœ } // ãªããžããªã®ãã¡ã¯ããªé¢æ°ã§ãfxãAccountRepositoryã®å®è£
ãåŸãããã«å¿
èŠã§ãã func NewAccountRepository() AccountRepository { return &accountRepository{} //AccountRepositoryã€ã³ã¿ãã§ãŒã¹ã®å®è£
ãè¿ã } func ExecUsecase(usecase PaymentUsecase) { usecase.Pay() } // èµ·åæã«Start, çµäºã«Stopãšåºåããã©ã€ããµã€ã¯ã«ããã¯ã§ãã func AssignLifeCycleLogging(lc fx.Lifecycle) { hook := fx.Hook{ OnStart: func (context.Context) error { fmt.Println( "Start!" ) return nil }, OnStop: func (context.Context) error { fmt.Println( "Stop!" ) return nil }, } lc.Append(hook) } // goã¢ããªã±ãŒã·ã§ã³ã®ãšã³ããªãã€ã³ãã§ãããã§fx.Appã®äœæãšå®è¡ãè¡ããŸãã func main() { // â åæåçšã®fx.Appãæ§ç¯ãã app := fx.New( //â¡ã¢ãžã¥ãŒã«ã®äŸåé¢ä¿ãå®çŸ©ãããäŸåé¢ä¿ãå®çŸ©ããfx.Optionã®å®è£
ãåŒæ°ã§äžãã fx.Provide( NewPaymentUsecase, NewAccountRepository, ), fx.Invoke(AssignLifeCycleLogging, ExecUsecase), ) if err := app.Err(); err != nil { log.Fatalf(err.Error()) } startCtx, cancel := context.WithTimeout(context.Background(), config.StartTimeOut) defer cancel() if err := app.Start(startCtx); err != nil { //â¢fx.Appãå®è¡ãã log.Fatal(err) } stopCtx, cancel := context.WithTimeout(context.Background(), config.StopTimeOut) defer cancel() if err := app.Stop(stopCtx); err != nil { log.Fatal(err) } } ãã®ããã«ãå©çšããã ããªãã°å°å
¥ã¯ãããŠé£ãããããŸããã ã§ãããäžå®ã®èŠæš¡ã®ãããžã§ã¯ãïŒæ°ååã®éçºè
ãããã€ã¡ãŒãžïŒãšãªããšãä»ã«ãèããªããã°ãªããªã課é¡ãããã€ããããŸãã éã«ãããçšåºŠã®èŠæš¡ã§ãªãéããDIã³ã³ããã®ãããªè€éãªä»æããå°å
¥ããã¡ãªããã¯åžèã§ãã æã
ããfxå°å
¥ã«ããã£ãŠã©ã®ãããªéçºéçšãããã®ããæ¬¡ç¯ä»¥éã§ã玹ä»ããŸãã ãããžã§ã¯ãã§fxã䜿ã éçºã®èŠæš¡ã倧ãããªã£ãŠãããšã1ã€ã®ããã±ãŒãžã«è€æ°ã® ãœãŒã¹ã³ãŒã ã䞊ã³ãç·æ°æ°åã«ãªãããšãçãããããŸããã 管ç察象ãšãªããªããžã§ã¯ããè¿ããã¡ã¯ããªé¢æ°ãã©ã®ããã«å®çŸ©ãã統治ãããã¯éèŠãªããŒãã§ãã ãã®èª²é¡ãã管ç察象ãªããžã§ã¯ããšãã¡ã¯ããªé¢æ°ã®å®è£
æéãããã¢ãžã¥ãŒã«å®çŸ©æ¹æ³ããããã«ãã¿ã°ãã®3ã€ã®ã¢ãããŒããã解決ããŸããã ãã®æ¹åæ§èªäœã¯ã wire ãšå°ãéãªãããéšåããããŸãã 管ç察象ãªããžã§ã¯ããšãã¡ã¯ããªé¢æ°ã®å®è£
æé ç¹å¥ãªããšã¯ãªãã以äžãšããŸããã 管ç察象ãšãããªããžã§ã¯ãã¯ã€ã³ã¿ãã§ãŒã¹ãèšãã察象ã€ã³ã¿ãã§ãŒã¹ãå®è£
ããæ§é äœãäœæãã æ§é äœã«äŸåãããªããžã§ã¯ãããã£ãŒã«ããšããŠä¿æãã æ§é äœåã¯ã€ã³ã¿ãã§ãŒã¹åç§°ã®å
é ãå°æåãšããŠexportããããã¡ã¯ããªé¢æ°ã§ã®ã¿çæå¯èœãšãã ãã¡ã¯ããªé¢æ°ã® ã·ã°ãã㣠ã§ã¯ã€ã³ã¿ãã§ãŒã¹ã宣èšããæ§é äœã®å®è£
ãè¿ã 管ç察象ã®ã€ã³ã¿ãã§ãŒã¹1ã€ã«ã€ãã1ãã¡ã€ã«ãäœæãã ã¢ãã¯å®è£
ãå¿
èŠãªå Žåã¯ãã€ã³ã¿ãã§ãŒã¹ã«go:generateãä»äžãã ãµã³ãã« ã®å®è£
ãµã³ãã«ã§ã¯ã type PaymentUsecase interface ãã NewPaymentUsecase ãŸã§ã®ä»¥äžã該åœããŸãã type PaymentUsecase interface { Pay() } type paymentUsecase struct { repo AccountRepository } func (paymentUsecase) Pay() { fmt.Println( "Paid!!" ) } func NewPaymentUsecase(repo AccountRepository) PaymentUsecase { return &paymentUsecase{repo: repo} } å¥ãã¡ã€ã«ã§go:generateã宣èšãã ãªããžã㪠å®è£
ã®äŸãèŠãŠèŠãŸãããã account_repository.go package repository //go:generate mockgen -source ./account_repository.go -destination ./account_repository_mock.generated.go -package repository type AccountRepository interface { GetByNo(AccountNo) Account } type accountRepository struct {} func (repo accountRepository) GetByNo(acntNo AccountNo) Account { // ã»ã»ã»çç¥ } ããã§ãã³ãã³ãã§ã IDE ããã§ãã¢ãã¯çæãå¯èœã§ãã IDE ã« VS Code ãçšããŠããã°ã以äžãã¯ãªãã¯ããã°çæãããŸãã ã¢ãžã¥ãŒã«å®çŸ©æ¹æ³ 管ç察象ã®ãªããžã§ã¯ããšãã¡ã¯ããªé¢æ°ã®å®è£
ããã¢ãžã¥ãŒã«ãšããŠã©ã管çããããæ¬¡ã®èª²é¡ã§ãã provider.goãšãããã¡ã¯ããªé¢æ°ãéçŽããå®è£
ãšããã¡ã¯ããªé¢æ°ãšFxãçµã³ã€ããmodule.goãå®è£
ããããšã«ããŸããã å
·äœçã«ã¯ä»¥äžã§ãã åããã±ãŒãžæ¯ã«1ã€ãprovider.goãšãããã¡ã€ã«ãèšããåœè©²ããã±ãŒãžã®ãã¡ã¯ããªé¢æ°ã䞊ã¹ã ãã¡ã¯ããªé¢æ°ãšFxãçµã³ã€ãããããåããã±ãŒãžæ¯ã«1ã€module.goãèšãã module.goã¯fx.Provideã«ããã±ãŒãžå
ã®å
šãã¡ã¯ããªé¢æ°ãæž¡ããçµæåŸãããfx.Optionãè¿ã åŸãããfx.Option㯠Module ãšããåç§°ã§exportãã 管ç察象ãªããžã§ã¯ããå¿
èŠãªå Žåãå©çšè
åŽã該åœããããã±ãŒãžã® Module ã fx.Options ã«äžããŠäŸåæ§ã解決ãã provider.goã¯çšéæ¯ã«ãã«ãã¿ã° [^2]ã§åãæ¿ããã ãããã¯ã·ã§ã³çšã¯provider.goã ãã åäœãã¹ã æã¯provider_ut.goãå
éš çµåãã¹ã æã¯provider_it.goãšãã£ãå
·å ãªããžã㪠ã«äŸåããUsecaseãè€æ°ããäŸã§ãåŒã³åºãåŽã®ã³ãŒããšåãããŠç¢ºèªããŸãã provider.go package usecase import ( "sample-prj/domain/repository" ) func NewPaymentUsecase(repo repository.AccountRepository) PaymentUsecase { return &paymentUsecase{repo} } func NewRcvUsecase(repo repository.AccountRepository) RcvUsecase { return &rcvUsecase{repo} } module.go package usecase import "go.uber.org/fx" var Module = fx.Provide(NewPaymentUsecase, NewRcvUsecase) å©çšåŽã¯ãfx.Appã« Module ãäžããŠäŸåæ§ã解決ããŸãã fx.New( fx.Options( repository.Module, //ãªããžããªã®äŸåæ§ã解決ããã¢ãžã¥ãŒã« usecase.Module, //Usecaseã®äŸåæ§ã解決ããã¢ãžã¥ãŒã« ), fx.Invoke(ãã»ã»ã»çç¥ ) ãã«ãã¿ã° provier.goãmodule.goã§äŸåæ§ã¯è§£æ±ºã§ããããã«ãªããŸããã ãã ãããã§ã¯ãŸã ç°å¢ãç¶æ³ã«å¿ããŠã€ã³ã¿ãã§ãŒã¹ã®å®è£
ãåãæ¿ããããšã¯åºæ¥ãŸããã ããã§ããã«ãã¿ã°ãçšããŸãã ãã«ãã¿ã°ãšã¯Go tool ã«ãã£ãŠæäŸããã ãã«ãå¶çŽã·ã¹ãã ã§ãã ã³ãŒãã®å
é ã« //go:build [ã¿ã°å] ãä»äžããããšã§ããã«ã察象ãã¡ã€ã«ãæå®ããŸãã go build ã®tagsãªãã·ã§ã³ã§è€æ°åã®ã¿ã°åãæå®å¯èœã§ã該åœããã¿ã°åã®goãã¡ã€ã«ã®ã¿ãã«ã察象ãšãªããŸãã ãããèžãŸããprovider.goãšçµã¿åããããã«ãæŠè¡ã¯ä»¥äžã§ãã provider.goã«çšéæ¯ã®ãã«ãã¿ã°ãä»äžããã äºåã«ä»äžããã¿ã°ã決ããŠãããutïŒ åäœãã¹ã ïŒãitïŒå
éš çµåãã¹ã ïŒãªã© provider.goã®ãã¡ã€ã«å ãµãã£ãã¯ã¹ ã«ã¿ã°åãä»äžãããããã«ããããããã¯ã·ã§ã³çšã¯provider.goã ãã åäœãã¹ã æã¯provider_ut.goãå
éš çµåãã¹ã æã¯provider_it.goãšãã£ãå
·åã§å¶åŸ¡å¯èœã«ãªã ã¢ãžã¥ãŒã«å®çŸ©æ¹æ³ ã®ãµã³ãã«ã³ãŒãã«ãutãã«ãã¿ã°ãšãã®ä»ã¿ã°ãä»äžããprovider.goã®å®è£
ã¯ä»¥äžã§ãã ãªããã¢ãã¯å®è£
ã«ã¯ gomock ãå©çšããŠããŸãã provider_ut.go //go:build ut package usecase import ( "github.com/golang/mock/gomock" ) func NewPaymentUsecase(ctrl *gomock.Controller) PaymentUsecase { return NewMockPaymentUsecase(ctrl) } func NewRcvUsecase(ctrl *gomock.Controller) RcvUsecase { return NewMockRcvUsecase(ctrl) } provider.go //go:build it || stg package usecase import ( "sample-prj/domain/repository" ) func NewPaymentUsecase(repo repository.AccountRepository) PaymentUsecase { return &paymentUsecase{repo} } func NewRcvUsecase(repo repository.AccountRepository) RcvUsecase { return &rcvUsecase{repo} } ãªããžã㪠ã«äŸåããUsecaseãè€æ°ããã±ãŒã¹ã§ãprovider_ut.goãšprovider.goã§å®è£
ãåãæ¿ããŸãã åäœãã¹ã (ut) æã¯èªåçæããUsecaseã®ã¢ãã¯å®è£
ãçšããããå
éš çµåãã¹ã 以éã¯æ£èŠã®å®è£
ãçšããããŸãã Module.goãåŒã³åºãåŽã®ã³ãŒãã«å€æŽã¯ãããŸããã ãã®ä»ã®äŸ¿å©æ©èœ ä»ã«fxã§ç©æ¥µçã«äœ¿çšããŠããæ©èœã¯ fx.In ã§ãã äŸåé¢ä¿ãå¢ããŠãããšããã¡ã¯ããªé¢æ°ã®åŒæ°ãçžåœæ°ã«ãªããã³ãŒãã®èŠéããä¿å®æ§ãèããäœäžããŸãã ãããã£ãå ŽåãäŸåé¢ä¿ã®ãªããžã§ã¯ããå
šãŠå®çŸ©ããæ§é äœãäœæããŠInjectionããŸãã ãã®æ§é äœããã©ã¡ãŒã¿æ§é äœãšåŒã³ãŸãã äŸåé¢ä¿ãå¢ããå Žåã§ããã©ã¡ãŒã¿æ§é äœã«ãã£ãŒã«ãã远å ããã ãã§æžã¿ãããªã匷åãªæ©èœã§ãã ãµã³ãã«ã³ãŒãã§éãã確èªããŸãã SetlUsecaseãšãããè€æ°ã®ãªããžã§ã¯ãã«äŸåãã ãŠãŒã¹ã±ãŒã¹ ãäŸã«ãã¢ãžã¥ãŒã«å®çŸ©ãšçæãèŠãŠã¿ãŸãã ãã©ã¡ãŒã¿æ§é äœã䜿ããªãäŸ type SetlUsecase interface { Settle() } type setlUsecase struct { config *Config repoAccount AccountRepository repoSetl SettlementRepository repoCode CodeMasterRepository cal *Calendar setlExecutor SetlExecutor priorityJudger PriorityJudger } func NewSetlUsecase(config *Config, repoAccount AccountRepository, repoSetl SettlementRepository, repoCode CodeMasterRepository, cal *Calendar, setlExecutor SetlExecutor, priorityJudger PriorityJudger) SetlUsecase { return &setlUsecase{ config: config, repoAccount: repoAccount, repoSetl: repoSetl, repoCode: repoCode, cal: cal, setlExecutor: setlExecutor, priorityJudger: priorityJudger, } } ãã®çšåºŠãªããããŸã§ã§ããªãã§ãããå®éã®éçºã§ã¯ãã£ãšå€ãã®ãªããžã§ã¯ãã«äŸåããã±ãŒã¹ããããŸãã ãã以äžãã¡ã¯ããªé¢æ°ã®åŒæ°ãå¢ããã®ã¯èŸãã§ãããã ãã©ã¡ãŒã¿æ§é äœã§çœ®ãæããã³ãŒããèŠãŠã¿ãŸãããã ãã©ã¡ãŒã¿æ§é äœã§å®è£
ããäŸ // SetlUsecaseãšsetlUsecaseã¯ããã©ã¡ãŒã¿æ§é äœã䜿ããªãäŸããšåæ§ã®ããçç¥ type UsecaseParams struct { fx.In Config *Config RepoAccount AccountRepository RepoSetl SettlementRepository RepoCode CodeMasterRepository Cal *Calendar SetlExecutor SetlExecutor PriorityJudger PriorityJudger } func NewSetlUsecase(params UsecaseParams) SetlUsecase { return &setlUsecase{ config: params.Config, repoAccount: params.RepoAccount, repoSetl: params.RepoSetl, repoCode: params.RepoCode, cal: params.Cal, setlExecutor: params.SetlExecutor, priorityJudger: params.PriorityJudger, } } NewSetlUsecaseããã£ããããŸããã ãã ãããã©ã¡ãŒã¿æ§é äœã䜿ãäžã§ã以äžã®2ç¹ã¯ã泚æãã ããã ãã©ã¡ãŒã¿æ§é äœã®ãã£ãŒã«ãã¯exportããªããã°ãªããªã ãã¡ã¯ããªé¢æ°ã«äžãããã©ã¡ãŒã¿æ§é äœã¯ããã€ã³ã¿ã§æž¡ãããšãåºæ¥ãªãã®ã§å€ãšããŠæž¡ã äžèš1, 2ã«éåããå Žåãå®è¡æfxããšã©ãŒãåºåããŸãã ãšã©ãŒåºåäŸïŒ cannot depend on a pointer to a parameter object, use a value instead: *main.UsecaseParams is a pointer to a struct that embeds dig.In ããã§ãsetlUsecaseã«äŸåãããªããžã§ã¯ããå¢ãããšããŠããã³ã³ã¹ã ã©ã¯ ã¿é¢æ°ã«åŒæ°ã远å ããããã©ã¡ãŒã¿æ§é äœãžã®è¿œå ã§æžã¿ãŸãã ãŸãšã ä»åã¯goéçºã§DIãå°å
¥ããã話ã§ããã åœåã®ç®ç ã¯å
šãŠéæã§ããŠããã倧ããªãããããªãå¿«é©ã«éçºåºæ¥ãŠããŸãã ãªããžã§ã¯ãã®çæåŠçãäžå
çã«ç®¡çããæçŸ©ã¯å€§ããã皌å確èªãäžçºããã°åæåã«äŒŽãå®è£
ãã¹ã¯ã»ãŒãªããªããŸããã ãŸã坿¬¡çãªå¹æãšããŠãã¢ãžã¥ãŒã«éã®äŸåé¢ä¿ãæèããããšã§ãã€ã³ã¿ãã§ãŒã¹ãæŽç·Žãããå°è±¡ããããŸãã çµæãæ§ã
ãªèšèªã®DIã³ã³ãããç®æããšããã§ãããã€ã³ã¿ãŒãã§ãŒã¹ãšå®è£
ãåé¢ããŠæœè±¡åºŠãé«ãã倿Žå®¹ææ§ãåäžãããšããç¹ãéæã§ããŸããã goéçºã§DIå°å
¥ãæ€èšäžãªãã uber-go/fx ãéžæè¢ã®äžã€ãšããŠãèãã«ãªã£ãŠã¯ãããã§ããããã å·çïŒ @mizuno.kazuhiro ãã¬ãã¥ãŒïŒ @sato.taichi ïŒ Shodo ã§å·çãããŸãã ïŒ Facebook ããã® inject ã¯ã2022幎3æçŸåš ã¢ãŒã«ã€ã ãããŠãããéžå®ããå€ããŸããã ↩
ããã«ã¡ã¯ã é»éåœéæ
å ±ãµãŒãã¹ (ISID) éèãœãªã¥ãŒã·ã§ã³äºæ¥éšã®æ°Žéã§ãã goèšèªã§éçºããŠãããããžã§ã¯ãã§ãDIãå°å
¥ããæ©äŒããã£ãã®ã§ç޹ä»ããŸãã éçºç°å¢ Visual Studio Code 1.64.2 go 1.17.8 ãªãDIãå¿
èŠãªã®ã goãšèšãã° go generateã«å
žåçãªèªåçæãã€ã¡ãŒãžãããæ¹ãå€ããä»ã®èšèªã§è¯ã䜿çšãããDIã³ã³ãããšã¯çžãèããšæãããæ¹ãå€ãã®ã§ã¯ãªãã§ããããã ç§ãå®ã¯ããèããŠããã¯ãã§ãããäŸåæ§ãåãé¢ããŠç¶æ³ã«å¿ããŠå¿
èŠãªå®è£
ãInjectionïŒæ³šå
¥ïŒãããšãã ã¢ãŒããã¯ã㣠ã¯ãèšèªãåããæçšã§ããã±ãŒã¹ã¯ãããŸãã 以äžã«äŸãæããŸãã ããŒã«ã«éçºç°å¢ã§ã¯DBã¢ã¯ã»ã¹ã䌎ããªãã¢ãã¯ã䜿ããããããã€ãããç°å¢ã§ã¯DBã¢ã¯ã»ã¹ã䌎ãã¢ãžã¥ãŒã«ã«å·®ãæ¿ããã åäœãã¹ã ã§ã¯åçš®éä¿¡ïŒ API ã³ãŒã«ãªã©ïŒãè¡ããªããããã以å€ã§ã¯å®éã«éä¿¡ãè¡ãã¢ãžã¥ãŒã«ã皌åããã ãã¡ã€ã«å
¥åºåãè¡ãæ©èœã§ãç¹å®ã®æ¡ä»¶äžã§ã¯ãã¡ã€ã«ãæ±ããã«ãšãã¥ã¬ãŒãããã¢ãŒãã«åãæ¿ããã ã€ã³ã¿ãã§ãŒã¹ã¯ç¢ºå®ãããå®è£
ãæªå®ã®å ŽåãäžæŠã¹ã¿ãå®è£
ãå
ãŠãŠããŒã«ã«ã§ã®éçºã¯æ»ããªãããã«ãããããããã€æã¯æ£åŒãªã¢ãžã¥ãŒã«ãçšãã å¥ã®è©±ã§ããããã®ã±ãŒã¹ã¯æ¬çªã¢ãžã¥ãŒã«ã®å®è£
ã宿ãããŸã§ã¯ãpanicããçã§æå³ãæç¢ºã«ããæ¹ãè¯ãã§ãããã ãªã©ãäžå®ã®èŠæš¡ãã€è€é床ã®ã·ã¹ãã ãæ§ç¯ããå ŽåãDIã³ã³ãããæ¬²ãããªãã±ãŒã¹ã¯å€ãã§ãã ãããã¯ãéžå® goã®DIã³ã³ãããšããŠã¯ã Google ããã® wire ã Uber ããã® fx ãæåã§ã 1 ã GitHub ã®Staræ°ã¯ wire ãäžçªå€ãã§ãããæã
ã¯fxãæ¡çšããŸããã éžå®ã«ã¯æ±ºå®çãšåŒã¹ãã»ã©ã®çç±ã¯ãªãã匷ããŠæãããš wire ã¯äŸåæ§ã解決ããã³ãŒããèªåçæããŸãããfxã¯æç€ºçã«äŸåæ§ã解決ããå®è£
ããããšããç¹ã§ãã wire ã®ã¡ãªãããšã㊠ã³ã³ãã€ã« æã«äŸåæ§ã®ç¢º ããã ããæ€èšŒåºæ¥ãŸãããå®éããŒã«ã«ã§äžåºŠã皌å確èªãããªãã±ãŒã¹ã¯æãåŸãªãã®ã§ãfxã§ç¹æ®µå°ãäºã¯ãªããšèããŸããã ãŸããçŽè¿ã®ã³ããããã°éããªãªãŒã¹é »åºŠïŒ wireã®ãªãªãŒã¹ ã fxã®ãªãªãŒã¹ ïŒãèŠããšã wire ã¯ããæè¿åæ»æ°å³ã§fxã®æ¹ã掻çºã«æŽ»åããŠããããšããã®ãçç±ã§ãã fxã®äœ¿ãæ¹ å°å
¥ã¯ä»ã®ã©ã€ãã©ãªåæ§ go get go.uber.org/fx ã§å®äºã§ããïŒãã ãgo modulesåæïŒ fxã®å
¬åŒããã¥ã¡ã³ã㯠ãã¡ã ã§ãããå©ç𿹿³ãšãµã³ãã«ã³ãŒãã瀺ããŸãã å©ç𿹿³ åæåçšã®fx.Appãæ§ç¯ãã fx.New ãåŒã³ãåæåçšã® App ãæ§ç¯ããŸãã ã¢ãžã¥ãŒã«ã®äŸåé¢ä¿ãå®çŸ©ãã fx.Newã®åŒæ°ã«ã¯ãæšç§»çãªäŸåãå«ããŠäŸåé¢ä¿ã®ã¢ãžã¥ãŒã«å®çŸ©ãæž¡ããŸãã ã¢ãžã¥ãŒã«å®çŸ©ãšã¯ãfx.Optionã€ã³ã¿ãã§ãŒã¹ãæºãããã®ã§ã ã·ã°ãã㣠ã¯ä»¥äžã§ãã type Option interface { fmt.Stringer apply(*module) } ã¢ãžã¥ãŒã«å®çŸ©ã«ã¯ã³ã³ã¹ã ã©ã¯ ã¿é¢æ°ãäžãã fx.Povide ãèµ·å颿°ãäžãã fx.Invoke çãå«ã¿ãŸã (fx.Optionãæºãããã)ã fx.Newã«ã¯ Invoke ã§åŸããã1ã€ä»¥äžã®èµ·å颿°ãšãäŸåé¢ä¿ã®è§£æ±ºã«å¿
èŠãªå
šãŠã®ã³ã³ã¹ã ã©ã¯ ã¿é¢æ°ãäžããŠåŸãããProviveã®æ»ãå€ãå¿
èŠ WithLogger( https://pkg.go.dev/go.uber.org/fx#WithLogger )ãªã©ããã®ä»Optionãè¿ã颿°ã¯ type Option åç
§ fx.Appãå®è¡ãã å®è¡ãããã£ãšãåçŽãªæ¹æ³ã¯App.RunãåŒã³ã ãäºã§ãããRunã§äºè¶³ããªãã±ãŒã¹ãå€ãã§ãããã ãã现ããå¶åŸ¡ãããå Žåã fx.App ã®App.Startã§èµ·åãéå§ããApp.Stopã§æç€ºçã«çµäºããŸãã fx.Appã®èµ·åã«ããã£ãŠã®ç¹åŸŽã¯ä»¥äžã§ãã App.Startã¯ãšã©ãŒãçºçããå Žåãé€ããApp.StopãåŒã°ãããŸã§åŠçãçµäºãããªã App.StartãApp.Stop㯠LifeCycle ã«ããèµ·åæãšçµäºæã®ããã¯ãå¯èœã§ãäœããã®åŠçãæã¿èŸŒãã App.Runã¯ãæç€ºçã«æå®ããªãéãããã©ã«ãã® ã¿ã€ã ã¢ãŠã å€ãçšããå
éšçã«ã¯ Done ïŒãããã¯ããã·ã°ãã«ã®ãã£ã³ãã«ïŒãšStartãçšããã·ã³ãã«ãªèµ·ååŠç Runã®å®è£
ã¯ä»¥äžã®3è¡ã®ã¿ if code := app.run(app.Done()); code != 0 { app.exit(code) } ãµã³ãã« fxãçšããããçšåºŠå®è·µçãªäŸåæ§ã解決ããã³ãŒããæžããŠã¿ãŸãã èµ·åãšçµäºã§ãã®ã³ã°ãããã㪠fx.Hook ãä»èŸŒãã§ã¿ãŸããã å©ç𿹿³ ã§ç€ºãã3ç¹ã¯ã ãœãŒã¹ã³ãŒã äžã®ãâ åæåçšã®fx.Appãæ§ç¯ãããããâ¡ã¢ãžã¥ãŒã«ã®äŸåé¢ä¿ãå®çŸ©ãããããâ¢fx.Appãå®è¡ãããã®ã³ã¡ã³ãã«å¯Ÿå¿ããŠããŸãã // ãŠãŒã¹ã±ãŒã¹ã®ã€ã³ã¿ãã§ãŒã¹ã§ãã // 䟿å®äž1ãã¡ã€ã«ã§æžããŠããŸãããæ¬äœã®å®è£
ãçµããåã¯æ«å®å®è£
ãDIãããªã©ãå¯èœã§ãã // ä»åã¯ãæ°è¡äžã®paymentUsecaseãæ¬ã€ã³ã¿ãã§ãŒã¹ã®å®è£
ããŠDIããŸãã type PaymentUsecase interface { Pay() } type paymentUsecase struct { repo AccountRepository } func (paymentUsecase) Pay() { // ãéã調éããŠæ¯æããŠãŒã¹ã±ãŒã¹å®è£
fmt.Println( "Paid!!" ) } // ãŠãŒã¹ã±ãŒã¹ã®ãã¡ã¯ããªé¢æ°ã§ãfxãPaymentUsecaseã®å®è£
ãåŸãããã«å¿
èŠã§ãã // fx.Newã®éã«ãã®ãã¡ã¯ããªé¢æ°ãäžããŠããªããšãäŸåæ§ã解決ã§ããã«å®è¡æãšã©ãŒã«ãªããŸãã func NewPaymentUsecase(repo AccountRepository) PaymentUsecase { return &paymentUsecase{repo: repo} //Usecaseã€ã³ã¿ãã§ãŒã¹ã®å®è£
ãè¿ã } // ãªããžããªã€ã³ã¿ãã§ãŒã¹ã§ãã // ã¢ãžã¥ãŒã«ãå®éã«DBã¢ã¯ã»ã¹ãããã©ãããªã©ããDIãããªããžã§ã¯ãã§åãæ¿ããå¯èœã§ãã type AccountRepository interface { GetByNo(AccountNo) Account } // ãªããžããªã®å®è£
ã§ããåŸè¿°ããŸãããã¢ãã¯ãªããžããªã«å·®ãæ¿ããŠDIãããªã©ãå¯èœã§ãã type accountRepository struct {} func (repo accountRepository) GetByNo(acntNo AccountNo) Account { return Account{ 1 } // å®è£
ã¯é©åœ } // ãªããžããªã®ãã¡ã¯ããªé¢æ°ã§ãfxãAccountRepositoryã®å®è£
ãåŸãããã«å¿
èŠã§ãã func NewAccountRepository() AccountRepository { return &accountRepository{} //AccountRepositoryã€ã³ã¿ãã§ãŒã¹ã®å®è£
ãè¿ã } func ExecUsecase(usecase PaymentUsecase) { usecase.Pay() } // èµ·åæã«Start, çµäºã«Stopãšåºåããã©ã€ããµã€ã¯ã«ããã¯ã§ãã func AssignLifeCycleLogging(lc fx.Lifecycle) { hook := fx.Hook{ OnStart: func (context.Context) error { fmt.Println( "Start!" ) return nil }, OnStop: func (context.Context) error { fmt.Println( "Stop!" ) return nil }, } lc.Append(hook) } // goã¢ããªã±ãŒã·ã§ã³ã®ãšã³ããªãã€ã³ãã§ãããã§fx.Appã®äœæãšå®è¡ãè¡ããŸãã func main() { // â åæåçšã®fx.Appãæ§ç¯ãã app := fx.New( //â¡ã¢ãžã¥ãŒã«ã®äŸåé¢ä¿ãå®çŸ©ãããäŸåé¢ä¿ãå®çŸ©ããfx.Optionã®å®è£
ãåŒæ°ã§äžãã fx.Provide( NewPaymentUsecase, NewAccountRepository, ), fx.Invoke(AssignLifeCycleLogging, ExecUsecase), ) if err := app.Err(); err != nil { log.Fatalf(err.Error()) } startCtx, cancel := context.WithTimeout(context.Background(), config.StartTimeOut) defer cancel() if err := app.Start(startCtx); err != nil { //â¢fx.Appãå®è¡ãã log.Fatal(err) } stopCtx, cancel := context.WithTimeout(context.Background(), config.StopTimeOut) defer cancel() if err := app.Stop(stopCtx); err != nil { log.Fatal(err) } } ãã®ããã«ãå©çšããã ããªãã°å°å
¥ã¯ãããŠé£ãããããŸããã ã§ãããäžå®ã®èŠæš¡ã®ãããžã§ã¯ãïŒæ°ååã®éçºè
ãããã€ã¡ãŒãžïŒãšãªããšãä»ã«ãèããªããã°ãªããªã課é¡ãããã€ããããŸãã éã«ãããçšåºŠã®èŠæš¡ã§ãªãéããDIã³ã³ããã®ãããªè€éãªä»æããå°å
¥ããã¡ãªããã¯åžèã§ãã æã
ããfxå°å
¥ã«ããã£ãŠã©ã®ãããªéçºéçšãããã®ããæ¬¡ç¯ä»¥éã§ã玹ä»ããŸãã ãããžã§ã¯ãã§fxã䜿ã éçºã®èŠæš¡ã倧ãããªã£ãŠãããšã1ã€ã®ããã±ãŒãžã«è€æ°ã® ãœãŒã¹ã³ãŒã ã䞊ã³ãç·æ°æ°åã«ãªãããšãçãããããŸããã 管ç察象ãšãªããªããžã§ã¯ããè¿ããã¡ã¯ããªé¢æ°ãã©ã®ããã«å®çŸ©ãã統治ãããã¯éèŠãªããŒãã§ãã ãã®èª²é¡ãã管ç察象ãªããžã§ã¯ããšãã¡ã¯ããªé¢æ°ã®å®è£
æéãããã¢ãžã¥ãŒã«å®çŸ©æ¹æ³ããããã«ãã¿ã°ãã®3ã€ã®ã¢ãããŒããã解決ããŸããã ãã®æ¹åæ§èªäœã¯ã wire ãšå°ãéãªãããéšåããããŸãã 管ç察象ãªããžã§ã¯ããšãã¡ã¯ããªé¢æ°ã®å®è£
æé ç¹å¥ãªããšã¯ãªãã以äžãšããŸããã 管ç察象ãšãããªããžã§ã¯ãã¯ã€ã³ã¿ãã§ãŒã¹ãèšãã察象ã€ã³ã¿ãã§ãŒã¹ãå®è£
ããæ§é äœãäœæãã æ§é äœã«äŸåãããªããžã§ã¯ãããã£ãŒã«ããšããŠä¿æãã æ§é äœåã¯ã€ã³ã¿ãã§ãŒã¹åç§°ã®å
é ãå°æåãšããŠexportããããã¡ã¯ããªé¢æ°ã§ã®ã¿çæå¯èœãšãã ãã¡ã¯ããªé¢æ°ã® ã·ã°ãã㣠ã§ã¯ã€ã³ã¿ãã§ãŒã¹ã宣èšããæ§é äœã®å®è£
ãè¿ã 管ç察象ã®ã€ã³ã¿ãã§ãŒã¹1ã€ã«ã€ãã1ãã¡ã€ã«ãäœæãã ã¢ãã¯å®è£
ãå¿
èŠãªå Žåã¯ãã€ã³ã¿ãã§ãŒã¹ã«go:generateãä»äžãã ãµã³ãã« ã®å®è£
ãµã³ãã«ã§ã¯ã type PaymentUsecase interface ãã NewPaymentUsecase ãŸã§ã®ä»¥äžã該åœããŸãã type PaymentUsecase interface { Pay() } type paymentUsecase struct { repo AccountRepository } func (paymentUsecase) Pay() { fmt.Println( "Paid!!" ) } func NewPaymentUsecase(repo AccountRepository) PaymentUsecase { return &paymentUsecase{repo: repo} } å¥ãã¡ã€ã«ã§go:generateã宣èšãã ãªããžã㪠å®è£
ã®äŸãèŠãŠèŠãŸãããã account_repository.go package repository //go:generate mockgen -source ./account_repository.go -destination ./account_repository_mock.generated.go -package repository type AccountRepository interface { GetByNo(AccountNo) Account } type accountRepository struct {} func (repo accountRepository) GetByNo(acntNo AccountNo) Account { // ã»ã»ã»çç¥ } ããã§ãã³ãã³ãã§ã IDE ããã§ãã¢ãã¯çæãå¯èœã§ãã IDE ã« VS Code ãçšããŠããã°ã以äžãã¯ãªãã¯ããã°çæãããŸãã ã¢ãžã¥ãŒã«å®çŸ©æ¹æ³ 管ç察象ã®ãªããžã§ã¯ããšãã¡ã¯ããªé¢æ°ã®å®è£
ããã¢ãžã¥ãŒã«ãšããŠã©ã管çããããæ¬¡ã®èª²é¡ã§ãã provider.goãšãããã¡ã¯ããªé¢æ°ãéçŽããå®è£
ãšããã¡ã¯ããªé¢æ°ãšFxãçµã³ã€ããmodule.goãå®è£
ããããšã«ããŸããã å
·äœçã«ã¯ä»¥äžã§ãã åããã±ãŒãžæ¯ã«1ã€ãprovider.goãšãããã¡ã€ã«ãèšããåœè©²ããã±ãŒãžã®ãã¡ã¯ããªé¢æ°ã䞊ã¹ã ãã¡ã¯ããªé¢æ°ãšFxãçµã³ã€ãããããåããã±ãŒãžæ¯ã«1ã€module.goãèšãã module.goã¯fx.Provideã«ããã±ãŒãžå
ã®å
šãã¡ã¯ããªé¢æ°ãæž¡ããçµæåŸãããfx.Optionãè¿ã åŸãããfx.Option㯠Module ãšããåç§°ã§exportãã 管ç察象ãªããžã§ã¯ããå¿
èŠãªå Žåãå©çšè
åŽã該åœããããã±ãŒãžã® Module ã fx.Options ã«äžããŠäŸåæ§ã解決ãã provider.goã¯çšéæ¯ã«ãã«ãã¿ã° [^2]ã§åãæ¿ããã ãããã¯ã·ã§ã³çšã¯provider.goã ãã åäœãã¹ã æã¯provider_ut.goãå
éš çµåãã¹ã æã¯provider_it.goãšãã£ãå
·å ãªããžã㪠ã«äŸåããUsecaseãè€æ°ããäŸã§ãåŒã³åºãåŽã®ã³ãŒããšåãããŠç¢ºèªããŸãã provider.go package usecase import ( "sample-prj/domain/repository" ) func NewPaymentUsecase(repo repository.AccountRepository) PaymentUsecase { return &paymentUsecase{repo} } func NewRcvUsecase(repo repository.AccountRepository) RcvUsecase { return &rcvUsecase{repo} } module.go package usecase import "go.uber.org/fx" var Module = fx.Provide(NewPaymentUsecase, NewRcvUsecase) å©çšåŽã¯ãfx.Appã« Module ãäžããŠäŸåæ§ã解決ããŸãã fx.New( fx.Options( repository.Module, //ãªããžããªã®äŸåæ§ã解決ããã¢ãžã¥ãŒã« usecase.Module, //Usecaseã®äŸåæ§ã解決ããã¢ãžã¥ãŒã« ), fx.Invoke(ãã»ã»ã»çç¥ ) ãã«ãã¿ã° provier.goãmodule.goã§äŸåæ§ã¯è§£æ±ºã§ããããã«ãªããŸããã ãã ãããã§ã¯ãŸã ç°å¢ãç¶æ³ã«å¿ããŠã€ã³ã¿ãã§ãŒã¹ã®å®è£
ãåãæ¿ããããšã¯åºæ¥ãŸããã ããã§ããã«ãã¿ã°ãçšããŸãã ãã«ãã¿ã°ãšã¯Go tool ã«ãã£ãŠæäŸããã ãã«ãå¶çŽã·ã¹ãã ã§ãã ã³ãŒãã®å
é ã« //go:build [ã¿ã°å] ãä»äžããããšã§ããã«ã察象ãã¡ã€ã«ãæå®ããŸãã go build ã®tagsãªãã·ã§ã³ã§è€æ°åã®ã¿ã°åãæå®å¯èœã§ã該åœããã¿ã°åã®goãã¡ã€ã«ã®ã¿ãã«ã察象ãšãªããŸãã ãããèžãŸããprovider.goãšçµã¿åããããã«ãæŠè¡ã¯ä»¥äžã§ãã provider.goã«çšéæ¯ã®ãã«ãã¿ã°ãä»äžããã äºåã«ä»äžããã¿ã°ã決ããŠãããutïŒ åäœãã¹ã ïŒãitïŒå
éš çµåãã¹ã ïŒãªã© provider.goã®ãã¡ã€ã«å ãµãã£ãã¯ã¹ ã«ã¿ã°åãä»äžãããããã«ããããããã¯ã·ã§ã³çšã¯provider.goã ãã åäœãã¹ã æã¯provider_ut.goãå
éš çµåãã¹ã æã¯provider_it.goãšãã£ãå
·åã§å¶åŸ¡å¯èœã«ãªã ã¢ãžã¥ãŒã«å®çŸ©æ¹æ³ ã®ãµã³ãã«ã³ãŒãã«ãutãã«ãã¿ã°ãšãã®ä»ã¿ã°ãä»äžããprovider.goã®å®è£
ã¯ä»¥äžã§ãã ãªããã¢ãã¯å®è£
ã«ã¯ gomock ãå©çšããŠããŸãã provider_ut.go //go:build ut package usecase import ( "github.com/golang/mock/gomock" ) func NewPaymentUsecase(ctrl *gomock.Controller) PaymentUsecase { return NewMockPaymentUsecase(ctrl) } func NewRcvUsecase(ctrl *gomock.Controller) RcvUsecase { return NewMockRcvUsecase(ctrl) } provider.go //go:build it || stg package usecase import ( "sample-prj/domain/repository" ) func NewPaymentUsecase(repo repository.AccountRepository) PaymentUsecase { return &paymentUsecase{repo} } func NewRcvUsecase(repo repository.AccountRepository) RcvUsecase { return &rcvUsecase{repo} } ãªããžã㪠ã«äŸåããUsecaseãè€æ°ããã±ãŒã¹ã§ãprovider_ut.goãšprovider.goã§å®è£
ãåãæ¿ããŸãã åäœãã¹ã (ut) æã¯èªåçæããUsecaseã®ã¢ãã¯å®è£
ãçšããããå
éš çµåãã¹ã 以éã¯æ£èŠã®å®è£
ãçšããããŸãã Module.goãåŒã³åºãåŽã®ã³ãŒãã«å€æŽã¯ãããŸããã ãã®ä»ã®äŸ¿å©æ©èœ ä»ã«fxã§ç©æ¥µçã«äœ¿çšããŠããæ©èœã¯ fx.In ã§ãã äŸåé¢ä¿ãå¢ããŠãããšããã¡ã¯ããªé¢æ°ã®åŒæ°ãçžåœæ°ã«ãªããã³ãŒãã®èŠéããä¿å®æ§ãèããäœäžããŸãã ãããã£ãå ŽåãäŸåé¢ä¿ã®ãªããžã§ã¯ããå
šãŠå®çŸ©ããæ§é äœãäœæããŠInjectionããŸãã ãã®æ§é äœããã©ã¡ãŒã¿æ§é äœãšåŒã³ãŸãã äŸåé¢ä¿ãå¢ããå Žåã§ããã©ã¡ãŒã¿æ§é äœã«ãã£ãŒã«ãã远å ããã ãã§æžã¿ãããªã匷åãªæ©èœã§ãã ãµã³ãã«ã³ãŒãã§éãã確èªããŸãã SetlUsecaseãšãããè€æ°ã®ãªããžã§ã¯ãã«äŸåãã ãŠãŒã¹ã±ãŒã¹ ãäŸã«ãã¢ãžã¥ãŒã«å®çŸ©ãšçæãèŠãŠã¿ãŸãã ãã©ã¡ãŒã¿æ§é äœã䜿ããªãäŸ type SetlUsecase interface { Settle() } type setlUsecase struct { config *Config repoAccount AccountRepository repoSetl SettlementRepository repoCode CodeMasterRepository cal *Calendar setlExecutor SetlExecutor priorityJudger PriorityJudger } func NewSetlUsecase(config *Config, repoAccount AccountRepository, repoSetl SettlementRepository, repoCode CodeMasterRepository, cal *Calendar, setlExecutor SetlExecutor, priorityJudger PriorityJudger) SetlUsecase { return &setlUsecase{ config: config, repoAccount: repoAccount, repoSetl: repoSetl, repoCode: repoCode, cal: cal, setlExecutor: setlExecutor, priorityJudger: priorityJudger, } } ãã®çšåºŠãªããããŸã§ã§ããªãã§ãããå®éã®éçºã§ã¯ãã£ãšå€ãã®ãªããžã§ã¯ãã«äŸåããã±ãŒã¹ããããŸãã ãã以äžãã¡ã¯ããªé¢æ°ã®åŒæ°ãå¢ããã®ã¯èŸãã§ãããã ãã©ã¡ãŒã¿æ§é äœã§çœ®ãæããã³ãŒããèŠãŠã¿ãŸãããã ãã©ã¡ãŒã¿æ§é äœã§å®è£
ããäŸ // SetlUsecaseãšsetlUsecaseã¯ããã©ã¡ãŒã¿æ§é äœã䜿ããªãäŸããšåæ§ã®ããçç¥ type UsecaseParams struct { fx.In Config *Config RepoAccount AccountRepository RepoSetl SettlementRepository RepoCode CodeMasterRepository Cal *Calendar SetlExecutor SetlExecutor PriorityJudger PriorityJudger } func NewSetlUsecase(params UsecaseParams) SetlUsecase { return &setlUsecase{ config: params.Config, repoAccount: params.RepoAccount, repoSetl: params.RepoSetl, repoCode: params.RepoCode, cal: params.Cal, setlExecutor: params.SetlExecutor, priorityJudger: params.PriorityJudger, } } NewSetlUsecaseããã£ããããŸããã ãã ãããã©ã¡ãŒã¿æ§é äœã䜿ãäžã§ã以äžã®2ç¹ã¯ã泚æãã ããã ãã©ã¡ãŒã¿æ§é äœã®ãã£ãŒã«ãã¯exportããªããã°ãªããªã ãã¡ã¯ããªé¢æ°ã«äžãããã©ã¡ãŒã¿æ§é äœã¯ããã€ã³ã¿ã§æž¡ãããšãåºæ¥ãªãã®ã§å€ãšããŠæž¡ã äžèš1, 2ã«éåããå Žåãå®è¡æfxããšã©ãŒãåºåããŸãã ãšã©ãŒåºåäŸïŒ cannot depend on a pointer to a parameter object, use a value instead: *main.UsecaseParams is a pointer to a struct that embeds dig.In ããã§ãsetlUsecaseã«äŸåãããªããžã§ã¯ããå¢ãããšããŠããã³ã³ã¹ã ã©ã¯ ã¿é¢æ°ã«åŒæ°ã远å ããããã©ã¡ãŒã¿æ§é äœãžã®è¿œå ã§æžã¿ãŸãã ãŸãšã ä»åã¯goéçºã§DIãå°å
¥ããã話ã§ããã åœåã®ç®ç ã¯å
šãŠéæã§ããŠããã倧ããªãããããªãå¿«é©ã«éçºåºæ¥ãŠããŸãã ãªããžã§ã¯ãã®çæåŠçãäžå
çã«ç®¡çããæçŸ©ã¯å€§ããã皌å確èªãäžçºããã°åæåã«äŒŽãå®è£
ãã¹ã¯ã»ãŒãªããªããŸããã ãŸã坿¬¡çãªå¹æãšããŠãã¢ãžã¥ãŒã«éã®äŸåé¢ä¿ãæèããããšã§ãã€ã³ã¿ãã§ãŒã¹ãæŽç·Žãããå°è±¡ããããŸãã çµæãæ§ã
ãªèšèªã®DIã³ã³ãããç®æããšããã§ãããã€ã³ã¿ãŒãã§ãŒã¹ãšå®è£
ãåé¢ããŠæœè±¡åºŠãé«ãã倿Žå®¹ææ§ãåäžãããšããç¹ãéæã§ããŸããã goéçºã§DIå°å
¥ãæ€èšäžãªãã uber-go/fx ãéžæè¢ã®äžã€ãšããŠãèãã«ãªã£ãŠã¯ãããã§ããããã å·çïŒ @mizuno.kazuhiro ãã¬ãã¥ãŒïŒ @sato.taichi ïŒ Shodo ã§å·çãããŸãã ïŒ Facebook ããã® inject ã¯ã2022幎3æçŸåš ã¢ãŒã«ã€ã ãããŠãããéžå®ããå€ããŸããã ↩
é»éåœéæ
å ±ãµãŒãã¹ ãã¯ãã¹ ã€ãããŒã·ã§ã³ æ¬éšããªãŒãã³ ã€ãããŒã·ã§ã³ ã©ãã®æ¯åã§ãã ããã§ã¯ã ãããã¯ãã§ãŒã³ é±å ±3/15ãã£ãŠã¿ãããã éåžžæã®æå·è³ç£ éåžžæã®æå·è³ç£ã®ãã¥ãŒã¹ NFTè©æ¬º NFTè©æ¬ºã®ãã¥ãŒã¹ ãã®ä»ã®ãã¥ãŒã¹ éåžžæã®æå·è³ç£ ãã·ã¢ã®æå·è³ç£ãåçµããåããåºãŠããŸãããããŸã广ã¯ãªãããããªãããšæããŸããã©ãããŠããšãããšåçµããããšããŠããå£åº§ã¯ãæå·è³ç£ååŒæã®å£åº§ãªã®ã§ããã§ã«æå·è³ç£ã¯å¥ã®å人å£åº§ã«ééãããŠããå¯èœæ§ãé«ãããã§ããæå·è³ç£ã¯ãéäžå€®éæš©çã«å人å£åº§ãç°¡åã«äœããŸãã éåžžæã®æå·è³ç£ã®ãã¥ãŒã¹ æ¿åºãä»®æ³é貚ååŒã®åæ¢èŠè«ãé²å¶è£ã§ïŒïŒç€Ÿã« NFTè©æ¬º NFTã¯ãNFTã®çºè¡å
ïŒã¯ ãªãšãŒã¿ ãŒïŒãã¡ãããšããæš©å©è
ã§ããããšã確èªããã®ãé£ããã®ã§ãè©æ¬ºã暪è¡ããŠããŸããçºè¡å
ãä¿¡é Œã§ããªãNFTã¯ãä»ã®æ®µéã§ã¯è²·ããªãã»ããè¯ããšæããŸãã NFTã®ãªãããŸã察çãããŠãããµãŒãã¹ããããŸãã NFT SpoofingïŒãªãããŸãïŒå¯Ÿç Adobe ã㯠ãªãšãŒã¿ ãŒãèªèº«ã®äœåã§ããããšã蚌æããæ©èœãæäŸããŠããŸãã NFTè©æ¬ºã®ãã¥ãŒã¹ ããæ¥ãå¢ã«å§¿ãæ¶ãã¡ãã£ãææªãªNFTè©æ¬ºã¯ãŒã¹ã7ïŒ2022幎2æçïŒ 2æã ãã§ã10åå匱ã被害ã«ãã£ããšããéãããŸãã ã¢ããã®ãBehanceãããœã©ãå¯Ÿå¿ Ethereumã¯ãææ°æãé«ã/åŠçãé
ã/ç°å¢ã«æªããšããåé¡ãæ±ããŠããã®ã§Solanaã«ã察å¿ããã¿ããã§ããã ãã®ä»ã®ãã¥ãŒã¹ åå ±å DYãNFTããŒã±ãããã¬ã€ã¹éèšãžââã¹ããŒããã¢ãã¡ã鳿¥œã§ ãã¯ã€ãããŠã¹ãæå·éè³ç£ã«é¢ãã倧統é 什ãçºè¡š ã€ãŒãµãªã¢ã äºæãããã¯ãã§ãŒã³æ§ç¯ã¯ã©ãŠããªã©ãæãããG.U.ãã¯ãããžãŒãºããã¬ã·ãªãŒãºAã§2.6ååã®è¿œå 調é ãããè±Ethereumã®æµã 決æžå€§æStripeãæå·è³ç£æ±ºæžã®ãµããŒããåé å
æèªå¹³ãåŒéèšå¿µããžã¿ã«ã¢ãŒãNFT販売㞠絵ïŒäŒŒé¡çµµïŒïŒã®äºå®æäœå
¥æäŸ¡æ Œã¯400äžåçžåœã®ETHïŒ ã€ãŒãµãªã¢ã ïŒãšã®ããšãåç»ã®æ¹ã¯300ç¹éå®ã§ãå®äŸ¡8äžåãšã®ããšã§ãã å·çïŒ @higa ïŒ Shodo ã§å·çãããŸãã ïŒ
é»éåœéæ
å ±ãµãŒãã¹ ãã¯ãã¹ ã€ãããŒã·ã§ã³ æ¬éšããªãŒãã³ ã€ãããŒã·ã§ã³ ã©ãã®æ¯åã§ãã ããã§ã¯ã ãããã¯ãã§ãŒã³ é±å ±3/15ãã£ãŠã¿ãããã éåžžæã®æå·è³ç£ éåžžæã®æå·è³ç£ã®ãã¥ãŒã¹ NFTè©æ¬º NFTè©æ¬ºã®ãã¥ãŒã¹ ãã®ä»ã®ãã¥ãŒã¹ éåžžæã®æå·è³ç£ ãã·ã¢ã®æå·è³ç£ãåçµããåããåºãŠããŸãããããŸã广ã¯ãªãããããªãããšæããŸããã©ãããŠããšãããšåçµããããšããŠããå£åº§ã¯ãæå·è³ç£ååŒæã®å£åº§ãªã®ã§ããã§ã«æå·è³ç£ã¯å¥ã®å人å£åº§ã«ééãããŠããå¯èœæ§ãé«ãããã§ããæå·è³ç£ã¯ãéäžå€®éæš©çã«å人å£åº§ãç°¡åã«äœããŸãã éåžžæã®æå·è³ç£ã®ãã¥ãŒã¹ æ¿åºãä»®æ³é貚ååŒã®åæ¢èŠè«ãé²å¶è£ã§ïŒïŒç€Ÿã« NFTè©æ¬º NFTã¯ãNFTã®çºè¡å
ïŒã¯ ãªãšãŒã¿ ãŒïŒãã¡ãããšããæš©å©è
ã§ããããšã確èªããã®ãé£ããã®ã§ãè©æ¬ºã暪è¡ããŠããŸããçºè¡å
ãä¿¡é Œã§ããªãNFTã¯ãä»ã®æ®µéã§ã¯è²·ããªãã»ããè¯ããšæããŸãã NFTã®ãªãããŸã察çãããŠãããµãŒãã¹ããããŸãã NFT SpoofingïŒãªãããŸãïŒå¯Ÿç Adobe ã㯠ãªãšãŒã¿ ãŒãèªèº«ã®äœåã§ããããšã蚌æããæ©èœãæäŸããŠããŸãã NFTè©æ¬ºã®ãã¥ãŒã¹ ããæ¥ãå¢ã«å§¿ãæ¶ãã¡ãã£ãææªãªNFTè©æ¬ºã¯ãŒã¹ã7ïŒ2022幎2æçïŒ 2æã ãã§ã10åå匱ã被害ã«ãã£ããšããéãããŸãã ã¢ããã®ãBehanceãããœã©ãå¯Ÿå¿ Ethereumã¯ãææ°æãé«ã/åŠçãé
ã/ç°å¢ã«æªããšããåé¡ãæ±ããŠããã®ã§Solanaã«ã察å¿ããã¿ããã§ããã ãã®ä»ã®ãã¥ãŒã¹ åå ±å DYãNFTããŒã±ãããã¬ã€ã¹éèšãžââã¹ããŒããã¢ãã¡ã鳿¥œã§ ãã¯ã€ãããŠã¹ãæå·éè³ç£ã«é¢ãã倧統é 什ãçºè¡š ã€ãŒãµãªã¢ã äºæãããã¯ãã§ãŒã³æ§ç¯ã¯ã©ãŠããªã©ãæãããG.U.ãã¯ãããžãŒãºããã¬ã·ãªãŒãºAã§2.6ååã®è¿œå 調é ãããè±Ethereumã®æµã 決æžå€§æStripeãæå·è³ç£æ±ºæžã®ãµããŒããåé å
æèªå¹³ãåŒéèšå¿µããžã¿ã«ã¢ãŒãNFT販売㞠絵ïŒäŒŒé¡çµµïŒïŒã®äºå®æäœå
¥æäŸ¡æ Œã¯400äžåçžåœã®ETHïŒ ã€ãŒãµãªã¢ã ïŒãšã®ããšãåç»ã®æ¹ã¯300ç¹éå®ã§ãå®äŸ¡8äžåãšã®ããšã§ãã å·çïŒ @higa ïŒ Shodo ã§å·çãããŸãã ïŒ
ããã«ã¡ã¯ã é»éåœéæ
å ±ãµãŒãã¹ (ISID) XïŒã¯ãã¹ïŒ ã€ãããŒã·ã§ã³ æ¬éš ãœãããŠã§ã¢ãã¶ã€ã³ã»ã³ã¿ãŒ ã»ãã¥ãªãã£ã°ã«ãŒãã®å±±å£ã§ãã ISIDã§ã»ãã¥ãªãã£ã®æ
åœãããŠããŸããã AWS ãAzureçã® ã¯ã©ãŠã ãµãŒãã¹ãå©çšããã·ã¹ãã æ§ç¯ãäžè¬çã«ãªãããªã³ãã¬ãã¹ã§ã·ã¹ãã æ§ç¯ãããŠããé ãããäžçšæãªèšå®ãã¹ã«ãã ã»ãã¥ãªãã£ã€ã³ã·ãã³ã ãããç°¡åã«èµ·ãã£ãŠããŸãæä»£ã«ãªã£ããšæããŠããŸãã ãã®ãã㪠ã»ãã¥ãªãã£ã€ã³ã·ãã³ã ã鲿¢ããããã®è§£æ±ºçã®1ã€ãšããŠã AWS Security Hub 1 ããããŸãã Security Hubã¯ã»ãã¥ãªãã£æ
å ±ãåéã»ãã§ãã¯ã»è©äŸ¡ãè¡ãCSPM(Cloud Security Posture Management)æ©èœãæãããµãŒãã¹ã§ãã ä»åã¯ãSecurity Hubã䜿ã£ãŠããŠå°ã£ãããšãäžæãªç¹ã詳ãã調ã¹ãããšã«ã€ããŠã玹ä»ããŸãã 1. Secrets Managerã䜿çšããŠãèŠåãåºãä»¶ 1.1. 察象ã®ã»ãã¥ãªãã£åºæº2 1.2. èšå®æ¹æ³ 1.3. çåç¹ 1.4.ã¡ãªã¿ã« 2. NOT_AVAILABLE åé¡ 2.1. å°ã£ãããš 2.2. è§£æ±ºæ¹æ³ 2.3. ã¡ãªã¿ã« 3. æ¶ããªãS3ãã±ããåé¡ 3.1. 察象ã®ã»ãã¥ãªãã£åºæº[^2] 3.2. èšå®æ¹æ³ 3.3. å°ã£ãããš 3.4. è§£æ±ºæ¹æ³ 4. HTTPããããŒã®åé€ãšDesyncç·©åã¢ãŒã 4.1. 察象ã®ã»ãã¥ãªãã£åºæº[^2] 4.2. åãããªãã£ãããš 4.3. 確èªããããš 5. ãããã« 1. Secrets Managerã䜿çšããŠãèŠåãåºãä»¶ 1.1. 察象ã®ã»ãã¥ãªãã£åºæº 2 [CodeBuild.2] CodeBuild ãããžã§ã¯ã ç°å¢å€æ° ã«ã¯ãªã¢ããã¹ãã®èªèšŒæ
å ±ãå«ããããšã¯ã§ããŸãã ããã¯ãCodeBuild å
ã§ AWS _ ACCESS _KEY_ID ã AWS _SECRET_ ACCESS _KEY ãªã©ã®èªèšŒæ
å ±ã¯ãã¬ãŒã³ããã¹ãïŒã¯ãªã¢ããã¹ãïŒã§ä¿åããªãã§ãã ãããããšããå
容ã§ãã 1.2. èšå®æ¹æ³ èšå®ã¯ãã«ããããžã§ã¯ãã®äœææã«è¡ããŸãã èšå®ç»é¢ãèŠããšäžèšã®3ã€ã®äžããéžæã§ããããšãåãããŸãã CodeBuild.2 ã®ã¢ã©ãŒããæ€åºãããªãããã«ããããã®æ£è§£ã¯ããã©ã¡ãŒã¿ãã§ãã Systems Manager ãã©ã¡ãŒã¿ã¹ãã¢ããèªèšŒæ
å ±ãååŸããããã«ã§ããŸãã ãã¬ãŒã³ããã¹ãïŒã¯ãªã¢ããã¹ãïŒ ãã©ã¡ãŒã¿ Secrets Manager 1.3. çåç¹ ãã¬ãŒã³ããã¹ããã»ãã¥ãªãã£äžåé¡ãšãªãããšã¯åãããŸãããSecrets Managerã䜿ãã®ã¯ããããã«æããŸãã ã§ãããå®éã«Secrets Managerãæå®ãããš CodeBuild.2 ã§ãã£ããã¢ã©ãŒããäžãããŸãã ãã®ããšã AWS ãµããŒãã«ååãããŸããããSecurity Hubã®ä»æ§ãšã®ããšã§ã¢ã©ãŒããæ€åºãããããªãå Žåã¯ã察象ã®ã«ãŒã«ïŒã»ãã¥ãªãã£åºæºïŒãç¡å¹åãããããªãããã§ãã 1.4.ã¡ãªã¿ã« CodeBuildã®å®è¡ç°å¢ãã AWS ãªãœãŒã¹ã«ã¢ã¯ã»ã¹ãããå Žå AWS _ ACCESS _KEY_ID ã AWS _SECRET_ ACCESS _KEY ãCodeBuildã® ç°å¢å€æ° ã«èšå®ããã®ã§ã¯ãªããCodeBuildãããžã§ã¯ãã®ãµãŒãã¹ããŒã«ã«å¿
èŠãªæš©éãä»äžããããšã§è§£æ±ºã§ããŸãã 2. NOT_AVAILABLE åé¡ 2.1. å°ã£ãããš ä»åæ€èšŒããç°å¢ã§ã¯äžå³ã®ããã«éçŽã¢ã«ãŠã³ããæºåããŠãè€ æ°ã®å ã¢ã«ãŠã³ãã®æ€åºçµæãéçŽã¢ã«ãŠã³ãã§ç¢ºèªã§ããããã«ããŸããã ïŒSecurity Hubã®åäœã€ã¡ãŒãžïŒ ãšãããäžéšã®ã¢ã«ãŠã³ãã«å¯ŸããŠãç¹å®ã®ã»ãã¥ãªãã£åºæºã®æ€åºçµæã§ãNOT_AVAILABLEããšè¡šç€ºãããŠããããšã«æ°ãä»ããŸããã 2.2. è§£æ±ºæ¹æ³ AWS ãµããŒãã«åãåããããšãããã AWS Configã« AWS ãªãœãŒã¹ã®èšå®è©³çްãååŸããããã®æš©éãè¶³ããŠããªãã®ã§ã¯ãªãããããšããåçã§ããã Security Hub㯠AWS Configã« AWS ãªãœãŒã¹ã®ãã§ãã¯ã代è¡ããŠãããåäœã®ããã AWS Configã«åçš®ãªãœãŒã¹ãžã®ã¢ã¯ã»ã¹æš©éãå¿
èŠãšãªããŸãã ä»å㯠AWS ã®ç®¡çããªã·ãŒ AWS_ConfigRole ã AWS Configã®ããŒã«ã«å²ãåœãŠãããšã§æ£åžžã«æ€åºçµæã衚瀺ãããããã«ãªããŸããã 2.3. ã¡ãªã¿ã« AWS Configã®èšå®ç»é¢ããã AWS Config ãµãŒãã¹ã«ãªã³ã¯ãããããŒã«ã®äœæããéžæãããš AWSConfigServiceRolePolicy ãå«ãããŒã«ã AWS Configã«å²ãåœãŠãããŸãã äžèšã®ãªã³ã¯ããããåããããã« AWSConfigServiceRolePolicy ãš AWS_ConfigRole ã¯ã©ã¡ãã䜿çšããŠãåãã¢ã¯ã»ã¹èš±å¯ïŒ2022幎2æçŸåšïŒãšãªãããããã®äœ¿ãåãã«ã€ããŠã¯äžæã§ãã https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/security-iam-awsmanpol.html 3. æ¶ããªãS3 ãã±ãã åé¡ 3.1. 察象ã®ã»ãã¥ãªãã£åºæº[^2] [S3.5] S3 ãã±ãã ã¯ãSecure Socket Layer ã䜿çšããããã®ãªã¯ ãšã¹ ããå¿
èŠã§ã ããã¯ãS3 ãã±ãã ã®ããªã·ãŒã§ãSecure Socket Layer ( SSL ) ã§ã®ã¢ã¯ã»ã¹ãå¿
é ã«èšå®ããŠãã ãããããšããå
容ã§ãã 3.2. èšå®æ¹æ³ èšå®ã¯S3 ãã±ãã ã® ãã±ãã ããªã·ãŒã§è¡ããŸãã { " Id ": " ExamplePolicy ", " Version ": " 2012-10-17 ", " Statement ": [ { " Sid ": " AllowSSLRequestsOnly ", " Action ": " s3:* ", " Effect ": " Deny ", " Resource ": [ " S3 ãã±ããã® ARN ", " S3 ãã±ããã® ARN/* " ] , " Condition ": { " Bool ": { " aws:SecureTransport ": " false " } } , " Principal ": " * " } ] } 3.3. å°ã£ãããš æ®æ®µãã HTTPS ã§ã¢ã¯ã»ã¹ããŠãããããäžèšã®èšå®ãæå¹ã«ãªã£ãŠãããã倿ã§ããªãã£ãã®ã§ãè»œãæ°æã¡ã§ ãã±ãã ããªã·ãŒã倿ŽããŸããã ïŒå€æŽåïŒ "aws:SecureTransport": "false" ïŒå€æŽåŸïŒ "aws:SecureTransport": "true" ãããããšåœç¶ã§ãããS3 ãã±ãã ã«å¯Ÿãããã©ãŠã¶ããã® HTTPS éä¿¡ã¯å
šãŠèš±å¯ãããªããªããŸãã ãããŠãŠå
ã«æ»ãããšãããäžèšã®ããã« ãã±ãã ããªã·ãŒèªäœã«ãã¢ã¯ã»ã¹ã§ããªããªã£ãŠããŸããŸããã 3.4. è§£æ±ºæ¹æ³ ã«ãŒãã¢ã«ãŠã³ãã§ãã°ã€ã³ããã° ãã±ãã ããªã·ãŒãåé€ã§ããããã§ãããæš©éããªãã£ãã®ã§CloudShellããäžèšã®ã³ãã³ããå®è¡ã㊠ãã±ãã ããªã·ãŒãåé€ããŸããã aws s3api delete-bucket-policy --bucket "ãã±ããå" --endpoint-url http://s3.ap-northeast-1.amazonaws.com 4. HTTPããããŒã®åé€ãšDesyncç·©åã¢ãŒã 4.1. 察象ã®ã»ãã¥ãªãã£åºæº[^2] [ELB.4] HTTP ããããŒãåé€ããããã«ã¢ããªã±ãŒã·ã§ã³ ããŒããã©ã³ãµãŒ ãèšå®ããå¿
èŠããããŸã ããã¯ãHTTP desync æ»æãé²ãããã«ãApplication Load Balancerã§ç¡å¹ãª HTTP ããããŒå€ãããããããããã«èšå®ããŠãã ãããããšããå
容ã§ãã 4.2. åãããªãã£ãããš ã ããŒããã©ã³ãµãŒ 屿§ã®ç·šéãç»é¢ã«ãŠãç¡å¹ãªHTTPããããŒãåé€ã ãã§ãã¯ããã¯ã¹ ããªã³ã«ããããšã§ãã»ãã¥ãªãã£åºæºã¯ã¯ãªã¢ã§ããŸãã ããã§ãç»é¢ã®äžã«ãããDesync ç·©åã¢ãŒãããšãã䌌ããããªç®çã«æãã ãã§ãã¯ããã¯ã¹ ããã£ãã®ã§éãã AWS ãµããŒãã«èããŠã¿ãŸããã 4.3. 確èªããããš åæãšããŠãDesync ç·©åã¢ãŒãã¯äžèšã®URLã«ããããã«ããªã¯ ãšã¹ ãã®åé¡ãšALBã®ã¢ãŒãèšå®ã«åºã¥ããŠåäœã決å®ããŸãã 詳现ã¯äžèšã®URLãã芧ãã ããã https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/application-load-balancers.html 2ã€ã® ãã§ãã¯ããã¯ã¹ ã®éãã衚ã«ãŸãšãããšäžèšã®ããã«ãªããŸãã æ¯èŒé
ç® ç¡å¹ãªHTTPããããŒãåé€ Desync ç·©åã¢ãŒã èšå®ãã©ã¡ãŒã¿ routing.http. drop _invalid_header_fields.enabled routing.http.desync_mitigation_mode æ€æ»å¯Ÿè±¡ HTTPããã㌠HTTPãªã¯ ãšã¹ ãå
šäœ äžæ£ãªHTTPããããŒã®æ±ã HTTPããããŒãåé€ããŠãªã¯ ãšã¹ ããã¿ãŒã²ããã«è»¢é HTTPãªã¯ ãšã¹ ããç Žæ£ è©äŸ¡é å
åŸ AWS ãµããŒãããã®åçããŸãšãããšãç¡å¹ãªHTTPããããŒãåé€ããšãDesync ç·©åã¢ãŒããã®äž¡æ¹ã§äžæ£ãšå€æãããHTTPããããŒãå«ãHTTPãªã¯ ãšã¹ ãã®å Žåã¯äžå³ã®ãããªåäœã€ã¡ãŒãžã«ãªãããã§ãã 3 ãDesync ç·©åã¢ãŒããã®æ€èšŒã§ãããããããŠããHTTPãªã¯ ãšã¹ ããããç¡å¹ãªHTTPããããŒãåé€ããæå¹ã«ããããšã§ã¿ãŒã²ãããŸã§å°çãããããªåäœã«ãªãããšãé¢çœãã§ããã ãã®ããã«ããç¡å¹ãªHTTPããããŒãåé€ããšãDesync ç·©åã¢ãŒããã¯é¢é£ã匷ãèšå®é
ç®ã®ããã§ãã 5. ãããã« Security Hubã¯å°å
¥ãç°¡åã§ããµãŒãã¹å©çšã³ã¹ããããŸãæãããã人éã®ãã£ãããã¹ãæ·¡ã
ãšãã§ãã¯ããŠãããé ŒããããµãŒãã¹ã ãšæããŸãããããã AWS ã®ã»ãã¥ãªãã£å¯Ÿçãå§ããæ¹ã«ã¯ããããèŠãã§ããŸããä»åã®èšäºãSecurity Hubãå°å
¥ããéã®åèã«ãªãã°å¹žãã§ãã å·çïŒ @yamaguchi.masahiro ãã¬ãã¥ãŒïŒ @higa ïŒ Shodo ã§å·çãããŸãã ïŒ https://aws.amazon.com/jp/security-hub/ ↩ AWS åºç€ã»ãã¥ãªãã£ã®ãã¹ãã ã©ã¯ ãã£ã¹ïŒ https://docs.aws.amazon.com/ja_jp/securityhub/latest/userguide/securityhub-standards-fsbp-controls.html ïŒ ↩ 2022幎2æçŸåšã®ALBã®åäœã§ãããæ£åŒã«å
¬è¡šãããŠãã仿§ã§ã¯ãªãã ↩
ããã«ã¡ã¯ã é»éåœéæ
å ±ãµãŒãã¹ (ISID) XïŒã¯ãã¹ïŒ ã€ãããŒã·ã§ã³ æ¬éš ãœãããŠã§ã¢ãã¶ã€ã³ã»ã³ã¿ãŒ ã»ãã¥ãªãã£ã°ã«ãŒãã®å±±å£ã§ãã ISIDã§ã»ãã¥ãªãã£ã®æ
åœãããŠããŸããã AWS ãAzureçã® ã¯ã©ãŠã ãµãŒãã¹ãå©çšããã·ã¹ãã æ§ç¯ãäžè¬çã«ãªãããªã³ãã¬ãã¹ã§ã·ã¹ãã æ§ç¯ãããŠããé ãããäžçšæãªèšå®ãã¹ã«ãã ã»ãã¥ãªãã£ã€ã³ã·ãã³ã ãããç°¡åã«èµ·ãã£ãŠããŸãæä»£ã«ãªã£ããšæããŠããŸãã ãã®ãã㪠ã»ãã¥ãªãã£ã€ã³ã·ãã³ã ã鲿¢ããããã®è§£æ±ºçã®1ã€ãšããŠã AWS Security Hub 1 ããããŸãã Security Hubã¯ã»ãã¥ãªãã£æ
å ±ãåéã»ãã§ãã¯ã»è©äŸ¡ãè¡ãCSPM(Cloud Security Posture Management)æ©èœãæãããµãŒãã¹ã§ãã ä»åã¯ãSecurity Hubã䜿ã£ãŠããŠå°ã£ãããšãäžæãªç¹ã詳ãã調ã¹ãããšã«ã€ããŠã玹ä»ããŸãã 1. Secrets Managerã䜿çšããŠãèŠåãåºãä»¶ 1.1. 察象ã®ã»ãã¥ãªãã£åºæº2 1.2. èšå®æ¹æ³ 1.3. çåç¹ 1.4.ã¡ãªã¿ã« 2. NOT_AVAILABLE åé¡ 2.1. å°ã£ãããš 2.2. è§£æ±ºæ¹æ³ 2.3. ã¡ãªã¿ã« 3. æ¶ããªãS3ãã±ããåé¡ 3.1. 察象ã®ã»ãã¥ãªãã£åºæº[^2] 3.2. èšå®æ¹æ³ 3.3. å°ã£ãããš 3.4. è§£æ±ºæ¹æ³ 4. HTTPããããŒã®åé€ãšDesyncç·©åã¢ãŒã 4.1. 察象ã®ã»ãã¥ãªãã£åºæº[^2] 4.2. åãããªãã£ãããš 4.3. 確èªããããš 5. ãããã« 1. Secrets Managerã䜿çšããŠãèŠåãåºãä»¶ 1.1. 察象ã®ã»ãã¥ãªãã£åºæº 2 [CodeBuild.2] CodeBuild ãããžã§ã¯ã ç°å¢å€æ° ã«ã¯ãªã¢ããã¹ãã®èªèšŒæ
å ±ãå«ããããšã¯ã§ããŸãã ããã¯ãCodeBuild å
ã§ AWS _ ACCESS _KEY_ID ã AWS _SECRET_ ACCESS _KEY ãªã©ã®èªèšŒæ
å ±ã¯ãã¬ãŒã³ããã¹ãïŒã¯ãªã¢ããã¹ãïŒã§ä¿åããªãã§ãã ãããããšããå
容ã§ãã 1.2. èšå®æ¹æ³ èšå®ã¯ãã«ããããžã§ã¯ãã®äœææã«è¡ããŸãã èšå®ç»é¢ãèŠããšäžèšã®3ã€ã®äžããéžæã§ããããšãåãããŸãã CodeBuild.2 ã®ã¢ã©ãŒããæ€åºãããªãããã«ããããã®æ£è§£ã¯ããã©ã¡ãŒã¿ãã§ãã Systems Manager ãã©ã¡ãŒã¿ã¹ãã¢ããèªèšŒæ
å ±ãååŸããããã«ã§ããŸãã ãã¬ãŒã³ããã¹ãïŒã¯ãªã¢ããã¹ãïŒ ãã©ã¡ãŒã¿ Secrets Manager 1.3. çåç¹ ãã¬ãŒã³ããã¹ããã»ãã¥ãªãã£äžåé¡ãšãªãããšã¯åãããŸãããSecrets Managerã䜿ãã®ã¯ããããã«æããŸãã ã§ãããå®éã«Secrets Managerãæå®ãããš CodeBuild.2 ã§ãã£ããã¢ã©ãŒããäžãããŸãã ãã®ããšã AWS ãµããŒãã«ååãããŸããããSecurity Hubã®ä»æ§ãšã®ããšã§ã¢ã©ãŒããæ€åºãããããªãå Žåã¯ã察象ã®ã«ãŒã«ïŒã»ãã¥ãªãã£åºæºïŒãç¡å¹åãããããªãããã§ãã 1.4.ã¡ãªã¿ã« CodeBuildã®å®è¡ç°å¢ãã AWS ãªãœãŒã¹ã«ã¢ã¯ã»ã¹ãããå Žå AWS _ ACCESS _KEY_ID ã AWS _SECRET_ ACCESS _KEY ãCodeBuildã® ç°å¢å€æ° ã«èšå®ããã®ã§ã¯ãªããCodeBuildãããžã§ã¯ãã®ãµãŒãã¹ããŒã«ã«å¿
èŠãªæš©éãä»äžããããšã§è§£æ±ºã§ããŸãã 2. NOT_AVAILABLE åé¡ 2.1. å°ã£ãããš ä»åæ€èšŒããç°å¢ã§ã¯äžå³ã®ããã«éçŽã¢ã«ãŠã³ããæºåããŠãè€ æ°ã®å ã¢ã«ãŠã³ãã®æ€åºçµæãéçŽã¢ã«ãŠã³ãã§ç¢ºèªã§ããããã«ããŸããã ïŒSecurity Hubã®åäœã€ã¡ãŒãžïŒ ãšãããäžéšã®ã¢ã«ãŠã³ãã«å¯ŸããŠãç¹å®ã®ã»ãã¥ãªãã£åºæºã®æ€åºçµæã§ãNOT_AVAILABLEããšè¡šç€ºãããŠããããšã«æ°ãä»ããŸããã 2.2. è§£æ±ºæ¹æ³ AWS ãµããŒãã«åãåããããšãããã AWS Configã« AWS ãªãœãŒã¹ã®èšå®è©³çްãååŸããããã®æš©éãè¶³ããŠããªãã®ã§ã¯ãªãããããšããåçã§ããã Security Hub㯠AWS Configã« AWS ãªãœãŒã¹ã®ãã§ãã¯ã代è¡ããŠãããåäœã®ããã AWS Configã«åçš®ãªãœãŒã¹ãžã®ã¢ã¯ã»ã¹æš©éãå¿
èŠãšãªããŸãã ä»å㯠AWS ã®ç®¡çããªã·ãŒ AWS_ConfigRole ã AWS Configã®ããŒã«ã«å²ãåœãŠãããšã§æ£åžžã«æ€åºçµæã衚瀺ãããããã«ãªããŸããã 2.3. ã¡ãªã¿ã« AWS Configã®èšå®ç»é¢ããã AWS Config ãµãŒãã¹ã«ãªã³ã¯ãããããŒã«ã®äœæããéžæãããš AWSConfigServiceRolePolicy ãå«ãããŒã«ã AWS Configã«å²ãåœãŠãããŸãã äžèšã®ãªã³ã¯ããããåããããã« AWSConfigServiceRolePolicy ãš AWS_ConfigRole ã¯ã©ã¡ãã䜿çšããŠãåãã¢ã¯ã»ã¹èš±å¯ïŒ2022幎2æçŸåšïŒãšãªãããããã®äœ¿ãåãã«ã€ããŠã¯äžæã§ãã https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/security-iam-awsmanpol.html 3. æ¶ããªãS3 ãã±ãã åé¡ 3.1. 察象ã®ã»ãã¥ãªãã£åºæº[^2] [S3.5] S3 ãã±ãã ã¯ãSecure Socket Layer ã䜿çšããããã®ãªã¯ ãšã¹ ããå¿
èŠã§ã ããã¯ãS3 ãã±ãã ã®ããªã·ãŒã§ãSecure Socket Layer ( SSL ) ã§ã®ã¢ã¯ã»ã¹ãå¿
é ã«èšå®ããŠãã ãããããšããå
容ã§ãã 3.2. èšå®æ¹æ³ èšå®ã¯S3 ãã±ãã ã® ãã±ãã ããªã·ãŒã§è¡ããŸãã { " Id ": " ExamplePolicy ", " Version ": " 2012-10-17 ", " Statement ": [ { " Sid ": " AllowSSLRequestsOnly ", " Action ": " s3:* ", " Effect ": " Deny ", " Resource ": [ " S3 ãã±ããã® ARN ", " S3 ãã±ããã® ARN/* " ] , " Condition ": { " Bool ": { " aws:SecureTransport ": " false " } } , " Principal ": " * " } ] } 3.3. å°ã£ãããš æ®æ®µãã HTTPS ã§ã¢ã¯ã»ã¹ããŠãããããäžèšã®èšå®ãæå¹ã«ãªã£ãŠãããã倿ã§ããªãã£ãã®ã§ãè»œãæ°æã¡ã§ ãã±ãã ããªã·ãŒã倿ŽããŸããã ïŒå€æŽåïŒ "aws:SecureTransport": "false" ïŒå€æŽåŸïŒ "aws:SecureTransport": "true" ãããããšåœç¶ã§ãããS3 ãã±ãã ã«å¯Ÿãããã©ãŠã¶ããã® HTTPS éä¿¡ã¯å
šãŠèš±å¯ãããªããªããŸãã ãããŠãŠå
ã«æ»ãããšãããäžèšã®ããã« ãã±ãã ããªã·ãŒèªäœã«ãã¢ã¯ã»ã¹ã§ããªããªã£ãŠããŸããŸããã 3.4. è§£æ±ºæ¹æ³ ã«ãŒãã¢ã«ãŠã³ãã§ãã°ã€ã³ããã° ãã±ãã ããªã·ãŒãåé€ã§ããããã§ãããæš©éããªãã£ãã®ã§CloudShellããäžèšã®ã³ãã³ããå®è¡ã㊠ãã±ãã ããªã·ãŒãåé€ããŸããã aws s3api delete-bucket-policy --bucket "ãã±ããå" --endpoint-url http://s3.ap-northeast-1.amazonaws.com 4. HTTPããããŒã®åé€ãšDesyncç·©åã¢ãŒã 4.1. 察象ã®ã»ãã¥ãªãã£åºæº[^2] [ELB.4] HTTP ããããŒãåé€ããããã«ã¢ããªã±ãŒã·ã§ã³ ããŒããã©ã³ãµãŒ ãèšå®ããå¿
èŠããããŸã ããã¯ãHTTP desync æ»æãé²ãããã«ãApplication Load Balancerã§ç¡å¹ãª HTTP ããããŒå€ãããããããããã«èšå®ããŠãã ãããããšããå
容ã§ãã 4.2. åãããªãã£ãããš ã ããŒããã©ã³ãµãŒ 屿§ã®ç·šéãç»é¢ã«ãŠãç¡å¹ãªHTTPããããŒãåé€ã ãã§ãã¯ããã¯ã¹ ããªã³ã«ããããšã§ãã»ãã¥ãªãã£åºæºã¯ã¯ãªã¢ã§ããŸãã ããã§ãç»é¢ã®äžã«ãããDesync ç·©åã¢ãŒãããšãã䌌ããããªç®çã«æãã ãã§ãã¯ããã¯ã¹ ããã£ãã®ã§éãã AWS ãµããŒãã«èããŠã¿ãŸããã 4.3. 確èªããããš åæãšããŠãDesync ç·©åã¢ãŒãã¯äžèšã®URLã«ããããã«ããªã¯ ãšã¹ ãã®åé¡ãšALBã®ã¢ãŒãèšå®ã«åºã¥ããŠåäœã決å®ããŸãã 詳现ã¯äžèšã®URLãã芧ãã ããã https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/application-load-balancers.html 2ã€ã® ãã§ãã¯ããã¯ã¹ ã®éãã衚ã«ãŸãšãããšäžèšã®ããã«ãªããŸãã æ¯èŒé
ç® ç¡å¹ãªHTTPããããŒãåé€ Desync ç·©åã¢ãŒã èšå®ãã©ã¡ãŒã¿ routing.http. drop _invalid_header_fields.enabled routing.http.desync_mitigation_mode æ€æ»å¯Ÿè±¡ HTTPããã㌠HTTPãªã¯ ãšã¹ ãå
šäœ äžæ£ãªHTTPããããŒã®æ±ã HTTPããããŒãåé€ããŠãªã¯ ãšã¹ ããã¿ãŒã²ããã«è»¢é HTTPãªã¯ ãšã¹ ããç Žæ£ è©äŸ¡é å
åŸ AWS ãµããŒãããã®åçããŸãšãããšãç¡å¹ãªHTTPããããŒãåé€ããšãDesync ç·©åã¢ãŒããã®äž¡æ¹ã§äžæ£ãšå€æãããHTTPããããŒãå«ãHTTPãªã¯ ãšã¹ ãã®å Žåã¯äžå³ã®ãããªåäœã€ã¡ãŒãžã«ãªãããã§ãã 3 ãDesync ç·©åã¢ãŒããã®æ€èšŒã§ãããããããŠããHTTPãªã¯ ãšã¹ ããããç¡å¹ãªHTTPããããŒãåé€ããæå¹ã«ããããšã§ã¿ãŒã²ãããŸã§å°çãããããªåäœã«ãªãããšãé¢çœãã§ããã ãã®ããã«ããç¡å¹ãªHTTPããããŒãåé€ããšãDesync ç·©åã¢ãŒããã¯é¢é£ã匷ãèšå®é
ç®ã®ããã§ãã 5. ãããã« Security Hubã¯å°å
¥ãç°¡åã§ããµãŒãã¹å©çšã³ã¹ããããŸãæãããã人éã®ãã£ãããã¹ãæ·¡ã
ãšãã§ãã¯ããŠãããé ŒããããµãŒãã¹ã ãšæããŸãããããã AWS ã®ã»ãã¥ãªãã£å¯Ÿçãå§ããæ¹ã«ã¯ããããèŠãã§ããŸããä»åã®èšäºãSecurity Hubãå°å
¥ããéã®åèã«ãªãã°å¹žãã§ãã å·çïŒ @yamaguchi.masahiro ãã¬ãã¥ãŒïŒ @higa ïŒ Shodo ã§å·çãããŸãã ïŒ https://aws.amazon.com/jp/security-hub/ ↩ AWS åºç€ã»ãã¥ãªãã£ã®ãã¹ãã ã©ã¯ ãã£ã¹ïŒ https://docs.aws.amazon.com/ja_jp/securityhub/latest/userguide/securityhub-standards-fsbp-controls.html ïŒ ↩ 2022幎2æçŸåšã®ALBã®åäœã§ãããæ£åŒã«å
¬è¡šãããŠãã仿§ã§ã¯ãªãã ↩