{"action":"created","issue":{"url":"https://api.github.com/repos/trezor/trezor-common/issues/11","repository_url":"https://api.github.com/repos/trezor/trezor-common","labels_url":"https://api.github.com/repos/trezor/trezor-common/issues/11/labels{/name}","comments_url":"https://api.github.com/repos/trezor/trezor-common/issues/11/comments","events_url":"https://api.github.com/repos/trezor/trezor-common/issues/11/events","html_url":"https://github.com/trezor/trezor-common/pull/11","id":155119000,"number":11,"title":"RFC: Ethereum support (GetEthereumAddress and SignEthereumTx)","user":{"login":"axic","id":20340,"avatar_url":"https://avatars.githubusercontent.com/u/20340?v=3","gravatar_id":"","url":"https://api.github.com/users/axic","html_url":"https://github.com/axic","followers_url":"https://api.github.com/users/axic/followers","following_url":"https://api.github.com/users/axic/following{/other_user}","gists_url":"https://api.github.com/users/axic/gists{/gist_id}","starred_url":"https://api.github.com/users/axic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/axic/subscriptions","organizations_url":"https://api.github.com/users/axic/orgs","repos_url":"https://api.github.com/users/axic/repos","events_url":"https://api.github.com/users/axic/events{/privacy}","received_events_url":"https://api.github.com/users/axic/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":32,"created_at":"2016-05-16T20:51:03Z","updated_at":"2016-05-17T20:31:29Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/trezor/trezor-common/pulls/11","html_url":"https://github.com/trezor/trezor-common/pull/11","diff_url":"https://github.com/trezor/trezor-common/pull/11.diff","patch_url":"https://github.com/trezor/trezor-common/pull/11.patch"},"body":"This is purely an RFC to discuss what would be the preferred way to implement Ethereum support.\r\n\r\n**Quick intro into Ethereum:**\r\n\r\n**0)** It uses only uncompressed public keys\r\n\r\n**1)** An address is formatted as:\r\n- Take the Keccak (pre-NIST SHA3) hash of the x and y points of the uncompressed key (i.e. remove the type field (0x04 for uncompressed) of the SEC1 format)\r\n- Take the 160 least significant bits\r\n- Use the hex string representation of the result\r\n\r\nAlbeit this is the format used internally and by all clients, there exist a backward compatible checksumming for the hex representation. Additionally several other address formats/proposals exist.\r\n\r\n**2)** Ethereum is based on account state and not UTXOs. This results in a very simple transaction format, which includes the recipient, value and additional fields signed by the sender address. Technically it is the following fields, in this order, serialized using RLP:\r\n- `nonce`\r\n- `gasPrice`\r\n- `gasLimit`\r\n- `to`\r\n- `value`\r\n- `data`\r\n- `v`\r\n- `r`\r\n- `s`\r\n\r\nWhere `nonce`, `gasPrice`, `gasLimit` and `value` are 256 bit big endian numbers, `data` is an optional arbitrary length field, `to` is the recipient address (as a binary and not as a hex string) and `v`/`r`/`s` correspond to the signature fields. \r\n\r\n**The proposal: address retrieval**\r\n\r\nBased on how different the address format is, a new method `GetEthereumAddress` with its return value `EthereumAddress` is proposed.\r\n\r\nI am not sure that this is the best way. Alternatively a field can be introduced in the `CoinType` to distinguish between Bitcoin-style and Ethereum-style addresses (sample implementation here: https://github.com/keepkey/device-protocol/pull/3) and use `GetAddress`.\r\n\r\nThe Ethereum address format is subject to change hence I am bit worried which option to take.\r\n\r\n**The proposal: transaction signing**\r\n\r\nAgain, as transactions have no similarity to Bitcoin, this proposes an entirely different format.\r\n\r\nRequest:\r\n```\r\nmessage EthereumSignTx {\r\n        repeated uint32 address_n = 1;\t\t// BIP-32 path to derive the key from master node\r\n        required bytes nonce = 2;\r\n        required string to = 3;\r\n        required bytes value = 4;               // 256-bit number (big endian)\r\n        optional bytes data = 5;\r\n        required bytes gasPrice = 6;            // 256-bit number (big endian)\r\n        optional bytes gasLimit = 7;            // 256-bit number (big endian)\r\n}\r\n```\r\n\r\nResponse:\r\n```\r\nmessage EthereumSignedTx {\r\n\trequired bytes rlp = 1;\r\n}\r\n```\r\n\r\nRemarks:\r\n- `gasLimit` is optional and defaults to `21000` (note: I should add it to the proto)\r\n- The user must be presented on screen with the recipient, total transaction cost (`value + (gasPrice * gasLimit)`) and some representation of the `data` field.\r\n- The `data` field behaves like `OP_RETURN` for transactions between *external accounts*, but is used as the ABI field (mostly method invocation) when transacting with *contract accounts*. A future improvement to this protocol could be moving the ABI encoding to the device instead in addition to the `data` field.\r\n\r\nSome questions:\r\n\r\n1) What is the preferred way for address generation?\r\n2) How to handle non-negative 256 bit big number fields? As `bytes` or differently?\r\n3) The `nonce` must be incremental. One can publish future transactions to the *mempool* by leaving a gap. Should the firmware take care about nonces?\r\n"},"comment":{"url":"https://api.github.com/repos/trezor/trezor-common/issues/comments/219844232","html_url":"https://github.com/trezor/trezor-common/pull/11#issuecomment-219844232","issue_url":"https://api.github.com/repos/trezor/trezor-common/issues/11","id":219844232,"user":{"login":"prusnak","id":42201,"avatar_url":"https://avatars.githubusercontent.com/u/42201?v=3","gravatar_id":"","url":"https://api.github.com/users/prusnak","html_url":"https://github.com/prusnak","followers_url":"https://api.github.com/users/prusnak/followers","following_url":"https://api.github.com/users/prusnak/following{/other_user}","gists_url":"https://api.github.com/users/prusnak/gists{/gist_id}","starred_url":"https://api.github.com/users/prusnak/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/prusnak/subscriptions","organizations_url":"https://api.github.com/users/prusnak/orgs","repos_url":"https://api.github.com/users/prusnak/repos","events_url":"https://api.github.com/users/prusnak/events{/privacy}","received_events_url":"https://api.github.com/users/prusnak/received_events","type":"User","site_admin":false},"created_at":"2016-05-17T20:31:29Z","updated_at":"2016-05-17T20:31:29Z","body":"I'd rather not mix messages for various \"apps\" together. Suppose there is some kind of \"router\" in the future that would need to route the message to the correct app without looking into its content.\r\n\r\nAnd clearly Bitcoin + Bitcoin-related altcoins and Ethereum + alts will be handled by separate apps."}}