Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

ࣗݾ঺հ Name: Ryo Manzoku @rmanzoku Work: double jump.tokyo inc Job: Blockchain Engineer Sidework: 
 SRE / Cloud Infrastructure Language:
 Golang / Python

Slide 4

Slide 4 text

https://mch.gg/

Slide 5

Slide 5 text

My Crypto Heroes֓ཁ My Crypto HeroesɺMCHɺϚΠΫϦ 2018-11-30 ਖ਼ࣜαʔϏε։࢝ EthereumΛར༻ͨ͠ϒϩοΫνΣʔϯήʔϜ ϫʔΧʔϓϨΠεϝϯτܕRPG Ξηοτ(ERC721)͸Ethereum mainnet ʹͯ؅ཧ ήʔϜϩδοΫ͸ΦϑνΣʔϯαʔόʹ࣮ͯߦ PCͰ΋εϚϗͰ΋ɺWallet͕ͳͯ͘΋༡΂Δ

Slide 6

Slide 6 text

My Crypto Heroes֓ཁ ήʔϜʹ͔͚ͨ࣌ؒ΋͓ۚ΋৘೤΋ɺ
 ͋ͳͨͷࢿ࢈ͱͳΔੈք Ethereumʹ͋ΔAsset͸Ϣʔβʔ͕ࣗ༝ʹѻ͏͜ͱ͕Ͱ͖Δ AssetΛҭ੒͢Δ͜ͱͰࢿ࢈ͱͯ͠ͷՁ஋ΛߴΊΔ͜ͱ͕Մೳ Assetͱͯ͠ύʔςΟʹฤ੒Ͱ͖ΔHeroͱHero͕૷උ͢Δ Extensionͷ2͕ͭ͋Δʢ2018/12/16࣌఺ʣ Asset͸Smart ContractʹΑͬͯൃߦ্ݶ͕ఆΊΒΕ͍ͯΔ

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

Assetॴ༗ݖ ERC 721 NFT ͩΕ͕͜ͷAssetΛॴ༗͍ͯ͠Δ͔ AssetΛੜΈग़͢Mint΍ॴ༗ݖΛҠৡ͢ΔTransferͳ Ͳ OpenZeppelin 2.0 RC1Λܧঝ Hero/Extensionͱ΋ʹERC721

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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); }

Slide 26

Slide 26 text

Asset Gateway ήʔϜ಺ͰAssetͷऔҾ͕ߦ͑ΔͨΊɺήʔϜ಺Ͱѻ͍ͬͯ ΔAssetʹసૹͳͲߦ͑ͳ͍Α͏ϩοΫ͢Δඞཁ͕͋Δɻ Gateway contract͕͋ΓɺͦͷContractʹAssetΛTransfer ͢Δ͜ͱͰ࣮ݱ Deposit / Withdrawͱ࣮ͯ͠૷ OpenZeppelinOSͰɺContract͕ड͚औΔ৔߹ ERC721Receiver͕نఆ͞Ε͍ͯΔͷͰै͏ͱྑ͍

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

ͭ·ΓͨͩͷBatch

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

$ 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) }

Slide 32

Slide 32 text

abigenΊͬͪΌศར ͦ΋ͦ΋Solidity/web3͸abi͔Βࢉग़Ͱ͖ΔόΠτίʔυΛ ΍ΓͱΓ͢ΔͷͰͦͷղऍΛ͢Δඞཁ͕͋Δ ϒϥ΢βͷ৔߹͸web3.jsΛ࢖͏ ͍ͭϝδϟʔόʔδϣϯ͕͋ΔΜͰ͠ΐ͏Ͷɺɺ αʔόͷ৔߹͸ɺNodeJSΛ࢖͏͔ɺabigenͨ͠GoΛ࢖͏ͷ ͕ݱঢ়ͷબ୒ࢶͰ͸ ༨ஊͰ͕͢ɺethereum/go-ethereumϦϙδτϦ͸͔ͳΓಡ ΈࠐΉ͜ͱʹͳΔʢυΩϡϝϯτ͸͋·Γͳ͍ʣ

Slide 33

Slide 33 text

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()) }

Slide 34

Slide 34 text

ߟྀ఺ Կ౓Ͱ΋͍͏͕ႈ౳ੑ͕ॏཁ ྫ͑͹ɺΦϑνΣʔϯͰॲཧΛߦͬͨͱ͍͏͜ͱΛ Ethererum্ʹه࿥͠Α͏ʹ΋࠶౓Tx͕ඞཁʹͳΔ EthereumͷTxHashΛ࢖ͬͯΦϑνΣʔϯଆͰႈ౳ ੑΛ୲อ͢Δ DBͷҰҙ੍໿Ͱ࣮ݱ

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

RE-BUILDING THE FUTURE OF GAMING WITH BLOCKCHAIN TECHNOLOGY

Slide 39

Slide 39 text

࣌ؒ༨ͬͨΒ஻Δωλ ࣮ࡍʹMainnetͰ΍Δͱ৭ʑπϥΠ OperatorRoleͷඞཁੑ CS໨ઢͰͷGas gRPC-webΛ࢖ͬͨSPAΞϓϦέʔγϣϯ ecrecover࢖ͬͨϩάΠϯػೳ Loom SDKΫϥελߏங Loom Go Plugin։ൃ αʔόʔϨε୹ॖURL੡଄ػ IPFS΁ͷը૾౤ߘػೳ ERC721 Metadataʹ͍ͭͯ ϒϩοΫνΣʔϯήʔϜΤίγεςϜʹ͍ͭͯͷ࢛ํࢁ࿩ ೔ຊʹ͓͚ΔNon Fungible Token αΠυνΣʔϯɺϦΞϧӡ༻ݶք