2023年8月30日(水)、ブロックチェーンハブ主催のブロックチェーンアカデミーにて使用したスライドです。
2 Ethereum ICSO /[email protected]— 2 Ethereum I — 2023-08-30 – p.1/37
View Slide
https://speakerdeck.com/ks91— 2 Ethereum I — 2023-08-30 – p.2/37
( )SFC ( )CSO (Chief Science Officer)1993 ( )2006 ( )SFC22 P2P (Peer-to-Peer)2011 ( )2018 2019VR 2021.9 & VR 2022.32023 AI VR&RPG 2023.5 “Don’t Be So Serious”VOXEL 2023.7 DAZE 2023→ ( )— 2 Ethereum I — 2023-08-30 – p.3/37
ERC-202ERC-20— 2 Ethereum I — 2023-08-30 – p.4/37
1. : ERC-202. :3. :— 2 Ethereum I — 2023-08-30 – p.5/37
1. : ERC-20$ brownie bake token— 2 Ethereum I — 2023-08-30 – p.6/37
SolidityJavaScript( , )(constructor)( )( )EtherEthereum— 2 Ethereum I — 2023-08-30 – p.7/37
pragma solidity ˆ0.6.0; /* 0.8.x */contract Token {( ):(EVM ):constructor (...) public { /* */:}function balanceOf(...) { /* ( ) */:}:}constructorC (/* */ // )— 2 Ethereum I — 2023-08-30 – p.8/37
ERC-20ERC (Ethereum Request for Comments) EIP (Ethereum Improvement Proposals) 20https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.mdcontract 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 allowanceERC-777— 2 Ethereum I — 2023-08-30 – p.9/37
ERC-20ERC-20( )⇒ ERC-20( ERC-20 )ERC-20⇒— 2 Ethereum I — 2023-08-30 – p.10/37
(fungible)ERC-20 → ERC-223 (draft) or ERC-777 ( )( )(non-fungible)ERC-721( )ERC-1155 ( )ERC-3525 (SLOT )— 2 Ethereum I — 2023-08-30 – p.11/37
Token ( )string public symbol;string public name;uint256 public decimals;uint256 public totalSupply;mapping(address => uint256) balances;...name, symboldecimals: 2 100 1.00mapping balances— 2 Ethereum I — 2023-08-30 – p.12/37
Token ( )event Transfer(address from, address to, uint256 value);Token function emit Transfer() ( )— 2 Ethereum I — 2023-08-30 – p.13/37
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— 2 Ethereum I — 2023-08-30 – p.14/37
Token balanceOf()function balanceOf(address _owner) public view returns (uint256) {return balances[_owner];}— 2 Ethereum I — 2023-08-30 – p.15/37
Token transfer()function transfer(address _to, uint256 _value) public returns (bool) {require(balances[msg.sender] >= _value, "Insufficient balance");balances[msg.sender] = balances[msg.sender].sub(_value);balances[_to] = balances[_to].add(_value);emit Transfer(msg.sender, _to, _value);return true;}require (function )( ↑ )OpenZeppelinhttps://openzeppelin.org— 2 Ethereum I — 2023-08-30 – p.16/37
2.— 2 Ethereum I — 2023-08-30 – p.17/37
GitHub git clone$ git clone https://github.com/ks91/sample-smart-contracts.gitsample-smart-contracts contracts, scriptstests tokenTokenSolidity 0.5 0.6/0.7(Token )Token Solidity 0.5 0.6Solidity— 2 Ethereum I — 2023-08-30 – p.18/37
(m2 )1 1— 2 Ethereum I — 2023-08-30 – p.19/37
IndivisibleAssetstring public _name_;string public _symbol_;uint256 public _quantity_;address public _owner_;_name_ ( )_symbol_ _quantity_ (m2 )_owner_‘_’ Solidity . . .— 2 Ethereum I — 2023-08-30 – p.20/37
IndivisibleAssetevent Transfer(address indexed from, address indexed to);from toindexed— 2 Ethereum I — 2023-08-30 – p.21/37
IndivisibleAssetconstructor (string name, string symbol, uint256 quantity) public {_name_ = name;_symbol_ = symbol;_quantity_ = quantity;_owner_ = msg.sender;}— 2 Ethereum I — 2023-08-30 – p.22/37
IndivisibleAsset getOwner()function getOwner() public view returns (address) {return (_owner_);}— 2 Ethereum I — 2023-08-30 – p.23/37
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— 2 Ethereum I — 2023-08-30 – p.24/37
scripts/indivisible asset.pyfrom brownie import *def main():accounts[0].deploy(IndivisibleAsset, "5322 Endo, Fujisawa", "mˆ2", 300)SFC (300m2 )( )— 2 Ethereum I — 2023-08-30 – p.25/37
from brownie import *import pytestdef 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 = 1except:done = 0assert done == 0accounts[0] accounts[1]— 2 Ethereum I — 2023-08-30 – p.26/37
$ pytest tests/test_indivisible_asset.py— 2 Ethereum I — 2023-08-30 – p.27/37
3.— 2 Ethereum I — 2023-08-30 – p.28/37
transfersettle, retrieve asset, retrieve token 3— 2 Ethereum I — 2023-08-30 – p.29/37
1. ( )2. ( )3. ( )— 2 Ethereum I — 2023-08-30 – p.30/37
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— 2 Ethereum I — 2023-08-30 – p.31/37
(1)from brownie import *import pytestdef 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")— 2 Ethereum I — 2023-08-30 – p.32/37
(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] 300300 TXaccounts[1] accounts[0] 300bake Token300 ETH wei— 2 Ethereum I — 2023-08-30 – p.33/37
(3)token.transfer(escrow, 300, {’from’: accounts[1]})asset.transfer(escrow, {’from’: accounts[0]})assert token.balanceOf(accounts[0]) == 999999999999999999700assert token.balanceOf(accounts[1]) == 0assert token.balanceOf(escrow) == 300assert asset.getOwner() == escrowaccounts[1] ( ) 300accounts[0] ( )— 2 Ethereum I — 2023-08-30 – p.34/37
(4)escrow.settle({’from’: accounts[0]})assert token.balanceOf(accounts[0]) == 1000000000000000000000assert token.balanceOf(accounts[1]) == 0assert token.balanceOf(escrow) == 0assert asset.getOwner() == accounts[1]settle()accounts[0] OK— 2 Ethereum I — 2023-08-30 – p.35/37
$ pytest tests/test_one_time_escrow.py:settle()— 2 Ethereum I — 2023-08-30 – p.36/37
3 Ethereum II:— 2 Ethereum I — 2023-08-30 – p.37/37