Upgrade to Pro — share decks privately, control downloads, hide ads and more …

BBc-1 とEthereum 演習 II / Practice 2 for BBc-1 an...

BBc-1 とEthereum 演習 II / Practice 2 for BBc-1 and Ethereum

2019年6月19日(水)、ブロックチェーンハブ主催で開催されたブロックチェーンアカデミー「実践!スマートコントラクトプログラミング 第3回 BBc-1 と Ethereum 演習 II」にて使用したスライドです。

Kenji Saito

June 19, 2019
Tweet

More Decks by Kenji Saito

Other Decks in Technology

Transcript

  1. ୈ3ճ BBc-1 ͱ Ethereum ԋशII ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά ϒϩοΫνΣʔϯϋϒ CSO / ܚጯٛक़େֶ

    SFC ݚڀॴ ্੮ॴһ ੪౻ ݡ࣐ [email protected] ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.1/35
  2. ؆୯ͳࣗݾ঺հ ੪౻ ݡ࣐ (͍͞ͱ͏ ͚Μ͡) ܚጯٛक़େֶ SFC ݚڀॴ ্੮ॴһɾ؀ڥ৘ใֶ෦ ߨࢣ

    (ඇৗۈ) גࣜձࣾϒϩοΫνΣʔϯϋϒ CSO (Chief Science Officer) Ұൠࣾஂ๏ਓϏϤϯυϒϩοΫνΣʔϯ ୅දཧࣄ Ұൠࣾஂ๏ਓΞΧσϛʔΩϟϯϓ ୅දཧࣄ ܦྺ 1993 ೥ɺίʔωϧେֶΑΓ޻ֶम࢜߸औಘ (ίϯϐϡʔλαΠΤϯε) 2006 ೥ɺܚጯٛक़େֶΑΓσδλϧ௨՟ͷݚڀͰത࢜߸औಘ (੓ࡦɾϝσΟΞ) ܚጯٛक़େֶ େֶӃ ੓ࡦɾϝσΟΞݚڀՊ΍ SFC ݚڀॴʹͯ 18 ೥Ҏ্ʹΘͨΓ P2P (Peer-to-Peer) ͓Αͼσδλϧ௨՟౳ͷݚڀʹैࣄ 2011 ೥ՆΑΓ෱ౡͷ͜Ͳ΋ͨͪͷͨΊͷʮΞΧσϛʔΩϟϯϓʯΛ஥ؒΒͱ։࠵ ࡢՆ͸ SFC ʹͯ ΞΧσϛʔΩϟϯϓ 2018 ՆʮΦοέʔάʔάϧɺ॓୊΍ͬͱ͍ͯʂʯΛ࣮ࢪ ࡢౙɺΞΧσϛʔΩϟϯϓ 2019 ౙʮԵঁͷͨΊͷΦʔτϝʔγϣϯ ∼ ΧϫΠΠ͸ࣗಈԽͰ͖ΔʂʯΛ࣮ࢪ → ࢲͷ಄ͷதͰ͸ͭͳ͕͍ͬͯ·͢ (͜Ε͔ΒͷࣾձͷσβΠϯ͸͜Ͳ΋ͨͪͱҰॹʹ) ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.3/35
  3. ࠓճͷςʔϚ BBc-1 ͱ Ethereum Λ૊Έ߹Θͤͯ༻͍Δ͜ͱͰɺ ه࿥ͷਅਖ਼ੑΛࣄޙʹݕূՄೳͳɺ෯޿͍ΞϓϦέʔγϣϯΛߏஙͰ͖·͢ ୈ 3 ճͱͳΔຊηϛφʔͰ͸ɺిࢠνέοτ΍σδλϧ௨՟ͷͨΊͷ γεςϜͮ͘Γʹ௅ઓ͠·͢

    ۩ମతʹ͸ Ethereum εϚʔτίϯτϥΫτʹΑͬͯ౔஍ചങΛߦͬͯΈ·͢ ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.4/35
  4. ࠓճͷߏ੒ 1. ࣮श՝୊ : ؆қͳ ERC20 ४ڌσδλϧτʔΫϯγεςϜ 2. ࣮श՝୊ :

    ؆қͳσδλϧΞηοτγεςϜͷ࡞੒ 3. ࣮श՝୊ : ؆қͳࣗಈΤεΫϩʔγεςϜͷ࡞੒ ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.5/35
  5. 1. ࣮श՝୊ : ؆қͳ ERC20 ४ڌ σδλϧτʔΫϯγεςϜ $ brownie bake

    token Ͱల։͞ΕͨϓϩδΣΫτΛվΊͯݟͯΈ·͠ΐ͏ ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.6/35
  6. ϓϩάϥϛϯάݴޠ Solidity ͷಛ௃ JavaScript ෩ ΦϒδΣΫτࢦ޲ ίϯτϥΫτΛ਽ܗ (ܕ, Ϋϥε) ͱͯ͠هड़͢Δ

    σϓϩΠ͢Δࡍʹߏஙࢠ (constructor) ͕ݺ͹ΕΔ ͦͷࡍʹߏஙࢠʹ౉͢ύϥϝʔλΛܾΊΔ σϓϩΠ͞ΕͨίϯτϥΫτ͸۩ମతͳ࣮ମ (Πϯελϯε) ΞΧ΢ϯτΛ΋ͭ (ΞυϨεͰࣝผ͞ΕΔ) ετϨʔδͱ Ether ࢒ߴΛ΋ͭ ଞͷίϯτϥΫτʹϝοηʔδΛૹΕΔ σϓϩΠ͞ΕͨίϯτϥΫτʹϝοηʔδΛૹͬͯૢ࡞͢Δ ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.7/35
  7. ίϯτϥΫτͷجຊߏจ pragma solidity ˆ0.5.0; contract Token { εςʔτม਺ (σʔλϝϯό) :

    Πϕϯτ (EVM ϩΪϯάΠϯλϑΣʔε) : constructor (...) public { /* ߏஙࢠ */ : } function balanceOf(...) { /* ؔ਺ (ϝιου) */ : } : } constructor Ωʔϫʔυʹଓ͘ແ໊ؔ਺͕ߏஙࢠͱͳΔ ΠϕϯτΛએݴ͠༻͍Δ͜ͱͰϩΪϯάՄೳ ஫ऍͷه๏͸ C ݴޠ෩ (/* */ ͰғΉɺ·ͨ͸ // Ҏ߱ߦ຤·Ͱ) ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.8/35
  8. 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) ౳ʹΑΓ֦ு͞Ε͍ͯΔ ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.9/35
  9. 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 ͸࢒ߴ ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.10/35
  10. Token ͷΠϕϯτ (ൈਮ) event Transfer(address from, address to, uint256 value);

    Token ͕ఆٛ͢Δ function ͷதͰ emit Transfer() ͢Δ (ϩΪϯά) ରԠ͢ΔπʔϧͰΠϕϯτΛදࣔͤ͞Δ͜ͱ͕Ͱ͖Δ ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.11/35
  11. 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 ʹॳظԽ͍ͯ͠Δ ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.12/35
  12. Token ͷ balanceOf() function balanceOf(address _owner) public view returns (uint256)

    { return balances[_owner]; } ͍ΘΏΔήολʔؔ਺Ͱ͢ ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.13/35
  13. 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 ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.14/35
  14. αϯϓϧίʔυ μ΢ϯϩʔυ͍ͯͩ͘͠͞ BcH-smart-contract-programming.zip ల։ͯ͠ಘΒΕͨ contracts, scrypts ͓Αͼ tests ҎԼͷϑΝΠϧ܈Λ token

    ϓϩδΣΫτͷಉ͡σΟϨΫτϦʹͦΕͧΕίϐʔ͍ͯͩ͘͠͞ ࠓ೔͸࠷ޙʹ Token ͱ૊Έ߹Θͤͯಈ͔͠·͢ ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.16/35
  15. IndivisibleAsset ͷεςʔτม਺ string public _name_; string public _symbol_; uint256 public

    _quantity_; address public _owner_; _name_ ͸Ξηοτͷ໊લ (ෆಈ࢈ͳΒॅॴͱ͔) _symbol_ ͱ _quantity_ ͸ͦΕͧΕ୯Ґ (m2 ͱ͔) ͱྔ _owner_ ͸ॴ༗ऀͷΞυϨε ‘_’ ͷҐஔ͕ Solidity ϓϩάϥϛϯάʹݟΒΕΔ׳शͱҟͳΓ·͕͢ . . . Ҿ਺΍ࣗಈม਺ͷग़ݱͷํ͕ଟ͍͠એݴՕॴ΋͍ۙͷ͔ͩΒɺΉ͠Ζεςʔτม਺ͷํΛ ࣝผ͠΍͘͢͢΂͖Ͱ͸ʁͱ͍͏໰୊ఏى ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.18/35
  16. IndivisibleAsset ͷΠϕϯτ event Transfer(address indexed from, address indexed to); Ҡస͞ΕΔͷ͸Ξηοτࣗ਎ͳͷͰ৘ใ͸

    from ͱ to Ͱे෼ indexed ͸ϩάͷݕࡧΩʔʹ͢Δ͜ͱΛࣔ͠·͢ ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.19/35
  17. IndivisibleAsset ͷߏஙࢠ constructor (string name, string symbol, uint256 quantity) public

    { _name_ = name; _symbol_ = symbol; _quantity_ = quantity; _owner_ = msg.sender; } εςʔτม਺ΛॳظԽ͠·͢ ॳظͷॴ༗ऀ͸ɺίϯτϥΫτΛσϓϩΠͨ͠ຊਓͱ͠·͢ ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.20/35
  18. IndivisibleAsset ͷ getOwner() function getOwner() public view returns (address) {

    return (_owner_); } ͍ΘΏΔήολʔؔ਺Ͱ͢ ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.21/35
  19. 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 ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.22/35
  20. scripts/indivisible asset.py from brownie import * def main(): accounts[0].deploy(IndivisibleAsset, "5322

    Endo, Fujisawa", "mˆ2", 300) ߏஙࢠʹύϥϝʔλΛ౉͠ɺσϓϩΠ͍ͯ͠·͢ ໊শ͸ܚጯ SFC ͷॅॴͰ͢ (300m2 ͱ͍͏͜ͱ͸͋Γ·ͤΜ͕) ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.23/35
  21. ςετίʔυ from brownie import * import scripts.indivisible_asset def setup(): scripts.indivisible_asset.main()

    def owner_and_transfer(): asset = IndivisibleAsset[0] 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] ʹΞηοτͷݖརΛҠస͢ΔςετͰ͢ ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.24/35
  22. ཁٻͱઃܭํ਑ ཁٻ Ξηοτ΍ྉۚͷ࣋ͪಀ͛Λ๷͙ͨΊʹɺ Ξηοτͱσδλϧ௨՟ͷ transfer ͕ಉ࣌ʹى͖ΔΑ͏ʹ͠·͢ ͦΕͧΕΤεΫϩʔαʔϏεʹ༬ୗ͠ɺଗͬͨΒऔҾ͕࣮ߦͰ͖·͢ ଗΘͳ͚Ε͹ചΓख΋ങ͍ख΋औΓফͤ·͢ ઃܭํ਑ ࢖͍੾ΓͷΤεΫϩʔίϯτϥΫτΛ༻ҙ͠·͢

    ߪೖ༻௨՟ɺങ͍खɺΞηοτɺചΓखɺՁ֨ΛσϓϩΠ࣌ʹࢦఆ͠·͢ settle, retrieve asset, retrieve token ͷ 3 ͭͷૢ࡞Λఏڙ͠·͢ ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.27/35
  23. ࣗಈΤεΫϩʔʹΑΔ౔஍ͷചങ 1. ౔஍΍୅ۚͷ࣋ͪಀ͛Λ๷͙ͨΊʹചങܖ໿Λۭதʹݻఆ (ͲͪΒ͕΍ͬͯ΋಺༰ΛݕূՄ) 2. ౔஍ͷݖར΍୅ۚΛചങܖ໿ʹ༬ୗ͢Δ (ؾ͕มΘͬͨΒऔΓ໭ͯ͠Α͍) 3. ࣮ߦ (͜Ε΋ͲͪΒ͕΍ͬͯ΋Α͍)

    ͢Δͱɺ৚͕݅ଗ͍ͬͯΔͳΒ౔஍ͷݖརͱ୅͕ۚಉ࣌ʹҠస͢Δ ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.28/35
  24. 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 ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.29/35
  25. ςετίʔυ (1) from brownie import * import scripts.indivisible_asset import scripts.token

    def setup(): scripts.indivisible_asset.main() scripts.token.main() τʔΫϯͱΞηοτͷίϯτϥΫτΛσϓϩΠ͍ͯ͠·͢ ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.30/35
  26. ςετίʔυ (2) def deploy_and_settle(): asset = IndivisibleAsset[0] token = Token[0]

    token.transfer(accounts[1], 300, {’from’: accounts[0]}) accounts[0].deploy(OneTimeEscrow, token, accounts[1], asset, accounts[0], 300) escrow = OneTimeEscrow[0] account0 ͔Β account1 ʹ 1Ether ΛૹΓɺ accounts[0] ͔Β accounts[1] ʹ 300 ίΠϯΛૹ͍ͬͯ·͢ ങ͍खͱͯ͠ 300 ίΠϯΛࢧ෷͏ TX Λ౤ೖ͢ΔͨΊͰ͢ ΤεΫϩʔͷίϯτϥΫτΛσϓϩΠ͍ͯ͠·͢ ങ͍ख͸ accounts[1]ɺചΓख͸ accounts[0]ɺՁ֨͸ 300 ίΠϯͰ͢ bake ͞Εͨ Token Λͦͷ··࢖͍ͬͯΔͷͰɺ 300 ίΠϯͱ͍͏ͷ͸ ETH Ͱݴ͏ wei ͷΑ͏ͳখ͞ͳ୯ҐͰ͢ ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.31/35
  27. ςετίʔυ (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] ͔ΒΞηοτΛΤεΫϩʔʹ༬ୗ͍ͯ͠·͢ ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.32/35
  28. ςετίʔυ (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 Ͱ͢ ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.33/35
  29. ςετίʔυͷ࣮ߦ ҎԼͷίϚϯυͰςετΛ࣮ߦ͠·͢ $ brownie test test_one_time_escrow.py ࿅श໰୊ : settle() Ҏ֎ͷϝοηʔδ΋ςετͰ͖ΔΑ͏ʹ

    ςετίʔυΛॻ͖׵͑ͯࢼͯ͠Έ·͠ΐ͏ ࣮ફʂεϚʔτίϯτϥΫτϓϩάϥϛϯά — ୈ 3 ճ BBc-1 ͱ Ethereum ԋश II — 2019-06-19 – p.34/35