From 8f70ba0d6f2f79b2ae0e20347299277d034c8f95 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Thu, 21 Feb 2019 15:50:57 +1300 Subject: [PATCH 1/2] Delete eip-1175.md --- eip-1175.md | 533 ---------------------------------------------------- 1 file changed, 533 deletions(-) delete mode 100644 eip-1175.md diff --git a/eip-1175.md b/eip-1175.md deleted file mode 100644 index fa8cc102511807..00000000000000 --- a/eip-1175.md +++ /dev/null @@ -1,533 +0,0 @@ ---- -eip: 1175 -title: Wallet & shop standard for all tokens (erc20) -author: Jet Lim (@Nitro888) -discussions-to: https://github.com/ethereum/EIPs/issues/1182 -status: Draft -type: Standards Track -category: ERC -created: 2018-06-21 -requires: 20 ---- - -# All tokens go to heaven -## Simple Summary -Make wallets and shops created from certified contracts make erc20 tokens easy to use for commerce. - -![wallet](https://user-images.githubusercontent.com/11692220/41762799-ee17c480-7636-11e8-9930-681be2c59b56.png) - -## Abstract -The mutual trust between the wallet and the shop created by the authenticated contract allows you to pay for and purchase items at a simple process. - -## Motivation -New standards with improvements have been released, but the majority of tokens currently being developed are erc20 tokens. So I felt I needed a proposal to use old tokens in commerce. - To use various erc20 tokens for trading, you need a custom contract. However, a single wallet with a variety of tokens, and a mutually trusted store, can make transactions that are simple and efficient. The erc20 token is traded through two calls, `approve (address _spender, uint256 _value)` and `transferFrom (address _from, address _to, uint256 _value)`, but when using the wallet contract, `paySafe (address _shop, uint256 _item)`will be traded only in one call. -And if you only reuse the store interface, you can also trade using `payUnsafe (address _shop, uint256 _item)`. - -## Specification -![workflow](https://user-images.githubusercontent.com/11692220/41841025-2ed6e024-78a2-11e8-9faf-2b43aeaa2303.png) -## WalletCenter -### Methods -#### createWallet -Create wallet contract and add to list. Returns the address of new wallet. - -``` js -function createWallet() public returns (address _wallet) -``` - -#### isWallet -Returns true or false value for test this address is a created by createWallet. - -``` js -function isWallet(address _wallet) public constant returns (bool) -``` - -#### createShop -Create Shop contract and add to list. Returns the address of new Shop with erc20 token address. - -``` js -function createShop(address _erc20) public returns (address _shop) -``` - -#### isShop -Returns true or false value for test this address is a created by createWallet. - -``` js -function isShop(address _shop) public constant returns (bool) -``` - -### Events -#### Wallet -Search for my wallet. -``` js -event Wallet(address indexed _owner, address indexed _wallet) -``` - -#### Shop -Search for my shop. -``` js -event Shop(address indexed _owner, address indexed _shop, address indexed _erc20) -``` - -## Wallet -Wallet must be created by wallet center. -### Methods -#### balanceOf -Returns the account balance of Wallet. -``` js -function balanceOf(address _erc20) public constant returns (uint256 balance) -``` - -#### withdrawal -withdrawal `_value` amount of `_erc20` token to `_owner`. -``` js -function withdrawal(address _erc20, uint256 _value) onlyOwner public returns (bool success) -``` - -#### paySafe -Pay for safe shop (created by contract) item with item index `_item`. -``` js -function paySafe(address _shop, uint256 _item) onlyOwner onlyShop(_shop) public payable returns (bool success) -``` - -#### payUnsafe -Pay for unsafe shop (did not created by contract) item with item index `_item`. -``` js -function payUnsafe(address _shop, uint256 _item) onlyOwner public payable returns (bool success) -``` - -#### payCancel -Cancel pay and refund. (only weekly model) -``` js -function payCancel(address _shop, uint256 _item) onlyOwner public returns (bool success) -``` - -#### refund -Refund from shop with item index `_item`. -``` js -function refund(uint256 _item, uint256 _value) public payable returns (bool success) -``` - -### Events -#### Pay -``` js -event Pay(address indexed _shop, uint256 indexed _item, uint256 indexed _value) -``` - -#### Refund -``` js -event Refund(address indexed _shop, uint256 indexed _item, uint256 indexed _value) -``` - -## Shop -Shop is created by wallet center or not. but Shop that created by wallet center is called safe shop. -### Methods -#### balanceOf -Returns the account balance of Shop. -``` js -function balanceOf(address _erc20) public constant returns (uint256 balance) -``` - -#### withdrawal -withdrawal `_value` amount of `_erc20` token to `_owner`. -``` js -function withdrawal(address _erc20, uint256 _value) onlyOwner public returns (bool success) -``` - -#### pay -Pay from buyer with item index `_item`. -``` js -function pay(uint256 _item) onlyWallet(msg.sender) public payable returns (bool success) -``` - -#### refund -refund token to `_to`. -``` js -function refund(address _buyer, uint256 _item, uint256 _value) onlyWallet(_buyer) onlyOwner public payable returns (bool success) -``` - -#### resister -Listing item for sell. -``` js -function resister(uint8 _category, uint256 _price, uint256 _stock) onlyOwner public returns (uint256 _itemId) -``` - -#### update -Update item state for sell. (change item `_price` or add item `_stock`) -``` js -function update(uint256 _item, uint256 _price, uint256 _stock) onlyOwner public -``` - -#### price -Get token address and price from buyer with item index `_item`. -``` js -function price(uint256 _item) public constant returns (address _erc20, uint256 _value) -``` - -#### canBuy -`_who` can Buy `_item`. -``` js -function canBuy(address _who, uint256 _item) public constant returns (bool _canBuy) -``` - -#### isBuyer -`_who` is buyer of `_item`. -``` js -function isBuyer(address _who, uint256 _item) public constant returns (bool _buyer) -``` - -#### info -Set shop information bytes. -``` js -function info(bytes _msgPack) -``` - -#### upVote -Up vote for this shop. -``` js -function upVote() -``` - -#### dnVote -Down vote for this shop. -``` js -function dnVote() -``` - -#### about -Get shop token, up vote and down vote. -``` js -function about() view returns (address _erc20, uint256 _up, uint256 _down) -``` - -#### infoItem -Set item information bytes. -``` js -function infoItem(uint256 _item, bytes _msgPack) -``` - -#### upVoteItem -Up vote for this item. -``` js -function upVoteItem(uint256 _item) -``` - -#### dnVoteItem -Down vote for this item. -``` js -function dnVoteItem(uint256 _item) -``` - -#### aboutItem -Get Item price, up vote and down vote. -``` js -function aboutItem(uint256 _item) view returns (uint256 _price, uint256 _up, uint256 _down) -``` - -### Events -#### Pay -``` js -event Pay(address indexed _buyer, uint256 indexed _item, uint256 indexed _value) -``` - -#### Refund -``` js -event Refund(address indexed _to, uint256 indexed _item, uint256 indexed _value) -``` - -#### Item -``` js -event Item(uint256 indexed _item, uint256 _price) -``` - -#### Info -``` js -event Info(bytes _msgPack) -``` - -#### InfoItem -``` js -event InfoItem(uint256 indexed _item, bytes _msgPack) -``` - -## Implementation -Sample token contract address is [0x393dd70ce2ae7b30501aec94727968c517f90d52](https://ropsten.etherscan.io/address/0x393dd70ce2ae7b30501aec94727968c517f90d52) - -WalletCenter contract address is [0x1fe0862a4a8287d6c23904d61f02507b5044ea31](https://ropsten.etherscan.io/address/0x1fe0862a4a8287d6c23904d61f02507b5044ea31) - -WalletCenter create shop contract address is [0x59117730D02Ca3796121b7975796d479A5Fe54B0](https://ropsten.etherscan.io/address/0x59117730D02Ca3796121b7975796d479A5Fe54B0) - -WalletCenter create wallet contract address is [0x39da7111844df424e1d0a0226183533dd07bc5c6](https://ropsten.etherscan.io/address/0x39da7111844df424e1d0a0226183533dd07bc5c6) - - -## Appendix -``` js -pragma solidity ^0.4.24; - -contract ERC20Interface { - function totalSupply() public constant returns (uint); - function balanceOf(address tokenOwner) public constant returns (uint balance); - function allowance(address tokenOwner, address spender) public constant returns (uint remaining); - function transfer(address to, uint tokens) public returns (bool success); - function approve(address spender, uint tokens) public returns (bool success); - function transferFrom(address from, address to, uint tokens) public returns (bool success); - - event Transfer(address indexed from, address indexed to, uint tokens); - event Approval(address indexed tokenOwner, address indexed spender, uint tokens); -} - -contract SafeMath { - function safeAdd(uint a, uint b) public pure returns (uint c) { - c = a + b; - require(c >= a); - } - function safeSub(uint a, uint b) public pure returns (uint c) { - require(b <= a); - c = a - b; - } - function safeMul(uint a, uint b) public pure returns (uint c) { - c = a * b; - require(a == 0 || c / a == b); - } - function safeDiv(uint a, uint b) public pure returns (uint c) { - require(b > 0); - c = a / b; - } -} - -contract _Base { - address internal owner; - address internal walletCenter; - - modifier onlyOwner { - require(owner == msg.sender); - _; - } - modifier onlyWallet(address _addr) { - require(WalletCenter(walletCenter).isWallet(_addr)); - _; - } - modifier onlyShop(address _addr) { - require(WalletCenter(walletCenter).isShop(_addr)); - _; - } - - function balanceOf(address _erc20) public constant returns (uint256 balance) { - if(_erc20==address(0)) - return address(this).balance; - return ERC20Interface(_erc20).balanceOf(this); - } - - function transfer(address _to, address _erc20, uint256 _value) internal returns (bool success) { - require((_erc20==address(0)?address(this).balance:ERC20Interface(_erc20).balanceOf(this))>=_value); - if(_erc20==address(0)) - _to.transfer(_value); - else - ERC20Interface(_erc20).approve(_to,_value); - return true; - } - - function withdrawal(address _erc20, uint256 _value) public returns (bool success); - - event Pay(address indexed _who, uint256 indexed _item, uint256 indexed _value); - event Refund(address indexed _who, uint256 indexed _item, uint256 indexed _value); - event Prize(address indexed _who, uint256 indexed _item, uint256 indexed _value); -} - -contract _Wallet is _Base { - constructor(address _who) public { - owner = _who; - walletCenter = msg.sender; - } - - function pay(address _shop, uint256 _item) private { - require(_Shop(_shop).canBuy(this,_item)); - - address _erc20; - uint256 _value; - (_erc20,_value) = _Shop(_shop).price(_item); - - transfer(_shop,_erc20,_value); - _Shop(_shop).pay(_item); - emit Pay(_shop,_item,_value); - } - - function paySafe(address _shop, uint256 _item) onlyOwner onlyShop(_shop) public payable returns (bool success) { - pay(_shop,_item); - return true; - } - function payUnsafe(address _shop, uint256 _item) onlyOwner public payable returns (bool success) { - pay(_shop,_item); - return true; - } - function payCancel(address _shop, uint256 _item) onlyOwner public returns (bool success) { - _Shop(_shop).payCancel(_item); - return true; - } - - function refund(address _erc20, uint256 _item, uint256 _value) public payable returns (bool success) { - require((_erc20==address(0)?msg.value:ERC20Interface(_erc20).allowance(msg.sender,this))==_value); - if(_erc20!=address(0)) - ERC20Interface(_erc20).transferFrom(msg.sender,this,_value); - emit Refund(msg.sender,_item,_value); - return true; - } - function prize(address _erc20, uint256 _item, uint256 _value) public payable returns (bool success) { - require((_erc20==address(0)?msg.value:ERC20Interface(_erc20).allowance(msg.sender,this))==_value); - if(_erc20!=address(0)) - ERC20Interface(_erc20).transferFrom(msg.sender,this,_value); - emit Prize(msg.sender,_item,_value); - return true; - } - - function withdrawal(address _erc20, uint256 _value) onlyOwner public returns (bool success) { - require((_erc20==address(0)?address(this).balance:ERC20Interface(_erc20).balanceOf(this))>=_value); - if(_erc20==address(0)) - owner.transfer(_value); - else - ERC20Interface(_erc20).transfer(owner,_value); - return true; - } -} - -contract _Shop is _Base, SafeMath{ - address erc20; - constructor(address _who, address _erc20) public { - owner = _who; - walletCenter = msg.sender; - erc20 = _erc20; - } - - struct item { - uint8 category; // 0 = disable, 1 = non Stock, non Expire, 2 = can Expire (after 1 week), 3 = stackable - uint256 price; - uint256 stockCount; - - mapping(address=>uint256) customer; - } - - uint index; - mapping(uint256=>item) items; - - function pay(uint256 _item) onlyWallet(msg.sender) public payable returns (bool success) { - require(canBuy(msg.sender, _item)); - require((erc20==address(0)?msg.value:ERC20Interface(erc20).allowance(msg.sender,this))==items[_item].price); - - if(erc20!=address(0)) - ERC20Interface(erc20).transferFrom(msg.sender,this,items[_item].price); - - if(items[_item].category==1 || items[_item].category==2 && now > safeAdd(items[_item].customer[msg.sender], 1 weeks)) - items[_item].customer[msg.sender] = now; - else if(items[_item].category==2 && now < safeAdd(items[_item].customer[msg.sender], 1 weeks) ) - items[_item].customer[msg.sender] = safeAdd(items[_item].customer[msg.sender], 1 weeks); - else if(items[_item].category==3) { - items[_item].customer[msg.sender] = safeAdd(items[_item].customer[msg.sender],1); - items[_item].stockCount = safeSub(items[_item].stockCount,1); - } - - emit Pay(msg.sender,_item,items[_item].customer[msg.sender]); - return true; - } - - function payCancel(uint256 _item) onlyWallet(msg.sender) public returns (bool success) { - require (items[_item].category==2&&safeAdd(items[_item].customer[msg.sender],2 weeks)>now&&balanceOf(erc20)>=items[_item].price); - - items[_item].customer[msg.sender] = safeSub(items[_item].customer[msg.sender],1 weeks); - transfer(msg.sender, erc20, items[_item].price); - _Wallet(msg.sender).refund(erc20,_item,items[_item].price); - emit Refund(msg.sender,_item,items[_item].price); - - return true; - } - function refund(address _to, uint256 _item) onlyWallet(_to) onlyOwner public payable returns (bool success) { - require(isBuyer(_to,_item)&&items[_item].category>0&&(items[_item].customer[_to]>0||(items[_item].category==2&&safeAdd(items[_item].customer[_to],2 weeks)>now))); - require((erc20==address(0)?address(this).balance:ERC20Interface(erc20).balanceOf(this))>=items[_item].price); - - if(items[_item].category==1) - items[_item].customer[_to] = 0; - else if(items[_item].category==2) - items[_item].customer[_to] = safeSub(items[_item].customer[_to],1 weeks); - else - items[_item].customer[_to] = safeSub(items[_item].customer[_to],1); - - transfer(_to, erc20, items[_item].price); - _Wallet(_to).refund(erc20,_item,items[_item].price); - emit Refund(_to,_item,items[_item].price); - - return true; - } - - event Item(uint256 indexed _item, uint256 _price); - function resister(uint8 _category, uint256 _price, uint256 _stock) onlyOwner public returns (uint256 _itemId) { - require(_category>0&&_category<4); - require(_price>0); - items[index] = item(_category,_price,_stock); - index = safeAdd(index,1); - emit Item(index,_price); - return safeSub(index,1); - } - function update(uint256 _item, uint256 _price, uint256 _stock) onlyOwner public { - require(items[_item].category>0); - require(_price>0); - uint256 temp = items[_item].price; - items[_item].price = _price; - items[_item].stockCount = safeAdd(items[_item].stockCount,_stock); - - if(temp!=items[_item].price) - emit Item(index,items[_item].price); - } - - function price(uint256 _item) public constant returns (address _erc20, uint256 _value) { - return (erc20,items[_item].price); - } - - function canBuy(address _who, uint256 _item) public constant returns (bool _canBuy) { - return (items[_item].category>0) && - !(items[_item].category==1&&items[_item].customer[_who]>0) && - (items[_item].stockCount>0); - } - - function isBuyer(address _who, uint256 _item) public constant returns (bool _buyer) { - return (items[_item].category==1&&items[_item].customer[_who]>0)||(items[_item].category==2&&safeAdd(items[_item].customer[_who],1 weeks)>now)||(items[_item].category==3&&items[_item].customer[_who]>0); - } - - uint lastWithdrawal; - function withdrawal(address _erc20, uint256 _value) onlyOwner public returns (bool success) { - require(safeAdd(lastWithdrawal,1 weeks)<=now); - require((_erc20==address(0)?address(this).balance:ERC20Interface(_erc20).balanceOf(this))>=_value); - if(_erc20==address(0)) - owner.transfer(_value); - else - ERC20Interface(_erc20).transfer(owner,_value); - lastWithdrawal = now; - return true; - } -} - -contract WalletCenter { - mapping(address=>bool) public wallet; - event Wallet(address indexed _owner, address indexed _wallet); - function createWallet() public returns (address _wallet) { - _wallet = new _Wallet(msg.sender); - wallet[_wallet] = true; - emit Wallet(msg.sender,_wallet); - return _wallet; - } - function isWallet(address _wallet) public constant returns (bool) { - return wallet[_wallet]; - } - mapping(address=>bool) public shop; - event Shop(address indexed _owner, address indexed _shop, address indexed _erc20); - function createShop(address _erc20) public returns (address _shop) { - _shop = new _Shop(msg.sender,_erc20); - shop[_shop] = true; - emit Shop(msg.sender,_shop,_erc20); - return _shop; - } - function isShop(address _shop) public constant returns (bool) { - return shop[_shop]; - } -} -``` -## Copyright -Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From da04d6ae863d80f45b12f72f4e8332a08afe6597 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Thu, 21 Feb 2019 15:51:37 +1300 Subject: [PATCH 2/2] Rename eip-1491.md to EIPS/eip-1491.md --- eip-1491.md => EIPS/eip-1491.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename eip-1491.md => EIPS/eip-1491.md (100%) diff --git a/eip-1491.md b/EIPS/eip-1491.md similarity index 100% rename from eip-1491.md rename to EIPS/eip-1491.md