Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
BlockchainTokyo23.pdf
Search
biga816
November 29, 2019
Technology
420
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
BlockchainTokyo23.pdf
biga816
November 29, 2019
More Decks by biga816
See All by biga816
Euler Finance Hacking Incident
biga816
0
690
BuidlMeetupVol2.pdf
biga816
0
41
Service Worker Cache Problems
biga816
1
1.8k
Consider how distributed IPFS is
biga816
2
5.3k
Centralized Dapps to read from Dapps game
biga816
1
2.5k
Usage of ethereum libraries for dapps
biga816
0
4.6k
Other Decks in Technology
See All in Technology
VPCセキュリティ対応の最新事情
nagisa53
2
350
事業成長とAI活用を止めないデータ基盤アーキテクチャの設計思想
hiracky16
1
790
LLMリーダーボードアップデートに向けたAgentic Math_SWEのトレースについて
nejumi
0
200
Master Dataグループ紹介資料
sansan33
PRO
1
4.8k
ガバメントクラウドでのランサムウェア対策
techniczna
1
580
検索技術知識0のエンジニアが広告検索システムを内製化して運用するまで
lycorptech_jp
PRO
0
200
AI驚き屋発見器
yama3133
2
400
クラウドを使う側から、作る側へ / 大吉祥寺.pm 2026前夜祭
fujiwara3
8
2k
個人OSSが、机の上から世界に広がるまでの話
shinyasaita
1
280
AI駆動開発は個人技からチーム戦へ:組織でAIを使いこなすための実践設計
moongift
PRO
0
400
セキュリティ研修【MIXI 26新卒技術研修】
mixi_engineers
PRO
32
28k
toio・myCobotでフィジカルAIっぽいことを行うための検討(とりあえず調査) / フィジカルAI LT(IoTLTによる開催)
you
PRO
0
250
Featured
See All Featured
Believing is Seeing
oripsolob
1
180
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
350
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
30k
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
240
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
230
Ruling the World: When Life Gets Gamed
codingconduct
0
290
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
2
3.7k
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
750
So, you think you're a good person
axbom
PRO
2
2.1k
Tell your own story through comics
letsgokoyo
1
1k
sira's awesome portfolio website redesign presentation
elsirapls
0
310
Transcript
%BQQTʹ͓͚Δ ΞʔΩςΫνϟͱͭΒΈ BLJIJSP UBOBLB
%BQQ։ൃ4QFDJBMʂ
%BQQ։ൃ4QFDJBMʂ
%BQQ։ൃ4QFDJBMʂ
αϒίϯςϯπ࢝·Γ·͢
ࣗݾհాதতത !CJHB #6*%-ϒϩοΫνΣʔϯΤϯδχΞɻ ৽ଔͰΞΫηϯνϡΞʹೖࣾޙɺ4*8&#ϞόΠϧΞϓϦͷ։ ൃϦʔυΛ୲ɻ ʹ.U(09Ͱશࣦͯͬͨ͜ͱ͔ΒϒϩοΫνΣʔϯʹ ֮ΊɺԼΞΠυϧ͚%"QQTͳͲΛख͕͚ͨɻ ݱࡏ#6*%-ʹͯ4)*&%-ͷ։ൃΛ୲͍ͯ͠Δɻ 5ZQF4DSJQU͕͖ɻ
։ൃͨ͠ΞϓϦέʔγϣϯͨͪ
اۀ͚ͷίϯαϧɾ։ൃଟ࣮ࢪத
ΞʔΩςΫνϟΛߟ͑Δ
%"QQTΞʔΩςΫνϟͷλΠϓ ϑϩϯτ݁ܕ Ψεߦܕ ΧετσΟܕ Φʔφʔϑϧݖݶܕ
ϑϩϯτ݁ܕ .FUB.BTLͳͲͷϒϥβΥϨοτΛ༻͍ͯΫϥΠΞϯτଆ ͔ΒτϥϯβΫγϣϯΛൃߦ͠ɺαʔόʔଆॲཧΛඞཁͱ͠ͳ͍ λΠϓ Front Node Server DB Tx
Ψεߦܕ .FUB.BTLͳͲͷϒϥβΥϨοτΛ༻͍ͯΫϥΠΞϯτଆ Ͱॺ໊͠ɺτϥϯβΫγϣϯͷൃߦΛαʔόʔଆͰ࣮ߦ͢ΔλΠ ϓ Front Node Server DB 署名付 Tx
ΧετσΟܕ Ϣʔβʔͷݤอɺॺ໊ɺτϥϯβΫγϣϯͷൃߦΛશͯαʔ όʔଆͰ࣮ߦ͢ΔλΠϓ Front Node Server DB Tx
Φʔφʔϑϧݖݶܕ ϢʔβʔͷݤอͤͣɺΦʔφݖݶΛ࣋ͬͨΞυϨεΛ༻͍ͯ αʔόʔଆͰτϥϯβΫγϣϯͷൃߦΛ࣮ߦ͢ΔλΠϓ ˞ϢʔβʔͷΥϨοτΞυϨεͱΞΧϯτใͷඥ͚ΛαʔόʔଆͰ͓࣋ͬͯ͘έʔε͋Δ Front Node Server DB Tx PXOFS
VTFS
ͲͷΞʔΩςΫνϟʹ͢Δ͖͔ λʔήοτ͕ҰൠϢʔβʔͷ߹ɺΧετσΟܕPSΦʔφʔϑ ϧݖݶܕʹ͢Δ # ϚωʔδυαʔϏε͕͑ΔέʔεͰɺ,BMFJEPΛ͏ͷ͕Ұ൪ָ ݤཧτϥϯβΫγϣϯཤྺཧ͕ෆཁɺ"1*ͰίϯτϥΫτ͕ίʔϧͰ͖Δ ݤฆࣦ࣌ʹϦΧόϦʔͰ͖Δ%*%ͳͲΛಋೖͰ͖Δ߹ϑϩϯ τ݁ܕΨεߦܕ༗ޮ # ͨͩ͠ɺΞʔΩςΫνϟͱͯ͠ෳࡶʹͳΔ
৭ʑͳͭΒΈ
τϥϯβΫγϣϯཤྺͷཧ લఏ # αʔόʔαΠυͰτϥϯβΫγϣϯΛൃߦ͢Δ # ύϒϦοΫνΣʔϯ ͭΒΈͱରԠ # ϢʔβʔʹτϥϯβΫγϣϯ͕֬ఆͨ͠ͷ͔Ͳ͏͔௨͢ΔͨΊʹτ ϥϯβΫγϣϯͷཤྺͱεςʔλεΛ%#ʹอ࣋͢Δඞཁ͕͋ΔͨΊɺ
ఆظతʹτϥϯβΫγϣϯΛࢹ͢Δඞཁ͕͋Δɻ # ޮΛߟ͑ͯશτϥϯβΫγϣϯͷεςʔλεΛࢹͤͣΠϕϯτ ͷࢹΛߦ͏͜ͱ͕ଟ͍͕ɺXFCKTͷXFCTPDLFUͷίωΫγϣϯ ͨ·ʹΕΔ͠ɺରΠϕϯτ͕૿͑ΔͱΧΦεʹͳΓ͕ͪɻ
τϥϯβΫγϣϯཤྺͷཧ export class HogeService { : connect(): void { const
provider = new Web3.providers.WebsocketProvider(GETH.HOST); const reconnect = () => { const interval = this.isReconnection ? 1000 : 0; setTimeout(() => { this.isReconnection = true; this.connect(); this.observer.next(false); }, interval); }; provider.on("error", () => reconnect()); provider.on("end", () => reconnect()); provider.on("connect", () => { this.isReconnection = false; this.observer.next(true); }); this.web3 = new Web3(provider); } on(): Observable<any> { const observable = new Observable((observer: Subscriber<any>) => { this.observer = observer; return; }); return observable; } : } export class Hoge { : async run(): Promise<void> { this.hogeService.on().subscribe(async (isConnected: boolean) => { if (isConnected) { this.watchEvents(); this.fetchPastBlocks(); } }); this.web3Service.connect(); } : }
%#ͱετϨʔδͷ࿈ܞ લఏ # ύϒϦοΫνΣʔϯϓϥΠϕʔτνΣʔϯ ͭΒΈͱରԠ # ݕࡧҰཡςʔϒϧͷදࣔ࣌ͷརศੑ্ͷͨΊʹɺετϨʔδʹॻ ͖ࠐΜͩσʔλΛ%#ʹ࿈ܞ͢Δඞཁ͕͋Δɻ # %#ͷॻ͖ࠐΈΛτϥϯβΫγϣϯͷൃߦΛಉ࣌ʹ͢Δ߹ɺΤ
ϥʔϋϯυϦϯά͕͍͠ɻ # ΠϕϯτΛࢹͯ͠%#ʹॻ͖ࠐΉ߹ɺڞ௨ԽͰ͖ͳ͍ͱࢹର ͕૿͑ͯॲཧ͕ΧΦεʹͳΓ͕ͪɻͲ͏͠Α͏ͳ͍ɻ
(BT-JNJU લఏ # αʔόʔαΠυͰτϥϯβΫγϣϯΛൃߦ͢Δ # ύϒϦοΫνΣʔϯ ͭΒΈͱରԠ # 8FCKTͷFTUJNBUF(BTΛ༻͍ͯHBT-JNJUΛઃఆ͍͕ͨ͠ɺ࣮ࡍͷফ අHBTΛԼճͬͨΓɺ#MPDLͷHBT-JNJUΛ͑ͯΤϥʔΛు͍ͨΓͯ͠
҆ఆ͠ͳ͍͜ͱ͕ͨ·ʹ͋Δɻ # ݁ہ࣮ࡍͷফඅHBTʹগ͠ΛόοϑΝΛ࣋ͨͨ͠ݻఆͱ͢Δͷ͕҆ ఆͦ͠͏ɻͨͩফඅHBTΛࢉग़͢Δͷ͕໘ɻ
/PODF લఏ # αʔόʔαΠυͰτϥϯβΫγϣϯΛൃߦ͢Δ # ύϒϦοΫνΣʔϯϓϥΠϕʔτνΣʔϯ ͭΒΈͱରԠ # ͭͷϓϩηεͰෳͷίϯτϥΫτͷϝιουΛಉ࣌ʹ࣮ߦ͢Δ ߹ɺ/PODFΛਖ਼͘͠ΠϯΫϦϝϯτ͠ͳ͍ͱΤϥʔʹɻ
# ͨͩͭͣͭ͠ॲཧ͕ऴΘΔͷΛ͍ͬͯͯͱͯඇޮɻ # ಉ࣮࣌ߦ࣌ΠϯΫϦ͢ΔλΠϛϯάΛ͢Δඞཁ͕͋Δɻ
/PODF export class SampleService { : call(): void { const
provider = new Web3.providers.WebsocketProvider(GETH.HOST); : let nonce = await this.web3Service.getPendingTxCount(ADDRESS); const getNonce = () => { const rv = nonce; nonce += 1; return rv; }; await Promise.all([ this.web3Service.send( contract, ‘setFoo’, { foo: 'bar' }, getNonce() ), this.web3Service.send( contract, 'setHage’, { hage: true }, getNonce() ), ]); } : }
ίϯτϥΫτංେԽ લఏ # ύϒϦοΫνΣʔϯ ͭΒΈͱରԠ # &3$ɺͳͲΛࢀরΛ͢ΔΑ͏ͳίϯτϥΫτΛ࡞͢ Δ߹ɺ୯७ʹJNQPSU͢ΔͱJNQPSUͨ͠ίϯτϥΫταΠζ͕ංେ Խͯ͠͠·͏ɻ #
ΠϯλʔϑΣʔε͚ͩJNQPSUͯ͠ΠϯελϯεԽͯ͠͠·͑ղܾʂ
ίϯτϥΫτංେԽ pragma solidity ^0.5.0; : contract IERC20 { function balanceOf(address
address) public returns (uint256); } contract HogeContract { function balanceOf(address token, address holder) external { return IERC20(token).balanceOf(holder); } : }
ಈ࡞֬ೝਏ͗͢ લఏ # ͳ͠ ͭΒΈͱରԠ # ґଘ͢ΔίϯτϥΫτ͕૿͑Δͱɺ3FNJYͩͱಈ࡞͢Δঢ়ଶ͍࣋ͬͯ ͘ͷ͕େมɻ # ͞ΒʹίϯτϥΫτΛԿίʔϧ͍ͯ͠ΔͱϑϦʔζͯ͠ಈ͔ͳ͘
ͳΔ͜ͱɻɻ # ͦ͜Ͱ4PMJEJUZͦ͜ςετۦಈ։ൃɻςετΛॻ͍͔ͯΒಈ͘Α͏ʹί ϯτϥΫτΛमਖ਼͠Α͏ʂ
ಈ࡞֬ೝਏ͗͢ const FooMarket = artifacts.require('FooMarket'); const HogeToken = artifacts.require('HogeToken'); :
contract('FooMarket', function ([owner, alice]) { beforeEach(async function () { this.HodeToken = await HogeToken.new(); this.FooMarket = await FooMarket.new(this.HodeToken.address, { from: owner }); await this.FooMarket.setWhitelisted(owner, true, { from: owner }); await this.FooMarket.setWhitelisted(alice, true, { from: owner }); }); describe('transfer hoge token', function () { it('token balance should be changed', async function () { await this.HogeToken.mint(alice, 100, { from: owner }); assert(await this.FooMarket.transfer(alice, bob, 100, { from: owner })); const aliceBalance = await this.HogeToken.balanceOf(alice); const bobBalance = await this.HogeToken.balanceOf(bob); assert.equal(aliceBalance, 0); assert.equal(bobBalance, 100); }); }); : });
4PMJEJUZͷ͕ͤ͘ڧ͗͢ લఏ # ͳ͠ ͨͩͷͭΒΈ # جຊGPS͑ͳ͍ɻͦͷͨΊಾͷঢ়ଶΛཧ͢Δม͕૿͑ͯ͠· ͏͜ͱ͕ଟʑ͋Δɻ # ྻͷআͷ༷͕͍·͍ͪͰਏ͍ɻྻͷॱ൪͕୲อ͞Εͳ͍ಾͷ
ํ๏͕ඞཁʹͳΔͷͰɺ·ͨঢ়ଶΛཧ͢Δม͕૿͑ͯ͠·͏ɻ # ͦͯ͠TUBDLUPPEFFQɻɻɻ
4PMJEJUZͷ͕ͤ͘ڧ͗͢ contract Hoge { uint256[] private targetValues; mapping(uint256 => uint256)
private targetValuesIndex; mapping(uint256 => bool) private valueStatus; function add(uint256 _targetId) public { require(!exists(_targetId)); targetValuesIndex[_targetId] = targetValues.push(_targetId) - 1; valueStatus[_targetId] = true; } function remove(uint256 _targetId) public { require(exists(_targetId)); uint256 targetIndex = targetValuesIndex[_targetId]; uint256 lastIndex = targetValues.length - 1; uint256 lastTargetId = targetValues[lastIndex]; valueStatus[_targetId] = false; targetValues[targetIndex] = lastTargetId; targetValues.length--; targetValuesIndex[lastTargetId] = targetIndex; targetValuesIndex[_targetId] = 0; } function exists(uint256 _targetId) public view returns (bool) { return valueStatus[_targetId]; } }
݁ہҰ൪ͷղܾࡦ
ίϯτϥΫτΛॻ͔ͳ͍
!CJHB