$30 off During Our Annual Pro Sale. View Details »

スマートコントラクトデザイン / Smart Contract Design

スマートコントラクトデザイン / Smart Contract Design

2022年11月7日(月)、慶應義塾大学大学院メディアデザイン研究科「サービスデザインプロジェクト B」2022秋で使用したスライドです。

Kenji Saito
PRO

November 07, 2022
Tweet

More Decks by Kenji Saito

Other Decks in Technology

Transcript

  1. Service Design, generated by Stable Diffusion
    B 2022
    4
    ( )
    B 2022 — 4 — 2022-11-07 – p.1/74

    View Slide

  2. https://speakerdeck.com/ks91
    ( )
    ( )
    Discord
    Discord ( / / )
    Zoom URL ( ) ( )
    B 2022 — 4 — 2022-11-07 – p.2/74

    View Slide

  3. ( )
    1 10 17 •
    2 10 24 •
    3 10 31 •
    4 11 7 •
    5 11 14 1
    6 11 21 2
    7 11 28
    8 12 5
    ( )
    4 ( 3 )

    B 2022 — 4 — 2022-11-07 – p.3/74

    View Slide

  4. Ethereum ( )
    (1) : ERC20
    (2) :
    (3) :
    Web3
    B 2022 — 4 — 2022-11-07 – p.4/74

    View Slide

  5. Ethereum ( )
    macOS (Monterey 12.6) + Homebrew
    Linux (Ubuntu 22.04) (x86/AMD64 and ARM)
    Windows 10/11 + Windows Subsystem for Linux (Ubuntu )
    Ethereum solidity brownie
    B 2022 — 4 — 2022-11-07 – p.5/74

    View Slide

  6. Solidity
    Ethereum ( )
    http://solidity.readthedocs.io/en/latest/installing-solidity.html
    Linux (on Windows) “sudo apt”, macOS “brew”
    Linux ARM
    git clone dependencies
    solc 0.8.17 (10/31 )
    $ solc --version
    brownie py-solc-x
    solc (dependencies) ( solc py-solc-x )
    B 2022 — 4 — 2022-11-07 – p.6/74

    View Slide

  7. Ganache
    Ethereum RPC
    npm ( )
    macOS
    https://qiita.com/kyosuke5_20/items/c5f68fc9d89b84c0df09
    Linux
    https://qiita.com/seibe/items/36cef7df85fe2cefa3ea
    npm Ganache
    $ sudo npm install -g ganache
    B 2022 — 4 — 2022-11-07 – p.7/74

    View Slide

  8. Python3
    macOS
    $ brew install python3
    Python
    3.8
    Homebrew
    $ brew uninstall --ignore-dependencies [email protected]
    $ brew install [email protected]
    /usr/local/opt/[email protected]/bin/python3
    Linux
    $ sudo apt update
    $ sudo apt install python3.8 python3.8-dev python3.8-venv python3.8-tk
    16.10 python3(.8) apt (PPA )
    python3
    python3-dev python3-venv python3-tk
    B 2022 — 4 — 2022-11-07 – p.8/74

    View Slide

  9. macOS : . . .
    macOS wget brew
    dyld: Library not loaded: /usr/local/opt/gettext/lib/libintl.8.dylib
    $ brew uninstall --force gettext
    $ brew install gettext
    B 2022 — 4 — 2022-11-07 – p.9/74

    View Slide

  10. Python (venv)
    macOS (Linux python3 ) ‘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 2022 — 4 — 2022-11-07 – p.10/74

    View Slide

  11. Brownie
    Python Ethereum
    https://eth-brownie.readthedocs.io
    Brownie
    $ pip install eth-brownie
    version 1.19.2 (10/31 )
    B 2022 — 4 — 2022-11-07 – p.11/74

    View Slide

  12. $ brownie init
    ( ERC-20 )
    $ brownie bake token
    $ cd token
    B 2022 — 4 — 2022-11-07 – p.12/74

    View Slide

  13. contracts
    (macOS Linux (x86/AMD64) )
    $ brownie compile
    Linux (ARM) (AMD64 )
    $ python #
    >>> import solcx
    >>> solcx.compile_solc(’0.6.12’) #
    >>> quit()
    /tmp ∼/.solcx/solc-v0.6.12
    ( )
    $ pytest tests
    B 2022 — 4 — 2022-11-07 – p.13/74

    View Slide

  14. Brownie
    $ brownie console
    Python
    >>> len(accounts)
    10
    >>> accounts[0].balance()
    100000000000000000000
    >>> quit()
    B 2022 — 4 — 2022-11-07 – p.14/74

    View Slide

  15. ( )
    10 Ethereum Görli
    11
    B 2022 — 4 — 2022-11-07 – p.15/74

    View Slide

  16. 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 2022 — 4 — 2022-11-07 – p.16/74

    View Slide


  17. orli ETH
    brownie console Görli
    >>> network.disconnect()
    >>> network.connect(’goerli’)
    >>> len(accounts)
    0
    >>> accounts.add()

    >>> accounts[0].private_key
    16
    >>> quit()
    Görli Testnet ETH Faucet ETH
    https://goerlifaucet.com ( )
    ( )
    https://metamask.io/
    B 2022 — 4 — 2022-11-07 – p.17/74

    View Slide


  18. orli ETH
    brownie console Görli ETH
    >>> network.disconnect()
    >>> network.connect(’goerli’)
    >>> len(accounts)
    0
    >>> accounts.add( 16 )

    >>> accounts[0].balace()
    ETH
    >>> quit()
    ETH
    >>> accounts[0].transfer(accounts[1], "0.01 ether")
    B 2022 — 4 — 2022-11-07 – p.18/74

    View Slide

  19. Ethereum ( )
    B 2022 — 4 — 2022-11-07 – p.19/74

    View Slide

  20. Ethereum
    Vitalik Buterin, “Ethereum White Paper: A NEXT GENERATION SMART
    CONTRACT & DECENTRALIZED APPLICATION PLATFORM”
    12
    (= )
    =


    Dapps ( / / )
    B 2022 — 4 — 2022-11-07 – p.20/74

    View Slide

  21. ( )
    B 2022 — 4 — 2022-11-07 – p.21/74

    View Slide

  22. . . .
    B 2022 — 4 — 2022-11-07 – p.22/74

    View Slide

  23. vs.
    B 2022 — 4 — 2022-11-07 – p.23/74

    View Slide

  24. = run
    B 2022 — 4 — 2022-11-07 – p.24/74

    View Slide

  25. Ether
    Ethereum
    EOA : Externally-Owned Account
    ( )
    Ether EVM
    EVM
    B 2022 — 4 — 2022-11-07 – p.25/74

    View Slide

  26. EVM : Ethereum Virtual Machine
    Gas ( EVM = ( burn))
    . . . B 2022 — 4 — 2022-11-07 – p.26/74

    View Slide

  27. EVM
    :
    : ←
    :
    Solidity — JavaScript
    LLL — Lisp
    Vyper — Python
    Fe — Vyper Rust ← NEW!
    Solidity
    Vyper Python
    B 2022 — 4 — 2022-11-07 – p.27/74

    View Slide

  28. Solidity ( )
    pragma solidityˆ0.7.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 2022 — 4 — 2022-11-07 – p.28/74

    View Slide

  29. ( , )
    (constructor)
    (deploy) =
    ( )
    ( )
    ETH
    Trusted Actor Model
    B 2022 — 4 — 2022-11-07 – p.29/74

    View Slide

  30. Ethereum
    B 2022 — 4 — 2022-11-07 – p.30/74

    View Slide

  31. (1) : ERC20
    $ brownie bake token
    B 2022 — 4 — 2022-11-07 – p.31/74

    View Slide

  32. Solidity
    JavaScript
    ( , )
    (constructor)
    ( )
    ( )
    Ether
    Ethereum
    B 2022 — 4 — 2022-11-07 – p.32/74

    View Slide

  33. pragma solidity ˆ0.6.0; /* 0.8.x */
    contract Token {
    ( )
    :
    (EVM )
    :
    constructor (...) public { /* */
    :
    }
    function balanceOf(...) { /* ( ) */
    :
    }
    :
    }
    constructor
    C (/* */ // )
    B 2022 — 4 — 2022-11-07 – p.33/74

    View Slide

  34. 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
    ERC-777 ( )
    B 2022 — 4 — 2022-11-07 – p.34/74

    View Slide

  35. ERC20
    ERC20
    ( )
    ⇒ ERC20
    ( ERC20 )
    ERC20

    B 2022 — 4 — 2022-11-07 – p.35/74

    View Slide

  36. (fungible)
    ERC-20 → ERC-223 (draft) or ERC-777 ( )( )
    (non-fungible)
    ERC-721
    ( )
    ERC-1155 ( )
    ERC-3525 (SLOT )
    B 2022 — 4 — 2022-11-07 – p.36/74

    View Slide

  37. 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 2022 — 4 — 2022-11-07 – p.37/74

    View Slide

  38. Token ( )
    event Transfer(address from, address to, uint256 value);
    Token function emit Transfer() ( )
    B 2022 — 4 — 2022-11-07 – p.38/74

    View Slide

  39. 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 2022 — 4 — 2022-11-07 – p.39/74

    View Slide

  40. Token balanceOf()
    function balanceOf(address _owner) public view returns (uint256) {
    return balances[_owner];
    }
    B 2022 — 4 — 2022-11-07 – p.40/74

    View Slide

  41. 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 2022 — 4 — 2022-11-07 – p.41/74

    View Slide

  42. (2) :
    B 2022 — 4 — 2022-11-07 – p.42/74

    View Slide

  43. 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 2022 — 4 — 2022-11-07 – p.43/74

    View Slide

  44. (m2 )
    1 1
    B 2022 — 4 — 2022-11-07 – p.44/74

    View Slide

  45. IndivisibleAsset
    string public _name_;
    string public _symbol_;
    uint256 public _quantity_;
    address public _owner_;
    _name_ ( )
    _symbol_ _quantity_ (m2 )
    _owner_
    ‘_’ Solidity . . .
    B 2022 — 4 — 2022-11-07 – p.45/74

    View Slide

  46. IndivisibleAsset
    event Transfer(address indexed from, address indexed to);
    from to
    indexed
    B 2022 — 4 — 2022-11-07 – p.46/74

    View Slide

  47. IndivisibleAsset
    constructor (string name, string symbol, uint256 quantity) public {
    _name_ = name;
    _symbol_ = symbol;
    _quantity_ = quantity;
    _owner_ = msg.sender;
    }
    B 2022 — 4 — 2022-11-07 – p.47/74

    View Slide

  48. IndivisibleAsset getOwner()
    function getOwner() public view returns (address) {
    return (_owner_);
    }
    B 2022 — 4 — 2022-11-07 – p.48/74

    View Slide

  49. 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 2022 — 4 — 2022-11-07 – p.49/74

    View Slide

  50. scripts/indivisible asset.py
    from brownie import *
    def main():
    accounts[0].deploy(IndivisibleAsset, "5322 Endo, Fujisawa", "mˆ2", 300)
    SFC (300m2 )
    ( )
    B 2022 — 4 — 2022-11-07 – p.50/74

    View Slide

  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 2022 — 4 — 2022-11-07 – p.51/74

    View Slide

  52. $ pytest tests/test_indivisible_asset.py
    B 2022 — 4 — 2022-11-07 – p.52/74

    View Slide

  53. (3) :
    B 2022 — 4 — 2022-11-07 – p.53/74

    View Slide

  54. transfer
    settle, retrieve asset, retrieve token 3
    B 2022 — 4 — 2022-11-07 – p.54/74

    View Slide

  55. 1. ( )
    2. ( )
    3. ( )
    B 2022 — 4 — 2022-11-07 – p.55/74

    View Slide

  56. 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 2022 — 4 — 2022-11-07 – p.56/74

    View Slide

  57. (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 2022 — 4 — 2022-11-07 – p.57/74

    View Slide

  58. (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 2022 — 4 — 2022-11-07 – p.58/74

    View Slide

  59. (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 2022 — 4 — 2022-11-07 – p.59/74

    View Slide

  60. (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 2022 — 4 — 2022-11-07 – p.60/74

    View Slide

  61. $ pytest tests/test_one_time_escrow.py
    :
    settle()
    ⇒ Discord
    B 2022 — 4 — 2022-11-07 – p.61/74

    View Slide

  62. B 2022 — 4 — 2022-11-07 – p.62/74

    View Slide

  63. 1.
    (1)
    (2) Ethereum
    2022 11 5 ( ) 23:59 JST
    B 2022 — 4 — 2022-11-07 – p.63/74

    View Slide

  64. . . . . . .
    6 2 ( ) ( )
    (← )
    ( )
    B 2022 — 4 — 2022-11-07 – p.64/74

    View Slide

  65. M
    Ethereum
    ⇒ 20 Discord
    . . .
    B 2022 — 4 — 2022-11-07 – p.65/74

    View Slide

  66. M
    VR

    B 2022 — 4 — 2022-11-07 – p.66/74

    View Slide

  67. T

    B 2022 — 4 — 2022-11-07 – p.67/74

    View Slide

  68. T
    ( ?)
    (
    )

    ( )
    B 2022 — 4 — 2022-11-07 – p.68/74

    View Slide

  69. Web3
    Web3
    HTTPS
    B 2022 — 4 — 2022-11-07 – p.69/74

    View Slide


  70. B 2022 — 4 — 2022-11-07 – p.70/74

    View Slide

  71. miro ( ) ( )
    B 2022 — 4 — 2022-11-07 – p.71/74

    View Slide

  72. B 2022 — 4 — 2022-11-07 – p.72/74

    View Slide

  73. 2. API
    (1) ( )
    (2) Web API
    2022 11 12 ( ) 23:59 JST
    B 2022 — 4 — 2022-11-07 – p.73/74

    View Slide

  74. B 2022 — 4 — 2022-11-07 – p.74/74

    View Slide