Upgrade to Pro — share decks privately, control downloads, hide ads and more …

実践ブロックチェーンゲーム/Blockchain Game in Practice

3383368c2bd31bbc7cc9c6043e335e09?s=47 Ryo Manzoku
December 17, 2018

実践ブロックチェーンゲーム/Blockchain Game in Practice

2018-12-17 blockchain.tokyo #15
https://blockchain-tokyo.connpass.com/event/110424/

3383368c2bd31bbc7cc9c6043e335e09?s=128

Ryo Manzoku

December 17, 2018
Tweet

Transcript

  1. None
  2. ࣮ફϒϩοΫνΣʔϯήʔϜ 2018-12-17 blockchain.tokyo#15 @rmanzoku

  3. ࣗݾ঺հ Name: Ryo Manzoku @rmanzoku Work: double jump.tokyo inc Job:

    Blockchain Engineer Sidework: 
 SRE / Cloud Infrastructure Language:
 Golang / Python
  4. https://mch.gg/

  5. My Crypto Heroes֓ཁ My Crypto HeroesɺMCHɺϚΠΫϦ 2018-11-30 ਖ਼ࣜαʔϏε։࢝ EthereumΛར༻ͨ͠ϒϩοΫνΣʔϯήʔϜ ϫʔΧʔϓϨΠεϝϯτܕRPG

    Ξηοτ(ERC721)͸Ethereum mainnet ʹͯ؅ཧ ήʔϜϩδοΫ͸ΦϑνΣʔϯαʔόʹ࣮ͯߦ PCͰ΋εϚϗͰ΋ɺWallet͕ͳͯ͘΋༡΂Δ
  6. My Crypto Heroes֓ཁ ήʔϜʹ͔͚ͨ࣌ؒ΋͓ۚ΋৘೤΋ɺ
 ͋ͳͨͷࢿ࢈ͱͳΔੈք Ethereumʹ͋ΔAsset͸Ϣʔβʔ͕ࣗ༝ʹѻ͏͜ͱ͕Ͱ͖Δ AssetΛҭ੒͢Δ͜ͱͰࢿ࢈ͱͯ͠ͷՁ஋ΛߴΊΔ͜ͱ͕Մೳ Assetͱͯ͠ύʔςΟʹฤ੒Ͱ͖ΔHeroͱHero͕૷උ͢Δ Extensionͷ2͕ͭ͋Δʢ2018/12/16࣌఺ʣ Asset͸Smart

    ContractʹΑͬͯൃߦ্ݶ͕ఆΊΒΕ͍ͯΔ
  7. ࠓ೔࿩͢͜ͱ HiCon2018Ͱൃදͨ͠಺༰ͷิ଍ MCHͰՔಇ͍ͯ͠ΔSmart Contractͷղઆ ࠓ೔ͷEthereumͰɺήʔϜͷΑ͏ͳෳࡶͳϩδοΫΛ࣮૷͢Δͷ͸ ෆՄೳ ͱ͸͍͑αʔϏεΛੈͷதʹग़͞Ͷ͹࢝·Βͳ͍ EthereumͷੈքͱήʔϜͷੈքΛܨ͙ٕज़ Թ౓ײ͕Θ͔Βͳ͔ͬͨͷͰط஌ͷ৘ใ͹͔ΓͩͬͨΒ͢Έ·ͤΜ

  8. ٕज़എܠ AssetΛΦϯνΣʔϯɺήʔϜ͸ΦϑνΣʔϯͱͯ͠اըʢ4݄ʣ Etheremonͷॿݴ΋͋ΓΦϯνΣʔϯʢEVMʣͰͷ࣮૷΁ํ਑స ׵ʢ6݄ʣ ʢࢲ͕δϣΠϯʣ Loom NetworkΛ࢖ͬͨότϧβΛ࣮ࢪɺݱ࣌఺ͰͷΦϯνΣʔϯ ࣮૷Λஅ೦ʢ10݄ʣ େ෦෼ΛΦϑνΣʔϯԽʢ11݄ʣ

  9. HiCon2018Ͱͷൃද https://mch.gg/hicon2018

  10. HiCon2018Ͱͷൃද https://mch.gg/hicon2018

  11. EVM on Loom SDK Loom݁ߏ଎͍ ϒϩοΫੜ੒଎౓͸1ඵ ͔͠͠ότϧॲཧʹ10ඵҎ্͔͔Δ ͦͷؒɺWrite͸͢΂ͯϒϩοΫ Read΋Կނ͔ॏ͍

  12. HiCon2018Ͱͷൃද https://mch.gg/hicon2018

  13. Eventϩʔυόϥϯαʔ Master LoomͷEventΛGoरͬͯɺSlave LoomʹॲཧΛ ྲྀ͢όον͕ಈ͍͍ͯΔ ൃ૝ͱͯ͠͸State-channelʹ͍ۙ͸ͣ ࣄ্࣮ͷϩʔυόϥϯαʔ ʢͦ΋ͦ΋Master/Slaveͬͯɺɺɺʣ EventΛरͬͯॲཧ͢ΔͷͰΤϯυΤϯυͩͱ਺ඵ͔͔ Δ͕ϒϩοΫ͸ͳ͘ͳΔ

  14. SidechainͰͷݶք ͦ΋ͦ΋ϒϩοΫνΣʔϯͰ͋ΔҎ্ɺγϦΞϧॲ ཧͰ͔࣮͠ߦͰ͖ͳ͍ CPUར༻ޮ཰͸ѱ͍ ࢖͍͍͑ͯͤͥ3ίΞఔ౓ ότϧͷϩάΛు͖͗ͯ͢1ϲ݄Ͱ100GB͘Β͍σΟ εΫΛ৯͏ ͜ͷ࣌ظɺேཁܾ݅·ͬͯ༦ํʹ͸৽نαʔόʹσ ϓϩΠΈ͍ͨͳঢ়گͩͬͨ

  15. HiCon2018Ͱͷൃද https://mch.gg/hicon2018

  16. HiCon2018Ͱͷൃද https://mch.gg/hicon2018

  17. None
  18. None
  19. MCHͷήʔϜੑ HeroΛETHͳͲͰखʹೖΕɺΫΤετʹ޲͔͍ใुͰ͋ ΔExtensionΛऩू Hero΍ExtensionͷϨϕϧΛ্͛ߴ೉қ౓ͷΫΤετ΁ ௅ઓ खʹೖΕͨHeroɺExtensionΛήʔϜ಺औҾॴͰചങ ॴ༗͢ΔHeroɺExtensionΛEthereum্΁సૹ

  20. Main chainͰ؅ཧ͢Δ΋ͷ Hero/Extension Assetॴ༗ݖ Hero/Extension Assetൃߦ্ݶ Hero/ExtensionΛήʔϜ಺Ͱར༻͢ΔͨΊͷGateway

  21. Smart contractʹ͍ͭͯ Ethereum্ͰϩδοΫΛಈ͔ͨ͢ΊͷϓϩάϥϜ MCHͰ͸ಁ໌ੑ֬อͷͨΊEtherscanͰެ։ https://mch.gg/etherscan ࠓޙOSS΍Ұ෦ϩδοΫʹ͍ͭͯ͸ϥΠηϯεܖ໿ ͷݩɺଞࣾͰ΋ར༻Ͱ͖ΔΑ͏ʹ੔උ༧ఆ MCH͸ۀքൃలͷͨΊੵۃతʹٕज़Λ৘ใެ։

  22. ERC 721ͱ͸ Ethereumͷඪ४ن֨ͷҰͭͰNon-Fungible TokenʢNFTʣΛنఆ ͨ͠ΠϯλʔϑΣʔε NFTͱ͸ɺ୅ସෆՄೳͳ΋ͷ CryptoKittiesΛൃ୺ʹEthereum্ͰToken/Assetͷॴ༗ݖͳͲΛن ఆ ࢀর࣮૷ͱͯ͠OpenZeppelinOSͷ΋ͷ͕༗໊ CryptoZombies΋ERC721

    ERC20ͱൺֱ͞ΕΔ
  23. Assetॴ༗ݖ ERC 721 NFT ͩΕ͕͜ͷAssetΛॴ༗͍ͯ͠Δ͔ AssetΛੜΈग़͢Mint΍ॴ༗ݖΛҠৡ͢ΔTransferͳ Ͳ OpenZeppelin 2.0 RC1Λܧঝ

    Hero/Extensionͱ΋ʹERC721
  24. Assetൃߦ্ݶ ERC 721ʹ௥Ճ࣮૷ ৽Hero΍৽Extension࣮૷࣌ʹࣄલʹൃߦ਺Ληοτ Mint࣌ʹൃߦ਺νΣοΫ Type͝ͱʹೳྗ͕͋ΓɺͦͷTypeͷൃߦ্ݶ͕ܾ·͍ͬͯΔ CryptoKittiesͳͲͱҧ͍ɺID͔Βೳྗ͕ܾఆ͢ΔΘ͚Ͱ͸ͳ͍ ΋ͪΖΜՁ஋ͷߴ͍΋ͷ΄Ͳൃߦ਺͕গͳ͍ ৫ా৴௕͸ੈքʹ10ମ͔͠ੜ·Ε·ͤΜʂΛContractͰอূ

  25. Assetൃߦ্ݶ mapping(uint16 => uint16) private extensionTypeToSupplyLimit; function setSupplyLimit(uint16 _extensionType, uint16

    _supplyLimit) external onlyMinter { require(_supplyLimit != 0); require(extensionTypeToSupplyLimit[_extensionType] == 0 || _supplyLimit < extensionTypeToSupplyLimit[_extensionType], "_supplyLimit is bigger”); extensionTypeToSupplyLimit[_extensionType] = _supplyLimit; } function mintExtensionAsset(address _owner, uint256 _tokenId) public onlyMinter { uint16 _extensionType = uint16(_tokenId / EXTENSION_TYPE_OFFSET); uint16 _extensionTypeIndex = uint16(_tokenId % EXTENSION_TYPE_OFFSET) - 1; require(_extensionTypeIndex < extensionTypeToSupplyLimit[_extensionType], "supply over"); _mint(_owner, _tokenId); }
  26. Asset Gateway ήʔϜ಺ͰAssetͷऔҾ͕ߦ͑ΔͨΊɺήʔϜ಺Ͱѻ͍ͬͯ ΔAssetʹసૹͳͲߦ͑ͳ͍Α͏ϩοΫ͢Δඞཁ͕͋Δɻ Gateway contract͕͋ΓɺͦͷContractʹAssetΛTransfer ͢Δ͜ͱͰ࣮ݱ Deposit / Withdrawͱ࣮ͯ͠૷

    OpenZeppelinOSͰɺContract͕ड͚औΔ৔߹ ERC721Receiver͕نఆ͞Ε͍ͯΔͷͰै͏ͱྑ͍
  27. ͦ΋ͦ΋ͳͥGateway͔ Ethereum্Ͱ͢΂ͯͷϩδοΫΛ࣮૷͢ΔͱGasͳͲͷϢʔ βʔίετ͕͔͔ΔɺUXతʹਏ͍ PlasmaΛච಄ʹεέʔϦϯάٕज़͸ߟҊ͞Ε͍ͯΔ΋ͷͷ ࣮Քಇ͍ͯ͠Δ΋ͷ͸΄΅ͳ͍ ϝΠϯνΣʔϯͱʮεέʔϦϯάٕज़XʯΛܨ͙ٕज़͕ඞཁ Xʹ͸޷͖ͳݴ༿ΛೖΕΑ͏ MCHͰ͸ΦϑνΣʔϯ

  28. ܨ͙ٕज़ ContractͷEventΛ࢖͏ GatewayʹAsset͕Transfer͞Εͨͱ͍͏EventΛ؂ࢹ EventΛΫϩʔϧ͠ɺΦϑνΣʔϯͷgRPCΛ࣮ߦ͢Δ औΓ͜΅͕͠ා͍ͷͰఆظ࣮ߦ͢Δ TxHashΛ࢖ͬͯႈ౳ੑΛอূ͢Δ

  29. ͭ·ΓͨͩͷBatch

  30. abigen Solidityͷίʔυ͔ΒGolangΫϥΠΞϯτίʔυΛࣗ ಈੜ੒ͯ͘͠ΕΔίϚϯυ https://github.com/ethereum/go-ethereum/wiki/ Native-DApps:-Go-bindings-to-Ethereum-contracts Event subscription͕·ͩ࢖͑ͳ͍ͦ͏Ͱ͕͢ɺόο ν༻్ʹ͸े෼࢖͑Δ

  31. $ abigen --abi token.abi -pkg main -type Token -out token.go

    package main import ( "fmt" “log" “token” "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethclient" ) func main() { // Create an IPC based RPC connection to a remote node conn, err := ethclient.Dial("/home/karalabe/.ethereum/testnet/geth.ipc") if err != nil { log.Fatalf("Failed to connect to the Ethereum client: %v", err) } // Instantiate the contract and display its name token, err := NewToken(common.HexToAddress("0x21e6fc92f93c8a1bb41e2be64b4e1f88a54d3576"), conn) if err != nil { log.Fatalf("Failed to instantiate a Token contract: %v", err) } name, err := token.Name(nil) if err != nil { log.Fatalf("Failed to retrieve token name: %v", err) } fmt.Println("Token name:", name) }
  32. abigenΊͬͪΌศར ͦ΋ͦ΋Solidity/web3͸abi͔Βࢉग़Ͱ͖ΔόΠτίʔυΛ ΍ΓͱΓ͢ΔͷͰͦͷղऍΛ͢Δඞཁ͕͋Δ ϒϥ΢βͷ৔߹͸web3.jsΛ࢖͏ ͍ͭϝδϟʔόʔδϣϯ͕͋ΔΜͰ͠ΐ͏Ͷɺɺ αʔόͷ৔߹͸ɺNodeJSΛ࢖͏͔ɺabigenͨ͠GoΛ࢖͏ͷ ͕ݱঢ়ͷબ୒ࢶͰ͸ ༨ஊͰ͕͢ɺethereum/go-ethereumϦϙδτϦ͸͔ͳΓಡ ΈࠐΉ͜ͱʹͳΔʢυΩϡϝϯτ͸͋·Γͳ͍ʣ

  33. op, _ := crawler.GetCommandOptions() c, err := crawler.NewCrawler(op) c.FilterOpts.End, err

    = c.SafeBlockNum(3) contract, err := gum_gateway.NewGumGateway(c.Contract()) iter, err := contract.FilterSold(c.FilterOpts, nil, nil) grpcClient := gateway.NewGatewayServiceClient(c.GRPC) for iter.Next() { e := iter.Event if e.Raw.Removed { fmt.Printf("level:info\tmsg:%s removed block\n", e.Raw.TxHash.String()) continue } input := &gateway.PurchaseInfo{ EthPurchaser: e.User.String(), EthAffiliator: e.Referrer.String(), EthAmountGwei: crawler.ToGwei(e.Value).Uint64(), TxHash: e.Raw.TxHash.String(), } if !op.DryRun { _, err := grpcClient.GumSale(context.Background(), input) if err != nil { if strings.HasPrefix(err.Error(), "rpc error: code = Unknown desc = Error 1062: Duplicate entry") { fmt.Printf("level:debug\tmsg:%s already affected\n", e.Raw.TxHash.String()) continue } return err } } fmt.Printf("level:info\tmsg:%s is affected \n", e.Raw.TxHash.String()) }
  34. ߟྀ఺ Կ౓Ͱ΋͍͏͕ႈ౳ੑ͕ॏཁ ྫ͑͹ɺΦϑνΣʔϯͰॲཧΛߦͬͨͱ͍͏͜ͱΛ Ethererum্ʹه࿥͠Α͏ʹ΋࠶౓Tx͕ඞཁʹͳΔ EthereumͷTxHashΛ࢖ͬͯΦϑνΣʔϯଆͰႈ౳ ੑΛ୲อ͢Δ DBͷҰҙ੍໿Ͱ࣮ݱ

  35. ߟྀ఺ AssetΛϢʔβʔʹฦ͢৔߹΋ಉ͡ɻ ΦϑνΣʔϯͰTxHashతͳ΋ͷΛൃߦ͠ɺίϯτϥ ΫτʹΘͨ͢ɻ ίϯτϥΫτͰҰҙ੍໿ɺɺͱ͍ͨ͠ͱ͜Ζ͕ͩݱঢ় ͸Eventൃߦ͍ͯ͠Δ͚ͩ όον্ͰEventΛݟͯႈ౳ੑΛ୲อ

  36. ߟྀ఺ SafeBlockͱ͍͏ߟ͑ ϒϩοΫνΣʔϯͳͷͰreorg͕͋Γ͑Δ nϒϩοΫܦͬͨΒ֬ఆͱΈͳ͢ Ϣʔβʔͷࢿ࢈ΛकΔͨΊʢ͜ͷล͸҉߸௨՟औҾ ॴ͞Μͷ΄͏͕ৄ͍͠͸ͣɺɺʣ γεςϜతʹ໊લ͍ͭͯͨΓ͠·͔͢Ͷʁ

  37. ·ͱΊ EthereumͰɺήʔϜͷΑ͏ͳෳࡶͳϩδοΫΛ࣮૷ ͢Δͷ͸ෆՄೳ αʔϏεͱͯ͠ੈͷதʹग़ͨ͢ΊʹɺͲ͏͢Ε͹࣮ ݱͰ͖Δ͔ྗٕͰ͜ͳ͍ͯ͘͠ ਺গͳ͍ࣄྫͩͱࢥ͏ͷͰԕྀͳ࣭͘໰ͯͩ͘͠͞ ͍ʂ

  38. RE-BUILDING THE FUTURE OF GAMING WITH BLOCKCHAIN TECHNOLOGY

  39. ࣌ؒ༨ͬͨΒ஻Δωλ ࣮ࡍʹMainnetͰ΍Δͱ৭ʑπϥΠ OperatorRoleͷඞཁੑ CS໨ઢͰͷGas gRPC-webΛ࢖ͬͨSPAΞϓϦέʔγϣϯ ecrecover࢖ͬͨϩάΠϯػೳ Loom SDKΫϥελߏங Loom Go

    Plugin։ൃ αʔόʔϨε୹ॖURL੡଄ػ IPFS΁ͷը૾౤ߘػೳ ERC721 Metadataʹ͍ͭͯ ϒϩοΫνΣʔϯήʔϜΤίγεςϜʹ͍ͭͯͷ࢛ํࢁ࿩ ೔ຊʹ͓͚ΔNon Fungible Token αΠυνΣʔϯɺϦΞϧӡ༻ݶք