Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
実践ブロックチェーンゲーム/Blockchain Game in Practice
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Ryo Manzoku
December 17, 2018
Technology
1.9k
6
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
実践ブロックチェーンゲーム/Blockchain Game in Practice
2018-12-17 blockchain.tokyo #15
https://blockchain-tokyo.connpass.com/event/110424/
Ryo Manzoku
December 17, 2018
More Decks by Ryo Manzoku
See All by Ryo Manzoku
ブロックチェーンゲーム開発におけるチェーンの選び方 / How to select a blockchain for BCG
rmanzoku
0
770
NFTを取り巻く技術要素とAWS利活用 / Technology and AWS of NFT
rmanzoku
0
970
NFTを中心とした新しいゲームの形 / The new approach of gaming with NFT
rmanzoku
0
460
NFTへの招待 / Invitation to NFT
rmanzoku
0
1.5k
Stringをどうにかする / Managing Solidity String
rmanzoku
0
1.4k
ブロックチェーン時代の認証 / Authentication in the Blockchain Era
rmanzoku
8
3.4k
ERC-721をかぞえて / Enumerate ERC-721
rmanzoku
3
8.9k
MCH+ Hackathon #1
rmanzoku
0
360
AWS上で動く世界No.1ブロックチェーンゲーム / No1 Blockchain Game on AWS
rmanzoku
1
3.1k
Other Decks in Technology
See All in Technology
Incremental HTTP
kazuho
5
2k
Lambda MicroVMsは常駐サーバーの代わりに なるか? Kiro Crew を動かして検証してみた / Kiro Crew on Lambda MicroVMs
k_adachi_01
2
350
人にやさしく、AIにやさしく、書き手を選ばないIaCのガードレール再考 / Rethinking IaC Guardrails for Humans and AI Alike
kohbis
5
2k
React Nativeでの OTA Updateって、 どう説明する?
ichiki1023
0
140
20260930_Gemma4_Hands-on
tsho
0
210
Claude Designがめちゃくちゃ便利なので使ってほしい
diggymo
0
200
BedrockとLambdaで作る リアルタイム進行型推理ゲーム
kawametho
0
160
『GOエコノミー 』(相乗りサービス) におけるスペック駆動開発
mot_techtalk
1
210
3人で1000GPU超を統合運用する?マルチクラウド&オンプレを跨ぐ、構築と運用のリアル!
kazukun0716
2
810
SDDの運用にめげずに向き合った話
sansantech
PRO
0
110
AI感のないAWS構成図をAIエージェントに描かせたい!
sagochiko
2
500
HolmesGPTで始めるSREエージェント入門!プラットフォームの障害調査はAIにお任せ 〜
sanghyuk
0
260
Featured
See All Featured
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
1.1k
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
3
3.8k
WCS-LA-2024
lcolladotor
0
840
So, you think you're a good person
axbom
PRO
2
2.2k
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
69
66k
The Spectacular Lies of Maps
axbom
PRO
1
1.1k
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
900
How to train your dragon (web standard)
notwaldorf
97
6.8k
Why You Should Never Use an ORM
jnunemaker
PRO
61
10k
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
3.1k
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
0
260
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
610
Transcript
None
࣮ફϒϩοΫνΣʔϯήʔϜ 2018-12-17 blockchain.tokyo#15 @rmanzoku
ࣗݾհ Name: Ryo Manzoku @rmanzoku Work: double jump.tokyo inc Job:
Blockchain Engineer Sidework: SRE / Cloud Infrastructure Language: Golang / Python
https://mch.gg/
My Crypto Heroes֓ཁ My Crypto HeroesɺMCHɺϚΠΫϦ 2018-11-30 ਖ਼ࣜαʔϏε։࢝ EthereumΛར༻ͨ͠ϒϩοΫνΣʔϯήʔϜ ϫʔΧʔϓϨΠεϝϯτܕRPG
Ξηοτ(ERC721)Ethereum mainnet ʹͯཧ ήʔϜϩδοΫΦϑνΣʔϯαʔόʹ࣮ͯߦ PCͰεϚϗͰɺWallet͕ͳͯ͘༡Δ
My Crypto Heroes֓ཁ ήʔϜʹ͔͚͓ͨ࣌ؒۚɺ ͋ͳͨͷࢿ࢈ͱͳΔੈք Ethereumʹ͋ΔAssetϢʔβʔ͕ࣗ༝ʹѻ͏͜ͱ͕Ͱ͖Δ AssetΛҭ͢Δ͜ͱͰࢿ࢈ͱͯ͠ͷՁΛߴΊΔ͜ͱ͕Մೳ Assetͱͯ͠ύʔςΟʹฤͰ͖ΔHeroͱHero͕උ͢Δ Extensionͷ2͕ͭ͋Δʢ2018/12/16࣌ʣ AssetSmart
ContractʹΑͬͯൃߦ্ݶ͕ఆΊΒΕ͍ͯΔ
ࠓ͢͜ͱ HiCon2018Ͱൃදͨ͠༰ͷิ MCHͰՔಇ͍ͯ͠ΔSmart Contractͷղઆ ࠓͷEthereumͰɺήʔϜͷΑ͏ͳෳࡶͳϩδοΫΛ࣮͢Δͷ ෆՄೳ ͱ͍͑αʔϏεΛੈͷதʹग़͞Ͷ࢝·Βͳ͍ EthereumͷੈքͱήʔϜͷੈքΛܨ͙ٕज़ Թײ͕Θ͔Βͳ͔ͬͨͷͰطͷใ͔ΓͩͬͨΒ͢Έ·ͤΜ
ٕज़എܠ AssetΛΦϯνΣʔϯɺήʔϜΦϑνΣʔϯͱͯ͠اըʢ4݄ʣ Etheremonͷॿݴ͋ΓΦϯνΣʔϯʢEVMʣͰͷ࣮ํస ʢ6݄ʣ ʢࢲ͕δϣΠϯʣ Loom NetworkΛͬͨότϧβΛ࣮ࢪɺݱ࣌ͰͷΦϯνΣʔϯ ࣮Λஅ೦ʢ10݄ʣ େ෦ΛΦϑνΣʔϯԽʢ11݄ʣ
HiCon2018Ͱͷൃද https://mch.gg/hicon2018
HiCon2018Ͱͷൃද https://mch.gg/hicon2018
EVM on Loom SDK Loom݁ߏ͍ ϒϩοΫੜ1ඵ ͔͠͠ότϧॲཧʹ10ඵҎ্͔͔Δ ͦͷؒɺWriteͯ͢ϒϩοΫ ReadԿނ͔ॏ͍
HiCon2018Ͱͷൃද https://mch.gg/hicon2018
Eventϩʔυόϥϯαʔ Master LoomͷEventΛGoरͬͯɺSlave LoomʹॲཧΛ ྲྀ͢όον͕ಈ͍͍ͯΔ ൃͱͯ͠State-channelʹ͍ۙͣ ࣄ্࣮ͷϩʔυόϥϯαʔ ʢͦͦMaster/Slaveͬͯɺɺɺʣ EventΛरͬͯॲཧ͢ΔͷͰΤϯυΤϯυͩͱඵ͔͔ Δ͕ϒϩοΫͳ͘ͳΔ
SidechainͰͷݶք ͦͦϒϩοΫνΣʔϯͰ͋ΔҎ্ɺγϦΞϧॲ ཧͰ͔࣮͠ߦͰ͖ͳ͍ CPUར༻ޮѱ͍ ͍͍͑ͯͤͥ3ίΞఔ ότϧͷϩάΛు͖͗ͯ͢1ϲ݄Ͱ100GB͘Β͍σΟ εΫΛ৯͏ ͜ͷ࣌ظɺேཁܾ݅·ͬͯ༦ํʹ৽نαʔόʹσ ϓϩΠΈ͍ͨͳঢ়گͩͬͨ
HiCon2018Ͱͷൃද https://mch.gg/hicon2018
HiCon2018Ͱͷൃද https://mch.gg/hicon2018
None
None
MCHͷήʔϜੑ HeroΛETHͳͲͰखʹೖΕɺΫΤετʹ͔͍ใुͰ͋ ΔExtensionΛऩू HeroExtensionͷϨϕϧΛ্͛ߴқͷΫΤετ ઓ खʹೖΕͨHeroɺExtensionΛήʔϜऔҾॴͰചങ ॴ༗͢ΔHeroɺExtensionΛEthereum্సૹ
Main chainͰཧ͢Δͷ Hero/Extension Assetॴ༗ݖ Hero/Extension Assetൃߦ্ݶ Hero/ExtensionΛήʔϜͰར༻͢ΔͨΊͷGateway
Smart contractʹ͍ͭͯ Ethereum্ͰϩδοΫΛಈ͔ͨ͢ΊͷϓϩάϥϜ MCHͰಁ໌ੑ֬อͷͨΊEtherscanͰެ։ https://mch.gg/etherscan ࠓޙOSSҰ෦ϩδοΫʹ͍ͭͯϥΠηϯεܖ ͷݩɺଞࣾͰར༻Ͱ͖ΔΑ͏ʹඋ༧ఆ MCHۀքൃలͷͨΊੵۃతʹٕज़Λใެ։
ERC 721ͱ Ethereumͷඪ४ن֨ͷҰͭͰNon-Fungible TokenʢNFTʣΛنఆ ͨ͠ΠϯλʔϑΣʔε NFTͱɺସෆՄೳͳͷ CryptoKittiesΛൃʹEthereum্ͰToken/Assetͷॴ༗ݖͳͲΛن ఆ ࢀর࣮ͱͯ͠OpenZeppelinOSͷͷ͕༗໊ CryptoZombiesERC721
ERC20ͱൺֱ͞ΕΔ
Assetॴ༗ݖ ERC 721 NFT ͩΕ͕͜ͷAssetΛॴ༗͍ͯ͠Δ͔ AssetΛੜΈग़͢Mintॴ༗ݖΛҠৡ͢ΔTransferͳ Ͳ OpenZeppelin 2.0 RC1Λܧঝ
Hero/ExtensionͱʹERC721
Assetൃߦ্ݶ ERC 721ʹՃ࣮ ৽Hero৽Extension࣮࣌ʹࣄલʹൃߦΛηοτ Mint࣌ʹൃߦνΣοΫ Type͝ͱʹೳྗ͕͋ΓɺͦͷTypeͷൃߦ্ݶ͕ܾ·͍ͬͯΔ CryptoKittiesͳͲͱҧ͍ɺID͔Βೳྗ͕ܾఆ͢ΔΘ͚Ͱͳ͍ ͪΖΜՁͷߴ͍ͷ΄Ͳൃߦ͕গͳ͍ ৫ా৴ੈքʹ10ମ͔͠ੜ·Ε·ͤΜʂΛContractͰอূ
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); }
Asset Gateway ήʔϜͰAssetͷऔҾ͕ߦ͑ΔͨΊɺήʔϜͰѻ͍ͬͯ ΔAssetʹసૹͳͲߦ͑ͳ͍Α͏ϩοΫ͢Δඞཁ͕͋Δɻ Gateway contract͕͋ΓɺͦͷContractʹAssetΛTransfer ͢Δ͜ͱͰ࣮ݱ Deposit / Withdrawͱ࣮ͯ͠
OpenZeppelinOSͰɺContract͕ड͚औΔ߹ ERC721Receiver͕نఆ͞Ε͍ͯΔͷͰै͏ͱྑ͍
ͦͦͳͥGateway͔ Ethereum্Ͱͯ͢ͷϩδοΫΛ࣮͢ΔͱGasͳͲͷϢʔ βʔίετ͕͔͔ΔɺUXతʹਏ͍ PlasmaΛච಄ʹεέʔϦϯάٕज़ߟҊ͞Ε͍ͯΔͷͷ ࣮Քಇ͍ͯ͠Δͷ΄΅ͳ͍ ϝΠϯνΣʔϯͱʮεέʔϦϯάٕज़XʯΛܨ͙ٕज़͕ඞཁ Xʹ͖ͳݴ༿ΛೖΕΑ͏ MCHͰΦϑνΣʔϯ
ܨ͙ٕज़ ContractͷEventΛ͏ GatewayʹAsset͕Transfer͞Εͨͱ͍͏EventΛࢹ EventΛΫϩʔϧ͠ɺΦϑνΣʔϯͷgRPCΛ࣮ߦ͢Δ औΓ͜΅͕͠ා͍ͷͰఆظ࣮ߦ͢Δ TxHashΛͬͯႈੑΛอূ͢Δ
ͭ·ΓͨͩͷBatch
abigen Solidityͷίʔυ͔ΒGolangΫϥΠΞϯτίʔυΛࣗ ಈੜͯ͘͠ΕΔίϚϯυ https://github.com/ethereum/go-ethereum/wiki/ Native-DApps:-Go-bindings-to-Ethereum-contracts Event subscription͕·ͩ͑ͳ͍ͦ͏Ͱ͕͢ɺόο ν༻్ʹे͑Δ
$ 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) }
abigenΊͬͪΌศར ͦͦSolidity/web3abi͔Βࢉग़Ͱ͖ΔόΠτίʔυΛ ΓͱΓ͢ΔͷͰͦͷղऍΛ͢Δඞཁ͕͋Δ ϒϥβͷ߹web3.jsΛ͏ ͍ͭϝδϟʔόʔδϣϯ͕͋ΔΜͰ͠ΐ͏Ͷɺɺ αʔόͷ߹ɺNodeJSΛ͏͔ɺabigenͨ͠GoΛ͏ͷ ͕ݱঢ়ͷબࢶͰ ༨ஊͰ͕͢ɺethereum/go-ethereumϦϙδτϦ͔ͳΓಡ ΈࠐΉ͜ͱʹͳΔʢυΩϡϝϯτ͋·Γͳ͍ʣ
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()) }
ߟྀ ԿͰ͍͏͕ႈੑ͕ॏཁ ྫ͑ɺΦϑνΣʔϯͰॲཧΛߦͬͨͱ͍͏͜ͱΛ Ethererum্ʹه͠Α͏ʹ࠶Tx͕ඞཁʹͳΔ EthereumͷTxHashΛͬͯΦϑνΣʔϯଆͰႈ ੑΛ୲อ͢Δ DBͷҰҙ੍Ͱ࣮ݱ
ߟྀ AssetΛϢʔβʔʹฦ͢߹ಉ͡ɻ ΦϑνΣʔϯͰTxHashతͳͷΛൃߦ͠ɺίϯτϥ ΫτʹΘͨ͢ɻ ίϯτϥΫτͰҰҙ੍ɺɺͱ͍ͨ͠ͱ͜Ζ͕ͩݱঢ় Eventൃߦ͍ͯ͠Δ͚ͩ όον্ͰEventΛݟͯႈੑΛ୲อ
ߟྀ SafeBlockͱ͍͏ߟ͑ ϒϩοΫνΣʔϯͳͷͰreorg͕͋Γ͑Δ nϒϩοΫܦͬͨΒ֬ఆͱΈͳ͢ Ϣʔβʔͷࢿ࢈ΛकΔͨΊʢ͜ͷล҉߸௨՟औҾ ॴ͞Μͷ΄͏͕ৄ͍ͣ͠ɺɺʣ γεςϜతʹ໊લ͍ͭͯͨΓ͠·͔͢Ͷʁ
·ͱΊ EthereumͰɺήʔϜͷΑ͏ͳෳࡶͳϩδοΫΛ࣮ ͢ΔͷෆՄೳ αʔϏεͱͯ͠ੈͷதʹग़ͨ͢ΊʹɺͲ͏͢Ε࣮ ݱͰ͖Δ͔ྗٕͰ͜ͳ͍ͯ͘͠ গͳ͍ࣄྫͩͱࢥ͏ͷͰԕྀͳ࣭ͯͩ͘͘͠͞ ͍ʂ
RE-BUILDING THE FUTURE OF GAMING WITH BLOCKCHAIN TECHNOLOGY
࣌ؒ༨ͬͨΒΔωλ ࣮ࡍʹMainnetͰΔͱ৭ʑπϥΠ OperatorRoleͷඞཁੑ CSઢͰͷGas gRPC-webΛͬͨSPAΞϓϦέʔγϣϯ ecrecoverͬͨϩάΠϯػೳ Loom SDKΫϥελߏங Loom Go
Plugin։ൃ αʔόʔϨεॖURLػ IPFSͷը૾ߘػೳ ERC721 Metadataʹ͍ͭͯ ϒϩοΫνΣʔϯήʔϜΤίγεςϜʹ͍ͭͯͷ࢛ํࢁ ຊʹ͓͚ΔNon Fungible Token αΠυνΣʔϯɺϦΞϧӡ༻ݶք