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
スマートコントラクトデザイン / Smart Contract Design
Search
Kenji Saito
PRO
November 01, 2021
Technology
0
110
スマートコントラクトデザイン / Smart Contract Design
2021年11月1日(月)、慶應義塾大学大学院メディアデザイン研究科「サービスデザインプロジェクト B」2021秋 第4回で使用されたスライドです。
Kenji Saito
PRO
November 01, 2021
Tweet
Share
More Decks by Kenji Saito
See All by Kenji Saito
We Never Took the Kobayashi Maru Test Until Now. What Do You Think of Our Solutions? — Journeys of the Mind Through a No-Win Game
ks91
PRO
0
4
思いつきが武器になる:研究というゲームを始めよう / Ideas Are Your Equipments : Let the Game of Research Begin!
ks91
PRO
0
59
ロボットを雰囲気(ヴァイブ)でプログラミングするこどもたち / Children Vibe-Programming Robots
ks91
PRO
0
21
アカデミーキャンプ 2025 SuuuuuuMMeR「燃えろ!!ロボコン」 / Academy Camp 2025 SuuuuuuMMeR "Burn the Spirit, Robocon!!" DAY 3
ks91
PRO
0
29
アカデミーキャンプ 2025 SuuuuuuMMeR「燃えろ!!ロボコン」 / Academy Camp 2025 SuuuuuuMMeR "Burn the Spirit, Robocon!!" DAY 2
ks91
PRO
0
31
アカデミーキャンプ 2025 SuuuuuuMMeR「燃えろ!!ロボコン」 / Academy Camp 2025 SuuuuuuMMeR "Burn the Spirit, Robocon!!" DAY 1
ks91
PRO
0
150
未来へのフォワードキャスト / Forward Cast to the Future
ks91
PRO
0
82
発表と総括 / Presentations and Summary
ks91
PRO
0
59
サイバーフィジカル社会、金融の未来とアイデアソン / Cyber Physical Society, Future of Finance, and Ideathon
ks91
PRO
0
76
Other Decks in Technology
See All in Technology
GitHub Copilot coding agent を推したい / AIDD Nagoya #1
tnir
4
4.7k
見てわかるテスト駆動開発
recruitengineers
PRO
6
590
RAID6 を楔形文字で組んで現代人を怖がらせましょう(実装編)
mimifuwa
1
310
実践アプリケーション設計 ②トランザクションスクリプトへの対応
recruitengineers
PRO
3
390
DeNA での思い出 / Memories at DeNA
orgachem
PRO
3
1.6k
フルカイテン株式会社 エンジニア向け採用資料
fullkaiten
0
8.6k
ソフトウェア エンジニアとしての 姿勢と心構え
recruitengineers
PRO
4
1.4k
知られざるprops命名の慣習 アクション編
uhyo
11
2.6k
AIドリブンのソフトウェア開発 - うまいやり方とまずいやり方
okdt
PRO
9
650
EKS Pod Identity における推移的な session tags
z63d
1
210
Postman MCP 関連機能アップデート / Postman MCP feature updates
yokawasa
1
160
Figma + Storybook + PlaywrightのMCPを使ったフロントエンド開発
yug1224
9
2.9k
Featured
See All Featured
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.4k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
229
22k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
61k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
161
15k
YesSQL, Process and Tooling at Scale
rocio
173
14k
Thoughts on Productivity
jonyablonski
69
4.8k
Build your cross-platform service in a week with App Engine
jlugia
231
18k
Imperfection Machines: The Place of Print at Facebook
scottboms
268
13k
Balancing Empowerment & Direction
lara
2
590
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
44
2.5k
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
Music & Morning Musume
bryan
46
6.7k
Transcript
B 2021 4 ( ) B 2021 — 4 —
2021-11-01 – p.1/51
https://speakerdeck.com/ks91 ( ) Discord Discord ( / / ) Zoom
URL ( ) B 2021 — 4 — 2021-11-01 – p.2/51
( ) 1 10 11 • 2 10 18 •
3 10 25 • 4 11 1 • 5 11 8 1 6 11 15 2 7 11 22 8 11 29 ( ) 4 ( 3 ) ↓ B 2021 — 4 — 2021-11-01 – p.3/51
brownie (1) : ERC20 (2) : (3) : Web 3.0
B 2021 — 4 — 2021-11-01 – p.4/51
brownie ropsten B 2021 — 4 — 2021-11-01 – p.5/51
infura.io Brownie https://infura.io SIGN UP PROJECT ID infura Ethereum API
infura . . . infura.io PROJECT ID WEB3_INFURA_PROJECT_ID PROJECT ID (~/.bash_profile ) $ export WEB3_INFURA_PROJECT_ID= PROJECT ID B 2021 — 4 — 2021-11-01 – p.6/51
ropsten ETH brownie console ropsten >>> network.disconnect() >>> network.connect(’ropsten’) >>>
len(accounts) 0 >>> accounts.add() <LocalAccount object ’ 16 ’> >>> accounts[0].private_key 16 >>> quit() Ropsten Testnet ETH Faucet 5.0ETH https://faucet.dimensions.network/ ( ) https://metamask.io/ B 2021 — 4 — 2021-11-01 – p.7/51
ropsten ETH brownie console ropsten ETH >>> network.disconnect() >>> network.connect(’ropsten’)
>>> len(accounts) 0 >>> accounts.add( 16 ) <LocalAccount object ’ 16 ’> >>> accounts[0].balace() ETH >>> quit() ( ) ETH >>> accounts[0].transfer(accounts[1], "1 ether") B 2021 — 4 — 2021-11-01 – p.8/51
(1) : ERC20 $ brownie bake token B 2021 —
4 — 2021-11-01 – p.9/51
Solidity JavaScript ( , ) (constructor) ( ) ( )
Ether Ethereum B 2021 — 4 — 2021-11-01 – p.10/51
pragma solidity ˆ0.6.0; /* 0.8.x */ contract Token { (
) : (EVM ) : constructor (...) public { /* */ : } function balanceOf(...) { /* ( ) */ : } : } constructor C (/* */ // ) B 2021 — 4 — 2021-11-01 – p.11/51
ERC20 ERC (Ethereum Request for Comment) 20 https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md contract ERC20
{ function totalSupply() constant returns (uint totalSupply); function balanceOf(address _owner) constant returns (uint balance); function transfer(address _to, uint _value) returns (bool success); function transferFrom(address _from, address _to, uint _value) returns (bool success); function approve(address _spender, uint _value) returns (bool success); function allowance(address _owner, address _spender) constant returns (uint remaining); event Transfer(address indexed _from, address indexed _to, uint _value); event Approval(address indexed _owner, address indexed _spender, uint _value); } name/ , symbol/ , decimals/ approve allowance ERC223 ( ), ERC721 (Non-Fungible) B 2021 — 4 — 2021-11-01 – p.12/51
ERC20 ERC20 ( ) ⇒ ERC20 ( ERC20 ) ERC20
⇒ B 2021 — 4 — 2021-11-01 – p.13/51
(fungible) ERC20 → ERC223 (draft) or ERC777 (non-fungible) ERC721 (
) (partially fungible) ERC1410 (draft) (ERC1400 ) B 2021 — 4 — 2021-11-01 – p.14/51
Token ( ) string public symbol; string public name; uint256
public decimals; uint256 public totalSupply; mapping(address => uint256) balances; . . . name, symbol decimals : 2 100 1.00 mapping balances B 2021 — 4 — 2021-11-01 – p.15/51
Token ( ) event Transfer(address from, address to, uint256 value);
Token function emit Transfer() ( ) B 2021 — 4 — 2021-11-01 – p.16/51
Token ( ) constructor( string memory _symbol, string memory _name,
uint256 _decimals, uint256 _totalSupply ) public { symbol = _symbol; name = _name; decimals = _decimals; totalSupply = _totalSupply; balances[msg.sender] = _totalSupply; } msg.sender _totalSupply B 2021 — 4 — 2021-11-01 – p.17/51
Token balanceOf() function balanceOf(address _owner) public view returns (uint256) {
return balances[_owner]; } B 2021 — 4 — 2021-11-01 – p.18/51
Token transfer() function transfer(address _to, uint256 _value) public returns (bool)
{ balances[msg.sender] = balances[msg.sender].sub(_value); balances[_to] = balances[_to].add(_value); emit Transfer(msg.sender, _to, _value); return true; } ( ↑ ) OpenZeppelin https://openzeppelin.org B 2021 — 4 — 2021-11-01 – p.19/51
(2) : B 2021 — 4 — 2021-11-01 – p.20/51
GitHub git clone $ git clone https://github.com/ks91/sample-smart-contracts.git sample-smart-contracts contracts, scripts
tests token Token Solidity 0.5 0.6/0.7 (Token ) Solidity B 2021 — 4 — 2021-11-01 – p.21/51
(m2 ) 1 1 B 2021 — 4 — 2021-11-01
– p.22/51
IndivisibleAsset string public _name_; string public _symbol_; uint256 public _quantity_;
address public _owner_; _name_ ( ) _symbol_ _quantity_ (m2 ) _owner_ ‘_’ Solidity . . . B 2021 — 4 — 2021-11-01 – p.23/51
IndivisibleAsset event Transfer(address indexed from, address indexed to); from to
indexed B 2021 — 4 — 2021-11-01 – p.24/51
IndivisibleAsset constructor (string name, string symbol, uint256 quantity) public {
_name_ = name; _symbol_ = symbol; _quantity_ = quantity; _owner_ = msg.sender; } B 2021 — 4 — 2021-11-01 – p.25/51
IndivisibleAsset getOwner() function getOwner() public view returns (address) { return
(_owner_); } B 2021 — 4 — 2021-11-01 – p.26/51
IndivisibleAsset transfer() function transfer(address to) public returns (bool) { require(_owner_
== msg.sender); _owner_ = to; emit Transfer(msg.sender, to); return true; } require (function ) ( ) $ brownie compile B 2021 — 4 — 2021-11-01 – p.27/51
scripts/indivisible asset.py from brownie import * def main(): accounts[0].deploy(IndivisibleAsset, "5322
Endo, Fujisawa", "mˆ2", 300) SFC (300m2 ) ( ) B 2021 — 4 — 2021-11-01 – p.28/51
from brownie import * import pytest def test_owner_and_transfer(IndivisibleAsset): asset =
accounts[0].deploy(IndivisibleAsset, "5322 Endo", "mˆ2", 300) assert asset.getOwner() == accounts[0] asset.transfer(accounts[1], {’from’: accounts[0]}) assert asset.getOwner() == accounts[1] try: asset.transfer(accounts[0], {’from’: accounts[0]}) done = 1 except: done = 0 assert done == 0 accounts[0] accounts[1] B 2021 — 4 — 2021-11-01 – p.29/51
$ pytest tests/test_indivisible_asset.py B 2021 — 4 — 2021-11-01 –
p.30/51
(3) : B 2021 — 4 — 2021-11-01 – p.31/51
transfer settle, retrieve asset, retrieve token 3 B 2021 —
4 — 2021-11-01 – p.32/51
1. ( ) 2. ( ) 3. ( ) B
2021 — 4 — 2021-11-01 – p.33/51
OneTimeEscrow settle() function settle() public returns (bool) { require(_token_.balanceOf(address(this)) >=
_price_); /* this */ require(_asset_.getOwner() == address(this)); _token_.transfer(_seller_ , _price_); _asset_.transfer(_buyer_); emit Settled(); /* */ return true; } settle() transfer ( / ) $ brownie compile B 2021 — 4 — 2021-11-01 – p.34/51
(1) from brownie import * import pytest def test_deploy_and_settle(Token, IndivisibleAsset,
OneTimeEscrow): asset = accounts[0].deploy(IndivisibleAsset, "5322 Endo", "mˆ2", 300) token = accounts[0].deploy(Token, "Test Token", "TEST", 18, "1000 ether") brownie console ropsten . . . ← accounts[0] seller, accounts[1] buyer buyer Ether (gas ) B 2021 — 4 — 2021-11-01 – p.35/51
(2) token.transfer(accounts[1], 300, {’from’: accounts[0]}) escrow = accounts[0].deploy(OneTimeEscrow, token, accounts[1],
asset, accounts[0], 300) accounts[0] accounts[1] 300 300 TX accounts[1] accounts[0] 300 bake Token 300 ETH wei B 2021 — 4 — 2021-11-01 – p.36/51
(3) token.transfer(escrow, 300, {’from’: accounts[1]}) asset.transfer(escrow, {’from’: accounts[0]}) assert token.balanceOf(accounts[0])
== 999999999999999999700 assert token.balanceOf(accounts[1]) == 0 assert token.balanceOf(escrow) == 300 assert asset.getOwner() == escrow accounts[1] ( ) 300 accounts[0] ( ) B 2021 — 4 — 2021-11-01 – p.37/51
(4) escrow.settle({’from’: accounts[0]}) assert token.balanceOf(accounts[0]) == 1000000000000000000000 assert token.balanceOf(accounts[1]) ==
0 assert token.balanceOf(escrow) == 0 assert asset.getOwner() == accounts[1] settle() accounts[0] OK B 2021 — 4 — 2021-11-01 – p.38/51
$ pytest tests/test_one_time_escrow.py : settle() ⇒ Discord B 2021 —
4 — 2021-11-01 – p.39/51
B 2021 — 4 — 2021-11-01 – p.40/51
1. (1) (2) Ethereum 1 2 2020 10 30 (
) 23:59 JST B 2021 — 4 — 2021-11-01 – p.41/51
. . . . . . 5 3 ( )
( ) (← ) (← ) ( ) ( ) B 2021 — 4 — 2021-11-01 – p.42/51
O ⇒ B 2021 — 4 — 2021-11-01 – p.43/51
K NFT ⇒ NFT SNS TikTok SNS ⇒ ( )
. . . B 2021 — 4 — 2021-11-01 – p.44/51
C ⇒ ( ) B 2021 — 4 — 2021-11-01
– p.45/51
Web 3.0 Web 3.0 HTTPS B 2021 — 4 —
2021-11-01 – p.46/51
NFT SNS ↑ B 2021 — 4 — 2021-11-01 –
p.47/51
miro ( ) ( ) B 2021 — 4 —
2021-11-01 – p.48/51
B 2021 — 4 — 2021-11-01 – p.49/51
2. API (1) ( ) (2) Web API 2020 11
6 ( ) 23:59 JST B 2021 — 4 — 2021-11-01 – p.50/51
B 2021 — 4 — 2021-11-01 – p.51/51