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
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
780
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
遠藤な_めぐろLT #38 「社内のAI活用推進」@麻布台_20261009
endonanana
0
130
QA4AI 2026-Oct 生成AI時代の品質保証
tokuty
1
860
10年後、Engineering 行為を剥奪されるとして、わたしたちは、どう、何を創ればいいだろうか。 / If Engineering Is Taken Away in 10 Years, How and What Should We Create?
bitkey
PRO
1
190
AI コーディングと人間の認知スループット / CTO Night & Day 2026 Morning Session / AI Coding and Human Cognitive Throughput
prog893
3
960
自作バイナリを動かす「入口」8選
puhitaku
2
1.3k
Temporal 最高!でも改めて「日付」について調べたら人類の負債すぎる件
riyaamemiya
0
130
Snapshot Testing in Practice: Predictable and Reliable SwiftUI Views
fespinoza
0
230
Local CI × GitHub Actions
gogutan
2
170
Gemini Intelligence 入門 ― AppFunctions と Gemini Nano
takuroabe
0
250
「事実」を「計測」して、「解釈」する 〜AWS Lambdaのメモリ最適解の見つけ方〜
maimyyym
0
170
LambdaWebFunctionsを試してみた / exploring-lambda-web-functions
koukihosaka
1
320
Refining Active Record
shugo
0
150
Featured
See All Featured
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.8k
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
360
Odyssey Design
rkendrick25
PRO
2
870
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
520
The Illustrated Children's Guide to Kubernetes
chrisshort
51
53k
GitHub's CSS Performance
jonrohan
1033
470k
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
600
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2.2k
Music & Morning Musume
bryan
48
7.4k
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
2
410
Intergalactic Javascript Robots from Outer Space
tanoku
273
28k
Building the Perfect Custom Keyboard
takai
2
910
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 αΠυνΣʔϯɺϦΞϧӡ༻ݶք