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
710
BuidlMeetupVol2.pdf
biga816
0
45
Service Worker Cache Problems
biga816
1
1.8k
Consider how distributed IPFS is
biga816
2
5.4k
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
DatadogのBits Chatが開発組織にもたらしたもの / What Bits Chat Has Brought Us
sms_tech
1
300
社内の7割が使うデータ基盤を、 データチーム2人で回すためにやったこと
koh_yoshi
4
1.5k
MulticaとPi Coding Agentで、小規模OSSを30本同時運用した流れ
eiei114
0
140
FDEの心得
noriakioji
5
6.4k
MIXIで活躍できるエンジニアを 若手社員目線で考えてみる
mixi_engineers
PRO
0
130
dbt と Snowflake と tag
kevinrobot34
1
120
Android skills に学ぶ
kokiko
0
150
猫付きpingコマンドを自作
uyuki234
0
290
同じWAFが、攻撃の“形”は弾く── 正当な“形”の不正は通す
kuroneko13
0
270
LLM・AIエージェントシステムベストプラクティス
shibuiwilliam
6
1.6k
地震情報アプリを作ってみた
yama3133
1
110
コネクションをピン留めさせずに SELECTクエリのタイムアウトを設定した話
codmoninc
0
210
Featured
See All Featured
Side Projects
sachag
455
43k
What's in a price? How to price your products and services
michaelherold
247
13k
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2.1k
So, you think you're a good person
axbom
PRO
2
2.1k
Thoughts on Productivity
jonyablonski
76
5.3k
[RailsConf 2023] Rails as a piece of cake
palkan
59
6.9k
Navigating Weather and Climate Data
rabernat
0
490
Ruling the World: When Life Gets Gamed
codingconduct
0
310
Exploring anti-patterns in Rails
aemeredith
3
470
Become a Pro
speakerdeck
PRO
31
6.2k
BBQ
matthewcrist
89
10k
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
6.1k
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