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
サービスデザインプロジェクトB 第3回「スマートコントラクトプログラミング」 / Smart ...
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Kenji Saito
PRO
October 26, 2020
Technology
140
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
サービスデザインプロジェクトB 第3回「スマートコントラクトプログラミング」 / Smart Contract Programming
2020年10月26日、慶應義塾大学大学院メディアデザイン研究科の「サービスデザインプロジェクトB (2020 秋)」第3回にて使用したスライドです。
Kenji Saito
PRO
October 26, 2020
More Decks by Kenji Saito
See All by Kenji Saito
FinTech 9-10 : Smart Contracts and Decentralized Finance
ks91
PRO
0
25
FinTech 7-8 : Blockchain
ks91
PRO
0
58
Fall 2026: A Guide & Workshop on Using AI for Academic Paper Writing
ks91
PRO
0
67
FinTech 5-6 : The World of Apps
ks91
PRO
0
62
終わらない幼年期とそのための下部構造・社会資本 / The Never-Ending Childhood and the Infrastructure and Social Capital Needed to Support It
ks91
PRO
0
37
FinTech 3-4 : Internet Technology and Governance
ks91
PRO
0
78
2026 秋 生成AI を活用した論文執筆ガイド/ワークショップ / Fall 2026: Guide and Workshop on Writing Papers Using Generative AI
ks91
PRO
0
160
AIとビジネス・メガトレンド 〜 サイバネティクス的経営観 / AI and Business Megatrends: A Cybernetic Perspective on Management
ks91
PRO
0
49
FinTech 1-2 : Overview of FinTech
ks91
PRO
0
170
Other Decks in Technology
See All in Technology
企画を Software Factory-ready にする——開発が高速になったとき、PdMの仕事はどう変わったか
yachibit
1
270
生成AI時代、PMは事業責任者に進化するともっと面白い〜PMだからこそ事業構造を動かせる時代に〜
kakehashi
PRO
0
870
reInvent2026stby LT00 "Change your life!"
shinichirokawano
1
290
野良MCPサーバーを排除せよ!MCPサーバーのガバナンス
yukiogawa
1
240
AWS Continuum for Penetration Testing に Deep Dive してみる
asanoharuki
1
1.3k
freeeにおける AI を用いた ブラウザ動作確認の自動化の取り組み
freee
PRO
0
220
Vue.jsのGitHubから学ぶ意思決定
yut0naga1_fa
1
260
AI秘書と毎日働くのはもう当たり前。開発以外の業務に足りない機能をどう埋める?
minorun365
PRO
2
1.7k
AIコーディングを実践してきた1年を振り返る / Looking Back on a Year of Practicing AI Coding
takedatakashi
1
140
Claude Code をローカルとサーバー上で利用した際の Bedrock 利用料をユーザー単位で一本化してみる
ohorig
0
160
プロダクトが成長すると、 プロダクトマネージャーの仕事はどう変わるのか - 「まず作る」から「小さく学び、確かめながら進む」へ
sansantech
PRO
1
370
"計画的無茶振り"を通してAIネイティブ世代の新人を育てる
subroh0508
1
110
Featured
See All Featured
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
2
330
SEO for Brand Visibility & Recognition
aleyda
0
4.8k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
Testing 201, or: Great Expectations
jmmastey
46
8.4k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
33
5.4k
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
2
490
Site-Speed That Sticks
csswizardry
13
1.6k
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
360
Believing is Seeing
oripsolob
1
250
Docker and Python
trallard
47
4.2k
Navigating Team Friction
lara
192
16k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Transcript
B 2020 3 ( ) B 2020 — 3 —
2020-10-26 – p.1/62
https://speakerdeck.com/ks91 Discord Discord ( / / ) Zoom URL (
) B 2020 — 3 — 2020-10-26 – p.2/62
( ) 1 10 12 • 2 10 19 •
3 10 26 • 4 11 2 5 11 9 1 6 11 16 2 7 11 30 8 12 7 B 2020 — 3 — 2020-10-26 – p.3/62
– : Ethereum – ( ) Ethereum (1) : ERC20
(2) : (3) : B 2020 — 3 — 2020-10-26 – p.4/62
– : Ethereum macOS (Catalina 10.15.7) + Homebrew Homebrew Linux
(Ubuntu 18.04) Windows 10 + Windows Subsystem for Linux (Ubuntu 18.04 ) WSL Ethereum solidity brownie B 2020 — 3 — 2020-10-26 – p.5/62
Solidity Ethereum http://solidity.readthedocs.io/en/latest/installing-solidity.html Linux (on Windows) “sudo apt”, macOS “brew”
solc 0.7.3 (10/10 ) $ solc --version brownie py-solc-x solc (dependencies) ( solc py-solc-x ) B 2020 — 3 — 2020-10-26 – p.6/62
Python3 macOS $ brew install python3 Linux $ sudo add-apt-repository
ppa:deadsnakes/ppa $ sudo apt update $ sudo apt install python3.8 python3.8-dev python3.8-venv python3.8-tk 16.10 python3(.8) apt B 2020 — 3 — 2020-10-26 – p.7/62
macOS : . . . macOS wget brew dyld: Library
not loaded: /usr/local/opt/gettext/lib/libintl.8.dylib $ brew uninstall --force gettext $ brew install gettext B 2020 — 3 — 2020-10-26 – p.8/62
Python (venv) macOS ‘python3.8’ ‘python3’ $ python3.8 -m venv bbc1env
$ source bbc1env/bin/activate (bbc1env) $ pip install -U pip (bbc1env) $ pip install wheel bbc1env ( BBc-1 ) ( ) (bbc1env) $ deactivate B 2020 — 3 — 2020-10-26 – p.9/62
Ganache CLI Ethereum RPC CLI : Command Line Interface npm
( ) macOS https://qiita.com/kyosuke5_20/items/c5f68fc9d89b84c0df09 Linux https://qiita.com/seibe/items/36cef7df85fe2cefa3ea npm Ganache CLI $ sudo npm install -g ganache-cli B 2020 — 3 — 2020-10-26 – p.10/62
Brownie Python Ethereum https://eth-brownie.readthedocs.io Brownie $ pip install eth-brownie version
1.11.8 (10/10 ) B 2020 — 3 — 2020-10-26 – p.11/62
$ brownie init ( ERC-20 ) $ brownie bake token
$ cd token ( ) $ brownie compile ( ) $ pytest tests B 2020 — 3 — 2020-10-26 – p.12/62
Brownie $ brownie console Python >>> len(accounts) 10 >>> accounts[0].balance()
100000000000000000000 >>> quit() B 2020 — 3 — 2020-10-26 – p.13/62
– ( ) Ethereum ropsten B 2020 — 3 —
2020-10-26 – p.14/62
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 2020 — 3 — 2020-10-26 – p.15/62
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 2020 — 3 — 2020-10-26 – p.16/62
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 2020 — 3 — 2020-10-26 – p.17/62
Ethereum B 2020 — 3 — 2020-10-26 – p.18/62
Ethereum Vitalik Buterin, “Ethereum White Paper: A NEXT GENERATION SMART
CONTRACT & DECENTRALIZED APPLICATION PLATFORM” 15 (= ) = ⇒ → Dapps ( / / ) B 2020 — 3 — 2020-10-26 – p.19/62
B 2020 — 3 — 2020-10-26 – p.20/62
. . . B 2020 — 3 — 2020-10-26 –
p.21/62
vs. B 2020 — 3 — 2020-10-26 – p.22/62
= run B 2020 — 3 — 2020-10-26 – p.23/62
Ether Ethereum EOA : Externally-Owned Account ( ) Ether EVM
EVM B 2020 — 3 — 2020-10-26 – p.24/62
EVM : Ethereum Virtual Machine (validator) ⇒ Gas B 2020
— 3 — 2020-10-26 – p.25/62
EVM : : ← : Solidity — JavaScript LLL —
Lisp Vyper — Python Fe — Vyper Rust ← NEW! Solidity Vyper Python B 2020 — 3 — 2020-10-26 – p.26/62
Solidity ( ) pragma solidityˆ0.5.0; contract IndivisibleAsset { /* */
string public _name; string public _symbol; uint256 public _quantity; address public _owner; constructor(string memory name, string memory symbol, uint256 quantity) public { _name = name; _symbol = symbol; _quantity = quantity; _owner = msg.sender; } function transfer(address to) public returns (bool) { require (_owner == msg.sender); _owner = to; return true; } } B 2020 — 3 — 2020-10-26 – p.27/62
Ethereum B 2020 — 3 — 2020-10-26 – p.28/62
(1) : ERC20 $ brownie bake token B 2020 —
3 — 2020-10-26 – p.29/62
Solidity JavaScript ( , ) (constructor) ( ) ( )
Ether Ethereum B 2020 — 3 — 2020-10-26 – p.30/62
pragma solidity ˆ0.5.0; contract Token { ( ) : (EVM
) : constructor (...) public { /* */ : } function balanceOf(...) { /* ( ) */ : } : } constructor C (/* */ // ) B 2020 — 3 — 2020-10-26 – p.31/62
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 2020 — 3 — 2020-10-26 – p.32/62
ERC20 ERC20 ( ) ⇒ ERC20 ( ERC20 ) ERC20
⇒ B 2020 — 3 — 2020-10-26 – p.33/62
(fungible) ERC20 → ERC223 (draft) or ERC777 (non-fungible) ERC721 (
) (partially fungible) ERC1410 (draft) (ERC1400 ) B 2020 — 3 — 2020-10-26 – p.34/62
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 2020 — 3 — 2020-10-26 – p.35/62
Token ( ) event Transfer(address from, address to, uint256 value);
Token function emit Transfer() ( ) B 2020 — 3 — 2020-10-26 – p.36/62
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 2020 — 3 — 2020-10-26 – p.37/62
Token balanceOf() function balanceOf(address _owner) public view returns (uint256) {
return balances[_owner]; } B 2020 — 3 — 2020-10-26 – p.38/62
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 2020 — 3 — 2020-10-26 – p.39/62
(2) : B 2020 — 3 — 2020-10-26 – p.40/62
GitHub git clone $ git clone https://github.com/ks91/sample-smart-contracts.git sample-smart-contracts contracts, scripts
tests token Token B 2020 — 3 — 2020-10-26 – p.41/62
(m2 ) 1 1 B 2020 — 3 — 2020-10-26
– p.42/62
IndivisibleAsset string public _name_; string public _symbol_; uint256 public _quantity_;
address public _owner_; _name_ ( ) _symbol_ _quantity_ (m2 ) _owner_ ‘_’ Solidity . . . B 2020 — 3 — 2020-10-26 – p.43/62
IndivisibleAsset event Transfer(address indexed from, address indexed to); from to
indexed B 2020 — 3 — 2020-10-26 – p.44/62
IndivisibleAsset constructor (string name, string symbol, uint256 quantity) public {
_name_ = name; _symbol_ = symbol; _quantity_ = quantity; _owner_ = msg.sender; } B 2020 — 3 — 2020-10-26 – p.45/62
IndivisibleAsset getOwner() function getOwner() public view returns (address) { return
(_owner_); } B 2020 — 3 — 2020-10-26 – p.46/62
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 token Solidity 0.6.0 0.5.0 token B 2020 — 3 — 2020-10-26 – p.47/62
scripts/indivisible asset.py from brownie import * def main(): accounts[0].deploy(IndivisibleAsset, "5322
Endo, Fujisawa", "mˆ2", 300) SFC (300m2 ) ( ) B 2020 — 3 — 2020-10-26 – p.48/62
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 2020 — 3 — 2020-10-26 – p.49/62
$ pytest tests/test_indivisible_asset.py B 2020 — 3 — 2020-10-26 –
p.50/62
(3) : B 2020 — 3 — 2020-10-26 – p.51/62
transfer settle, retrieve asset, retrieve token 3 B 2020 —
3 — 2020-10-26 – p.52/62
1. ( ) 2. ( ) 3. ( ) B
2020 — 3 — 2020-10-26 – p.53/62
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 2020 — 3 — 2020-10-26 – p.54/62
(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") B 2020 — 3 — 2020-10-26 – p.55/62
(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 2020 — 3 — 2020-10-26 – p.56/62
(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 2020 — 3 — 2020-10-26 – p.57/62
(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 2020 — 3 — 2020-10-26 – p.58/62
$ pytest tests/test_one_time_escrow.py : settle() ⇒ Discord B 2020 —
3 — 2020-10-26 – p.59/62
B 2020 — 3 — 2020-10-26 – p.60/62
1. (1) (2) Ethereum 1 2 2020 10 31 (
) 23:59 JST B 2020 — 3 — 2020-10-26 – p.61/62
B 2020 — 3 — 2020-10-26 – p.62/62