tktechblog

日々の記録用です。blockchain,bitcoin,ethereumメインです。

eip20/223/721

ERC-721 Non-Fungible Token Standard

  • eip-721:
simple summary

A standard interface for non-fungible tokens, also known as deeds.

abstract

NFTsのためのapi実行を許可する基本方針をまとめたもの。

ex) * Physical property — houses, unique artwork * Virtual collectables — unique pictures of kittens, collectable cards * "Negative value" assets — loans, burdens and other responsibilities

NFTs are distinguishable and you must track the ownership of each one separately.

broker:仲介

motivation

Ethereumネットワーク上でNFTsを利用するwallet/broker/auction application任意の量のNFTsを発行することを可能にする。

この企画はeip20にインスパイヤされて立てられたものであるが、eip20ではNFTsのトラッキング機能が不足したいた。なぜなら、トークンで扱う量はidentical(特定可能)/fungibleな性質を持つ。その一方で、eip720で提案しているものは各々のアセットがそれぞれに代替不可能性、独自性を有する(non-fungible)なトークンであるためである

interrogate:問い合わせ enumeration:列挙 abide by:遵守 mutablity:変わりやすさ

specification

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

結構要件が指定されてる。
- Every ERC-721 compliant contract must implement the ERC721 and ERC165 interfaces (subject to "caveats" below):
これはmust

pragma solidity ^0.4.20;

/// @title ERC-721 Non-Fungible Token Standard
/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
///  Note: the ERC-165 identifier for this interface is 0x80ac58cd.
interface ERC721 /* is ERC165 */ {
    /// @dev This emits when ownership of any NFT changes by any mechanism.
    ///  This event emits when NFTs are created (`from` == 0) and destroyed
    ///  (`to` == 0). Exception: during contract creation, any number of NFTs
    ///  may be created and assigned without emitting Transfer. At the time of
    ///  any transfer, the approved address for that NFT (if any) is reset to none.
    event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);

    /// @dev This emits when the approved address for an NFT is changed or
    ///  reaffirmed. The zero address indicates there is no approved address.
    ///  When a Transfer event emits, this also indicates that the approved
    ///  address for that NFT (if any) is reset to none.
    event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);

    /// @dev This emits when an operator is enabled or disabled for an owner.
    ///  The operator can manage all NFTs of the owner.
    event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);

    /// @notice Count all NFTs assigned to an owner
    /// @dev NFTs assigned to the zero address are considered invalid, and this
    ///  function throws for queries about the zero address.
    /// @param _owner An address for whom to query the balance
    /// @return The number of NFTs owned by `_owner`, possibly zero
    function balanceOf(address _owner) external view returns (uint256);

    /// @notice Find the owner of an NFT
    /// @dev NFTs assigned to zero address are considered invalid, and queries
    ///  about them do throw.
    /// @param _tokenId The identifier for an NFT
    /// @return The address of the owner of the NFT
    function ownerOf(uint256 _tokenId) external view returns (address);

    /// @notice Transfers the ownership of an NFT from one address to another address
    /// @dev Throws unless `msg.sender` is the current owner, an authorized
    ///  operator, or the approved address for this NFT. Throws if `_from` is
    ///  not the current owner. Throws if `_to` is the zero address. Throws if
    ///  `_tokenId` is not a valid NFT. When transfer is complete, this function
    ///  checks if `_to` is a smart contract (code size > 0). If so, it calls
    ///  `onERC721Received` on `_to` and throws if the return value is not
    ///  `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
    /// @param _from The current owner of the NFT
    /// @param _to The new owner
    /// @param _tokenId The NFT to transfer
    /// @param data Additional data with no specified format, sent in call to `_to`
    function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;

    /// @notice Transfers the ownership of an NFT from one address to another address
    /// @dev This works identically to the other function with an extra data parameter,
    ///  except this function just sets data to "".
    /// @param _from The current owner of the NFT
    /// @param _to The new owner
    /// @param _tokenId The NFT to transfer
    function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;

    /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE
    ///  TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE
    ///  THEY MAY BE PERMANENTLY LOST
    /// @dev Throws unless `msg.sender` is the current owner, an authorized
    ///  operator, or the approved address for this NFT. Throws if `_from` is
    ///  not the current owner. Throws if `_to` is the zero address. Throws if
    ///  `_tokenId` is not a valid NFT.
    /// @param _from The current owner of the NFT
    /// @param _to The new owner
    /// @param _tokenId The NFT to transfer
    function transferFrom(address _from, address _to, uint256 _tokenId) external payable;

    /// @notice Change or reaffirm the approved address for an NFT
    /// @dev The zero address indicates there is no approved address.
    ///  Throws unless `msg.sender` is the current NFT owner, or an authorized
    ///  operator of the current owner.
    /// @param _approved The new approved NFT controller
    /// @param _tokenId The NFT to approve
    function approve(address _approved, uint256 _tokenId) external payable;

    /// @notice Enable or disable approval for a third party ("operator") to manage
    ///  all of `msg.sender`'s assets
    /// @dev Emits the ApprovalForAll event. The contract MUST allow
    ///  multiple operators per owner.
    /// @param _operator Address to add to the set of authorized operators
    /// @param _approved True if the operator is approved, false to revoke approval
    function setApprovalForAll(address _operator, bool _approved) external;

    /// @notice Get the approved address for a single NFT
    /// @dev Throws if `_tokenId` is not a valid NFT.
    /// @param _tokenId The NFT to find the approved address for
    /// @return The approved address for this NFT, or the zero address if there is none
    function getApproved(uint256 _tokenId) external view returns (address);

    /// @notice Query if an address is an authorized operator for another address
    /// @param _owner The address that owns the NFTs
    /// @param _operator The address that acts on behalf of the owner
    /// @return True if `_operator` is an approved operator for `_owner`, false otherwise
    function isApprovedForAll(address _owner, address _operator) external view returns (bool);
}

interface ERC165 {
    /// @notice Query if a contract implements an interface
    /// @param interfaceID The interface identifier, as specified in ERC-165
    /// @dev Interface identification is specified in ERC-165. This function
    ///  uses less than 30,000 gas.
    /// @return `true` if the contract implements `interfaceID` and
    ///  `interfaceID` is not 0xffffffff, `false` otherwise
    function supportsInterface(bytes4 interfaceID) external view returns (bool);
}  
  • A wallet/broker/auction application MUST implement the wallet interface if it will accept safe transfers.

同じく

/// @dev Note: the ERC-165 identifier for this interface is 0x150b7a02.
interface ERC721TokenReceiver {
    /// @notice Handle the receipt of an NFT
    /// @dev The ERC721 smart contract calls this function on the recipient
    ///  after a `transfer`. This function MAY throw to revert and reject the
    ///  transfer. Return of other than the magic value MUST result in the
    ///  transaction being reverted.
    ///  Note: the contract address is always the message sender.
    /// @param _operator The address which called `safeTransferFrom` function
    /// @param _from The address which previously owned the token
    /// @param _tokenId The NFT identifier which is being transferred
    /// @param _data Additional data with no specified format
    /// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
    ///  unless throwing
    function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes _data) external returns(bytes4);
}
  • The metadata extension is OPTIONAL for ERC-721 smart contracts (see "caveats", below). This allows your smart contract to be interrogated for its name and for details about the assets which your NFTs represent.

これはoptional

/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension
/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
///  Note: the ERC-165 identifier for this interface is 0x5b5e139f.
interface ERC721Metadata /* is ERC721 */ {
    /// @notice A descriptive name for a collection of NFTs in this contract
    function name() external view returns (string _name);

    /// @notice An abbreviated name for NFTs in this contract
    function symbol() external view returns (string _symbol);

    /// @notice A distinct Uniform Resource Identifier (URI) for a given asset.
    /// @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC
    ///  3986. The URI may point to a JSON file that conforms to the "ERC721
    ///  Metadata JSON Schema".
    function tokenURI(uint256 _tokenId) external view returns (string);
}
  • This is the "ERC721 Metadata JSON Schema" referenced above.

JSONスキーマ形式に変えたもの

{
    "title": "Asset Metadata",
    "type": "object",
    "properties": {
        "name": {
            "type": "string",
            "description": "Identifies the asset to which this NFT represents",
        },
        "description": {
            "type": "string",
            "description": "Describes the asset to which this NFT represents",
        },
        "image": {
            "type": "string",
            "description": "A URI pointing to a resource with mime type image/* representing the asset to which this NFT represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive.",
        }
    }
}
  • The enumeration extension is OPTIONAL for ERC-721 smart contracts (see "caveats", below). This allows your contract to publish its full list of NFTs and make them discoverable.

enumeration extension(列挙型)でoptional

/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
///  Note: the ERC-165 identifier for this interface is 0x780e9d63.
interface ERC721Enumerable /* is ERC721 */ {
    /// @notice Count NFTs tracked by this contract
    /// @return A count of valid NFTs tracked by this contract, where each one of
    ///  them has an assigned and queryable owner not equal to the zero address
    function totalSupply() external view returns (uint256);

    /// @notice Enumerate valid NFTs
    /// @dev Throws if `_index` >= `totalSupply()`.
    /// @param _index A counter less than `totalSupply()`
    /// @return The token identifier for the `_index`th NFT,
    ///  (sort order not specified)
    function tokenByIndex(uint256 _index) external view returns (uint256);

    /// @notice Enumerate NFTs assigned to an owner
    /// @dev Throws if `_index` >= `balanceOf(_owner)` or if
    ///  `_owner` is the zero address, representing invalid NFTs.
    /// @param _owner An address where we are interested in NFTs owned by them
    /// @param _index A counter less than `balanceOf(_owner)`
    /// @return The token identifier for the `_index`th NFT assigned to `_owner`,
    ///   (sort order not specified)
    function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256);
}
  • Caveats:注意事項
    The 0.4.20 Solidity interface grammar is not expressive enough to document the ERC-721 standard. A contract which complies with ERC-721 MUST also abide by the following:
* Solidity issue #3412: The above interfaces include explicit mutability guarantees for each function. Mutability guarantees are, in order weak to strong: payable, implicit nonpayable, view, and pure. Your implementation MUST meet the mutability guarantee in this interface and you MAY meet a stronger guarantee. For example, a payablefunction in this interface may be implemented as nonpayble (no state mutability specified) in your contract. We expect a later Solidity release will allow your stricter contract to inherit from this interface, but a workaround for version 0.4.20 is that you can edit this interface to add stricter mutability before inheriting from your contract.
* Solidity issue #3419: A contract that implements ERC721Metadata or ERC721Enumerable SHALL also implement ERC721. ERC-721 implements the requirements of interface ERC-165.
* Solidity issue #2330: If a function is shown in this specification as external then a contract will be compliant if it uses public visibility. As a workaround for version 0.4.20, you can edit this interface to switch to public before inheriting from your contract.
* Solidity issues #3494, #3544: Use of this.  
*.selector is marked as a warning by Solidity, a future version of Solidity will not mark this as an error
  • Rationale
    tracking distinguishable assetsに依存したスマートコントラクトは多くのユースケースが提案されている。

    • decentraland: land
    • the eponymous punks in CryptoPunks
    • in-game items using systems like DMarket or EnjinCoin
    • tracking real-world assets, like real-estate (as envisioned by companies like Ubitquity or Propy.
  • nftのネーミングを考えてる時に他の候補にあったもの。 cf: distinguishable asset, title, token, asset, equity, ticketなど

  • NFT Identifiers

Every NFT is identified by a unique uint256 ID inside the ERC-721 smart contract. This identifying number SHALL NOT change for the life of the contract. The pair (contract address, uint256 tokenId) will then be a globally unique and fully-qualified identifier for a specific asset on an Ethereum chain. While some ERC-721 smart contracts may find it convenient to start with ID 0 and simply increment by one for each new NFT, callers SHALL NOT assume that ID numbers have any specific pattern to them, and MUST treat the ID as a "black box". Also note that a NFTs MAY become invalid (be destroyed). Please see the enumerations functions for a supported enumeration interface. The choice of uint256 allows a wide variety of applications because UUIDs and sha3 hashes are directly convertible to uint256.
こだわりがあるらしい

  • transfer mechanism

a safe transfer function safeTransferFrom (overloaded with and without a bytes parameter) and an unsafe function transferFrom. Transfers may be initiated by

  • The owner of an NFT
  • The approved address of an NFT
  • An authorized operator of the current owner of an NFT

an authorized operator may set the approved address for an NFT. This provides a powerful set of tools for wallet, broker and auction applications to quickly use a large number of NFTs.

binance/coinbase/bitmain

上記三社の投資先、買収先を調べてみた。 今までの事業内容と合わせて、今後のコングロマリット化を想像してみると参考になった。

bitmainの場合は、手元キャッシュがどうなるのかわからない、ハードの赤字額が膨らんでいてIPOに対してどのような影響があるのかなども考えてみようと思う。

ブロックチェーンのレイヤーを大きく分けて行くと、今後自分の身のおく場所はどのレイヤーにするのかと考える必要があるなと思った。

user/developer/minerの調和のなかで初めて価値を有するblockchainと言う技術であることを考えると、どの立場に立って、どのようなビジョン、未来像を持って、開発を進めて行くのかと言うことはかなり重要。

最近は開発とリサーチどちらもやっているし、国内、国外、ビジネス面、開発者コミュニティの中での分布図をなんとなく把握できたので、どのベクトルに向けてみんなが動いているのかと言うことも大方理解できてきた。

最近はethereum/bitcoin以外にも新しいネットワークも立ち上がってきた。

自分の仮説が正しいのか、解像度を高めて行くために引き続き、リサーチと開発をすすめていき、早めに長期的な道筋を定めて、素早く打ち手をとって行きたい。

Cannot find module './build/Release/scrypt'

truffleやnpmいじってるとたまに出てくるこのエラーに関して良い解説が見つからなかったけど、中国のソース掘ったら良いものがあって、解決できた。
デバッグ時に英語だけでなく中国ソースも掘っていこうと感じた。 打开/usr/local/lib/node_modules/remix-ide/node_modules/scrypt/index.js将require("./build/Release/scrypt")改为require("scrypt")

開発中の細かなところ

  • 無駄に使ってるプロセスは切る。

  • guiでなくちゃならないものでなければ、処理が重くなるだけなのでcliで起動させる

  • node_moduleは詳しく見とく

  • package.jsonは詳しく見とく

  • クライアント、サーバーコントラクトはそれぞれ設計をきちんと考える。

  • 良い仕組みがあればモジュール化して再利用できるように自分で作っておく。

  • 環境構築は再現性を持たせるために、ドキュメントかdotfilesに残す。

  • 開発で学んだこと、できなかったことはブログに残して、振り返って次に活かす。

EIP1080,1081

eip-1080:recoverable token

simple summary

A standard interface for tokens that support chargebacks, theft prevention, and lost & found resolutions.

盗難時やlost&found resolutionsの時のトークンの扱いの基準。

abstract

The following standard allows for the implementation of a standard API for tokens extending ERC-20 or ERC-791. This standard provides basic functionality to recover stolen or lost accounts, as well as provide for the chargeback of tokens.
erc20やerc791のようなトークンのapi実行を許可する基準。

motivation

強盗にあってトークンやアセットの無くなったり盗まれたりした際に影響を和らげたり、他の紛争の手助けになるようにすること。ethereumプロトコルは無くなったり、盗まれたり、紛争によって修正されるべきではない。それらの問題はプロトコルレイヤーで解決可能である

specification
  • Recoverable token
    methods
  - claimLost
`function claimLost(address lostAccount) returns (bool success)`  

  - cancelLostClaim
`function claimLost() returns (bool success)`  

  - reportStoren  
`function reportStolen() returns (bool success)`  

  - chargeback  
`function chargeback(uint256 pendingTransferNumber) returns (bool success)`  

  - getPendingTransferTimeInMinutes  
`function getPendingTransferTime(address account) view returns (uint256 minutes)`

  - setPendingTransferTimeInMinutes  
`function setPendingTransferTime(uint256 minutes) returns (bool success)`  

  - getLostAccountRecoveryTimeInMinutes  
`function getLostAccountRecoveryTimeInMinutes(address account) view returns (uint256 minutes)`  

  - setLostAccountRecoveryTimeInMInutes
`function setLostAccountRecoveryTimeInMinutes(uint256 minutes) returns (bool success)`  
  • Events
  - AccountRecovered  
`event AccountClaimedLost(address indexed account, address indexed newAccount)`

  - AccountClaimedLostCanceled  
`event AccountClaimedLost(address indexed account)`  

  - AccountClaimedLost  
`event AccountClaimedLost(address indexed account)`  

  - PendingTransfer  
`event PendingTransfer(address indexed from, address indexed to, uint256 value, uint256 pendingTransferNumber)`  

  - ChargebackRequested  
`event ChargebackRequested(address indexed from, address indexed to, uint value, uint256 pendingTransferNumber)`  

  - Chargeback  
`event Chargeback(address indexed from, address indexed to, uint256 value, uint256 indexed pendingTransferNumber)`  

  - AccountFrozen 
`event AccountFrozen(address indexed reported)`  
Rationale
  • A recoverable token standard can provide configurable saftey for users or contracts who desire this saftey.
  • Implementations of this standard will give users the ability to select a dispute resolution process on an opt-in basis and benefit the community by decreasing the necessity of consideration of token recovery actions.

recoverable token standardは安全性の構成可能性の提供によって、ユーザーやコントラクトの安全性の要求に答える

このstandardの実行は、ユーザーにオプトインベースでユーザーに論争解決の選択肢として提供することができるし、コミュニティにとっても、補填行動に意識をおく負担が減る。

source

github.com

eip-1081:Standard Bounties

simple summary

A standard contract and interface for issuing bounties on Ethereum, usable for any type of task, paying in any ERC20 token or in ETH.

erc20トークンやethにcontractやinterfaceに解決不能なissueを記入し、報酬と合わせて支払いを行う仕組みの提案。bug bounty.

abstract/motivation

web2.0はbug bountyとともに開発スピードが高まって行ったが、イーサリアムにもあった方が開発が早く進むと考える。

specification
  • a bounty is issued: an issuer specifies the requirements for the task, describing the desired outcome, and how much they would be willing to pay for the completion of that task (denoted in one or several tokens).
  • a bounty is fulfilled: a bounty fulfiller may see the bounty, complete the task, and produce a deliverable which is itself the desired outcome of the task, or simply a record that it was completed. Hashes of these deliverables should be stored immutably on-chain, to serve as proof after the fact.
  • a fulfillment is accepted: a bounty issuer or arbiter may select one or more submissions to be accepted, thereby releasing payment to the bounty fulfiller(s), and transferring ownership over the given deliverable to the issuer.

フローとコードベースの仕様がEIP状に載っている。

ex)

{
   name: // optional - A string representing the name of the persona
   email: // optional - A string representing the preferred contact email of the persona
   githubUsername: // optional - A string representing the github username of the persona
   address: // required - A string web3 address of the persona
}

bounty issuance data Schema

{
  payload: {
    title: // A string representing the title of the bounty
    description: // A string representing the description of the bounty, including all requirements
    issuer: {
       // persona for the issuer of the bounty
    },
    funders:[
       // array of personas of those who funded the issue.
    ],
    categories: // an array of strings, representing the categories of tasks which are being requested
    created: // the timestamp in seconds when the bounty was created
    tokenSymbol: // the symbol for the token which the bounty pays out
    tokenAddress: // the address for the token which the bounty pays out (0x0 if ETH)

    // ------- add optional fields here -------
    sourceFileName: // A string representing the name of the file
    sourceFileHash: // The IPFS hash of the file associated with the bounty
    sourceDirectoryHash: // The IPFS hash of the directory which can be used to access the file
    webReferenceURL: // The link to a relevant web reference (ie github issue)
  },
  meta: {
    platform: // a string representing the original posting platform (ie 'gitcoin')
    schemaVersion: // a string representing the version number (ie '0.1')
    schemaName: // a string representing the name of the schema (ie 'standardSchema' or 'gitcoinSchema')
  }
}

bounty fulfillment data schema

{
  payload: {
    description: // A string representing the description of the fulfillment, and any necessary links to works
    sourceFileName: // A string representing the name of the file being submitted
    sourceFileHash: // A string representing the IPFS hash of the file being submitted
    sourceDirectoryHash: // A string representing the IPFS hash of the directory which holds the file being submitted
    fulfillers: {
      // personas for the individuals whose work is being submitted
    }

    // ------- add optional fields here -------
  },
  meta: {
    platform: // a string representing the original posting platform (ie 'gitcoin')
    schemaVersion: // a string representing the version number (ie '0.1')
    schemaName: // a string representing the name of the schema (ie 'standardSchema' or 'gitcoinSchema')
  }
}
rationale

web3.0 ecosystem

source

github.com

day6:EIP107,1077,1078

eip107:safe "eth_sendTransaction" authorization via html popup

  • abstract

This draft EIP describes the details of an authorization method that if provided by rpc enabled ethereum nodes would allow regular websites to send transactions (via eth_sendTransaction) without the need to enable CORS. Instead, user would be asked to confirm the transaction via an html popup.

Every read only rpc call the dapp wants to perform is redirected to an invisible iframe from the node's domain and for every transaction that the dapp wish to execute, an html popup is presented to the user to allow him/her to cancel or confirm the transaction. This allows the dapp to connect to the node's rpc api without being granted any kind of privileges. This allows users to safely interact with dapps running in their everyday web browser while their accounts are unlocked. In case the account is not unlocked, and the node has allowed the "personal" api via rpc,the html page also allow the user to enter their password to unlock the account for the scope of the transaction.

authorization methodの詳細に関しての提案。既存のウェブサイトがCORSの必要なしにトランザクションを送る(via eth_sendTransaction)。その代わりにユーザーにhtmlのポップアップを使って、トランザクションの商品を得るという仕様に関しての提案。

  • motivaiton

現状:既存のブラウザではセキュリティの観点からdappsはデフォルトでrpc apiにアクセスすることができない。CORSを考えないwebsite domainではdappsは動かない。困ったことにCORSを考えると、ユーザーは強制的にdappウスを信用しないといけなし、userconsentの必要なしにアンロックアカウントからsend transactionが可能になる。言い換えると、nodeのdefault settingを変える必要があるだけでなく、それを使うためにユーザーはそのdappsをtrustすることを強制させる。これは受け入れがたいことだし、既存のdappsの立場上よくない。

  • 単純なtransactionを行うために、"Mist"のようなwalletを盲目的に信頼するか尋ねられる

  • node command line interfaceを経由して、トランザクションをするかどうか尋ねられる

みたいな面倒なケースも考えられる。

そんなわけで、この提案はsafeでuser friendlyを提供することが狙い。
いくつかのscreenshotを元に実装例を提案。

  • Account unlocked

f:id:doobiedo222:20180826193046p:plain

  • account locked and no "personal" api exposed via rpc:

This is not ideal since this requires the user to know how to unlock an account:

f:id:doobiedo222:20180826193117p:plain これはuxとして理想的なものではない

  • account locked but node exposing the "personal" api via rpc

f:id:doobiedo222:20180826193135p:plain

this is better.

  • specification (invisible iframe and popup window).二つのパターンを提案
{
  id:<a an id>, //so responses can be match as there is no guarantee of the order of the response
  payload:<json rpc object> //this is the exact object that usually send to the node
}
  • eth_sendTransaction

In all the cases, the iframe/window will send a message back to the dapp using the following object:

{
  id:<id matchign the request>,
  result:<rpc result as is>,
  error:<error object>
}

the error object cannot be a javascript Error object due to postMessage limitation.

{
  message:<a string describing the error>,
  type:<a string defining the type of error> //type="cancel" means the user cancel the transaction
}
  • rationale

simplicity and securityのために提案。oauth-likeなプロトコルも検討したが、実装が大変だし、gethの仕様と合わせて話し合う必要がある。そのため、iframe/windowの方が、組み込みが容易だと判断し、こちらを提案。

  • source

EIPs/eip-107.md at master · ethereum/EIPs · GitHub

eip-1077:Executable Signed Messages refunded by the contract

  • simple summary

    Allowing users to sign messages to show intent of execution, but allowing a third party relayer to execute them is an emerging pattern being used in many projects. Standardizing a common format for them, as well as a way in which the user allows the transaction to be paid in tokens, gives app developers a lot of flexibility and can become the main way in which app users interact with the Blockchain.

userが実行許可にサインすることはある。しかし、多くのプロジェクトでthird paty relayerがそれらを実行するために扱われるパターンもある。そのため、仕様を統一することによって、トランザクションに対してトークンが支払われることを許可するように、app developerに多くのflexibilityを与えて、アプリケーションをuserとblockchainの連携をすることに集中させたい。

  • abstract
##### User pain points:

users don't want to think about ether
users don't want to think about backing up private keys or seed phrases
users want to be able to pay for transactions using what they already have on the system, be apple pay, xbox points or even a credit card
Users don’t want to sign a new transaction at every move
Users don’t want to download apps/extensions (at least on the desktop) to connect to their apps  

##### App developer pain points:

Many apps use their own token and would prefer to use those as the main accounting
Apps want to be able to have apps in multiple platforms without having to share private keys between devices or have to spend transaction costs moving funds between them
Token developers want to be able for their users to be able to move funds and pay fees in the token
While the system provides fees and incentives for miners, there are no inherent business model for wallet developers (or other apps that initiate many transactions)
Using signed messages, specially combined with an identity contract that holds funds, and multiple disposable ether-less keys that can sign on its behalf, solves many of these pain points.

Using signed messages, specially combined with an identity contract that holds funds, and multiple disposable ether-less keys that can sign on its behalf, solves many of these pain points.

資金を保持するID契約と特別に結合された署名付きメッセージと、それに代わって署名することができる複数の使い捨てether-less keyを使用することで、これらのpoin pointsの多くが解決されます。

  • implementation
    signed messagesにはこれらが必要
- To: the target contract the transaction will be executed upon
- From: the account that will be executed on behalf of
Value: the amount in ether to - be sent
Data: the bytecode to be executed
- Nonce: a nonce or a timestamp
- GasToken: a token in which the gas will be paid (leave 0 for ether)
- Gasprice: the gas price (paid in the selected token)
- GasLimit: the maximum gas to be paid
  • Signing the message
    以下の順番で連結されないといけない。
keccak256(
    byte(0x19),
    byte(0),
    from,
    to,
    value,
    dataHash,
    nonce,
    gasPrice,
    gasLimit,
    gasToken,
    callPrefix,
    operationType,
    extraHash
);
  • backwards and forwards capability:
Not all executable signed messages contracts will have the same requirements, therefore some fields are optional. Fields byte(0x19), byte(0), from, to, value, dataHash are obligatory while nonce, gasPrice, gasLimit, gasToken, callPrefix, operationType are optional, but must be hashed in this order.
  • Multiple signatures

    If multiple signatures are required, then all signed messageHashes should then be ordered by account and sent to the receiveing contract which then will execute the following actions:

  • Supported functions

If multiple signatures are required, then all signed messageHashes should then be ordered by account and sent to the receiveing contract which then will execute the following actions:

  • similar implementaions この辺が似通った提案らしい

EIP 877 An attempt of doing the same but with a change in the protocol Status Aragon (this might not be the best link to show their work in this area) Token Standard Functions for Preauthorized Actions Token Standard Extension 865 Iuri Matias: Transaction Relay uPort: Meta transactions uPort: safe Identities Gnosis safe contracts

おそらく結構重い提案というか、初期から肉付けされて巨大化したeipっぽい。他の関連部分も読み返しながら、あとで振り返って改めて読み返そうと思う。

  • source

github.com

eip-1078:Universal login / signup using ENS subdomains

  • abstract

    This presents a method to replace the usual signup/login design pattern with a minimal ethereum native scheme, that doesn’t require passwords, backing up private keys nor typing seed phrases. From the user point of view it will be very similar to patterns they’re already used to with second factor authentication (without relying in a central server), but for dapp developers it requires a new way to think about ethereum transactions.

signup/loginをデザインパターンとして、パスワード不要、private keyもseed typeも必要なしにする提案。ユーザーにとってはsecond factor authentication (without relying in a central server),として慣れしんだものだが、dapps developersにとってethereum transactionに関して言えば新しく考える必要のある方法である。

  • simple summary
    user accountをauth tokens, rather than unique keysとして扱う。

  • login process

1.  Request a name from the user  
 
2.  a) create a new identity  


2-1.Generate a private key which it will keep saved locally on the device or browser, the safest way possible.  

2-2.Create (or set up) an identity contract which supports both ERC720 and ERC1077  

2-3.Register the private key created on step 1 as the only admin key of the contract (the app must not add any app-controlled key, except as recovery option - see 5)  

2-4.Register the requested subdomain and transfer its ownership to the contract (while the app controls the main domain and may keep the option to reassign them at will, the ownership of the subdomain itself should belong to the identity, therefore allowing them to transfer it)  

2-5.(Optionally) Register a recovery method on the contract, which allows the user to regain access to the contract in case the main key is lost.  

  2.b) Connect to an existing identity

続きはeipを直に読んだ方が良い。
EIPs/eip-1078.md at master · ethereum/EIPs · GitHub

現状まだdraftのため、実装例はないが、アプリケーションをもっと軽くして、サインアップ手続きを減らしたり、既存のwebのようにもっと簡単に触れるようにしようということが狙い。