From 62d0a0a6593f072b972521fdd40b202d49158909 Mon Sep 17 00:00:00 2001 From: WTRMQDev <44411763+WTRMQDev@users.noreply.github.com> Date: Fri, 3 May 2019 20:45:12 +0300 Subject: [PATCH 1/5] EIP-1057 Update progpow test-vectors (#1855) --- EIPS/eip-1057.md | 5 +- assets/eip-1057/test-vectors-0.9.2.json | 107 +++++++++++++++++++++++ assets/eip-1057/test-vectors-0.9.3.json | 108 ++++++++++++++++++++++++ assets/eip-1057/test-vectors.md | 66 ++++++++------- 4 files changed, 255 insertions(+), 31 deletions(-) create mode 100644 assets/eip-1057/test-vectors-0.9.2.json create mode 100644 assets/eip-1057/test-vectors-0.9.3.json diff --git a/EIPS/eip-1057.md b/EIPS/eip-1057.md index 41a27c9de94450..b3b897b9e7d910 100644 --- a/EIPS/eip-1057.md +++ b/EIPS/eip-1057.md @@ -478,6 +478,7 @@ This algorithm is not backwards compatible with the existing Ethash, and will re ## Test Cases +### progpow 0.9.2 The algorithm run on block 30,000 produces the following digest and result: ``` header ffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff @@ -488,6 +489,8 @@ result: 5b7ccd472dbefdd95b895cac8ece67ff0deb5a6bd2ecc6e162383d00c3728ece ``` Additional test vectors can be found [in the test vectors file](../assets/eip-1057/test-vectors.md#progPowHash). +### progpow 0.9.3 +[Machine-readable test vectors](https://github.com/ethereum/EIPs/blob/ad4e73f239d53d72a21cfd8fdc89dc81eb9d2688/assets/eip-1057/test-vectors-0.9.3.json) ## Implementation @@ -496,4 +499,4 @@ The reference ProgPoW mining implementation located at [ProgPOW](https://github. The ProgPoW algorithm and this specification are a new work. Copyright and related rights are waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). -The reference ProgPoW mining implementation located at [ProgPOW](https://github.com/ifdefelse/ProgPOW) is a derivative of ethminer so retains the GPL license. \ No newline at end of file +The reference ProgPoW mining implementation located at [ProgPOW](https://github.com/ifdefelse/ProgPOW) is a derivative of ethminer so retains the GPL license. diff --git a/assets/eip-1057/test-vectors-0.9.2.json b/assets/eip-1057/test-vectors-0.9.2.json new file mode 100644 index 00000000000000..b10408ae736ac4 --- /dev/null +++ b/assets/eip-1057/test-vectors-0.9.2.json @@ -0,0 +1,107 @@ +[ + { + "block_height": 30000, + "nonce": "123456789abcdef0", + "header_hash": "ffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff", + "mix_hash": "11f19805c58ab46610ff9c719dcf0a5f18fa2f1605798eef770c47219274767d", + "final_hash": "5b7ccd472dbefdd95b895cac8ece67ff0deb5a6bd2ecc6e162383d00c3728ece" + }, + { + "block_height": 0, + "nonce": "0000000000000000", + "header_hash": "0000000000000000000000000000000000000000000000000000000000000000", + "mix_hash": "faeb1be51075b03a4ff44b335067951ead07a3b078539ace76fd56fc410557a3", + "final_hash": "63155f732f2bf556967f906155b510c917e48e99685ead76ea83f4eca03ab12b" + }, + { + "block_height": 49, + "nonce": "0000000006ff2c47", + "header_hash": "63155f732f2bf556967f906155b510c917e48e99685ead76ea83f4eca03ab12b", + "mix_hash": "c789c1180f890ec555ff42042913465481e8e6bc512cb981e1c1108dc3f2227d", + "final_hash": "9e7248f20914913a73d80a70174c331b1d34f260535ac3631d770e656b5dd922" + }, + { + "block_height": 50, + "nonce": "00000000076e482e", + "header_hash": "9e7248f20914913a73d80a70174c331b1d34f260535ac3631d770e656b5dd922", + "mix_hash": "c7340542c2a06b3a7dc7222635f7cd402abf8b528ae971ddac6bbe2b0c7cb518", + "final_hash": "de37e1824c86d35d154cf65a88de6d9286aec4f7f10c3fc9f0fa1bcc2687188d" + }, + { + "block_height": 99, + "nonce": "000000003917afab", + "header_hash": "de37e1824c86d35d154cf65a88de6d9286aec4f7f10c3fc9f0fa1bcc2687188d", + "mix_hash": "f5e60b2c5bfddd136167a30cbc3c8dbdbd15a512257dee7964e0bc6daa9f8ba7", + "final_hash": "ac7b55e801511b77e11d52e9599206101550144525b5679f2dab19386f23dcce" + }, + { + "block_height": 29950, + "nonce": "005d409dbc23a62a", + "header_hash": "ac7b55e801511b77e11d52e9599206101550144525b5679f2dab19386f23dcce", + "mix_hash": "07393d15805eb08ee6fc6cb3ad4ad1010533bd0ff92d6006850246829f18fd6e", + "final_hash": "e43d7e0bdc8a4a3f6e291a5ed790b9fa1a0948a2b9e33c844888690847de19f5" + }, + { + "block_height": 29999, + "nonce": "005db5fa4c2a3d03", + "header_hash": "e43d7e0bdc8a4a3f6e291a5ed790b9fa1a0948a2b9e33c844888690847de19f5", + "mix_hash": "7551bddf977491da2f6cfc1679299544b23483e8f8ee0931c4c16a796558a0b8", + "final_hash": "d34519f72c97cae8892c277776259db3320820cb5279a299d0ef1e155e5c6454" + }, + { + "block_height": 30000, + "nonce": "005db8607994ff30", + "header_hash": "d34519f72c97cae8892c277776259db3320820cb5279a299d0ef1e155e5c6454", + "mix_hash": "f1c2c7c32266af9635462e6ce1c98ebe4e7e3ecab7a38aaabfbf2e731e0fbff4", + "final_hash": "8b6ce5da0b06d18db7bd8492d9e5717f8b53e7e098d9fef7886d58a6e913ef64" + }, + { + "block_height": 30049, + "nonce": "005e2e215a8ca2e7", + "header_hash": "8b6ce5da0b06d18db7bd8492d9e5717f8b53e7e098d9fef7886d58a6e913ef64", + "mix_hash": "57fe6a9fbf920b4e91deeb66cb0efa971e08229d1a160330e08da54af0689add", + "final_hash": "c2c46173481b9ced61123d2e293b42ede5a1b323210eb2a684df0874ffe09047" + }, + { + "block_height": 30050, + "nonce": "005e30899481055e", + "header_hash": "c2c46173481b9ced61123d2e293b42ede5a1b323210eb2a684df0874ffe09047", + "mix_hash": "ba30c61cc5a2c74a5ecaf505965140a08f24a296d687e78720f0b48baf712f2d", + "final_hash": "ea42197eb2ba79c63cb5e655b8b1f612c5f08aae1a49ff236795a3516d87bc71" + }, + { + "block_height": 30099, + "nonce": "005ea6aef136f88b", + "header_hash": "ea42197eb2ba79c63cb5e655b8b1f612c5f08aae1a49ff236795a3516d87bc71", + "mix_hash": "cfd5e46048cd133d40f261fe8704e51d3f497fc14203ac6a9ef6a0841780b1cd", + "final_hash": "49e15ba4bf501ce8fe8876101c808e24c69a859be15de554bf85dbc095491bd6" + }, + { + "block_height": 59950, + "nonce": "02ebe0503bd7b1da", + "header_hash": "49e15ba4bf501ce8fe8876101c808e24c69a859be15de554bf85dbc095491bd6", + "mix_hash": "21511fbaa31fb9f5fc4998a754e97b3083a866f4de86fa7500a633346f56d773", + "final_hash": "f5c50ba5c0d6210ddb16250ec3efda178de857b2b1703d8d5403bd0f848e19cf" + }, + { + "block_height": 59999, + "nonce": "02edb6275bd221e3", + "header_hash": "f5c50ba5c0d6210ddb16250ec3efda178de857b2b1703d8d5403bd0f848e19cf", + "mix_hash": "653eda37d337e39d311d22be9bbd3458d3abee4e643bee4a7280a6d08106ef98", + "final_hash": "341562d10d4afb706ec2c8d5537cb0c810de02b4ebb0a0eea5ae335af6fb2e88" + }, + { + "block_height": 10000000, + "nonce": "005e30899481055e", + "header_hash": "efda178de857b2b1703d8d5403bd0f848e19cff5c50ba5c0d6210ddb16250ec3", + "mix_hash": "b2403f56c426177856eaf0eedd707c86ae78a432b9169c3689a67058fcf2a848", + "final_hash": "206aee640c0fd21473d5cc3654d63c80442d9e2dfa676d2801d3ec1fbab38a6d" + }, + { + "block_height": 100000000, + "nonce": "02abe0589481055e", + "header_hash": "49e15ba4bf501ce8fe88765403bd0f848e19cff5c50ba5c0d6210ddb16250ec3", + "mix_hash": "ac452084d6f4e6eacf4282ad58dbd4ce7ef2653fb5e6b5c877f56928c907432a", + "final_hash": "b879f84923e71b812ef5a42ece0b5b9366c31cab218f40afe65f8a2cae448a6f" + } +] diff --git a/assets/eip-1057/test-vectors-0.9.3.json b/assets/eip-1057/test-vectors-0.9.3.json new file mode 100644 index 00000000000000..054c3dadb44980 --- /dev/null +++ b/assets/eip-1057/test-vectors-0.9.3.json @@ -0,0 +1,108 @@ +[ + { + "block_height": 30000, + "nonce": "123456789abcdef0", + "header_hash": "ffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff", + "mix_hash": "6018c151b0f9895ebe44a4ca6ce2829e5ba6ae1a68a4ccd05a67ac01219655c1", + "final_hash": "34d8436444aa5c61761ce0bcce0f11401df2eace77f5c14ba7039b86b5800c08" + }, + { + "block_height": 0, + "nonce": "0000000000000000", + "header_hash": "0000000000000000000000000000000000000000000000000000000000000000", + "mix_hash": "f4ac202715ded4136e72887c39e63a4738331c57fd9eb79f6ec421c281aa8743", + "final_hash": "b3bad9ca6f7c566cf0377d1f8cce29d6516a96562c122d924626281ec948ef02" + }, + { + "block_height": 49, + "nonce": "0000000006ff2c47", + "header_hash": "63155f732f2bf556967f906155b510c917e48e99685ead76ea83f4eca03ab12b", + "mix_hash": "8f744dec9140938453c8a502a489861aedec7e98ce7e11b10a3b661940c38786", + "final_hash": "ca0c365f1290ede4ee0d19cab08cd827030425ae8aba96b5248faafe732f1f80" + }, + { + "block_height": 50, + "nonce": "00000000076e482e", + "header_hash": "9e7248f20914913a73d80a70174c331b1d34f260535ac3631d770e656b5dd922", + "mix_hash": "bd772e573609acead3b0f27d7935022ea0bf72f22ecf0980f0c21a74cc2fa3ef", + "final_hash": "75439f6c6e153d3c798309f01ba37e7a284d172f50841c7b523e81c1b8247083" + }, + { + "block_height": 99, + "nonce": "000000003917afab", + "header_hash": "de37e1824c86d35d154cf65a88de6d9286aec4f7f10c3fc9f0fa1bcc2687188d", + "mix_hash": "18a5d2f1eaa3df5a54f254c3f90bfa8e40c63913664175c93a9e5136f4dc7c5c", + "final_hash": "2618185c024ad29fd75bc350da388cc0d47cdebbd6798400f17692a7ccf3314c" + }, + { + "block_height": 29950, + "nonce": "005d409dbc23a62a", + "header_hash": "ac7b55e801511b77e11d52e9599206101550144525b5679f2dab19386f23dcce", + "mix_hash": "d98cd262f73f9e110d994e592ad793ffca5fa92d8aff0e6f40fe3e84940e09e5", + "final_hash": "8ec8a0486e759c59c6f7ba586450dc2a5c8c3586b52345efb9b604fa82f40f65" + }, + { + "block_height": 29999, + "nonce": "005db5fa4c2a3d03", + "header_hash": "e43d7e0bdc8a4a3f6e291a5ed790b9fa1a0948a2b9e33c844888690847de19f5", + "mix_hash": "53979a1e55d7b1987664570920a3d9121052f06326b99c6698b38255ed419003", + "final_hash": "de03c1354159e07cf804ecc9a53f82b0187dd4a24837d20e56cae28b65c35eb0" + }, + { + "block_height": 30000, + "nonce": "005db8607994ff30", + "header_hash": "d34519f72c97cae8892c277776259db3320820cb5279a299d0ef1e155e5c6454", + "mix_hash": "ec3eed8a744b1950ae72439e8d28a47b868f4cdc26e5c37084e441cceb289c21", + "final_hash": "a717a28081999625860cbb09262dbbcc6090427411a5a3c60fb86a0ded8d369e" + }, + { + "block_height": 30049, + "nonce": "005e2e215a8ca2e7", + "header_hash": "8b6ce5da0b06d18db7bd8492d9e5717f8b53e7e098d9fef7886d58a6e913ef64", + "mix_hash": "ed3764d1cf0abc3798c594a372679dd076f7dda15b552e7ec83d3ba8b27cbe0c", + "final_hash": "dd85d293db9b1063c6428ac9ca74e8d5d4d9fee49e0123bafb914fa787f58e89" + }, + { + "block_height": 30050, + "nonce": "005e30899481055e", + "header_hash": "c2c46173481b9ced61123d2e293b42ede5a1b323210eb2a684df0874ffe09047", + "mix_hash": "732a4c5f7de1cc6d2a3702e9ea717b4f9da0de66e75897a2d5dc6cf407e883fc", + "final_hash": "4e83a686a5390b8105a261c4c1480b23a17938d4d029d1239042be7515e980fa" + }, + { + "block_height": 30099, + "nonce": "005ea6aef136f88b", + "header_hash": "ea42197eb2ba79c63cb5e655b8b1f612c5f08aae1a49ff236795a3516d87bc71", + "mix_hash": "be8789da582670b3b5091d3693b7584b5a554cd258c9a3f299645cfaf13acff9", + "final_hash": "72a6b01403faf90b2e74cb28920e953016d2c04f3e22d64aa4712ed00b5b6681" + }, + { + "block_height": 59950, + "nonce": "02ebe0503bd7b1da", + "header_hash": "49e15ba4bf501ce8fe8876101c808e24c69a859be15de554bf85dbc095491bd6", + "mix_hash": "3d1093e05b7ac6f23bda5afecf36f01379f05df06a28bcefd3459b70941bbc41", + "final_hash": "56c9fefbfe93eac6de18b1bd4e42d6bf784f9dc5a112955d2ffa6d5fb3cc0657" + }, + { + "block_height": 59999, + "nonce": "02edb6275bd221e3", + "header_hash": "f5c50ba5c0d6210ddb16250ec3efda178de857b2b1703d8d5403bd0f848e19cf", + "mix_hash": "855c62aba873a0955345556f2ba33cb1d74b7d42067402e6ec145dd031087b23", + "final_hash": "116053ccb7866e23df4263a359794fa84afceb0d11d97cb9389ffa763b7be43a" + }, + { + "block_height": 10000000, + "nonce": "005e30899481055e", + "header_hash": "efda178de857b2b1703d8d5403bd0f848e19cff5c50ba5c0d6210ddb16250ec3", + "mix_hash": "3cb394b257046429e7a18528f2d1bc64e3b712031534ecb1f60f5c6d61fd60ca", + "final_hash": "5dca7eab5997b489420b5d05d56394b8be83824bcb5916b84d8b39d54186a6d6" + }, + { + "block_height": 100000000, + "nonce": "02abe0589481055e", + "header_hash": "49e15ba4bf501ce8fe88765403bd0f848e19cff5c50ba5c0d6210ddb16250ec3", + "mix_hash": "cc8a24ce78d5df7787f7b47bad87c7ef5d4e159ba5d32d5d6b01a6c5c4a2b536", + "final_hash": "eba819f45d27b39cc0a8deb68b6dde03c37a9790634eeb6a1d0edb40ed26ee1d" + } +] + diff --git a/assets/eip-1057/test-vectors.md b/assets/eip-1057/test-vectors.md index a47c7e89d2b1ba..991e2509acb496 100644 --- a/assets/eip-1057/test-vectors.md +++ b/assets/eip-1057/test-vectors.md @@ -336,122 +336,128 @@ loop 1 are as follows. ## progPowHash +### 0.9.2 +[Machine-readable data](https://github.com/ethereum/EIPs/blob/ad4e73f239d53d72a21cfd8fdc89dc81eb9d2688/assets/eip-1057/test-vectors-0.9.3.json) + Block 30000: - `prog_seed` - 600 - `nonce` - `123456789abcdef0` - `header` - `ffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff` -- _digest_ - `11f19805c58ab46610ff9c719dcf0a5f18fa2f1605798eef770c47219274767d` -- _result_ - `5b7ccd472dbefdd95b895cac8ece67ff0deb5a6bd2ecc6e162383d00c3728ece` +- `mix_hash` - `11f19805c58ab46610ff9c719dcf0a5f18fa2f1605798eef770c47219274767d` +- `final_hash` - `5b7ccd472dbefdd95b895cac8ece67ff0deb5a6bd2ecc6e162383d00c3728ece` Block 0: - `prog_seed` - 0 - `nonce` - `0000000000000000` - `header` - `0000000000000000000000000000000000000000000000000000000000000000` -- _digest_ - `faeb1be51075b03a4ff44b335067951ead07a3b078539ace76fd56fc410557a3` -- _result_ - `63155f732f2bf556967f906155b510c917e48e99685ead76ea83f4eca03ab12` +- `mix_hash` - `faeb1be51075b03a4ff44b335067951ead07a3b078539ace76fd56fc410557a3` +- `final_hash` - `63155f732f2bf556967f906155b510c917e48e99685ead76ea83f4eca03ab12b` Block 49: - `prog_seed` - 0 - `nonce` - `0000000006ff2c47` - `header` - `63155f732f2bf556967f906155b510c917e48e99685ead76ea83f4eca03ab12b` -- _digest_ - `c789c1180f890ec555ff42042913465481e8e6bc512cb981e1c1108dc3f2227d` -- _result_ - `9e7248f20914913a73d80a70174c331b1d34f260535ac3631d770e656b5dd92` +- `mix_hash` - `c789c1180f890ec555ff42042913465481e8e6bc512cb981e1c1108dc3f2227d` +- `final_hash` - `9e7248f20914913a73d80a70174c331b1d34f260535ac3631d770e656b5dd922` Block 50: - `prog_seed` - 1 - `nonce` - `00000000076e482e` - `header` - `9e7248f20914913a73d80a70174c331b1d34f260535ac3631d770e656b5dd922` -- _digest_ - `c7340542c2a06b3a7dc7222635f7cd402abf8b528ae971ddac6bbe2b0c7cb518` -- _result_ - `de37e1824c86d35d154cf65a88de6d9286aec4f7f10c3fc9f0fa1bcc2687188` +- `mix_hash` - `c7340542c2a06b3a7dc7222635f7cd402abf8b528ae971ddac6bbe2b0c7cb518` +- `final_hash` - `de37e1824c86d35d154cf65a88de6d9286aec4f7f10c3fc9f0fa1bcc2687188d` Block 99: - `prog_seed` - 1 - `nonce` - `000000003917afab` - `header` - `de37e1824c86d35d154cf65a88de6d9286aec4f7f10c3fc9f0fa1bcc2687188d` -- _digest_ - `f5e60b2c5bfddd136167a30cbc3c8dbdbd15a512257dee7964e0bc6daa9f8ba7` -- _result_ - `ac7b55e801511b77e11d52e9599206101550144525b5679f2dab19386f23dcc` +- `mix_hash` - `f5e60b2c5bfddd136167a30cbc3c8dbdbd15a512257dee7964e0bc6daa9f8ba7` +- `final_hash` - `ac7b55e801511b77e11d52e9599206101550144525b5679f2dab19386f23dcce` Block 29,950: - `prog_seed` - 599 - `nonce` - `005d409dbc23a62a` - `header` - `ac7b55e801511b77e11d52e9599206101550144525b5679f2dab19386f23dcce` -- _digest_ - `07393d15805eb08ee6fc6cb3ad4ad1010533bd0ff92d6006850246829f18fd6e` -- _result_ - `e43d7e0bdc8a4a3f6e291a5ed790b9fa1a0948a2b9e33c844888690847de19f` +- `mix_hash` - `07393d15805eb08ee6fc6cb3ad4ad1010533bd0ff92d6006850246829f18fd6e` +- `final_hash` - `e43d7e0bdc8a4a3f6e291a5ed790b9fa1a0948a2b9e33c844888690847de19f5` Block 29,999: - `prog_seed` - 599 - `nonce` - `005db5fa4c2a3d03` - `header` - `e43d7e0bdc8a4a3f6e291a5ed790b9fa1a0948a2b9e33c844888690847de19f5` -- _digest_ - `7551bddf977491da2f6cfc1679299544b23483e8f8ee0931c4c16a796558a0b8` -- _result_ - `d34519f72c97cae8892c277776259db3320820cb5279a299d0ef1e155e5c645` +- `mix_hash` - `7551bddf977491da2f6cfc1679299544b23483e8f8ee0931c4c16a796558a0b8` +- `final_hash` - `d34519f72c97cae8892c277776259db3320820cb5279a299d0ef1e155e5c6454` Block 30,000: - `prog_seed` - 600 - `nonce` - `005db8607994ff30` - `header` - `d34519f72c97cae8892c277776259db3320820cb5279a299d0ef1e155e5c6454` -- _digest_ - `f1c2c7c32266af9635462e6ce1c98ebe4e7e3ecab7a38aaabfbf2e731e0fbff4` -- _result_ - `8b6ce5da0b06d18db7bd8492d9e5717f8b53e7e098d9fef7886d58a6e913ef6` +- `mix_hash` - `f1c2c7c32266af9635462e6ce1c98ebe4e7e3ecab7a38aaabfbf2e731e0fbff4` +- `final_hash` - `8b6ce5da0b06d18db7bd8492d9e5717f8b53e7e098d9fef7886d58a6e913ef64` Block 30,049: - `prog_seed` - 600 - `nonce` - `005e2e215a8ca2e7` - `header` - `8b6ce5da0b06d18db7bd8492d9e5717f8b53e7e098d9fef7886d58a6e913ef64` -- _digest_ - `57fe6a9fbf920b4e91deeb66cb0efa971e08229d1a160330e08da54af0689add` -- _result_ - `c2c46173481b9ced61123d2e293b42ede5a1b323210eb2a684df0874ffe0904` +- `mix_hash` - `57fe6a9fbf920b4e91deeb66cb0efa971e08229d1a160330e08da54af0689add` +- `final_hash` - `c2c46173481b9ced61123d2e293b42ede5a1b323210eb2a684df0874ffe09047` Block 30,050: - `prog_seed` - 601 - `nonce` - `005e30899481055e` - `header` - `c2c46173481b9ced61123d2e293b42ede5a1b323210eb2a684df0874ffe09047` -- _digest_ - `ba30c61cc5a2c74a5ecaf505965140a08f24a296d687e78720f0b48baf712f2d` -- _result_ - `ea42197eb2ba79c63cb5e655b8b1f612c5f08aae1a49ff236795a3516d87bc7` +- `mix_hash` - `ba30c61cc5a2c74a5ecaf505965140a08f24a296d687e78720f0b48baf712f2d` +- `final_hash` - `ea42197eb2ba79c63cb5e655b8b1f612c5f08aae1a49ff236795a3516d87bc71` Block 30,099: - `prog_seed` - 601 - `nonce` - `005ea6aef136f88b` - `header` - `ea42197eb2ba79c63cb5e655b8b1f612c5f08aae1a49ff236795a3516d87bc71` -- _digest_ - `cfd5e46048cd133d40f261fe8704e51d3f497fc14203ac6a9ef6a0841780b1cd` -- _result_ - `49e15ba4bf501ce8fe8876101c808e24c69a859be15de554bf85dbc095491bd` +- `mix_hash` - `cfd5e46048cd133d40f261fe8704e51d3f497fc14203ac6a9ef6a0841780b1cd` +- `final_hash` - `49e15ba4bf501ce8fe8876101c808e24c69a859be15de554bf85dbc095491bd6` Block 59,950: - `prog_seed` - 1,199 - `nonce` - `02ebe0503bd7b1da` - `header` - `49e15ba4bf501ce8fe8876101c808e24c69a859be15de554bf85dbc095491bd6` -- _digest_ - `21511fbaa31fb9f5fc4998a754e97b3083a866f4de86fa7500a633346f56d773` -- _result_ - `f5c50ba5c0d6210ddb16250ec3efda178de857b2b1703d8d5403bd0f848e19c` +- `mix_hash` - `21511fbaa31fb9f5fc4998a754e97b3083a866f4de86fa7500a633346f56d773` +- `final_hash` - `f5c50ba5c0d6210ddb16250ec3efda178de857b2b1703d8d5403bd0f848e19cf` Block 59,999: - `prog_seed` - 1,199 - `nonce` - `02edb6275bd221e3` - `header` - `f5c50ba5c0d6210ddb16250ec3efda178de857b2b1703d8d5403bd0f848e19cf` -- _digest_ - `653eda37d337e39d311d22be9bbd3458d3abee4e643bee4a7280a6d08106ef98` -- _result_ - `341562d10d4afb706ec2c8d5537cb0c810de02b4ebb0a0eea5ae335af6fb2e8` +- `mix_hash` - `653eda37d337e39d311d22be9bbd3458d3abee4e643bee4a7280a6d08106ef98` +- `final_hash` - `341562d10d4afb706ec2c8d5537cb0c810de02b4ebb0a0eea5ae335af6fb2e88` Block 10,000,000: - `prog_seed` - 200,000 - `nonce` - `005e30899481055e` - `header` - `efda178de857b2b1703d8d5403bd0f848e19cff5c50ba5c0d6210ddb16250ec3` -- _digest_ - `b2403f56c426177856eaf0eedd707c86ae78a432b9169c3689a67058fcf2a848` -- _result_ - `206aee640c0fd21473d5cc3654d63c80442d9e2dfa676d2801d3ec1fbab38a6d` +- `mix_hash` - `b2403f56c426177856eaf0eedd707c86ae78a432b9169c3689a67058fcf2a848` +- `final_hash` - `206aee640c0fd21473d5cc3654d63c80442d9e2dfa676d2801d3ec1fbab38a6d` Block 100,000,000: - `prog_seed` - 2,000,000 - `nonce` - `02abe0589481055e` - `header` - `49e15ba4bf501ce8fe88765403bd0f848e19cff5c50ba5c0d6210ddb16250ec3` -- _digest_ - `ac452084d6f4e6eacf4282ad58dbd4ce7ef2653fb5e6b5c877f56928c907432a` -- _result_ - `b879f84923e71b812ef5a42ece0b5b9366c31cab218f40afe65f8a2cae448a6f` \ No newline at end of file +- `mix_hash` - `ac452084d6f4e6eacf4282ad58dbd4ce7ef2653fb5e6b5c877f56928c907432a` +- `final_hash` - `b879f84923e71b812ef5a42ece0b5b9366c31cab218f40afe65f8a2cae448a6f` + +### 0.9.3 +[Machine-readable data](https://github.com/ethereum/EIPs/blob/ad4e73f239d53d72a21cfd8fdc89dc81eb9d2688/assets/eip-1057/test-vectors-0.9.3.json) From 7cdf2de23473798c2ec55ee8197a2dc942d67132 Mon Sep 17 00:00:00 2001 From: Greg Colvin Date: Fri, 3 May 2019 15:34:38 -0600 Subject: [PATCH 2/5] Add editors --- EIPS/eip-1.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/EIPS/eip-1.md b/EIPS/eip-1.md index 8fc28d16cb96f9..039a21481e0a7b 100644 --- a/EIPS/eip-1.md +++ b/EIPS/eip-1.md @@ -205,6 +205,10 @@ The current EIP editors are ` * Martin Becze (@wanderer)` +` * Greg Colvin (@gcolvin)` + +` * Alex Beregszaszi (@axic)` + ## EIP Editor Responsibilities For each new EIP that comes in, an editor does the following: From dd6e4f76193d20badf20d23507694e423a5421bc Mon Sep 17 00:00:00 2001 From: Andrew Cooke Date: Fri, 3 May 2019 17:51:49 -0400 Subject: [PATCH 3/5] Automatically merged updates to draft EIP(s) 1155 (#1993) Hi, I'm a bot! This change was automatically merged because: - It only modifies existing Draft or Last Call EIP(s) - The PR was approved or written by at least one author of each modified EIP - The build is passing --- EIPS/eip-1155.md | 135 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 98 insertions(+), 37 deletions(-) diff --git a/EIPS/eip-1155.md b/EIPS/eip-1155.md index edda721eb36ca2..23801061477e86 100644 --- a/EIPS/eip-1155.md +++ b/EIPS/eip-1155.md @@ -1,7 +1,7 @@ --- eip: 1155 title: ERC-1155 Multi Token Standard -author: Witek Radomski , Andrew Cooke , Philippe Castonguay , James Therien , Eric Binet +author: Witek Radomski , Andrew Cooke , Philippe Castonguay , James Therien , Eric Binet type: Standards Track category: ERC status: Draft @@ -34,7 +34,7 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S **Smart contracts implementing the ERC-1155 standard MUST implement the `ERC1155` and `ERC165` interfaces.** ```solidity -pragma solidity ^0.5.7; +pragma solidity ^0.5.8; /** @title ERC-1155 Multi Token Standard @@ -63,7 +63,7 @@ interface ERC1155 /* is ERC165 */ { event TransferBatch(address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _values); /** - @dev MUST emit when an approval is updated. + @dev MUST emit when approval for a second party/operator address to manage all tokens for an owner address is enabled or disabled (absense of an event assumes disabled). */ event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); @@ -77,34 +77,34 @@ interface ERC1155 /* is ERC165 */ { /** @notice Transfers value amount of an _id from the _from address to the _to address specified. @dev MUST emit TransferSingle event on success. - Caller must be approved to manage the _from account's tokens (see isApprovedForAll). - MUST throw if `_to` is the zero address. - MUST throw if balance of sender for token `_id` is lower than the `_value` sent. - MUST throw on any other error. - When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0). If so, it MUST call `onERC1155Received` on `_to` and revert if the return value is not `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`. + Caller must be approved to manage the _from account's tokens (see "Approval" section of the standard). + MUST revert if `_to` is the zero address. + MUST revert if balance of sender for token `_id` is lower than the `_value` sent. + MUST revert on any other error. + After the transfer succeeds, this function MUST check if `_to` is a smart contract (eg. code size > 0). If so, it MUST call `onERC1155Received` on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard). @param _from Source address @param _to Target address @param _id ID of the token type @param _value Transfer amount - @param _data Additional data with no specified format, sent in call to `_to` + @param _data Additional data with no specified format, sent in call to `onERC1155Received` on `_to` */ function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external; /** @notice Send multiple types of Tokens from a 3rd party in one transfer (with safety call). @dev MUST emit TransferBatch event on success. - Caller must be approved to manage the _from account's tokens (see isApprovedForAll). - MUST throw if `_to` is the zero address. - MUST throw if length of `_ids` is not the same as length of `_values`. - MUST throw if any of the balance of sender for token `_ids` is lower than the respective `_values` sent. - MUST throw on any other error. - When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0). If so, it MUST call `onERC1155BatchReceived` on `_to` and revert if the return value is not `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`. + Caller must be approved to manage the _from account's tokens (see "Approval" section of the standard). + MUST revert if `_to` is the zero address. + MUST revert if length of `_ids` is not the same as length of `_values`. + MUST revert if any of the balance of sender for token `_ids` is lower than the respective `_values` sent. + MUST revert on any other error. Transfers and events MUST occur in the array order they were submitted (_ids[0] before _ids[1], etc). + After all the transfer(s) in the batch succeed, this function MUST check if `_to` is a smart contract (eg. code size > 0). If so, it MUST call `onERC1155BatchReceived` on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard). @param _from Source addresses @param _to Target addresses - @param _ids IDs of each token type - @param _values Transfer amounts per token type - @param _data Additional data with no specified format, sent in call to `_to` + @param _ids IDs of each token type (order and length must match _values array) + @param _values Transfer amounts per token type (order and length must match _ids array) + @param _data Additional data with no specified format, sent in call to `onERC1155BatchReceived` on `_to` */ function safeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _values, bytes calldata _data) external; @@ -144,58 +144,116 @@ interface ERC1155 /* is ERC165 */ { ### ERC-1155 Token Receiver -Smart contracts **MUST** implement this interface to accept transfers. +Smart contracts **MUST** implement this interface to accept transfers. See "Safe Transfer Rules" for further detail. ```solidity -pragma solidity ^0.5.7; +pragma solidity ^0.5.8; interface ERC1155TokenReceiver { /** @notice Handle the receipt of a single ERC1155 token type. - @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeTransferFrom` after the balance has been updated. - This function MAY throw to revert and reject the transfer. - Return of other than the magic value MUST result in the transaction being reverted. + @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeTransferFrom` after the balance has been updated. + This function MUST return whether it accepts or rejects the transfer via the prescribed keccak256 generated values. + Return of any other value than the prescribed keccak256 generated values WILL result in the transaction being reverted. Note: The contract address is always the message sender. - @param _operator The address which called the `safeTransferFrom` function + @param _operator The address which initiated the transfer (i.e. msg.sender) @param _from The address which previously owned the token @param _id The id of the token being transferred @param _value The amount of tokens being transferred @param _data Additional data with no specified format - @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` + @return `bytes4(keccak256("accept_erc1155_tokens()"))`==0x4dc21a2f or `bytes4(keccak256("reject_erc1155_tokens()"))`==0xafed434d */ function onERC1155Received(address _operator, address _from, uint256 _id, uint256 _value, bytes calldata _data) external returns(bytes4); - + /** @notice Handle the receipt of multiple ERC1155 token types. - @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeBatchTransferFrom` after the balances have been updated. - This function MAY throw to revert and reject the transfer. - Return of other than the magic value WILL result in the transaction being reverted. + @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeBatchTransferFrom` after the balances have been updated. + This function MUST return whether it accepts or rejects the transfer via the prescribed keccak256 generated values. + Return of any other value than the prescribed keccak256 generated values WILL result in the transaction being reverted. Note: The contract address is always the message sender. - @param _operator The address which called the `safeBatchTransferFrom` function + @param _operator The address which initiated the batch transfer (i.e. msg.sender) @param _from The address which previously owned the token - @param _ids An array containing ids of each token being transferred - @param _values An array containing amounts of each token being transferred + @param _ids An array containing ids of each token being transferred (order and length must match _values array) + @param _values An array containing amounts of each token being transferred (order and length must match _ids array) @param _data Additional data with no specified format - @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` + @return `bytes4(keccak256("accept_batch_erc1155_tokens()"))`==0xac007889 or `bytes4(keccak256("reject_erc1155_tokens()"))`==0xafed434d */ function onERC1155BatchReceived(address _operator, address _from, uint256[] calldata _ids, uint256[] calldata _values, bytes calldata _data) external returns(bytes4); } ``` +### Safe Transfer Rules + +To be more explicit about how safeTransferFrom and safeBatchTransferFrom MUST operate, a list of rules follows: + +* onERC1155Received and onERC1155BatchReceived MUST NOT be called on an EOA account. +* onERC1155Received and onERC1155BatchReceived MUST NOT be called outside of a mint or transfer process. + +##### When the recipient is a contract: + +* The onERC1155Received hook MUST be called every time one and only one token type is transferred to an address in the transaction. +* The onERC1155Received hook MUST NOT be called when more than one token type is transferred to an address in the transaction. +* The onERC1155BatchReceived hook MUST be called when more than one token type is transferred to an address in the transaction with the entire list of what was transferred to it. +* The onERC1155BatchReceived hook MUST NOT be called when only one token type is transferred to an address in the transaction. + +* If implementation specific functions are used to transfer 1155 tokens to a contract the appropriate hook MUST still be called with the same rules as if safeTransferFrom/safeBatchTransferFrom was used. +* If the destination/to contract does not implement the appropriate hook the transfer MUST be reverted with the one caveat below. + - If the tokens being sent are part of a hybrid implementation of another standard, that particular standard's rules on sending to a contract MAY now be followed instead. See "Compatibility with other standards" section. + +* When calling either onERC1155Received or onERC1155BatchReceived: + - operator MUST be the address of the account/contract that initiated the transfer (i.e. msg.sender). + - from MUST be the address of the holder whose balance is decreased. + - to MUST be the address of the recipient whose balance is increased. + - from MUST be 0x0 for a mint. + - data MUST contain the extra information provided by the sender (if any) for a transfer. + - the hook MUST be called after all the balances in the transaction have been updated to match the senders intent. + +* When calling onERC1155Received + - id MUST be the token type being transferred. + - value MUST be the number of tokens the holder balance is decreased by and match what the recipient balance is increased by. + - If the return value is anything other than `bytes4(keccak256("accept_erc1155_tokens()"))` or `bytes4(keccack256("reject_erc1155_tokens()"))` the transaction MUST be reverted. + +* When calling onERC1155BatchReceived + - ids MUST be the list of tokens being transferred. + - values MUST be the list of number of tokens (specified in ids) the holder balance is decreased by and match what the recipient balance is increased by. + - If the return value is anything other than `bytes4(keccak256("accept_batch_erc1155_tokens()"))` or `bytes4(keccack256("reject_erc1155_tokens()"))` the transaction MUST be reverted. + +* The destination/to contract MAY accept an increase of its balance by returning the acceptance magic value `bytes4(keccak256("accept_erc1155_tokens()"))` for onERC1155Received or `bytes4(keccak256("accept_batch_erc1155_tokens()"))` for onERC1155BatchReceived. + - If such explicit acceptance happens the transfer MUST be completed, unless other conditions apply. +* The destination/to contract MAY reject an increase of its balance by returning the rejection magic value `bytes4(keccack256("reject_erc1155_tokens()"))`. + - If such explicit rejection happens, the transfer MUST be reverted with the one caveat below. + - If the tokens being sent are part of a hybrid implementation of another standard, that particular standard's rules on sending to a contract MAY now be followed instead. See "Compatibility with other standards" section. + +* A solidity example of the keccak256 generated constants for the return magic is: + - bytes4 constant public ERC1155_REJECTED = 0xafed434d; // keccak256("reject_erc1155_tokens()") + - bytes4 constant public ERC1155_ACCEPTED = 0x4dc21a2f; // keccak256("accept_erc1155_tokens()") + - bytes4 constant public ERC1155_BATCH_ACCEPTED = 0xac007889; // keccak256("accept_batch_erc1155_tokens()") + +##### Compatibility with other standards + +There have been requirements during the design discussions to have this standard be compatible with older standards when sending to contract addresses, specifically ERC721 at time of writing. +To cater for this there is some leeway with the rejection logic should a contract return `bytes4(keccack256("reject_erc1155_tokens()"))` from the call to onERC1155Received/onERC1155BatchReceived as detailed in the main "Safe Transfer Rules" section above. +In this case the hybrid implementation MAY now follow the secondary standard's rules when transferring token(s) to a contract address. + +Note however it is recommended that a hybrid solution NOT be followed and a pure implementation of a single standard is followed instead, as a hybrid solution is an unproven method to date. + +An example of a hybrid 1155+721 contract is linked in the references section under implementations. + ### Metadata -The URI value allows for ID substitution by clients. If the string `{id}` exists in any URI, clients MUST replace this with the actual token ID in hexadecimal form. This allows for large number of tokens to use the same on-chain string by defining a URI once, for a large collection of tokens. Example of such a URI: `https://token-cdn-domain/{id}.json` would be replaced with `https://token-cdn-domain/780000000000001e000000000000000000000000000000000000000000000000.json` if the client is referring to token ID `780000000000001e000000000000000000000000000000000000000000000000`. +The URI value allows for ID substitution by clients. If the string `{id}` exists in any URI, clients MUST replace this with the actual token ID in hexadecimal form. This allows for large number of tokens to use the same on-chain string by defining a URI once, for a large collection of tokens. Example of such a URI: `https://token-cdn-domain/{id}.json` would be replaced with `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004CCE0.json` if the client is referring to token ID 314592/0x4CCE0. The string format of the substituted hexadecimal ID MUST be lowercase alphanumeric: `[0-9a-f]` with no 0x prefix. +The string format of the substituted hexadecimal ID MUST be leading zero padded to 64 hex characters length if necessary. #### Metadata Extensions The following optional extensions can be identified with the (ERC-165 Standard Interface Detection)[https://eips.ethereum.org/EIPS/eip-165]. -Changes to the URI MUST emit the `URI` event if the change can be expressed with an event. If the optional ERC1155Metadata_URI extension is included, the value returned by this function SHOULD be used to retrieve values for which no event was emitted. The function MUST return the same value as the event if it was emitted. +Changes to the URI MUST emit the `URI` event if the change can be expressed with an event (i.e. it isn't dynamic). If the optional ERC1155Metadata_URI extension is included, the 'uri' function SHOULD be used to retrieve values for which no event was emitted. The function MUST return the same value as the event if it was emitted. ```solidity -pragma solidity ^0.5.7; +pragma solidity ^0.5.8; /** Note: The ERC-165 identifier for this interface is 0x0e89341c. @@ -277,7 +335,7 @@ An example of an ERC-1155 Metadata JSON file follows. The properties array propo ##### Localization -Metadata localization should be standardized to increase presentation uniformity accross all languages. As such, a simple overlay method is proposed to enable localization. If the metadata JSON file contains a `localization` attribute, its content MAY be used to provide localized values for fields that need it. The `localization` attribute should be a sub-object with three attributes: `uri`, `default` and `locales`. If the string `{locale}` exists in any URI, it MUST be replaced with the chosen locale by all client software. +Metadata localization should be standardized to increase presentation uniformity across all languages. As such, a simple overlay method is proposed to enable localization. If the metadata JSON file contains a `localization` attribute, its content MAY be used to provide localized values for fields that need it. The `localization` attribute should be a sub-object with three attributes: `uri`, `default` and `locales`. If the string `{locale}` exists in any URI, it MUST be replaced with the chosen locale by all client software. ##### JSON Schema @@ -362,6 +420,9 @@ fr.json: ### Approval The function `setApprovalForAll` allows an operator to manage one's entire set of tokens on behalf of the approver. To permit approval of a subset of token IDs, an interface such as [ERC-1761 Scoped Approval Interface (DRAFT)](https://eips.ethereum.org/EIPS/eip-1761) is suggested. +The counterpart `isAprrovedForAll` provides introspection into status set by `setApprovalForAll`. + +An owner SHOULD be assumed to always be able to operate on their own tokens regardless of approval status, so should SHOULD NOT have to call `setApprovalForAll` to approve themselves as an operator before they can operate on them. ## Rationale From b859ddbb4663775f71f2c3f6c7036d73ae880e7a Mon Sep 17 00:00:00 2001 From: Andrew Cooke Date: Fri, 3 May 2019 20:16:07 -0400 Subject: [PATCH 4/5] Automatically merged updates to draft EIP(s) 1155 (#1995) Hi, I'm a bot! This change was automatically merged because: - It only modifies existing Draft or Last Call EIP(s) - The PR was approved or written by at least one author of each modified EIP - The build is passing --- EIPS/eip-1155.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-1155.md b/EIPS/eip-1155.md index 23801061477e86..afcd5bfb374697 100644 --- a/EIPS/eip-1155.md +++ b/EIPS/eip-1155.md @@ -241,7 +241,7 @@ An example of a hybrid 1155+721 contract is linked in the references section und ### Metadata -The URI value allows for ID substitution by clients. If the string `{id}` exists in any URI, clients MUST replace this with the actual token ID in hexadecimal form. This allows for large number of tokens to use the same on-chain string by defining a URI once, for a large collection of tokens. Example of such a URI: `https://token-cdn-domain/{id}.json` would be replaced with `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004CCE0.json` if the client is referring to token ID 314592/0x4CCE0. +The URI value allows for ID substitution by clients. If the string `{id}` exists in any URI, clients MUST replace this with the actual token ID in hexadecimal form. This allows for large number of tokens to use the same on-chain string by defining a URI once, for a large collection of tokens. Example of such a URI: `https://token-cdn-domain/{id}.json` would be replaced with `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json` if the client is referring to token ID 314592/0x4CCE0. The string format of the substituted hexadecimal ID MUST be lowercase alphanumeric: `[0-9a-f]` with no 0x prefix. The string format of the substituted hexadecimal ID MUST be leading zero padded to 64 hex characters length if necessary. From b922d593401c67c1473b334fdb6919b31a27d34f Mon Sep 17 00:00:00 2001 From: Vincent Date: Sun, 5 May 2019 23:09:31 +0200 Subject: [PATCH 5/5] EIP-1775 - App Keys, application specific wallet accounts (#1775) --- EIPS/eip-1775.md | 634 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 634 insertions(+) create mode 100644 EIPS/eip-1775.md diff --git a/EIPS/eip-1775.md b/EIPS/eip-1775.md new file mode 100644 index 00000000000000..1c623887562991 --- /dev/null +++ b/EIPS/eip-1775.md @@ -0,0 +1,634 @@ +--- +eip: 1775 +title: App Keys, application specific wallet accounts +author: Vincent Eli (@Bunjin), Dan Finlay (@DanFinlay) +discussions-to: https://ethereum-magicians.org/t/eip-erc-app-keys-application-specific-wallet-accounts/2742 +status: Draft +type: Standards Track +category: ERC +created: 2019-02-20 +requires: 137 +--- + + +## Simple Summary + + +Among others cryptographic applications, scalability and privacy solutions for ethereum blockchain require that an user performs a significant amount of signing operations. It may also require her to watch some state and be ready to sign data automatically (e.g. sign a state or contest a withdraw). The way wallets currently implement accounts poses several obstacles to the development of a complete web3.0 experience both in terms of UX, security and privacy. + +This proposal describes a standard and api for a new type of wallet accounts that are derived specifically for a each given application. We propose to call them `app keys`. They allow to isolate the accounts used for each application, thus potentially increasing privacy. They also allow to give more control to the applications developpers over account management and signing delegation. For these app keys, wallets can have a more permissive level of security (e.g. not requesting user's confirmation) while keeping main accounts secure. Finally wallets can also implement a different behavior such as allowing to sign transactions without broadcasting them. + +This new accounts type can allow to significantly improve UX and permit new designs for applications of the crypto permissionned web. + +## Abstract + +In a wallet, an user often holds most of her funds in her main accounts. These accounts require a significant level of security and should not be delegated in any way, this significantly impacts the design of cryptographic applications if a user has to manually confirm every action. Also often an user uses the same accounts across apps, which is a privacy and potentially also a security issue. + +We introduce here a new account type, app keys, which permits signing delegation and accounts isolation across applications for privacy and security. + +In this EIP, we provide a proposal on how to uniquely identify and authenticate each application, how to derive the accounts along an Hierachical Deterministic (HD) path restricted for the domain and we finally define an API for applications to derive and use these app keys. This ERC aims at finding a standard that will fit the needs of wallets and application developers while also allowing app keys to be used across wallets and yield the same accounts for the user for each application. + +## Motivation + +Wallets developers have agreed on an HD derivation path for ethereum accounts using BIP32, BIP44, SLIP44, [(see the discussion here)](https://github.com/ethereum/EIPs/issues/84). Web3 wallets have implemented in a roughly similar way the rpc eth api. [EIP1102](https://eips.ethereum.org/EIPS/eip-1102) introduced privacy through non automatic opt-in of a wallet account into an app increasing privacy. + +However several limitations remain in order to allow for proper design and UX for crypto permissioned apps. + +Most of GUI based current wallets don't allow to: +* being able to automatically and effortlessly use different keys / accounts for each apps, +* being able to sign some app's action without prompting the user with the same level of security as sending funds from their main accounts, +* being able to use throwable keys to improve anonymity, +* effortlessly signing transactions for an app without broadcasting these while still being able to perform other transaction signing as usual from their main accounts, +* All this while being fully restorable using the user's mnemonic or hardware wallet and the HD Path determined uniquely by the app's ens name. + +We try to overcome these limitations by introducing a new account's type, app keys, made to be used along side the existing main accounts. + +These new app keys can permit to give more power and flexibility to the crypto apps developers. This can allow to improve a lot the UX of crypto dapps and to create new designs that were not possible before leveraging the ability to create and handle many accounts, to presign messages and broadcast them later. These features were not compatible with the level of security we were requesting for main accounts that hold most of an user's funds. + + +## Specification + + +### Applications + +An app is a website (or other) that would like to request from a wallet to access app keys. It can be any form of cryptography/identity relying application, ethereum but not only. + +Once connected to a wallet, an application can request to access a set of accounts derived exclusively for that application using the hierarchical deterministic (HD) paths. + +### Applications' HD path + +Using the BIP32 and BIP43 standards, we propose to use the following HD path for each app keys: + +`m / [standardized Path Beginning]' / [persona path]' / [application uniquely assigned path]' / [app's custom subpath]` + +Where: + +`standardized HD Path Beginning` is based on the EIP number that will be assigned to this EIP and we harden it. We use a different path than 44' since it's not bip44 compliant. At this point, I'm not sure if there is a list of BIP43 codes of standards following the `purpose` field specification of [BIP43](https://github.com/bitcoin/bips/blob/master/bip-0043.mediawiki). + +`persona path` allows to use applications with different and isolated personas (or in other words accounts) that are tracable by the application. They will still be fully restorable from the same mnemonic. + +`application uniquely assigned path` isolate each application along unique branches of the tree through these unique subPath combination. + +`app's custom subPath` give freedom to application to use this BIP32 compliant subPath to manage accounts and other needed parameters. + +Note that we suggest that each of these indexes, except those belonging to the app's custom subpath, must be hardened to fully isolate the public keys across personas and applications. + +### Standardized HD Path Beginning + +For the path header, several alternative are possible depending on what the cryptocommunities agree upon. + +The least contentious is the following one (as suggested [here in the BIP repository](https://github.com/bitcoin/bips/pull/523)): + +` 43' / 60' / 1775 ' ` + +However, there may be benefits to use only one depth instead of 3. We could use the `EIP Number'` (ie. 1775) or a ` BIP Number'` if we attain some cross crypto agreement that would avoid collision. + + +### Personas + +We allow the user to use different personas in combination to her mnemonic to potentially fully isolate her interaction with a given app accross personas. One can use this for instance to create a personal and business profile for a given's domain both backup up from the same mnemonic, using 2 different personnas indexes. The app or domain, will not be aware that it is the same person and mnemonic behind both. + +We use a string following BIP32 format (can be hardened) to define personas. +The indexes should be hex under 0x80000000, 31 bits. + +E.g. `0'` or `0'/1/2'/0` or `1d7b'/a41c'` + +### Applications' Unique Identifiers + +#### Applications Names + +We need a way to uniquely identify each application. We will use a naming and a hashing scheme. + +In our favored spec, each application is uniquely defined and authenticated by its name, a domain string. It can be a Domain Name Service DNS name or and Ethereum Name Service ENS name. + +There are a few restrictions however on the characters used and normalisation, each name should be passed through the [NamePrep Algorithm](https://tools.ietf.org/html/rfc3491) + +In addition there must be a maximum size to the domain string that we need to determine such that the mapping from strings to nodes remains injective, to avoid collision. + +We recommend this standard to be following the [ENS Specs](http://docs.ens.domains/en/latest/implementers.html#namehash), reproduced below for convinience and reference. + +``` +Normalising and validating names +Before a name can be converted to a node hash using Namehash, the name must first be normalised and checked for validity - for instance, converting fOO.eth into foo.eth, and prohibiting names containing forbidden characters such as underscores. It is crucial that all applications follow the same set of rules for normalisation and validation, as otherwise two users entering the same name on different systems may resolve the same human-readable name into two different ENS names. +``` + +#### Hashing and Applications UIDs + +The ENS uses an hashing scheme to associate a domain to a unique hash, `node`, through the `namehash` function. We will use this hashing scheme both for ENS and for DNS names. + +This gives an unique identifier (UID) of 32 bytes. + +``` +e.g. for foo.bar.eth +app's uid 0x6033644d673b47b3bea04e79bbe06d78ce76b8be2fb8704f9c2a80fd139c81d3 +``` + +For reference, here are the specs of ENS: + +``` +domain - the complete, human-readable form of a name; eg, ‘vitalik.wallet.eth’. +label - a single component of a domain; eg, ‘vitalik’, ‘wallet’, or ‘eth’. A label may not contain a period (‘.’). +label hash - the output of the keccak-256 function applied to a label; eg, keccak256(‘eth’) = 0x4f5b812789fc606be1b3b16908db13fc7a9adf7ca72641f84d75b47069d3d7f0. +node - the output of the namehash function, used to uniquely identify a name in ENS. +Algorithm +First, a domain is divided into labels by splitting on periods (‘.’). So, ‘vitalik.wallet.eth’ becomes the list [‘vitalik’, ‘wallet’, ‘eth’]. + +The namehash function is then defined recursively as follows: + +namehash([]) = 0x0000000000000000000000000000000000000000000000000000000000000000 +namehash([label, …]) = keccak256(namehash(…), keccak256(label)) + +keccak256(‘eth’) = 0x4f5b812789fc606be1b3b16908db13fc7a9adf7ca72641f84d75b47069d3d7f0 + +``` + +We thus propose to use the node of each app's domain as a unique identifier for each app but one can think of other UIDs, we include some alternative specs in the [Rationale](#Rationale) section below. + +### Applications' authentication + +If the application is using a DNS name then we simply authenticate the application by using the url of the loaded browser webpage. + +For applications using ENS, we can authenticate the application through ENS resolution. +The ENS can also allow to register and resolve metadata for the application such as `url`, and other parameters. + +If we use for instance this resolver profile defined in [EIP634](https://eips.ethereum.org/EIPS/eip-634) which permits the lookup of arbitrary key-value text data, we can for instance use the key `url` to point to a website. + +``` +A new resolver interface is defined, consisting of the following method: + +function text(bytes32 node, string key) constant returns (string text); +The interface ID of this interface is 0x59d1d43c. + +The text data may be any arbitrary UTF-8 string. If the key is not present, the empty string must be returned. +``` + +One can think of other authentication methods and even use some of them alongside the url-resolution method through ENS. We mention other methods in the [Rationale](#Rationale) section. + +We suggest for instance to also add an `authorEthAddress` text metadata field that can be used to authenticate messages from the application, with for instance a sign challenge. + +### Applications UID decomposition to get a BIP32 HD path + +Since each child index in an HD path only has 31 bits we will decompose the domain's hash as several child indexes, first as hex bytes then parsed as integers. + +For the applications's uid we use an `ENS namehash node` of 32 bytes, 256 bits (removing the leading `0x`). + +e.g. `foo.bar.eth` which gives the following namehash node: `0x6033644d673b47b3bea04e79bbe06d78ce76b8be2fb8704f9c2a80fd139c81d3` + +We can decompose it in several ways, here are 2 potential ways: + +* First approach could favor having the least indexes: + +This requires to first convert the hex uid to 256 bits then decompose it as 8 * 31 bits + 8 bits + +``` +x = x0 || x1 || x2 || x3 || x4 || x5 || x6 || x7 || x8 +``` +where `x0` to `x7` are 31 bits and `x8` is 8 bits + +then we convert the `x_i` to uints. + +The derivation sub-path would be: +`x0'/x1'/x2'/x3'/x4'/x5'/x6'/x7'/x8'` + + +``` +E.g. + +foo.bar.eth + + +0x6033644d673b47b3bea04e79bbe06d78ce76b8be2fb8704f9c2a80fd139c81d3 + +converted to binary (256 bits) + +6033644d673b +011000000011001101100100010011010110011100111011 +47b3bea04e79 +010001111011001110111110101000000100111001111001 +bbe06d78ce76 +101110111110000001101101011110001100111001110110 +b8be2fb8704f +101110001011111000101111101110000111000001001111 +9c2a80fd139c +100111000010101010000000111111010001001110011100 +81d3 +1000000111010011 + +256 bits: +0110000000110011011001000100110101100111001110110100011110110011101111101010000001001110011110011011101111100000011011010111100011001110011101101011100010111110001011111011100001110000010011111001110000101010100000001111110100010011100111001000000111010011 + +converted to less than or equal to 31 bits indexes: + +8 * 31 bits + 1 * 8 bits + +0110000000110011011001000100110 +1011001110011101101000111101100 +1110111110101000000100111001111 +0011011101111100000011011010111 +1000110011100111011010111000101 +1111000101111101110000111000001 +0011111001110000101010100000001 +1111101000100111001110010000001 +11010011 + +and converted to uints + +806990374'/1506726380'/2010384847'/465438423'/1181988293'/2025775553'/523785473'/2098437249'/211' + + +``` + + +* Second approach favors an homogenous decomposition: + +Equal lenght indexes would be 16 * 16 bits or in other words 16 * 2 bytes, cleanest and favored spec: + +``` +x = x0 || x1 || x2 || x3 || x4 || x5 || x6 || x7 || x8 || x9 || x10 || x11 || x12 || x13 || x14 || x15 + +where || is concatenation +``` + + +``` +E.g. + +foo.bar.eth +0x6033644d673b47b3bea04e79bbe06d78ce76b8be2fb8704f9c2a80fd139c81d3 +6033 644d 673b 47b3 bea0 4e79 bbe0 6d78 ce76 b8be 2fb8 704f 9c2a 80fd 139c 81d3 +6033'/644d'/673b'/47b3'/bea0'/4e79'/bbe0'/6d78'/ce76'/b8be'/2fb8'/704f'/9c2a'/80fd'/139c'/81d3' +24627'/25677'/26427'/18355'/48800'/20089'/48096'/28024'/52854'/47294'/12216'/28751'/39978'/33021'/5020'/33235' +``` + + +Between these 2 decomposition approaches, there is a trade-off between computational efficiency (having less depth) and having an homegenous decomposition. We tend to favor the first approach with least indexes. + + +### Application customisable HD sub path + +Finally, the last part of the hd path is under the application's control. This will allow applications developers to use the HD path structure that best fits their needs. Developers can for instance, among any combination of other parameters they like, choose to include a `version` field if they would like to use different signing accounts when updating to a new version. They can then also manage the user accounts in the way they would like, for instance including or not an index for `sets of accounts` (called `accounts` in BIP44), an index for `change` and an index for `account` (called `address_index` in BIP44). +We consider that a given child on the HD tree should be called an `account` and not an `address` since it is composed of a private key, a public key and an address. + +Similarly to the persona path, this sub path must follow bip32, with hex under 0x80000000, 31 bits. +It can be hardened depending on each application's needs and can be writen as hex or unsigned integers. +It can include a large number of indexes. + +Q [Should we set a limit on the persona and application customsable hd path number of indexes?] + +### Example HD paths for app keys: + +``` +Dummy data: +EIP Number: 1775 +personaPath: 0'/712' +application's name: foo.bar.eth +uid: 0x6033644d673b47b3bea04e79bbe06d78ce76b8be2fb8704f9c2a80fd139c81d3 +app custom path params: app_version, set_of_accounts_index, account_index +``` + +`m/43'/60'/1775'/0'/712'/806990374'/1506726380'/2010384847'/465438423'/1181988293'/2025775553'/523785473'/2098437249'/211'/0'/0'/0` + +## API: + +We propose to introduce new RPC methods but they should be restricted and wrapped such that some parameters (e.g. domain name) are imposed by the wallet on the caller depending on the caller's authentication. + +[TBD] Specify scope of RPC methods (some params should be forced to the authenticated domain value) and how to integrate them into web3 api. + +### App keys exposure: + +* `wallet.appkey.enable(options)` +This method allows to enable app keys (getting user permission to use and allow him to select the persona she would like to use). + +[TBD] Could return the account public key from the HD path before `the app's custom subPath`. Hence from this app's root account, one could derive all non hardened childs public keys of the app's keys. + +[TBD] where `options` is a javascript object containing the permissions requested for these app keys. +Options could also include a challenge to be signed by the app's root account (would serve as authentication of the users from the app's perspective). The signature should then be also returned. + +Options should also include a parameter for the application to indicate which name should be used to compute the domain's HD path. That's required for applications that are loaded through ENS. They could be authenticated either through ENS or through DNS. These applications may like to use the DNS name even when they are resolved through ENS. (e.g. an application that just upgraded to ENS may like to continue using DNS paths to be retro-compatible for its former users). + +Uses the persona selected by the user (not known nor controllable by application). + +Uses the domain ens namehash (node) that was resolved to load window (not provided by application itself) + +### Ethereum accounts methods: + +* `appKey_eth_getPublicKey(hdSubPath) returns publicKey 64 bytes`: + +`hdSubPath` string with BIP32 format, "index_i / index_(i+1) '", can use hardening + +`publicKey` returns e.g. 0x80b994e25fb98f69518b1a03e59ddf4494a1a86cc66019131a732ff4a85108fbb86491e2bc423b2cdf6f1f0f4468ec73db0535a1528ca192d975116899289a4b + +* `appKey_eth_getAddress(hdSubPath) returns address 20 bytes`: + +`hdSubPath`: string with BIP32 format, "index_i / index_(i+1) '", can use hardening + +`address` e.g. 0x9df77328a2515c6d529bae90edf3d501eaaa268e + +* `appKey_eth_derivePublicKeyFromParent(parentPublicKey, hdSubPath) returns publicKey 64 bytes` + +`hdSubPath`: string with BIP32 format, "index_i / index_(i+1) '", should not use hardening here. + +* `appKey_eth_getAddressForPublicKey(publicKey) returns address 20 bytes` + +`publicKey` 64 bytes + +### Ethereum signing methods: + +* `appKey_eth_signTransaction(fromAddress, tx)` +tx is ethereum-js tx object + +* `appKey_eth_sign(fromAddress, message)` +* `appKey_eth_personalSign(fromAddress, message)` +* `appKey_eth_signTypedMessage(fromAddress, message)` +EIP712 + +### Ethereum broadcasting methods: + +* `appKey_eth_broadcastTransaction(tx, signedTx)` +tx is ethereum-js tx object + + +### Other potential methods: + +#### Other cryptocurrencies: +We defined for now Ethereum accounts and signing methods. However, one could do the same for other cryptocurrencies deriving accounts along their standards. This may open to some very interesting cross-blockchains application designs. + +#### Other cryptographic methods: +Similarly, using entropy provided by the HD Path, one could think of other cryptographic methods such as encryption and also other curve types. + + +#### Storage: +The HD path for each application can also be used as a key to isolate databases for user's persistent data. We could introduce methods that allow to read and write in a database specific to the application. + +Q [Benefit of this compared to using classical browser local storage?] + +### API permissions and confirmations from users: + +#### Initial permission request and full access afterwards: + +Each wallet has freedom in the way they implement their permission system along with this EIP and this API. We tend to favor a design where the applications would request once and for all full access to the applications keys (for their domain) and that the user has to confirm this once. From then on, any account derivation or signing for those applications keys will not prompt a confirmation request on the wallet side. +However applications themselves are free to reproduce some confirmation at their own level if they would like the users to double check the transactions or signatures they are making at the application level. This will be of course dependent on trusting the application code. + +#### Paranoia mode: +However, we would like to give users the option to monitor at any point applications keys and how applications user them. We therefore encourage wallets to introduce a `paranoia mode` that users can activate (for instance in the wallet advanced settings) to force confirmations request for all the applications keys actions. + +## Rationale + +### Isolated paths but customisable +The proposed specifications permit to have isolation between personas and between applications. Each persona / application combination will yield a unique subtree that can be explored by the application using the structure it would like to use. + +Personas are known only by the user and its wallet, application' UID based path is computable by everyone from the application's name. And then the application decides and communicates the final levels of the path. + +Only the wallet and the user will know the full tree and where we are in the tree (depth, parents). Applications will have knowledge only of the subtree, starting after the persona. + + +### API not exposing private keys + +Applications can derive accounts and request signing from them but they will not get access to the private keys of these accounts. So when the user closes her wallet entirely, the application can not continue signing for the user. This is of course in order to keep an user's ultimate control over its accounts. + +If there is a strong demand, we could add a method that exposes the private keys for the application accounts but it would be an optional to request upon app keys initial setup. + +We indeed think that writing applications that don't need to manipulate the user private keys is a better pattern. For instance, if one needs the user to sign data while being offline, one should for instance rather implement a delegation method to an external application's controlled account rather than storing the user private key on a server that stays online. + +### Persona isolation accross applications for privacy + +The persona path is set by the user-wallet interaction and known only by them. There is thus a strict isolation between 2 different persona subpaths as if they were generated by different mnemonics. + + +Instead of personas, an alternative proposal would be to make the `application UID based path` a subset of a user's ethereum main accounts) + +Most wallets use the following derivation path for ethereum accounts: +`m/44'/60'/a'/0/n` +where a is a set of account number and n is the account index + +We could use: +`m/44'/60'/a'/0/n / [Application UID based path] / [App controlled HD subPath]` + +This way, we could use accounts as personas. + +However it does not necessarily make sense to anchor an application to a single main account. Some applications may like to interact with several "main accounts" or allow the user to change the main account they are using to deposit while keeping the same signing `app keys` accounts. Some applications may even like to use non ethereum accounts. + +Also this alternative specification HD path would not be BIP44 compliant but would be using this purpose field. + +Also it may add complexity to restore a wallet and the used accounts, one should remember which account is associated with which application and application can not suggest you which account to use because they are not aware of this part of the path. +If we don't harden the level indexes after the main account index, we could however enumerate all app keys of an user given a list a applications. We would first enumerate over the main accounts (assuming the wallet uses an [account gap limit](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#Address_gap_limit)), then over the Applications list and then over the `Application controlled HD subPath` if it allows to do so and has an account gap limit. + +For the persona specification this may not be possible, unless we impose some structure on the personas such as using a basic index. + +### Hardened and non-hardened indexes: privacy and functionality + +Hardening allows to increase privacy. If the extended public key of a parent level in the HD tree is known, public keys of its childs can not be computed if they are hardened. On the contrary if the child indexes are not hardened one can enumerate the child public keys and use that for the application design or to easily restore a wallet and it increases functionality. + +For the first parts of the HD tree, we need isolation and privacy. Thus we use hardened indexes for the persona and application paths in case some extended public key leaks at some previous level of the tree, it would protect the sub trees (of course this has no impact if private keys leak). + +For instance if we don't harden the application path, in case a persona public key is known and the application subpath does not use hardening either, one could get all `app keys` public keys for every application for this persona. + +However the app can use non hardened indexes in their custom path part to be able to benefit from guessing child public keys from parent one (for instance for counterfactual state channel interaction accross 2 peers that would like to use new keys every time they counterfactually instantiate a new sub app). + +### Alternatives for the HD derivation path + +Our proposed specification follows [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) and [BIP43](https://github.com/bitcoin/bips/blob/master/bip-0043.mediawiki): + +`m / purpose' / *` + +It is of course not be BIP44 compliant which uses the following tree level structure: +`m / purpose' / coin_type' / account' / change / address_index` + +One could think of alternative specifications deviating from BIP43 or even BIP32. Or on the contrary, one could try to become BIP44 compliant, although we do not really see the benefit of that for app keys and it would impose serious limitations on how to identify the applications using potentially the `coin_type` field. + + +### HD derivation path purpose field + +If we agree on not using BIP44 but following BIP32 and BIP43, we need to settle on a purpose field. We can either use the 3 depth path proposed here (https://github.com/bitcoin/bips/pull/523) or try to rech agreement on a one depth path. A one depth path should however avoid collision. This can be achieves by either submitting a BIP or by maintening a list of BIP 43 purpose fields. + +We did not find a list of BIP43 purpose code so here is what we could gather: + + +| code | Reference | Title | +|------|--------------------------------------------------------------------------|-------| +| 44 | [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) | Multi-Account Hierarchy for Deterministic Wallets | +| 45 | [BIP45](https://github.com/bitcoin/bips/blob/master/bip-0045.mediawiki) | Structure for Deterministic P2SH Multisignature Wallets| +| 48 | [SLIP48](https://github.com/satoshilabs/slips/issues/49) | Deterministic Key Hierarchy for Graphene-based Networks | +| 49 | [BIP49](https://github.com/bitcoin/bips/blob/master/bip-0049.mediawiki) | Derivation scheme for P2WPKH-nested-in-P2SH based accounts | +| 80 | [BIP80](https://github.com/bitcoin/bips/blob/master/bip-0080.mediawiki) | Hierarchy for Non-Colored Voting Pool Deterministic Multisig Wallets | +| 84 | [BIP84](https://github.com/bitcoin/bips/blob/master/bip-0084.mediawiki) | Derivation scheme for P2WPKH based accounts | +| 535348 | [Ledger app ssh](https://github.com/LedgerHQ/ledger-app-ssh-agent/blob/master/getPublicKey.py#L49) | | +| 80475047| [GPG/SSH Ledger](https://github.com/LedgerHQ/ledger-app-openpgp-card/blob/master/doc/developper/gpgcard3.0-addon.rst#deterministic-key-derivation)| | +| 1775 | EIP1775 | App Keys: application specific wallet accounts | + + +### Application's identification + +#### Favoring a deterministic scheme for application uids + +Quoting Vitalik in his post [Meta: we should value privacy more](https://ethereum-magicians.org/t/meta-we-should-value-privacy-more/2475), we indeed favor a deterministic scheme for applications specific accounts generation: + +``` +It would be nice to keep wallet software stateless, so users can easily export and import their keys between wallets; this implies using some deterministic scheme like privkey_for_dapp = hash(master_key + dapp_id). But then what is the dapp_id? How would that work for multi-contract dapps? +``` +And we proposed to use the ENS domain hash, or node, as the dapp_id and to use a BIP32 structure instead to derive the private keys. + +#### Alternative: using a centraly maintened index of application uids + +[EIP1581: Non-wallet usage of keys derived from BIP32 trees](https://eips.ethereum.org/EIPS/eip-1581) +also discussed [here](https://ethereum-magicians.org/t/non-wallet-usage-of-keys-derived-from-bip-32-trees/1817/4) proposes a scheme that relies on a list of indexes where application should register (similar to SLIP44 list for instance). + +We think our approach while also being more englobing benefits from not requiring a centrally maintained registry. In our approach every application has already a potential unique identifier assigned to it. + + +#### Shortening the Hash node + +Our current approach uses identification through an ENS name converted to a hash node and sliced fully but one could potentially keep only the first 16 bytes of the node for instance and slice them similarly. This may increase the chance of app collision but we probably can reduce the lenght while retaining an injective mapping from strings to hashes. + +#### Alternative application identification specification + +For the application unique identifiers, an alternative specification could favor using an `ethereum author address` and including a signed message challenge for author for authentication. + +It would also need to specify how to decompose this address. +The same reasoning as before would apply, if we use an `eth address` of 20 bytes, 160 bits + +e.g. 0x9df77328a2515c6d529bae90edf3d501eaaa268e + +``` +x = x0 || x1 || x2 || x3 || x4 || x5 +``` +where `x0` to `x4` are 30 bits and `x5` is 10 bits. + + +or alternatively equal length +``` +x = x0 || x1 || x2 || x3 || x4 || x5 || x6 || x7 +``` +where `x0` to `x7` are 20 bits. + + +Another alternative could be to use the plain website url and get rid of ens altogether but it would require another way to authenticate applications. See for instance [SLIP13](https://github.com/satoshilabs/slips/blob/master/slip-0013.md) for such a proposal. + +### Application's authentication + +For authentication we use DNS and ENS resolution, and browsing to a given url resolved. A few comments on this: + +A few comments in case of ENS resolution: +* First connection requires the wallet to connect to ethereum mainnet, but once first resolution is done we could use some metadata paramater such as `author address` for a blockchain less authentication of the application (e.g. application server signs a challenge message with the author address resolved in the ENS metadata). + +* The url the name resolves to through ENS can change without the user knowing and then a different application/website may be granted access to his app keys. But this means the ENS name owner address was copromised. This would be similar to using a signing challenge authentified by a known public key. If this known public key is compromised we have a similar problem. + +* Homoglyph attacks are not a bigger problem for `app keys` than it is for ENS since it will not grant access to `app keys` from the real domain (they would be derived along a different path). However homoglyph applications may lure the user to send funds from her main account to an `app key` of a malicious homoglyphic domain. + +Other metadata resolution through ENS that can be used alongside: +* `author address`: already mentionned above +* `contract address`: For app keys that would be designed to interact with a given ethereum contract (for instance app keys for a given token, if one desires to do so), other metadata fields could be used such as contract addresses. +* [TBD] + +In relation to the SLIP13 proposal mentionned above, one could think of alternative specifications that would use some certificate for authentication similar to https. + +### An Account gap limit standard for application controlled hd sub-path? + +If applications don't enumerate through their hd sub-path structure, we won't be able to restore `app keys` accounts by enumeration. However it has benefits to give total freedom to applications over the way they create accounts and use their sub-path. Also, it may be safe to assume that the part of the restoring procedure will be carried by the application itself and not by the wallets. The application will need a way to remember what accounts were derived for each user. + + +### Privacy and the funding trail + +If all an application needs to do with its keys is to sign messages and it does not require funding, then this EIP allows for privacy through the use of distinct keys for each application with a simple deterministic standard compatible across wallets. + +However if these application keys require funding, there can be trail and the use of app keys would not fully solve the privacy problem there. + +Mixers or anonymous ways of funding an ethereum address (ring signatures) along with this proposal would guarantee privacy. + +Even if privacy is not solved fully without this anonymous funding method, we still need a way to easily create and restore different accounts/addresses for each application + +## Backwards Compatibility + +From a wallet point of view, there does not seem to be incompatibities since these are separate accounts from those that were used previously by wallets and they are supposed to be used along-side in synergy. + +However, for applications that associated in some way their users to their main accounts ethereum addresses may want to reflect on if and how they would like to leverage the power offered by `app keys` to migrate to them and increase their user's privacy, security and potentially also user-flow. + + + +## Test Cases + +[TBD] + +Provide some examples of accounts derived from a given mnemonic, persona, application and application's custom subpath. + +## Implementation + +[WIP] +[See here for an early implementation of the HD methods](https://github.com/Bunjin/appKeys) + +## Example use cases + +* signing transactions without broadcasting them +https://github.com/MetaMask/metamask-extension/issues/3475 + +* token contract +https://github.com/ethereum/EIPs/issues/85 + +* default account for dapps +https://ethereum-magicians.org/t/default-accounts-for-dapps/904 + +* non wallet/crypto accounts +[EIP1581: Non-wallet usage of keys derived from BIP32 trees](https://eips.ethereum.org/EIPS/eip-1581) + +* state channel application + +* privacy solution + +* non custodian cross cryptocurrency exchange... + +## Acknowledgements +MetaMask team, Christian Lundkvist, Counterfactual team, Liam Horne, Erik Bryn, Richard Moore, Jeff Coleman. + + +## References + +### HD and mnemonics +#### BIPs +* [BIP32: Hierarchical Deterministic Wallets:](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) + +* [BIP39: Mnemonic code for generating deterministic keys:](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) + +* [BIP43: Purpose Field for Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0043.mediawiki) + +* [BIP44: Multi-Account Hierarchy for Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#Address_gap_limit) + +* [SLIP44: Registered coin types for BIP44](https://github.com/satoshilabs/slips/blob/master/slip-0044.md) + +* [Is there a comprehensive list of registered BIP43 purposes?](https://bitcoin.stackexchange.com/questions/60470/is-there-a-comprehensive-list-of-registered-bip43-purposes) + +#### Derivation path for eth +* [Issue 84](https://github.com/ethereum/EIPs/issues/84) + +* [Issue 85](https://github.com/ethereum/EIPs/issues/85) + +* [EIP600 Ethereum purpose allocation for Deterministic Wallets](https://eips.ethereum.org/EIPS/eip-600) + + +* [EIP601 Ethereum hierarchy for deterministic wallets](https://eips.ethereum.org/EIPS/eip-601) + +#### Accounts Privacy + + +### ENS +* [EIP137: Ethereum Domain Name Service - specification](https://eips.ethereum.org/EIPS/eip-137) + +* [EIP165: Standard Interface Detection](https://eips.ethereum.org/EIPS/eip-165) + +* [EIP634: Storage of text record in ENS](https://eips.ethereum.org/EIPS/eip-634) + +* [ENS docs about namehash:](http://docs.ens.domains/en/latest/implementers.html#namehash) + +### Previous proposals and discussions related to app keys +* [Meta: we should value privacy more](https://ethereum-magicians.org/t/meta-we-should-value-privacy-more/2475) + +* [EIP1102: Opt-in account exposure](https://eips.ethereum.org/EIPS/eip-1102) + +* [EIP1581: Non-wallet usage of keys derived from BIP-32 trees](https://eips.ethereum.org/EIPS/eip-1581) + +* [EIP1581: discussion](https://ethereum-magicians.org/t/non-wallet-usage-of-keys-derived-from-bip-32-trees/1817/4) + +* [SLIP13: Authentication using deterministic hierarchy](https://github.com/satoshilabs/slips/blob/master/slip-0013.md) + + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).