From 968969af75be4885b6a46e7b3f3b95ab1c795fc6 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Thu, 31 Oct 2019 08:49:40 -0600 Subject: [PATCH 01/47] Automatically merged updates to draft EIP(s) 1679 (#2332) 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-1679.md | 82 +++++++++--------------------------------------- 1 file changed, 15 insertions(+), 67 deletions(-) diff --git a/EIPS/eip-1679.md b/EIPS/eip-1679.md index f02b6bf2a8b996..8d323b1aa50886 100644 --- a/EIPS/eip-1679.md +++ b/EIPS/eip-1679.md @@ -16,78 +16,26 @@ This meta-EIP specifies the changes included in the Ethereum hardfork named Ista ## Specification - Codename: Istanbul -- Activation: TBD - -### Included EIPs - -- TBD - -### Accepted EIPs - -- [EIP-152](https://github.com/ethereum/EIPs/pull/2129): Add Blake2 compression function `F` precompile -- [EIP-1108](https://eips.ethereum.org/EIPS/eip-1108): Reduce alt_bn128 precompile gas costs -- [EIP-1344](https://eips.ethereum.org/EIPS/eip-1344): Add ChainID opcode -- [EIP-1884](https://eips.ethereum.org/EIPS/eip-1884): Repricing for trie-size-dependent opcodes -- [EIP-2028](https://eips.ethereum.org/EIPS/eip-2028): Calldata gas cost reduction -- [EIP-2200](https://github.com/ethereum/EIPs/pull/2200): Rebalance net-metered SSTORE gas cost with consideration of SLOAD gas cost change - -### Tentatively Accepted EIPs -#### Istanbul 2 -- [EIP-663](https://eips.ethereum.org/EIPS/eip-663): Unlimited SWAP and DUP instructions -- [EIP-1057](https://eips.ethereum.org/EIPS/eip-1057): ProgPoW, a Programmatic - Proof-of-Work - - There is a - [pending audit](https://medium.com/ethereum-cat-herders/progpow-audit-goals-expectations-75bb902a1f01), - above and beyond standard security considerations, that should be evaluated - prior to inclusion. -- [EIP-1380](https://eips.ethereum.org/EIPS/eip-1380): Reduced gas cost for call to self -- [EIP-1702](https://eips.ethereum.org/EIPS/eip-1702): Generalized account versioning scheme -- [EIP-1962](https://eips.ethereum.org/EIPS/eip-1962): EC arithmetic and pairings with runtime definitions - - replaces EIP-1829 -- [EIP-1985](https://eips.ethereum.org/EIPS/eip-1985): Sane limits for certain EVM parameters -- [EIP-2045](https://eips.ethereum.org/EIPS/eip-2045): Particle gas costs for EVM opcodes -- [EIP-2046](https://eips.ethereum.org/EIPS/eip-2046): Reduced gas cost for static calls made to precompiles +### Activation + - `Block >= 9,069,000` on the Ethereum mainnet + - `Block >= 6,485,846` on the Ropsten testnet + - `Block >= 14,111,141` on the Kovan testnet + - `Block >= 5,435,345` on the Rinkeby testnet + - `Block >= 1,561,651` on the Görli testnet -### Rejected/Withdrawn EIPs - -- [EIP-615](https://eips.ethereum.org/EIPS/eip-615): Subroutines and Static Jumps for the EVM - *Withdrawn* -- [EIP-1109](https://eips.ethereum.org/EIPS/eip-1109): PRECOMPILEDCALL opcode (Remove CALL costs for precompiled contracts) - - requirement of EIP-1962 -- [EIP-1283](https://eips.ethereum.org/EIPS/eip-1283): Net gas metering for SSTORE without dirty maps - - replaced by EIP-2200 -- [EIP-1352](https://eips.ethereum.org/EIPS/eip-1352): Specify restricted address range for precompiles/system contracts -- [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559): Fee market change for ETH 1.0 chain -- [EIP-1706](https://eips.ethereum.org/EIPS/eip-1706): Disable SSTORE with gasleft lower than call stipend - - replaced by EIP-2200 -- [EIP-1959](https://eips.ethereum.org/EIPS/eip-1959): New Opcode to check if a chainID is part of the history of chainIDs -- [EIP-1803](https://eips.ethereum.org/EIPS/eip-1803): Rename opcodes for clarity -- [EIP-1829](http://eips.ethereum.org/EIPS/eip-1829): Precompile for Elliptic Curve Linear Combinations - - replaced by EIP-1962 -- [EIP-1930](https://eips.ethereum.org/EIPS/eip-1930): CALLs with strict gas semantic. Revert if not enough gas available. -- [EIP-1965](https://eips.ethereum.org/EIPS/eip-1965): Method to check if a chainID is valid at a specific block Number -- [EIP-2014](https://eips.ethereum.org/EIPS/eip-2014): Extended State Oracle - *Withdrawn* -- [EIP-2025](https://eips.ethereum.org/EIPS/eip-2025): Funding Eth1.x with Developer Block Rewards - *Withdrawn* -- [EIP-2026](https://eips.ethereum.org/EIPS/eip-2026): State Rent H - Fixed Prepayment for accounts -- [EIP-2027](https://eips.ethereum.org/EIPS/eip-2027): State Rent C - Net contract size accounting -- [EIP-2029](https://eips.ethereum.org/EIPS/eip-2029): State Rent A - State counters contract - - requirement of EIP-2031 -- [EIP-2031](https://eips.ethereum.org/EIPS/eip-2031): State Rent B - Net transaction counter -- [EIP-2035](https://eips.ethereum.org/EIPS/eip-2035): Stateless Clients - Repricing SLOAD and SSTORE to pay for block proofs - -### Proposed EIPs - - -## Timeline - -* 2019-05-17 (Fri) hard deadline to accept proposals for "Istanbul" -* 2019-07-19 (Fri) soft deadline for major client implementations -* 2019-09-04 (Wed) projected date for testnet network upgrade (Ropsten, Görli, or ad-hoc testnet) -* 2019-10-16 (Wed) projected date for mainnet upgrade ("Istanbul") +### Included EIPs + - [EIP-152](https://eips.ethereum.org/EIPS/eip-152): Add Blake2 compression function `F` precompile + - [EIP-1108](https://eips.ethereum.org/EIPS/eip-1108): Reduce alt_bn128 precompile gas costs + - [EIP-1344](https://eips.ethereum.org/EIPS/eip-1344): Add ChainID opcode + - [EIP-1884](https://eips.ethereum.org/EIPS/eip-1884): Repricing for trie-size-dependent opcodes + - [EIP-2028](https://eips.ethereum.org/EIPS/eip-2028): Calldata gas cost reduction + - [EIP-2200](https://eips.ethereum.org/EIPS/eip-2200): Rebalance net-metered SSTORE gas cost with consideration of SLOAD gas cost change ## References -- [Core Dev call notes](https://github.com/ethereum/pm/issues/66#issuecomment-450840440) where timeline was proposed and accepted +1. Included EIPs were finalized in [All Core Devs Call #68](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2068.md) +2. https://medium.com/ethereum-cat-herders/istanbul-testnets-are-coming-53973bcea7df ## Copyright From 14f9b244330db83253e3d9b0cb3c442208f8dfb7 Mon Sep 17 00:00:00 2001 From: Ev Date: Thu, 31 Oct 2019 16:21:19 -0400 Subject: [PATCH 02/47] Fix: double curly braces causes syntax error on Liquid template system (#2340) --- EIPS/eip-225.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-225.md b/EIPS/eip-225.md index f224cb96c49761..a1630f29d574d8 100644 --- a/EIPS/eip-225.md +++ b/EIPS/eip-225.md @@ -211,7 +211,9 @@ tests := []struct { { // Single signer, no votes cast signers: []string{"A"}, - blocks: []block{{signer: "A"}}, + blocks: []block{ + {signer: "A"} + }, results: []string{"A"}, }, { // Single signer, voting to add two others (only accept first, second needs 2 votes) From 04fa20bbbe612d7d2052ca6fad0005a970cd34c1 Mon Sep 17 00:00:00 2001 From: Juliano Rizzo Date: Thu, 31 Oct 2019 21:06:52 -0300 Subject: [PATCH 03/47] EIP-1191: Change status to Last Call (#2234) * Update eip-1191.md * Adds Abstract and Motivation sections. * adds review-period-end --- EIPS/eip-1191.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-1191.md b/EIPS/eip-1191.md index 162db6ce8e2b03..4c247217c9c0dd 100644 --- a/EIPS/eip-1191.md +++ b/EIPS/eip-1191.md @@ -2,16 +2,24 @@ eip: 1191 title: Add chain id to mixed-case checksum address encoding author: Juliano Rizzo (@juli) -status: Draft +status: Last Call +review-period-end: 2019-11-18 type: Standards Track category: ERC created: 2018-03-18 requires: 55, 155 discussions-to: https://github.com/ethereum/EIPs/issues/1121 --- + ## Simple Summary This EIP extends EIP-55 by optionally adding a chain id defined by EIP-155 to the checksum calculation. +## Abstract +The EIP-55 was created to prevent users from losing funds by sending them to invalid addresses. This EIP extends EIP-55 to protect users from losing funds by sending them to addresses that are valid but that where obtained from a client of another network.For example, if this EIP is implemented, a wallet can alert the user that is trying to send funds to an Ethereum Testnet address from an Ethereum Mainnet wallet. + +## Motivation +The motivation of this proposal is to provide a mechanism to allow software to distinguish addresses from different Ethereum based networks. This proposal is necessary because Ethereum addresses are hashes of public keys and do not include any metadata. By extending the EIP-55 checksum algorithm it is possible to achieve this objective. + ## Specification Convert the address using the same algorithm defined by EIP-55 but if a registered chain id is provided, add it to the input of the hash function. If the chain id passed to the function belongs to a network that opted for using this checksum variant, prefix the address with the chain id and the `0x` separator before calculating the hash. Then convert the address to hexadecimal, but if the ith digit is a letter (ie. it's one of `abcdef`) print it in uppercase if the 4*ith bit of the calculated hash is 1 otherwise print it in lowercase. @@ -89,12 +97,14 @@ for chainid, cases in test_cases.items(): | RSK Testnet | 31 | Yes | ### Implementation Table -| Wallet | Adopted this EIP | Implementation | +| Project | Adopted this EIP | Implementation | |----------------|------------------| -------------- | | MyCrypto | Yes | [JavaScript](https://github.com/MyCryptoHQ/MyCrypto/blob/develop/common/utils/formatters.ts#L126) | | MyEtherWallet | Yes | [JavaScript](https://github.com/MyEtherWallet/MyEtherWallet/blob/73c4a24f8f67c655749ac990c5b62efd92a2b11a/src/helpers/addressUtils.js#L22) | | Ledger | Yes | [C](https://github.com/LedgerHQ/ledger-app-eth/blob/master/src_common/ethUtils.c#L203) | | Trezor | Yes | [Python](https://github.com/trezor/trezor-core/blob/270bf732121d004a4cd1ab129adaccf7346ff1db/src/apps/ethereum/get_address.py#L32) and [C](https://github.com/trezor/trezor-crypto/blob/4153e662b60a0d83c1be15150f18483a37e9092c/address.c#L62) | +| Web3.js | Yes | [JavaScript](https://github.com/ethereum/web3.js/blob/aaf26c8806bc9fb60cf6dcb6658104963c6c7fc7/packages/web3-utils/src/Utils.js#L140) | +| EthereumJS-util | Yes | [JavaScript](https://github.com/ethereumjs/ethereumjs-util/pull/204/commits/cdf0b3c996b05ac5b1f758f17ea9f9ed1847c1eb) | ## Copyright From ee0bf86e1909055fd2be35198f7f5965cddf2cce Mon Sep 17 00:00:00 2001 From: Dominic Letz Date: Fri, 1 Nov 2019 16:37:47 +0100 Subject: [PATCH 04/47] Added EIP-2330: EXTSLOAD (#2330) * Added EIP-2330: SLOAD2 and ABI * Renamed SLOAD2 to EXTSLOAD * Clarifying opcode specification --- EIPS/eip-2330.md | 71 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 EIPS/eip-2330.md diff --git a/EIPS/eip-2330.md b/EIPS/eip-2330.md new file mode 100644 index 00000000000000..db413b11db1884 --- /dev/null +++ b/EIPS/eip-2330.md @@ -0,0 +1,71 @@ +--- +eip: 2330 +title: EXTSLOAD opcode +author: Dominic Letz (@dominicletz) +discussions-to: https://ethereum-magicians.org/t/eip-2330-extsload-and-abi-for-lower-gas-cost-and-off-chain-apps/3733 +status: Draft +type: Standards Track +category: Core +created: 2019-10-29 +--- + + + +## Simple Summary + +A new `EXTSLOAD ` EVM opcode to read external contract storage data and corresponding allowing to build registry and token contracts that use less gas. + +## Abstract + +While any off-chain application can read all contract storage data of all contracts, this is not possible for deployed smart contracts themselves. These are bound to use contract calls for any interaction including reading data from other contracts. This EIP adds an EVM opcode to directly read external contract storage. + +## Motivation + +The gas cost when reading from registry style contract such as ERC-20s, ENS and other data contracts is very high, because they incur cross contract call cost, cost for ABI encoding, decoding and dispatching and finally loading the data. In many cases the underlying storage that is being queried is though just a simple mapping. In these cases a new `EXTSLOAD` call directly accessing the mapping in storage could not only **reduce the gas cost** of the interaction more than 10x, but also it would make the gas cost **predictable** for the reading contract. + +## Specification + +**Proposal** + +A new EVM instruction `EXTSLOAD (0x5c)` that works like `SLOAD (0x54)` but an additional parameter representing the contract that is to be read from. The gas cost of `EXTSLOAD` would be the sum of the [fee schedule G](https://ethereum.github.io/yellowpaper/paper.pdf) for G\[EXTCODE\](700) + G\[SLOAD\](800) = 1500 gas + +``` +EXTSLOAD (0x5c) +``` + +The `EXTSLOAD` instruction pops 2 values from the stack, first `contract` a contract address and then second `slot` a storage address within `contract`. As result `EXTSLOAD` pushes on the stack the value from the contract storage of `contract` at the storage `slot` address or `0` in case the account `contract` does not exist. + +**Example** + +An example assuming [further Solidity changes](https://github.com/ethereum/solidity/issues/7593) for illustration: + +```solidity +interface MemberList { + public fixed(@5) mapping(address => bool) members; +} +``` + +And a corresponding contract function that uses this member list. Similarly tokens or other registries could be implemented. + +```solidity +function membersOnly(address list, address member) { + MemberList ml = MemberList(list); + if (ml.members[client] == false) revert("Nonmember!"); +} +``` + +The call `ml.members[client]` here could let the Solidity compiler generate the normal map access logic but using the new `EXTSLOAD ` instructions to read from the `ml` contract storage instead of the local contract storage. + +## Backwards Compatibility +This change is fully backwards compatible since it adds a new instruction. + +## Test Cases + +Not started yet. + +## Implementation + +Not started yet. + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 833e35e7a417062fd805413ba22dd310bb074302 Mon Sep 17 00:00:00 2001 From: Juliano Rizzo Date: Sun, 3 Nov 2019 13:04:54 -0300 Subject: [PATCH 05/47] Automatically merged updates to draft EIP(s) 1191 (#2345) 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-1191.md | 73 +++++++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/EIPS/eip-1191.md b/EIPS/eip-1191.md index 4c247217c9c0dd..ab41d49050bb49 100644 --- a/EIPS/eip-1191.md +++ b/EIPS/eip-1191.md @@ -47,41 +47,50 @@ def eth_checksum_encode(addr, chainid=1): ``` ## Test Cases ```python -eth_mainnet= [ -'0x88021160C5C792225E4E5452585947470010289D', -'0x27b1fdb04752bbc536007a920d24acb045561c26', -'0x52908400098527886E0F7030069857D2E4169EE7', -'0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed', -'0x8617E340B3D01FA5F11F306F4090FD50E238070D', -'0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb', -'0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB', -'0xde709f2102306220921060314715629080e2fb77', -'0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359', +eth_mainnet = [ +"0x27b1fdb04752bbc536007a920d24acb045561c26", +"0x3599689E6292b81B2d85451025146515070129Bb", +"0x42712D45473476b98452f434e72461577D686318", +"0x52908400098527886E0F7030069857D2E4169EE7", +"0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed", +"0x6549f4939460DE12611948b3f82b88C3C8975323", +"0x66f9664f97F2b50F62D13eA064982f936dE76657", +"0x8617E340B3D01FA5F11F306F4090FD50E238070D", +"0x88021160C5C792225E4E5452585947470010289D", +"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb", +"0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB", +"0xde709f2102306220921060314715629080e2fb77", +"0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359", ] rsk_mainnet = [ -'0x6549F4939460DE12611948B3F82B88C3C8975323', -'0x27b1FdB04752BBc536007A920D24ACB045561c26', -'0x3599689E6292B81B2D85451025146515070129Bb', -'0x52908400098527886E0F7030069857D2E4169ee7', -'0x5aaEB6053f3e94c9b9a09f33669435E7ef1bEAeD', -'0x8617E340b3D01Fa5f11f306f4090fd50E238070D', -'0xD1220A0Cf47c7B9BE7a2e6ba89F429762E7B9adB', -'0xDBF03B407c01E7CD3cBea99509D93F8Dddc8C6FB', -'0xDe709F2102306220921060314715629080e2FB77', -'0xFb6916095cA1Df60bb79ce92cE3EA74c37c5d359', +"0x27b1FdB04752BBc536007A920D24ACB045561c26", +"0x3599689E6292B81B2D85451025146515070129Bb", +"0x42712D45473476B98452f434E72461577d686318", +"0x52908400098527886E0F7030069857D2E4169ee7", +"0x5aaEB6053f3e94c9b9a09f33669435E7ef1bEAeD", +"0x6549F4939460DE12611948B3F82B88C3C8975323", +"0x66F9664f97f2B50F62d13EA064982F936de76657", +"0x8617E340b3D01Fa5f11f306f4090fd50E238070D", +"0x88021160c5C792225E4E5452585947470010289d", +"0xD1220A0Cf47c7B9BE7a2e6ba89F429762E7B9adB", +"0xDBF03B407c01E7CD3cBea99509D93F8Dddc8C6FB", +"0xDe709F2102306220921060314715629080e2FB77", +"0xFb6916095cA1Df60bb79ce92cE3EA74c37c5d359", ] -rsk_testnet= [ -'0x42712D45473476B98452F434E72461577D686318', -'0x27B1FdB04752BbC536007a920D24acB045561C26', -'0x3599689e6292b81b2D85451025146515070129Bb', -'0x52908400098527886E0F7030069857D2e4169EE7', -'0x5aAeb6053F3e94c9b9A09F33669435E7EF1BEaEd', -'0x66f9664F97F2b50f62d13eA064982F936DE76657', -'0x8617e340b3D01fa5F11f306F4090Fd50e238070d', -'0xDE709F2102306220921060314715629080e2Fb77', -'0xFb6916095CA1dF60bb79CE92ce3Ea74C37c5D359', -'0xd1220a0CF47c7B9Be7A2E6Ba89f429762E7b9adB', -'0xdbF03B407C01E7cd3cbEa99509D93f8dDDc8C6fB', +rsk_testnet = [ +"0x27B1FdB04752BbC536007a920D24acB045561C26", +"0x3599689e6292b81b2D85451025146515070129Bb", +"0x42712D45473476B98452F434E72461577D686318", +"0x52908400098527886E0F7030069857D2e4169EE7", +"0x5aAeb6053F3e94c9b9A09F33669435E7EF1BEaEd", +"0x6549f4939460dE12611948b3f82b88C3c8975323", +"0x66f9664F97F2b50f62d13eA064982F936DE76657", +"0x8617e340b3D01fa5F11f306F4090Fd50e238070d", +"0x88021160c5C792225E4E5452585947470010289d", +"0xd1220a0CF47c7B9Be7A2E6Ba89f429762E7b9adB", +"0xdbF03B407C01E7cd3cbEa99509D93f8dDDc8C6fB", +"0xDE709F2102306220921060314715629080e2Fb77", +"0xFb6916095CA1dF60bb79CE92ce3Ea74C37c5D359", ] test_cases = {30 : rsk_mainnet, 31 : rsk_testnet, 1 : eth_mainnet} From db356bc1bfc8853da8945a2946c6d25ac7999849 Mon Sep 17 00:00:00 2001 From: Juliano Rizzo Date: Mon, 4 Nov 2019 10:34:07 -0300 Subject: [PATCH 06/47] Automatically merged updates to draft EIP(s) 1191 (#2347) 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-1191.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-1191.md b/EIPS/eip-1191.md index ab41d49050bb49..8487a9ba9ecca8 100644 --- a/EIPS/eip-1191.md +++ b/EIPS/eip-1191.md @@ -101,19 +101,20 @@ for chainid, cases in test_cases.items(): ## Adoption ### Adoption Table | Network | Chain id | Supports this EIP | -|--------------|----------|-------------------| +|-|-|-| | RSK Mainnet | 30 | Yes | | RSK Testnet | 31 | Yes | ### Implementation Table | Project | Adopted this EIP | Implementation | -|----------------|------------------| -------------- | +|-|-|-| | MyCrypto | Yes | [JavaScript](https://github.com/MyCryptoHQ/MyCrypto/blob/develop/common/utils/formatters.ts#L126) | | MyEtherWallet | Yes | [JavaScript](https://github.com/MyEtherWallet/MyEtherWallet/blob/73c4a24f8f67c655749ac990c5b62efd92a2b11a/src/helpers/addressUtils.js#L22) | | Ledger | Yes | [C](https://github.com/LedgerHQ/ledger-app-eth/blob/master/src_common/ethUtils.c#L203) | | Trezor | Yes | [Python](https://github.com/trezor/trezor-core/blob/270bf732121d004a4cd1ab129adaccf7346ff1db/src/apps/ethereum/get_address.py#L32) and [C](https://github.com/trezor/trezor-crypto/blob/4153e662b60a0d83c1be15150f18483a37e9092c/address.c#L62) | | Web3.js | Yes | [JavaScript](https://github.com/ethereum/web3.js/blob/aaf26c8806bc9fb60cf6dcb6658104963c6c7fc7/packages/web3-utils/src/Utils.js#L140) | | EthereumJS-util | Yes | [JavaScript](https://github.com/ethereumjs/ethereumjs-util/pull/204/commits/cdf0b3c996b05ac5b1f758f17ea9f9ed1847c1eb) | +| ENS address-encoder | Yes | [TypeScript](https://github.com/ensdomains/address-encoder/commit/5bf53b13fa014646ea28c9e5f937361dc9b40590) | ## Copyright From 7c7d8e1ac898dd56346f56e402760d6a88682252 Mon Sep 17 00:00:00 2001 From: Juliano Rizzo Date: Mon, 4 Nov 2019 16:40:26 -0300 Subject: [PATCH 07/47] Automatically merged updates to draft EIP(s) 1191 (#2351) 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-1191.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/EIPS/eip-1191.md b/EIPS/eip-1191.md index 8487a9ba9ecca8..e5939234d118c3 100644 --- a/EIPS/eip-1191.md +++ b/EIPS/eip-1191.md @@ -100,12 +100,14 @@ for chainid, cases in test_cases.items(): ``` ## Adoption ### Adoption Table + | Network | Chain id | Supports this EIP | |-|-|-| | RSK Mainnet | 30 | Yes | | RSK Testnet | 31 | Yes | ### Implementation Table + | Project | Adopted this EIP | Implementation | |-|-|-| | MyCrypto | Yes | [JavaScript](https://github.com/MyCryptoHQ/MyCrypto/blob/develop/common/utils/formatters.ts#L126) | From 2c12dfd97939e0c9b5ece1747e15ddc7b112469e Mon Sep 17 00:00:00 2001 From: Ev Date: Mon, 4 Nov 2019 18:49:08 -0500 Subject: [PATCH 08/47] Updates block number for rinkeby (#2352) --- EIPS/eip-1716.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-1716.md b/EIPS/eip-1716.md index adda1b4e4f7571..eca11e0c84b78c 100644 --- a/EIPS/eip-1716.md +++ b/EIPS/eip-1716.md @@ -20,7 +20,7 @@ This meta-EIP specifies the changes included in the Ethereum hardfork that remov - `Block >= 7_280_000` on the Ethereum mainnet - `Block >= 4_939_394` on the Ropsten testnet - `Block >= 10_255_201` on the Kovan testnet - - `Block >= 9_999_999` on the Rinkeby testnet + - `Block >= 4_321_234` on the Rinkeby testnet - `Block >= 0` on the Görli testnet - Removed EIPs: - [EIP 1283](./eip-1283.md): Net gas metering for SSTORE without dirty maps From 8350c1f49831908e2d2f16a6dbe1b6f7b901ffd3 Mon Sep 17 00:00:00 2001 From: Sam Richards Date: Mon, 4 Nov 2019 17:27:38 -0800 Subject: [PATCH 09/47] Update meta tags (#2325) * Add Matomo tracking * Add development instructions to README * Add dynamic metadata for EIP pages * Escape title strings * Remove Matomo * Use variables from _config.yaml in head.html * Omit Jekyll version from header * Also use twitter_username from _config.yml --- README.md | 38 ++++++++++++++++++++++++++++++++++++ _config.yml | 2 +- _includes/head.html | 45 +++++++++++++++++++++++++++++++++++++++++++ assets/css/style.scss | 5 +++++ 4 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 _includes/head.html create mode 100644 assets/css/style.scss diff --git a/README.md b/README.md index 1081864a2e2b27..75b0d57f27463b 100644 --- a/README.md +++ b/README.md @@ -49,3 +49,41 @@ eip_validator # Automerger The EIP repository contains an "auto merge" feature to ease the workload for EIP editors. If a change is made via a PR to a draft EIP, then the authors of the EIP can Github approve the change to have it auto-merged by the [eip-automerger](https://github.com/eip-automerger/automerger) bot. + +# Local development + +## Prerequisites + +1. Open Terminal. + +2. Check whether you have Ruby 2.1.0 or higher installed: + +``` +$ ruby --version +``` + +3. If you don't have Ruby installed, install Ruby 2.1.0 or higher. + +4. Install Bundler: + +``` +$ gem install bundler +``` + +5. Install dependencies: + +``` +$ bundle install +``` + +## Build your local Jekyll site + +1. Bundle assets and start the server: + +``` +$ bundle exec jekyll serve +``` + +2. Preview your local Jekyll site in your web browser at `http://localhost:4000`. + +More information on Jekyll and Github pages [here](https://help.github.com/en/enterprise/2.14/user/articles/setting-up-your-github-pages-site-locally-with-jekyll). diff --git a/_config.yml b/_config.yml index cbb7de1b21e085..d37dd58530d843 100644 --- a/_config.yml +++ b/_config.yml @@ -18,7 +18,7 @@ description: >- Ethereum Improvement Proposals (EIPs) describe standards for the Ethereum platform, including core protocol specifications, client APIs, and contract standards. -url: "http://eips.ethereum.org" +url: "https://eips.ethereum.org" twitter_username: ethereum github_username: ethereum header_pages: diff --git a/_includes/head.html b/_includes/head.html new file mode 100644 index 00000000000000..18790668c28e97 --- /dev/null +++ b/_includes/head.html @@ -0,0 +1,45 @@ + + + + + {% if page.layout == "eip" %} + EIP {{ page.eip }}: {{ page.title | escape }} + + + + + {% else %} + {{ page.title | escape }} | {{site.title}} + + + + + {% endif %} + + + + + + + + + + {%- feed_meta -%} + diff --git a/assets/css/style.scss b/assets/css/style.scss new file mode 100644 index 00000000000000..5654c2bbb956ee --- /dev/null +++ b/assets/css/style.scss @@ -0,0 +1,5 @@ +--- +# Only the main Sass file needs front matter (the dashes are enough) +--- + +@import "minima"; \ No newline at end of file From f69654a0e07969af9f991097be1db5d2417df9ed Mon Sep 17 00:00:00 2001 From: William Entriken Date: Tue, 5 Nov 2019 05:49:49 -0500 Subject: [PATCH 10/47] Bounce EIP-615 to draft (#2353) --- EIPS/eip-615.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/EIPS/eip-615.md b/EIPS/eip-615.md index 17caf69b381a95..9022111ff81f8e 100644 --- a/EIPS/eip-615.md +++ b/EIPS/eip-615.md @@ -1,8 +1,7 @@ --- eip: 615 title: Subroutines and Static Jumps for the EVM -status: Last Call -review-period-end: 2019-07-29 +status: Draft type: Standards Track category: Core author: Greg Colvin , Brooklyn Zelenka (@expede) , Paweł Bylica (@chfast), Christian Reitwiessner(@chriseth) From 361c33c62a6277f8a13e3861bb14422424c50ce9 Mon Sep 17 00:00:00 2001 From: Dominic Letz Date: Tue, 5 Nov 2019 12:15:04 +0100 Subject: [PATCH 11/47] Automatically merged updates to draft EIP(s) 2330 (#2354) 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-2330.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-2330.md b/EIPS/eip-2330.md index db413b11db1884..0c0655da4bfd7d 100644 --- a/EIPS/eip-2330.md +++ b/EIPS/eip-2330.md @@ -65,7 +65,7 @@ Not started yet. ## Implementation -Not started yet. +[Aleth Pull Request](https://github.com/ethereum/aleth/pull/5805) ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From a8d19c58e8189d99b8f55465f076e5a84e020cef Mon Sep 17 00:00:00 2001 From: MrChico Date: Tue, 5 Nov 2019 14:45:54 +0100 Subject: [PATCH 12/47] Draft EIP: BEGINDATA opcode (#2327) * Draft EIP: BEGINDATA opcode * EIP-BEGINDATA: Add discussions-to link * use eip number 2327 * Update EIPS/eip-2327.md Co-Authored-By: Danno Ferrin * eip-2327: Update formatting and clarify CODECOPY behaviour --- EIPS/eip-2327.md | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 EIPS/eip-2327.md diff --git a/EIPS/eip-2327.md b/EIPS/eip-2327.md new file mode 100644 index 00000000000000..e18534f3ed4745 --- /dev/null +++ b/EIPS/eip-2327.md @@ -0,0 +1,49 @@ +--- +eip: 2327 +title: BEGINDATA opcode +author: Martin Lundfall (@MrChico) +discussions-to: https://ethereum-magicians.org/t/new-opcode-begindata/3727 +status: Draft +type: Standards Track +category: Core +created: 2019-10-28 +--- + +## Simple Summary + +Introduces a new opcode `BEGINDATA`, which indicates that the remaining bytes of the contract should be regarded as data rather than contract code. + +## Abstract + +It is common for smart contracts to efficiently store data directly in the contract bytecode. Examples include constant variables, compiler metadata and the contract runtime during the init phase. Currently, such data is not distinguished from normal bytecode and is still being analysed for `JUMPDEST`s by EVM interpreters. This EIP introduces a new opcode `BEGINDATA` at byte `0xb6`, which marks the remainding bytecode as data, indicating to EVM interpreters, static analysis tools and chain explorers that the remaining bytes do not represent opcodes. + +## Motivation + +The `BEGINDATA` opcode has been suggested before as part of the EIP `Subroutines and Static Jumps for the EVM` [EIP-615](https://eips.ethereum.org/EIPS/eip-615) as a way to determine the position of jumptables in contract bytecode. It is here introduced in its own right in order to exclude data from the `JUMPDEST` analysis of contracts, making it impossible to jump to data. This makes it easier for static analysis tools to analyse contracts, allows disassemblers, chain explorers and debuggers to not display data as a mess of INVALID opcodes and may even provide a marginal improvement in performance. Additionally, it paves the way for suggestions such as [EIP 1712](https://github.com/ethereum/EIPs/pull/1712) to disallow unused opcodes, jumptables [EIP-615](https://eips.ethereum.org/EIPS/eip-615) and speculative proposals to disallow for deployment of contracts with stack usage violations. + +## Specification + +While computing the valid `JUMPDEST`s of a contract, halt analysis if `BEGINDATA` is encountered. A `JUMP` to a value higher than the `PC` value of `BEGINDATA` should throw with a `BAD_JUMP_DESTINATION` error. Bytes past `BEGINDATA` remain accessible via `CODECOPY` and `EXTCODECOPY`. +If `BEGINDATA` is encountered during contract execution, it has the same semantics as `STOP`. It uses 0 gas. + +## Rationale + +The byte `0xb6` was chosen to align with [EIP-615](https://eips.ethereum.org/EIPS/eip-615). +The choice to `STOP` if `BEGINDATA` is encountered is somewhat arbitrary. An alternative would be to be to abort the execution with an out-of-gas error. + +## Backwards Compatibility + +The proposal will not change any existing contracts unless their current behaviour relies upon the usage of unused opcodes. + +## Test Cases + +Test cases should include: +1) A contract which jumps to a destination `X`, where `X` has a pc value higher than the `BEGINDATA` opcode, and the byte at `X` is `0x5b`. This should fail with a `BAD_JUMP_DESTINATION` error. +2) A contract which encounters the `BEGINDATA` opcode (should stop executing the current call frame) + +## Implementation + +Not yet. + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 98c541f1e0825877f61ad70b00456053a1dc7cce Mon Sep 17 00:00:00 2001 From: Antonio Salazar Cardozo Date: Tue, 5 Nov 2019 05:56:34 -0800 Subject: [PATCH 13/47] Update EIP-1108 to reflect Final status (#2295) Since the Istanbul meta-EIP has EIP-1108 listed for the hardfork and the implementation tracker lists everyone as having merged, this EIP seems reasonable to move to Final status. --- EIPS/eip-1108.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-1108.md b/EIPS/eip-1108.md index ce6438e3a66202..661097a7244559 100644 --- a/EIPS/eip-1108.md +++ b/EIPS/eip-1108.md @@ -3,7 +3,7 @@ eip: 1108 title: Reduce alt_bn128 precompile gas costs author: Antonio Salazar Cardozo (@shadowfiend), Zachary Williamson (@zac-williamson) discussions-to: https://ethereum-magicians.org/t/eip-1108-reduce-alt-bn128-precompile-gas-costs/3206 -status: Draft +status: Final type: Standards Track category: Core created: 2018-05-21 From b174a81d3a6915bebed2c96acc1d504b70e79ee0 Mon Sep 17 00:00:00 2001 From: Matt Luongo Date: Tue, 5 Nov 2019 08:57:24 -0500 Subject: [PATCH 14/47] Finalize EIP-152 (#2297) --- EIPS/eip-152.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index 62ff0e1d43ccdf..91a11d2d20e5db 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -3,7 +3,7 @@ eip: 152 title: Add BLAKE2 compression function `F` precompile author: Tjaden Hess , Matt Luongo (@mhluongo), Piotr Dyraga (@pdyraga), James Hancock (@MadeOfTin) discussions-to: https://github.com/ethereum/EIPs/issues/152 -status: Draft +status: Final type: Standards Track category: Core created: 2016-10-04 From 9b7274e97f4a627ff5cf3c4cbc4181783b861c53 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Tue, 5 Nov 2019 14:58:36 +0100 Subject: [PATCH 15/47] make eip 1884 final (#2296) --- EIPS/eip-1884.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-1884.md b/EIPS/eip-1884.md index 163062d8d85f39..200f2759996930 100644 --- a/EIPS/eip-1884.md +++ b/EIPS/eip-1884.md @@ -5,7 +5,7 @@ author: Martin Holst Swende (@holiman) type: Standards Track category: Core discussions-to: https://ethereum-magicians.org/t/opcode-repricing/3024 -status: Draft +status: Final created: 2019-03-28 requires: 150, 1052 --- From 9f133839b36b823fa658051ad433f25d2521d50d Mon Sep 17 00:00:00 2001 From: Bryant Eisenbach Date: Tue, 5 Nov 2019 08:59:51 -0500 Subject: [PATCH 16/47] EIP-1344: Added link to test PR (#2268) --- EIPS/eip-1344.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-1344.md b/EIPS/eip-1344.md index 4c42b51a114dc2..3e39cf9db4bd8d 100644 --- a/EIPS/eip-1344.md +++ b/EIPS/eip-1344.md @@ -40,7 +40,7 @@ This EIP is fully backwards compatible with all chains which implement EIP-155 c This was previously suggested as part of [EIP901](https://github.com/ethereum/EIPs/issues/901). ## Test Cases -TBD +Test Cases added to [ethereum/tests](https://github.com/ethereum/tests/pull/627) ## Implementation A reference implementation for the Trinity Python client is [here](https://github.com/ethereum/py-evm/pull/1803). From 4459af0ef16774ec073e4e68658e714414bc603f Mon Sep 17 00:00:00 2001 From: Juliano Rizzo Date: Tue, 5 Nov 2019 22:39:20 -0300 Subject: [PATCH 17/47] Automatically merged updates to draft EIP(s) 1191 (#2355) 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-1191.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/EIPS/eip-1191.md b/EIPS/eip-1191.md index e5939234d118c3..3934e8649a23fc 100644 --- a/EIPS/eip-1191.md +++ b/EIPS/eip-1191.md @@ -26,6 +26,7 @@ Convert the address using the same algorithm defined by EIP-55 but if a register ## Rationale Benefits: - By means of a minimal code change on existing libraries, users are protected from losing funds by mixing addresses of different Ethereum based networks. + ## Backwards Compatibility This proposal is fully backward compatible. The checksum calculation is changed only for new networks that choose to adopt this EIP and add their chain numbers to the Adoption Table included in this document. @@ -45,6 +46,7 @@ def eth_checksum_encode(addr, chainid=1): out = addr[:2] + ''.join([c.upper() if int(a,16) >= 8 else c for c,a in aggregate]) return out ``` + ## Test Cases ```python eth_mainnet = [ @@ -99,6 +101,7 @@ for chainid, cases in test_cases.items(): assert ( addr == eth_checksum_encode(addr,chainid) ) ``` ## Adoption + ### Adoption Table | Network | Chain id | Supports this EIP | From cc5b1ac2557b6c6d2607ef5d6a93689a5e49e3dc Mon Sep 17 00:00:00 2001 From: Dominic Letz Date: Wed, 6 Nov 2019 12:50:31 +0100 Subject: [PATCH 18/47] Automatically merged updates to draft EIP(s) 2330 (#2359) 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-2330.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-2330.md b/EIPS/eip-2330.md index 0c0655da4bfd7d..6442268a1f35f5 100644 --- a/EIPS/eip-2330.md +++ b/EIPS/eip-2330.md @@ -1,7 +1,7 @@ --- eip: 2330 title: EXTSLOAD opcode -author: Dominic Letz (@dominicletz) +author: Dominic Letz (@dominicletz), Santiago Palladino (@spalladino) discussions-to: https://ethereum-magicians.org/t/eip-2330-extsload-and-abi-for-lower-gas-cost-and-off-chain-apps/3733 status: Draft type: Standards Track @@ -21,7 +21,7 @@ While any off-chain application can read all contract storage data of all contra ## Motivation -The gas cost when reading from registry style contract such as ERC-20s, ENS and other data contracts is very high, because they incur cross contract call cost, cost for ABI encoding, decoding and dispatching and finally loading the data. In many cases the underlying storage that is being queried is though just a simple mapping. In these cases a new `EXTSLOAD` call directly accessing the mapping in storage could not only **reduce the gas cost** of the interaction more than 10x, but also it would make the gas cost **predictable** for the reading contract. +The gas cost when reading from registry style contract such as ERC-20s, ENS and other data contracts is very high, because they incur cross contract call cost, cost for ABI encoding, decoding and dispatching and finally loading the data. In many cases the underlying storage that is being queried is though just a simple mapping. In these cases a new `EXTSLOAD` call directly accessing the mapping in storage could not only **reduce the gas cost** of the interaction more than 10x, but also it would make the gas cost **predictable** for the reading contract. Furthermore with the use of the existing `EXTCODEHASH` an external contracts implementation can be verified and allows `EXTSLOAD` to make deterministic reads even from third-party smart contracts. ## Specification From 69355e6dc6221aa7ff22dff3c1803018976c93fd Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Thu, 7 Nov 2019 22:12:29 +0100 Subject: [PATCH 19/47] Automatically merged updates to draft EIP(s) 1702 (#2363) 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-1702.md | 52 +++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/EIPS/eip-1702.md b/EIPS/eip-1702.md index f2b7501b12d386..db69cfaf15e3f9 100644 --- a/EIPS/eip-1702.md +++ b/EIPS/eip-1702.md @@ -116,7 +116,7 @@ with `version` field being `0`. ### Additional Fields in Account State RLP In the future we may need to associate more information into an -account, and we already have some EIPs that define new additional +account, and we already have some EIP/ECIPs that define new additional fields in the account state RLP. In this section, we define the parsing strategy when additional fields are added. @@ -140,22 +140,22 @@ improves functionality of base layer account versioning. Note that this section is provided only for documentation purpose. When "enabling EIP-1702", those extensions should not be -enabled unless the extension EIP is also included. +enabled unless the extension specification is also included. -- [EIP-2138: Account Versioning Extension for Contract Creation - Transaction](https://github.com/ethereum/EIPs/pull/2138) -- [EIP-2139: Account Versioning Extension for CREATE and - CREATE2](https://github.com/ethereum/EIPs/pull/2139) +- [44-VERTXN: Account Versioning Extension for Contract Creation + Transaction](https://specs.that.world/44-vertxn/) +- [45-VEROP: Account Versioning Extension for CREATE and + CREATE2](https://specs.that.world/45-verop/) ## Usage Template -This section defines how other EIPs might use this account versioning -EIP. Note that currently we only define the usage template for base -layer. +This section defines how other EIP/ECIPs might use this account +versioning specification. Note that currently we only define the usage +template for base layer. -Account versioning is usually applied directly to a hard fork meta -EIP. EIPs in the hard fork are grouped by the virtual machine type, -for example, EVM and eWASM. For each of them, we define: +Account versioning is usually applied directly to a hard fork +meta. EIP/ECIPs in the hard fork are grouped by the virtual machine +type, for example, EVM and eWASM. For each of them, we define: * **Version**: a non-zero scalar less than `2^256` that uniquely identifies this version. Note that it does not need to be @@ -168,7 +168,7 @@ for example, EVM and eWASM. For each of them, we define: * **Features**: all additional features that are enabled upon this version. -If a meta EIP includes EIPs that provide additional account state RLP +If a meta EIP/ECIP includes EIP/ECIPs that provide additional account state RLP fields, we also define: * **Account fields**: all account fields up to the end of this meta @@ -187,16 +187,18 @@ state. The design above gets account versioning by making the contract needed to be provided by contract creation transaction, and there is no restrictions on formats of code for any version. If we want to support multiple newest VMs (for example, EVM and WebAssembly running -together), then this will requires extensions such as EIP-2138 and -EIP-2139. +together), then this will requires extensions such as 44-VERTXN and +45-VEROP. Alternatively, account versioning can also be done through: -* **EIP-1707** and **EIP-1712**: This makes an account's versioning - soly dependent on its code header prefix. If with only EIP-1707, it - is not possible to certify any code is valid, because current VM - allows treating code as data. This can be fixed by EIP-1712, but the - drawback is that it's potentially backward incompatible. +* **[26-VER](https://specs.that.world/26-ver/)** and + **[40-UNUSED](https://specs.that.world/40-unused/)**: This makes an + account's versioning soly dependent on its code header prefix. If + with only 26-VER, it is not possible to certify any code is valid, + because current VM allows treating code as data. This can be fixed + by 40-UNUSED, but the drawback is that it's potentially backward + incompatible. * **EIP-1891**: Instead of writing version field into account RLP state, we write it in a separate contract. This can accomplish the same thing as this EIP and potentially reduces code complexity, but @@ -229,6 +231,16 @@ defined as above. To be added. +## References + +The source of this specification can be found at +[43-VER](https://specs.that.world/43-ver/). This specification is +also realized in: + +* Ethereum Classic Improvement Proposals as + [ECIP-1040](https://ecips.ethereumclassic.org/ECIPs/ecip-1040). + + ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 598df5a75e69b4ef65c29a6dd2191f3497a4d9cb Mon Sep 17 00:00:00 2001 From: William Entriken Date: Tue, 12 Nov 2019 12:09:17 -0500 Subject: [PATCH 20/47] Fix fences (#2373) --- EIPS/eip-1077.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-1077.md b/EIPS/eip-1077.md index bd509879b54735..73a7800df7919f 100644 --- a/EIPS/eip-1077.md +++ b/EIPS/eip-1077.md @@ -51,7 +51,7 @@ In order to be compliant, the transaction **MUST** request to sign a messageHash The fields **MUST** be concatenated in this order: -``` +```solidity keccak256( byte(0x19), byte(0), From 4b6f52eb0545a564f41784e0c4f6b36753c97133 Mon Sep 17 00:00:00 2001 From: Vincent Date: Tue, 12 Nov 2019 19:58:54 +0100 Subject: [PATCH 21/47] Automatically merged updates to draft EIP(s) 1775 (#2376) 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-1775.md | 501 ++++------------------------------------------- 1 file changed, 42 insertions(+), 459 deletions(-) diff --git a/EIPS/eip-1775.md b/EIPS/eip-1775.md index ee340c2d4cc4bc..b5aec0e9163598 100644 --- a/EIPS/eip-1775.md +++ b/EIPS/eip-1775.md @@ -1,7 +1,7 @@ --- eip: 1775 title: App Keys, application specific wallet accounts -author: Vincent Eli (@Bunjin), Dan Finlay (@DanFinlay) +author: Vincent Eli (@Bunjin), Dan Finlay (@DanFinlay), Erik Marks (@rekmarks) discussions-to: https://ethereum-magicians.org/t/eip-erc-app-keys-application-specific-wallet-accounts/2742 status: Draft type: Standards Track @@ -26,7 +26,8 @@ In a wallet, an user often holds most of her funds in her main accounts. These a 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 Hierarchical 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. +In this EIP, we provide a proposal on how to uniquely identify and authenticate each application, how to derive a master account (or app key) unique for the domain from an user private key (her root private key or any other private key of an account derived or not from her root one). This EIP aims at becoming a standard on how to derive keys specific to each application that can be regenerated from scratch without further input from the user if she restores her wallet and uses again the application for which this key was derived. +These app keys can then be endowed a different set of permissions (through the requestPermission model introduced in EIP [EIP2255](https://eips.ethereum.org/EIPS/eip-2255)). This will potentially allow an user to partly trust some apps to perform some crypto operations on their behalf without compromising any security with respect to her main accounts. ## Motivation @@ -51,60 +52,30 @@ These new app keys can permit to give more power and flexibility to the crypto a ### 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. +An app is a website (or other) that would like to request from a wallet to access a cryptographic key specifically derived for this usage. It can be any form of cryptography/identity relying application, Ethereum based 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. +Once connected to a wallet, an application can request to access an account derived exclusively for that application using the following algorithm. -### Applications' HD path +### Private App Key generation algorithm -Using the BIP32 and BIP43 standards, we propose to use the following HD path for each app keys: +We now propose an algorithm to generate keys specific to each application using only the user's master seed entropy, the BIP44 index of one of this user's accounts and the application unique identifier. This allows to generate application keys that: +- are uniquely defined, with respect to the account that the user selected to generate these keys, +- and thus can be isolated when changing the user account, allowing persona management (see next section), +- are specific to each application, +- can be fully restored from the user master seed mnemonic and the applications' names. -`m / [standardized Path Beginning]' / [persona path]' / [application uniquely assigned path]' / [app's custom subpath]` +#### Using different accounts as personas -Where: +We allow the user to span a different set of application keys by changing the account selected to generate each key. Thus from the same master seed mnemonic, an user can use each of her account index to generate an alternative set of application keys. One can describe this as using different personas. +This would allow potentially an user to fully isolate her interaction with a given app across 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 accounts to generate these. The app or domain, will not be aware that it is the same person and mnemonic behind both. +If an application interacts with several main accounts of an user, one of these accounts, a master account can be used as persona and the others as auxiliary accounts. -`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). +#### Applications' Unique Identifiers -`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 across 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. +Each application is uniquely defined and authenticated by its name, a domain string. It can be a Domain Name Service (DNS) name or, in the future, an Ethereum Name Service (ENS) name or IPFS hash. 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 convenience and reference. ``` @@ -112,265 +83,33 @@ 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. +#### Private App Key generation algorithm -### Applications' authentication +Using the domain name of an application, we generate a private key for each application (and per main account) : -If the application is using a DNS name then we simply authenticate the application by using the url of the loaded browser webpage. +`const appKeyPrivKey = ethUtil.keccak(privKey + originString, 256)` -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. +where privKey is the private key of the user's account selected to span the application key and originString represents the origin url from which the permission call to access the application key is originated from. -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. +This is exposed as an RPC method to allow any domain to request its own app key associated with the current requested account (if available): ``` -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. +const appKey = await provider.send({ + method: 'wallet_getAppKeyForAccount', + params: [address1] +}); ``` -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. +See here for an implementation: +https://github.com/MetaMask/eth-simple-keyring/blob/master/index.js#L169 -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 homogeneous decomposition: - -Equal length 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 written 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 children 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`: +requestPermission can be extended in the future introducing new signing methods and more. -`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 @@ -381,151 +120,12 @@ Personas are known only by the user and its wallet, application' UID based 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. +### Sharing application keys across domains: +While this does not explicit cover cases of sharing these app keys between pages on its own, this need can be met by composition: -### 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 across 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 children 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 across 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 length 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 parameter 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 mentioned 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 mentioned 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. +Since a domain would get a unique key, and because domains can intercommunicate, one domain (app) could request another domain (signer) to perform its cryptographic operation on some data, with its appKey as a seed, potentially allowing new signing strategies to be added as easily as new websites. +This could also pass it to domains that are loading specific signing strategies. This may sound dangerous at first, but if a domain represents a static hash of a trusted cryptographic function implementation, it could be as safe as calling any audited internal dependency. ### Privacy and the funding trail @@ -539,22 +139,21 @@ Even if privacy is not solved fully without this anonymous funding method, we st ## 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. +From a wallet point of view, there does not seem to be compatibility issues 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. +However, for applications that associated in some way their users to their main accounts may want to reflect on if and how they would like to leverage the power offered by `app keys` to migrate to them and leverage on the new app designs they permit. +## Implementation + +Here is an early implementation of app keys for standard (non HW) MetaMask accounts. +https://github.com/MetaMask/eth-simple-keyring/blob/6d12bd9d73adcccbe0b0c7e32a99d279085e2934/index.js#L139-L152 -## Test Cases - -[TBD] +See here for a fork of metamask that implements app keys along side plugins: +https://github.com/MetaMask/metamask-snaps-beta +https://github.com/MetaMask/metamask-snaps-beta/wiki/Plugin-API -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 @@ -588,13 +187,8 @@ MetaMask team, Christian Lundkvist, Counterfactual team, Liam Horne, Erik Bryn, * [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) @@ -606,17 +200,6 @@ MetaMask team, Christian Lundkvist, Counterfactual team, Liam Horne, Erik Bryn, * [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) From 5b37d7c22f023f33843aa792bfba5fd5b2c1fba2 Mon Sep 17 00:00:00 2001 From: Vincent Date: Tue, 12 Nov 2019 21:26:53 +0100 Subject: [PATCH 22/47] Automatically merged updates to draft EIP(s) 1775 (#2377) 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-1775.md | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/EIPS/eip-1775.md b/EIPS/eip-1775.md index b5aec0e9163598..fb6f63b016f512 100644 --- a/EIPS/eip-1775.md +++ b/EIPS/eip-1775.md @@ -7,7 +7,6 @@ status: Draft type: Standards Track category: ERC created: 2019-02-20 -requires: 137 --- @@ -104,21 +103,8 @@ See here for an implementation: https://github.com/MetaMask/eth-simple-keyring/blob/master/index.js#L169 -## 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. - -requestPermission can be extended in the future introducing new signing methods and more. - - ## 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. ### Sharing application keys across domains: While this does not explicit cover cases of sharing these app keys between pages on its own, this need can be met by composition: @@ -149,7 +135,7 @@ However, for applications that associated in some way their users to their main Here is an early implementation of app keys for standard (non HW) MetaMask accounts. https://github.com/MetaMask/eth-simple-keyring/blob/6d12bd9d73adcccbe0b0c7e32a99d279085e2934/index.js#L139-L152 -See here for a fork of metamask that implements app keys along side plugins: +See here for a fork of MetaMask that implements app keys along side plugins: https://github.com/MetaMask/metamask-snaps-beta https://github.com/MetaMask/metamask-snaps-beta/wiki/Plugin-API From 8873ddf8e2c9f470c758274fea1b2e844f75bd9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Wed, 13 Nov 2019 14:31:43 +0200 Subject: [PATCH 23/47] EIP-2364: eth/64: forkid-extended protocol handshake (#2364) * EIP-2364: eth/64: forkid-extended protocol handshake * EIP-2364: fix review issues from Martin Co-Authored-By: Martin Holst Swende * EIP-2364: Add reference to current eth/63 spec Co-Authored-By: Alex Beregszaszi * EIP-2364: Fix title to make the web generator happy Co-Authored-By: Alex Beregszaszi --- EIPS/eip-2364.md | 75 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 EIPS/eip-2364.md diff --git a/EIPS/eip-2364.md b/EIPS/eip-2364.md new file mode 100644 index 00000000000000..88654d3d9d8ad5 --- /dev/null +++ b/EIPS/eip-2364.md @@ -0,0 +1,75 @@ +--- +eip: 2364 +title: "eth/64: forkid-extended protocol handshake" +author: Péter Szilágyi +discussions-to: https://github.com/ethereum/EIPs/issues/2365 +status: Draft +type: Standards Track +category: Networking +created: 2019-11-08 +requires: 2124 +--- + +## Abstract + +The [`forkid` (EIP-2124)](https://eips.ethereum.org/EIPS/eip-2124) was designed to permit two Ethereum nodes to quickly and cheaply decide if they are compatible or not, not only at a genesis/networking level, but also from the perspective of the currently passed network updates (i.e. forks). + +[EIP-2124](https://eips.ethereum.org/EIPS/eip-2124) only defines how the `forkid` is calculated and validated, but does not specify how the `forkid` should be exchanged between peers. This EIP specifies the inclusion of the `forkid` as a new field in the Ethereum wire protocol (`eth`) handshake (releasing a new version, `eth/64`). + +By cross-validating `forkid` during the handshake, incompatible nodes can disconnect before expensive block exchanges and validations take place (PoW check, EVM execution, state reconstruction). This further prevents peer slots from being taken up by nodes that are incompatible, but have not yet been detected as such. + +## Motivation + +From a micro perspective, cutting off incompatible nodes from one another ensures that a node only spends its resources on tasks that are genuinely useful to it. The sooner we can decide the remote peer is useless, the less time and processing we expend in vain. + +From a macro perspective, keeping incompatible nodes partitioned from one another ensures that disjoint clusters retain more resources for maintaining their own chain, thus raising the quality of service for all networks globally. + +## Specification + +The specification is tiny since most parts are already specified in EIP-2124. `eth/63` is not specified as an EIP, but is maintained [here](https://github.com/ethereum/devp2p/blob/master/caps/eth.md). + +- Implement `forkid` generation and validation per [EIP-2124](https://eips.ethereum.org/EIPS/eip-2124). +- Advertise a new `eth` protocol capability (version) at `eth/64`. + - The old `eth/63` protocol should still be kept alive side-by-side, until `eth/64` is sufficiently adopted by implementors. +- Redefine `Status (0x00)` for `eth/64` to add a trailing `forkid` field: + - Old packet: `[protocolVersion, networkId, td, bestHash, genesisHash]` + - New packet: `[protocolVersion, networkId, td, bestHash, genesisHash, forkid]`, + where `forkid` is `[forkHash: [4]byte, forkNext: uint64]` (fields per [EIP-2124](https://eips.ethereum.org/EIPS/eip-2124) ). + +Whenever two peers connect using the `eth/64` protocol, the updated `Status` message must be sent as the protocol handshake, and each peer must validate the remote `forkid`, disconnecting at a detected incompatibility. + +## Rationale + +##### EIP-2124 mentions advertising the `forkid` in the discovery protocol too. How does that compare to advertising in the `eth` protocol? Why is the redundancy needed? + +Advertising and validating the `forkid` in the discovery protocol is a more optimal solution, as it can help avoid the cost of setting up the TCP connection and cryptographic RLPx stream, only to be torn down if `eth/64` rejects it. + +Compared to the `eth` protocol however, discovery is a bit fuzzy. The goal there is to suggest potential peers, not to be fool-proof. Information may be outdated, nodes may have changed or disappeared. Discovery can do a rough filtering, but more precision is still needed afterwards. + +Additionally, `forkid` validation via the discovery protocol requires ENR implementation ([EIP-778](https://eips.ethereum.org/EIPS/eip-778)) and ENR extension support ([EIP-868](https://eips.ethereum.org/EIPS/eip-868)), which is not mandated by the Ethereum network currently. Lastly, the discovery protocol is just one way to find peers, but systems that cannot use UDP or that rely on other mechanism (e.g. DNS discovery ([EIP-1459](https://eips.ethereum.org/EIPS/eip-1459))) still need a way to filter connections. + +##### The `forkid` implicitly contains the genesis hash checksummed into the `FORK_HASH` field. Why doesn't this proposal remove the `genesisHash` field from the `eth` handshake? + +Originally this EIP did remove it as redundant data, since filtering based on the `forkid` is a superset of filtering based on genesis hash. The reason for backing out of that decision was that the genesis hash may be useful for other things too, not just connection filtering (network crawlers use it currently to split nodes across networks). + +Although the `forkid` will hopefully take over all the roles of the genesis hash currently in use, there's no reason to be overly aggressive in deduplicating data. It's fine to keep both side-by-side for now, and remove in a future version when 3rd party infrastructures switch over. + +## Backwards Compatibility + +This EIP extends the `eth` protocol handshake in a backwards incompatible way and requires rolling out a new version, `eth/64`. However, `devp2p` supports running multiple versions of the same wire protocol side-by-side, so rolling out `eth/64` does not require client coordination, since non-updated clients can keep using `eth/63`. + +This EIP does not change the consensus engine, thus does _not_ require a hard fork. + +## Test Cases + +For calculating and validating fork IDs, see test cases in [EIP-2124](https://eips.ethereum.org/EIPS/eip-2124). + +Testing proper advertising and validation at the networking level will require a [hive](https://github.com/ethereum/hive) test. + +## Implementation + +Geth: https://github.com/ethereum/go-ethereum/pull/20140 + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 8481c7f73dd77260b33aef97af882e00afeb2379 Mon Sep 17 00:00:00 2001 From: Vincent Date: Thu, 14 Nov 2019 19:34:29 +0100 Subject: [PATCH 24/47] Automatically merged updates to draft EIP(s) 1775 (#2380) 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-1775.md | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/EIPS/eip-1775.md b/EIPS/eip-1775.md index fb6f63b016f512..7d1cd0c4825792 100644 --- a/EIPS/eip-1775.md +++ b/EIPS/eip-1775.md @@ -26,7 +26,7 @@ In a wallet, an user often holds most of her funds in her main accounts. These a 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 a master account (or app key) unique for the domain from an user private key (her root private key or any other private key of an account derived or not from her root one). This EIP aims at becoming a standard on how to derive keys specific to each application that can be regenerated from scratch without further input from the user if she restores her wallet and uses again the application for which this key was derived. -These app keys can then be endowed a different set of permissions (through the requestPermission model introduced in EIP [EIP2255](https://eips.ethereum.org/EIPS/eip-2255)). This will potentially allow an user to partly trust some apps to perform some crypto operations on their behalf without compromising any security with respect to her main accounts. +These app keys can then be endowed a different set of permissions (through the requestPermission model introduced in [EIP2255](https://eips.ethereum.org/EIPS/eip-2255)). This will potentially allow an user to partly trust some apps to perform some crypto operations on their behalf without compromising any security with respect to her main accounts. ## Motivation @@ -57,7 +57,7 @@ Once connected to a wallet, an application can request to access an account deri ### Private App Key generation algorithm -We now propose an algorithm to generate keys specific to each application using only the user's master seed entropy, the BIP44 index of one of this user's accounts and the application unique identifier. This allows to generate application keys that: +We now propose an algorithm to generate application keys that: - are uniquely defined, with respect to the account that the user selected to generate these keys, - and thus can be isolated when changing the user account, allowing persona management (see next section), - are specific to each application, @@ -71,24 +71,21 @@ If an application interacts with several main accounts of an user, one of these #### Applications' Unique Identifiers -Each application is uniquely defined and authenticated by its name, a domain string. It can be a Domain Name Service (DNS) name or, in the future, an Ethereum Name Service (ENS) name or IPFS hash. +Each application is uniquely defined and authenticated by its origin, a domain string. It can be a Domain Name Service (DNS) name or, in the future, an Ethereum Name Service (ENS) name or IPFS hash. -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) +For Ipfs or swam origins, but we could probably use the ipfs or swarm addresses as origin or we could require those to be pointed at through an ENS entry and use the ENS address as origin, although this would mean that the content it refers to could change. It would thus allow for different security and updatibility models. -We recommend this standard to be following the [ENS Specs](http://docs.ens.domains/en/latest/implementers.html#namehash), reproduced below for convenience and reference. +We will probably require for protocol prefixes when using an ENS domain to point to an IPFS address: +`ens://ipfs.snap.eth` -``` -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. -``` #### Private App Key generation algorithm Using the domain name of an application, we generate a private key for each application (and per main account) : -`const appKeyPrivKey = ethUtil.keccak(privKey + originString, 256)` +`const appKeyPrivKey = keccak256(privKey + originString)` -where privKey is the private key of the user's account selected to span the application key and originString represents the origin url from which the permission call to access the application key is originated from. +where `+` is concatenation, `privKey` is the private key of the user's account selected to span the application key and `originString` represents the origin url from which the permission call to access the application key is originated from. This is exposed as an RPC method to allow any domain to request its own app key associated with the current requested account (if available): From 14134bbaa6e18d4ea52530c908bfef5de743fdf0 Mon Sep 17 00:00:00 2001 From: Bryan Stitt Date: Tue, 19 Nov 2019 12:22:01 -0800 Subject: [PATCH 25/47] Automatically merged updates to draft EIP(s) 1898 (#2382) 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-1898.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-1898.md b/EIPS/eip-1898.md index 677c7e85a6269f..0d6ade6c5c64fc 100644 --- a/EIPS/eip-1898.md +++ b/EIPS/eip-1898.md @@ -80,7 +80,7 @@ Backwards compatible. ## Implementation -None yet. +It is supported by Geth 1.9.6 ([PR](https://github.com/ethereum/go-ethereum/pull/19491)). ## Copyright From 3e8203c8b1b81aec69fefc30e4f73412216c3464 Mon Sep 17 00:00:00 2001 From: ligi Date: Thu, 21 Nov 2019 06:23:10 +0900 Subject: [PATCH 26/47] Replace question with suggestion (#2383) --- EIPS/eip-634.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-634.md b/EIPS/eip-634.md index c79ec48523968b..c9aaf9b0fc89cc 100644 --- a/EIPS/eip-634.md +++ b/EIPS/eip-634.md @@ -46,8 +46,8 @@ services must be prefixed with `vnd.`. - **description** - A description of the name - **notice** - A notice regarding this name; - **keywords** - A list of comma-separated keywords, ordered by most significant first; clients that interpresent this field may choose a threshold beyond which to ignore -- **vnd.twitter** - a twitter username (should it be prefixed with an @?) -- **vnd.github** - a GitHub username +- **vnd.twitter** - a twitter username (SHOULD not be prefixed with an @ symbol) +- **vnd.github** - a GitHub username (SHOULD not be prefixed with an @ symbol) ## Rationale From 1a627a7c0d9256fcdce370288630168643b6be3a Mon Sep 17 00:00:00 2001 From: econoar Date: Fri, 22 Nov 2019 12:33:07 -0800 Subject: [PATCH 27/47] EIP-2384 - Difficulty Bomb Delay (#2384) --- EIPS/eip-2384.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 EIPS/eip-2384.md diff --git a/EIPS/eip-2384.md b/EIPS/eip-2384.md new file mode 100644 index 00000000000000..8461b5cee0659a --- /dev/null +++ b/EIPS/eip-2384.md @@ -0,0 +1,40 @@ +--- +eip: 2384 +title: Istanbul/Berlin Difficulty Bomb Delay +author: Eric Conner (@econoar) +discussions-to: https://ethereum-magicians.org/t/eip-2384-difficulty-bomb-delay +type: Standards Track +category: Core +status: Draft +created: 2019-11-20 +--- + +## Simple Summary +The average block times are increasing due to the difficulty bomb (also known as the "_ice age_") and slowly accelerating. This EIP proposes to delay the difficulty bomb for another 4,000,000 blocks (~611 days). + +## Abstract +Starting with `???_FORK_BLKNUM` the client will calculate the difficulty based on a fake block number suggesting to the client that the difficulty bomb is adjusting 9 million blocks later than the Homestead fork, which is also 7 million blocks later than the Byzantium fork and 4 million blocks later than the Constantinople fork. + +## Motivation +The difficulty bomb started to become noticeable again on October 5th 2019 at block 8,600,000. Block times have been around 13.1s on average and now as of block 8,900,000 are around 14.3s. This will start to accelerate exponentially every 100,000 blocks. Estimating the added impact from the difficulty bomb on block times shows that we will see 20s block times near the end of December 2019 and 30s+ block times starting February 2020. This will start making the chain bloated and more costly to use. It's best to delay the difficulty bomb again to around the time of expected launch of the Eth2 finality gadget. + +## Specification +#### Relax Difficulty with Fake Block Number +For the purposes of `calc_difficulty`, simply replace the use of `block.number`, as used in the exponential ice age component, with the formula: + + fake_block_number = max(0, block.number - 9_000_000) if block.number >= ???_FORK_BLKNUM else block.number + +## Rationale +This will delay the ice age by 52 million seconds (approximately 611 days), so the chain would be back at 20 second block times around July 2021. It's important to note this pushes the ice age 4,000,000 blocks from ~block 8,800,000 NOT from when this EIP is activated in a fork. + +## Backwards Compatibility +This EIP is not forward compatible and introduces backwards incompatibilities in the difficulty calculation. Therefore, it should be included in a scheduled hardfork at a certain block number. It's suggested to include this EIP shortly after the Istanbul fork. + +## Test Cases +Test cases shall be created once the specification is to be accepted by the developers or implemented by the clients. + +## Implementation +The implementation in it's logic does not differ from [EIP-649](https://eips.ethereum.org/EIPS/eip-649) or [EIP-1234](https://eips.ethereum.org/EIPS/eip-1234); an implementation for Parity-Ethereum is available in [parity-ethereum#9187](https://github.com/paritytech/parity-ethereum/pull/9187). + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From d5259bc809e72d71657d84892484b857f3bb9b08 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 22 Nov 2019 16:02:58 -0500 Subject: [PATCH 28/47] Fix spelling of GitHub [R4R] (#2369) --- EIPS/eip-1.md | 6 +++--- EIPS/eip-1155.md | 2 +- EIPS/eip-1261.md | 6 +++--- EIPS/eip-1319.md | 2 +- EIPS/eip-1470.md | 2 +- EIPS/eip-1761.md | 4 ++-- EIPS/eip-2135.md | 4 ++-- EIPS/eip-2255.md | 2 +- EIPS/eip-233.md | 2 +- PULL_REQUEST_TEMPLATE.md | 2 +- README.md | 6 +++--- 11 files changed, 19 insertions(+), 19 deletions(-) diff --git a/EIPS/eip-1.md b/EIPS/eip-1.md index 27f86ba5ce0d02..ecd42fd7bc114c 100644 --- a/EIPS/eip-1.md +++ b/EIPS/eip-1.md @@ -56,7 +56,7 @@ In addition to making sure your idea is original, it will be your role as the au For Core EIPs, given that they require client implementations to be considered **Final** (see "EIPs Process" below), you will need to either provide an implementation for clients or convince clients to implement your EIP. -The best way to get client implementers to review your EIP is to present it on an AllCoreDevs call. You can request to do so by posting a comment linking your EIP on an [AllCoreDevs agenda Github Issue]. +The best way to get client implementers to review your EIP is to present it on an AllCoreDevs call. You can request to do so by posting a comment linking your EIP on an [AllCoreDevs agenda GitHub Issue]. The AllCoreDevs call serve as a way for client implementers to do three things. First, to discuss the technical merits of EIPs. Second, to gauge what other clients will be implementing. Third, to coordinate EIP implementation for network upgrades. @@ -249,7 +249,7 @@ For each new EIP that comes in, an editor does the following: - Read the EIP to check if it is ready: sound and complete. The ideas must make technical sense, even if they don't seem likely to get to final status. - The title should accurately describe the content. -- Check the EIP for language (spelling, grammar, sentence structure, etc.), markup (Github flavored Markdown), code style +- Check the EIP for language (spelling, grammar, sentence structure, etc.), markup (GitHub flavored Markdown), code style If the EIP isn't ready, the editor will send it back to the author for revision, with specific instructions. @@ -314,7 +314,7 @@ See [the revision history for further details](https://github.com/ethereum/EIPs/ [Bitcoin's BIP-0001]: https://github.com/bitcoin/bips [Python's PEP-0001]: https://www.python.org/dev/peps/ [the Ethereum Magicians forum]: https://ethereum-magicians.org/ -[AllCoreDevs agenda Github Issue]: https://github.com/ethereum/pm/issues +[AllCoreDevs agenda GitHub Issue]: https://github.com/ethereum/pm/issues ## Copyright diff --git a/EIPS/eip-1155.md b/EIPS/eip-1155.md index a35e508c6070f7..2065e432dccfa9 100644 --- a/EIPS/eip-1155.md +++ b/EIPS/eip-1155.md @@ -700,7 +700,7 @@ Another simple way to represent non-fungibles is to allow a maximum value of 1 f - [The Sandbox - Dual ERC-1155/721 Contract](https://github.com/pixowl/thesandbox-contracts/tree/master/src/Asset) **Articles & Discussions** -- [Github - Original Discussion Thread](https://github.com/ethereum/EIPs/issues/1155) +- [GitHub - Original Discussion Thread](https://github.com/ethereum/EIPs/issues/1155) - [ERC-1155 - The Crypto Item Standard](https://blog.enjincoin.io/erc-1155-the-crypto-item-standard-ac9cf1c5a226) - [Here Be Dragons - Going Beyond ERC-20 and ERC-721 To Reduce Gas Cost by ~80%](https://medium.com/horizongames/going-beyond-erc20-and-erc721-9acebd4ff6ef) - [Blockonomi - Ethereum ERC-1155 Token Perfect for Online Games, Possibly More](https://blockonomi.com/erc1155-gaming-token/) diff --git a/EIPS/eip-1261.md b/EIPS/eip-1261.md index 132383e5eee994..425e38cb0ee53e 100644 --- a/EIPS/eip-1261.md +++ b/EIPS/eip-1261.md @@ -295,9 +295,9 @@ One can think of the set of MVTs as identifying a user, and you cannot split the The assign and revoke functions' documentation only specify conditions when the transaction MUST throw. Your implementation MAY also throw in other situations. This allows implementations to achieve interesting results: -- **Disallow additional memberships after a condition is met** — Sample contract available on Github -- **Blacklist certain address from receiving MV tokens** — Sample contract available on Github -- **Disallow additional memberships after a certain time is reached** — Sample contract available on Github +- **Disallow additional memberships after a condition is met** — Sample contract available on GitHub +- **Blacklist certain address from receiving MV tokens** — Sample contract available on GitHub +- **Disallow additional memberships after a certain time is reached** — Sample contract available on GitHub - **Charge a fee to user of a transaction** — require payment when calling `assign` and `revoke` so that condition checks from external sources can be made **ERC-173 Interface** diff --git a/EIPS/eip-1319.md b/EIPS/eip-1319.md index e51788eefd4ee0..20121871ff7289 100644 --- a/EIPS/eip-1319.md +++ b/EIPS/eip-1319.md @@ -170,7 +170,7 @@ Registries may offer more complex `read` APIs that manage requests for packages No existing standard exists for package registries. The package registry currently deployed by EthPM would not comply with the standard since it implements only one of the method signatures described in the specification. ## Implementation -A reference implementation of this proposal is in active development at the EthPM organization on Github [here](https://github.com/ethpm/escape-truffle). +A reference implementation of this proposal is in active development at the EthPM organization on GitHub [here](https://github.com/ethpm/escape-truffle). ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/EIPS/eip-1470.md b/EIPS/eip-1470.md index d6f9dffc24f455..8e613bff7100fb 100644 --- a/EIPS/eip-1470.md +++ b/EIPS/eip-1470.md @@ -104,7 +104,7 @@ properties: ## Implementation -The Smart Contract Weakness Classification registry located in this [Github repository](https://github.com/SmartContractSecurity/SWC-registry) uses the SWC scheme proposed in this EIP. A Github Pages rendered version is also available [here](https://smartcontractsecurity.github.io/SWC-registry/). +The Smart Contract Weakness Classification registry located in this [GitHub repository](https://github.com/SmartContractSecurity/SWC-registry) uses the SWC scheme proposed in this EIP. A GitHub Pages rendered version is also available [here](https://smartcontractsecurity.github.io/SWC-registry/). ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/EIPS/eip-1761.md b/EIPS/eip-1761.md index 7d7a51163d293d..d5bec18d120538 100644 --- a/EIPS/eip-1761.md +++ b/EIPS/eip-1761.md @@ -168,8 +168,8 @@ The Scope Metadata JSON Schema was added in order to support human-readable scop - [Enjin Coin](https://enjincoin.io) ([github](https://github.com/enjin)) **Articles & Discussions** -- [Github - Original Discussion Thread](https://github.com/ethereum/EIPs/issues/1761) -- [Github - ERC-1155 Discussion Thread](https://github.com/ethereum/EIPs/issues/1155) +- [GitHub - Original Discussion Thread](https://github.com/ethereum/EIPs/issues/1761) +- [GitHub - ERC-1155 Discussion Thread](https://github.com/ethereum/EIPs/issues/1155) ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/EIPS/eip-2135.md b/EIPS/eip-2135.md index 547a3ead117f5e..181110035d7eae 100644 --- a/EIPS/eip-2135.md +++ b/EIPS/eip-2135.md @@ -64,11 +64,11 @@ This interface is designed to be compatible with ERC-721. A reference implementation accompany with tests of **ERC-721 based ticket** contract is built and you can found it [here](https://github.com/xinbenlv/eip-2135/blob/master/impl/contracts/Ticket721.sol). -See [Github/xinbenlv/eip-2135/impl](https://github.com/xinbenlv/eip-2135/tree/master/impl) +See [GitHub/xinbenlv/eip-2135/impl](https://github.com/xinbenlv/eip-2135/tree/master/impl) ## Test Cases -See [Github/xinbenlv/eip-2135/impl/test](https://github.com/xinbenlv/eip-2135/tree/master/impl/test) +See [GitHub/xinbenlv/eip-2135/impl/test](https://github.com/xinbenlv/eip-2135/tree/master/impl/test) ## Reference diff --git a/EIPS/eip-2255.md b/EIPS/eip-2255.md index 63807737d16121..7789a4ea6a1cf4 100644 --- a/EIPS/eip-2255.md +++ b/EIPS/eip-2255.md @@ -26,7 +26,7 @@ Web3 Wallets are built around the responsibility of mediating the interactions b Today web3 browsers like MetaMask always prompt on a per-action basis. This provides security at the cost of substantial user friction. We believe that a single permissions request can achieve the same level of security with vastly improved UX. -The pattern of permissions requests is common around the web, from login with Facebook, Twitter, Github, and even Apple, making it a very familiar pattern. +The pattern of permissions requests is common around the web, from login with Facebook, Twitter, GitHub, and even Apple, making it a very familiar pattern. ![facebook permissions](https://proxy.duckduckgo.com/iu/?u=https%3A%2F%2Fi.stack.imgur.com%2FG7dRV.png&f=1) diff --git a/EIPS/eip-233.md b/EIPS/eip-233.md index a3378d67c30efb..7dde4bafe65594 100644 --- a/EIPS/eip-233.md +++ b/EIPS/eip-233.md @@ -52,7 +52,7 @@ The Meta EIP representing the hard fork should move in to the `Accepted` state o ## Template -A template for the [Istanbul Hardfork Meta 1679](https://eips.ethereum.org/EIPS/eip-1679) is included below ([source file on Github](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1679.md)): +A template for the [Istanbul Hardfork Meta 1679](https://eips.ethereum.org/EIPS/eip-1679) is included below ([source file on GitHub](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1679.md)): ``` {% raw %} diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index bff8b61ec8f619..1a9b8b1e9a71c9 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -4,5 +4,5 @@ We have a GitHub bot that automatically merges some PRs. It will merge yours imm - The PR edits only existing draft PRs. - The build passes. - - Your Github username or email address is listed in the 'author' header of all affected PRs, inside . + - Your GitHub username or email address is listed in the 'author' header of all affected PRs, inside . - If matching on email address, the email address is the one publicly listed on your GitHub profile. diff --git a/README.md b/README.md index 75b0d57f27463b..9ffb99361a51f6 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Your first PR should be a first draft of the final EIP. It must meet the formatt If your EIP requires images, the image files should be included in a subdirectory of the `assets` folder for that EIP as follows: `assets/eip-N` (where **N** is to be replaced with the EIP number). When linking to an image in the EIP, use relative links such as `../assets/eip-1/image.png`. -Once your first PR is merged, we have a bot that helps out by automatically merging PRs to draft EIPs. For this to work, it has to be able to tell that you own the draft being edited. Make sure that the 'author' line of your EIP contains either your Github username or your email address inside . If you use your email address, that address must be the one publicly shown on [your GitHub profile](https://github.com/settings/profile). +Once your first PR is merged, we have a bot that helps out by automatically merging PRs to draft EIPs. For this to work, it has to be able to tell that you own the draft being edited. Make sure that the 'author' line of your EIP contains either your GitHub username or your email address inside . If you use your email address, that address must be the one publicly shown on [your GitHub profile](https://github.com/settings/profile). When you believe your EIP is mature and ready to progress past the draft phase, you should do one of two things: @@ -48,7 +48,7 @@ eip_validator # Automerger -The EIP repository contains an "auto merge" feature to ease the workload for EIP editors. If a change is made via a PR to a draft EIP, then the authors of the EIP can Github approve the change to have it auto-merged by the [eip-automerger](https://github.com/eip-automerger/automerger) bot. +The EIP repository contains an "auto merge" feature to ease the workload for EIP editors. If a change is made via a PR to a draft EIP, then the authors of the EIP can GitHub approve the change to have it auto-merged by the [eip-automerger](https://github.com/eip-automerger/automerger) bot. # Local development @@ -86,4 +86,4 @@ $ bundle exec jekyll serve 2. Preview your local Jekyll site in your web browser at `http://localhost:4000`. -More information on Jekyll and Github pages [here](https://help.github.com/en/enterprise/2.14/user/articles/setting-up-your-github-pages-site-locally-with-jekyll). +More information on Jekyll and GitHub pages [here](https://help.github.com/en/enterprise/2.14/user/articles/setting-up-your-github-pages-site-locally-with-jekyll). From 7a4f40b5a6409aad2de1d4d10aae13f4ac9c690b Mon Sep 17 00:00:00 2001 From: Loredana Cirstea Date: Fri, 22 Nov 2019 23:21:07 +0200 Subject: [PATCH 29/47] dType Functions Extension - Decentralized Type System for EVM (#2267) --- EIPS/eip-1921.md | 141 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 EIPS/eip-1921.md diff --git a/EIPS/eip-1921.md b/EIPS/eip-1921.md new file mode 100644 index 00000000000000..29ad1312cd2ac6 --- /dev/null +++ b/EIPS/eip-1921.md @@ -0,0 +1,141 @@ +--- +eip: 1921 +title: dType Functions Extension +author: Loredana Cirstea (@loredanacirstea), Christian Tzurcanu (@ctzurcanu) +discussions-to: https://github.com/ethereum/EIPs/issues/1921 +status: Draft +type: Standards Track +category: ERC +created: 2019-04-06 +requires: 1900 +--- + +## Simple Summary +In the context of dType, the Decentralized Type System described in [EIP-1900](https://eips.ethereum.org/EIPS/eip-1900), we are proposing to add support for registering functions (with a preference for `pure` and `view`) in the dType Registry. + +## Abstract + +This proposal is part of a series of EIPs focused on expanding the concept of a Decentralized Type System, as explained in [EIP-1900](https://eips.ethereum.org/EIPS/eip-1900). +The current EIP specifies the data definitions and interfaces needed to support registering individual smart contract functions, as entries in the dType Registry. + +## Motivation + +In order to evolve the EVM into a Singleton Operating System, we need a way to register, find and address contract functions that we want to run in an automated way. +This implies having access to all the data needed to run the function inside the EVM. + +Aside from the above motivation, there are also near future benefits for this proposal. Having a globally available, non-custodial functions registry, will democratize the development of tools, such as those targeting: blockchain data analysis (e.g. block explorers), smart contract IDEs, security analysis of smart contracts. + +Registering new smart contract functions can be done through the same consensus mechanism as [EIP-1900](https://eips.ethereum.org/EIPS/eip-1900) mentions, in order to avoid burdening the chain state with redundant or improper records. + + +## Specification + +This specification targets `pure` and `view` functions. + +For each function, we can store: +* `name` - type `string` unique function name, as defined in EIP-1900; required +* `types` - the type data and label of each input, as defined in EIP-1900; required +* `outputs` - the type data and label of each output; required +* `contractAddress` - type `address` - smart contract where the function resides, as defined in EIP-1900; optional for interfaces +* `source` - type `bytes32` - reference to an external file containing the function source code, as defined in EIP-1900; optional + +Therefore, this proposal adds `outputs` to the EIP-1900 type registration definition. + +An example of a function registration object for the dType registry is: + +``` +{ + "name": "setStaked", + "types": [ + {"name": "TypeA", "label": "typeA", "relation":0, "dimensions":[]} + ], + "typeChoice": 4, + "contractAddress":
, + "source": , + "outputs": [ + {"name": "TypeB", "label": "typeB", "relation":0, "dimensions":[]} + ] +} +``` + +The above object will be passed to `.insert({...})` + +An additional `setOutputs` function is proposed for the dType registry: + +``` +function setOutputs( + bytes32 identifier, + dTypes[] memory outputs +) + public +``` + +- `identifier` - type `bytes32`, the type's identifier, as defined in EIP-1900 +- `outputs` - type `dTypes`, as defined in EIP-1900 + +### Implementation Suggestions + + +In the dType registry implementation, `outputs` can be stored in a `mapping`: + +``` +mapping(bytes32 => dTypes[]) public outputs; +``` + +## Rationale + + +The suggestion to treat each `pure` or `view` function as a separate entity instead of having a contract-based approach allows us to: +* have a global context of readily available functions +* scale designs through functional programming patterns rather than contract-encapsulated logic (which can be successfully used to scale development efforts independently) +* bidirectionally connect functions with the types they use, making automation easier +* cherry-pick functions from already deployed contracts if the other contract functions do not pass community consensus +* have scope-restricted improvements - instead of redeploying entire contracts, we can just redeploy the new function versions that we want to be added to the registry +* enable fine-grained auditing of individual functions, for the common good +* enable testing directly on a production chain, without state side-effects + +The proposal to store the minimum ABI information on-chain, for each function, allows us to: +* enable on-chain automation (e.g. function chaining and composition) +* be backward compatible in case the function signature format changes (e.g. from `bytes4` to `bytes32`): multiple signature calculation functions can be registered with dType. Examples: + +``` +function getSignatureBytes4(bytes32 identifier) + view + public + returns (bytes4 signature) + +function getSignatureBytes32(bytes32 identifier) + view + public + returns (bytes32 signature) +``` + +- `identifier` - the type's identifier, as defined in EIP-1900 +- `signature` - the function's signature + + +Concerns about this design might be: +* redundancy of storing `contractAddress` for each function that is part of the same contract + +We think that state/storage cost will be compensated through DRYness across the chain, due to reusing types and functions that have already been registered and are now easy to find. Other state/storage cost calculations will be added once the specification and implementation are closer to be finalized. + + +Note that the input and output types are based on types that have already been registered. This lowers the amount of ABI information needed to be stored for each function and enables developers to aggregate and find functions that use the same types for their I/O. This can be a powerful tool for interoperability and smart contract composition. + + +## Backwards Compatibility + +This proposal does not affect extant Ethereum standards or implementations. Registering functions for existing contract deployments should be fully supported. + +## Test Cases + +Will be added. + + +## Implementation + +In-work implementation examples can be found at https://github.com/pipeos-one/dType. +This proposal will be updated with an appropriate implementation when consensus is reached on the specifications. + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From ab16033a02fb1bfbe4155d32e4ebe5111dd170e1 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Fri, 22 Nov 2019 22:23:29 +0000 Subject: [PATCH 30/47] Clarify that empty accounts also return 0 in EIP-1052 (#2388) --- EIPS/eip-1052.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-1052.md b/EIPS/eip-1052.md index cce394ecd9cd1c..fd919b449274d8 100644 --- a/EIPS/eip-1052.md +++ b/EIPS/eip-1052.md @@ -7,6 +7,7 @@ status: Final type: Standards Track category: Core created: 2018-05-02 +requires: 161 --- ## Abstract @@ -24,7 +25,7 @@ takes one argument from the stack, zeros the first 96 bits and pushes to the stack the keccak256 hash of the code of the account at the address being the remaining 160 bits. -In case the account does not exist `0` is pushed to the stack. +In case the account does not exist or is empty (as defined by [EIP-161](https://eips.ethereum.org/EIPS/eip-161)) `0` is pushed to the stack. In case the account does not have code the keccak256 hash of empty data (i.e. `c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470`) From 118a48da107d3995af56898cce40adc8387f3c6a Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Fri, 22 Nov 2019 22:27:21 +0000 Subject: [PATCH 31/47] Fix the username of @pizza-r0b in EIP-2309 (#2389) --- EIPS/eip-2309.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-2309.md b/EIPS/eip-2309.md index 6df4126566c6b6..85dfd5f1b89636 100644 --- a/EIPS/eip-2309.md +++ b/EIPS/eip-2309.md @@ -1,7 +1,7 @@ --- eip: 2309 title: ERC-721 Consecutive Transfer Extension -author: Sean Papanikolas (@pizza_r0b) +author: Sean Papanikolas (@pizza-r0b) discussions-to: https://github.com/ethereum/EIPs/issues/2309 status: Draft type: Standards Track From 60edc53d14bd5569a62cf046ba6d7839359d336e Mon Sep 17 00:00:00 2001 From: Daniel Lehrner Date: Fri, 22 Nov 2019 23:42:04 +0100 Subject: [PATCH 32/47] EIP-1996: Holdable token (#1996) --- EIPS/eip-1996.md | 294 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 294 insertions(+) create mode 100644 EIPS/eip-1996.md diff --git a/EIPS/eip-1996.md b/EIPS/eip-1996.md new file mode 100644 index 00000000000000..53cee83fae0a1b --- /dev/null +++ b/EIPS/eip-1996.md @@ -0,0 +1,294 @@ +--- +eip: 1996 +title: Holdable Token +author: Julio Faura , Fernando Paris , Daniel Lehrner +discussions-to: https://github.com/ethereum/EIPs/issues/2103 +status: Draft +type: Standards Track +category: ERC +created: 2019-04-10 +requires: 20 +--- + +## Simple Summary +An extension to the ERC-20 standard token that allows tokens to be put on hold. This guarantees a future transfer and makes the held tokens unavailable for transfer in the mean time. Holds are similar to escrows in that are firm and lead to final settlement. + +## Actors + +#### Operator +An account which has been approved by an account to create holds on its behalf. + +#### Hold issuer +The account, which creates a hold. This can be the account owner itself, or any account, which has been approved as an operator for the account. + +#### Notary +The account which decides if a hold should be executed. + +## Abstract +A hold specifies a payer, a payee, a maximum amount, a notary and an expiration time. When the hold is created, the specified token balance from the payer is put on hold. A held balance cannot be transferred until the hold is either executed or released. The hold can only be executed by the notary, which triggers the transfer of the tokens from the payer to the payee. If a hold is released, either by the notary at any time, or by anyone after the expiration, no transfer is carried out and the amount is available again for the payer. + +A hold can be partially executed, if the execution specifies an amount less than the maximum amount. In this case the specified amount is transferred to the payee and the remaining amount is available again to the payer. + +Holds can be specified to be perpetual. In this case, the hold cannot be released upon expiration, and thus can only be executed by the notary or released by the notary or payee. + +## Motivation + +A hold has to be used in different scenarios where a immediate transfer between accounts is not possible or has to be guaranteed beforehand: + +1. A regulated token may not allow to do a token transfer between accounts without verifying first, that it follows all the regulations. In this case a clearable transfer has to be used. During the clearing process a hold is created to ensure, that the transfer is successful after all checks have passed. If the transfer violates any of the regulations, it is cleared and not further processed. + +1. In certain business situations a payment has to be guaranteed before its services can be used. For example: When checking in a hotel, the hotel will put a hold on the guest's account to ensure that enough balance is available to pay for the room before handing over the keys. + +1. In other occasions a payment has to be guaranteed without knowing the exact amount beforehand. To stay with the hotel example: The hotel can put a hold on the guest's account as a guarantee for any possible extras, like room service. When the guest checks out the hold is partially executed and the remaining amount is available again on the guest's account. + +The ERC-20 `approve` function provides some of the necessary functionality for the use cases above. The main difference to holds, is that `approve` does not ensure a payment, as the approved money is not blocked and can be transferred at any moment. + +## Specification + +```solidity +interface IHoldable /* is ERC-20 */ { + enum HoldStatusCode { + Nonexistent, + Ordered, + Executed, + ReleasedByNotary, + ReleasedByPayee, + ReleasedOnExpiration + } + + function hold(string calldata operationId, address to, address notary, uint256 value, uint256 timeToExpiration) external returns (bool); + function holdFrom(string calldata operationId, address from, address to, address notary, uint256 value, uint256 timeToExpiration) external returns (bool); + function releaseHold(string calldata operationId) external returns (bool); + function executeHold(string calldata operationId, uint256 value) external returns (bool); + function renewHold(string calldata operationId, uint256 timeToExpiration) external returns (bool); + function retrieveHoldData(string calldata operationId) external view returns (address from, address to, address notary, uint256 value, uint256 expiration, HoldStatusCode status); + + function balanceOnHold(address account) external view returns (uint256); + function netBalanceOf(address account) external view returns (uint256); + function totalSupplyOnHold() external view returns (uint256); + + function authorizeHoldOperator(address operator) external returns (bool); + function revokeHoldOperator(address operator) external returns (bool); + function isHoldOperatorFor(address operator, address from) external view returns (bool); + + event HoldCreated(address indexed holdIssuer, string operationId, address from, address to, address indexed notary, uint256 value, uint256 expiration); + event HoldExecuted(address indexed holdIssuer, string operationId, address indexed notary, uint256 heldValue, uint256 transferredValue); + event HoldReleased(address indexed holdIssuer, string operationId, HoldStatusCode status); + event HoldRenewed(address indexed holdIssuer, string operationId, uint256 oldExpiration, uint256 newExpiration); + event AuthorizedHoldOperator(address indexed operator, address indexed account); + event RevokedHoldOperator(address indexed operator, address indexed account); +} +``` + +### Functions + +#### hold + +Creates a hold on behalf of the msg.sender in favor of the payee. It specifies a notary who is responsible to either execute or release the hold. The function must revert if the operation ID has been used before. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify the hold | +| to | The address of the payee, to whom the tokens are to be transferred if executed | +| notary | The address of the notary who is going to determine whether the hold is to be executed or released | +| value | The amount to be transferred. Must be less or equal than the balance of the payer. | +| timeToExpiration | The duration until the hold is expired. If it is '0' the hold must be perpetual. | + +#### holdFrom + +Creates a hold on behalf of the payer in favor of the payee. The `from` account has to approve beforehand, that another account can issue holds on its behalf by calling `approveToHold`. The function must revert if the operation ID has been used before. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify the hold | +| from | The address of the payer, from whom the tokens are to be taken if executed | +| to | The address of the payee, to whom the tokens are to be transferred if executed | +| notary | The address of the notary who is going to determine whether the hold is to be executed or released | +| value | The amount to be transferred. Must be less or equal than the balance of the payer. | +| timeToExpiration | The duration until the hold is expired. If it is '0' the hold must be perpetual. | + +#### releaseHold + +Releases a hold. Release means that the transfer is not executed and the held amount is available again for the payer. Until a hold has expired it can only be released by the notary or the payee. After it has expired it can be released by anyone. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify the hold | + +#### executeHold + +Executes a hold. Execute means that the specified value is transferred from the payer to the payee. If the specified value is less than the hold value the remaining amount is available again to the payer. The implementation must verify that only the notary is able to successfully call the function. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify the hold | +| value | The amount to be transferred. This amount has to be less or equal than the hold value | + +#### renewHold + +Renews a hold. The new expiration time must be the block timestamp plus the given `timeToExpiration`, independently if the hold was perpetual or not before that. Furthermore a hold must be made perpetual if `timeToExpiration` is '0'. The implementation must verify that only the payer or operator are able to successfully call the function. Furthermore the only a hold, which has not yet expired can be successfully renewed. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify the hold | +| timeToExpiration | The new duration until the hold is expired. | + +#### retrieveHoldData + +Retrieves all the information available for a particular hold. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify the hold | + +#### balanceOnHold + +Retrieves how much of the balance is currently held and therefore not available for transfer. + +| Parameter | Description | +| ---------|-------------| +| account | The address which held balance should be returned | + +#### netBalanceOf + +Retrieves the net balance, which is the sum of `balanceOf` and `balanceOnHold`. + +| Parameter | Description | +| ---------|-------------| +| account | The address which net balance should be returned | + +#### totalSupplyOnHold + +Retrieves the total sum of how many tokens are on hold. + +| Parameter | Description | +| ---------|-------------| +| - | - | + +#### authorizeHoldOperator + +Approves an operator to issue holds on behalf of msg.sender. + +| Parameter | Description | +| ---------|-------------| +| operator | The address to be approved as operator of holds | + +#### revokeHoldOperator + +Revokes the approval to issue holds on behalf of msg.sender. + +| Parameter | Description | +| ---------|-------------| +| operator | The address to be revoked as operator of holds | + +#### isHoldOperatorFor + +Retrieves if an operator is approved to create holds on behalf of `from`. + +| Parameter | Description | +| ---------|-------------| +| operator | The address to be a operator of holds | +| from | The address on which the holds would be created | + +#### balanceOf + +The standard implementation of ERC-20 has to be changed in order to deduct the held balance from the ERC-20 balance. + +#### transfer + +The standard implementation of ERC-20 has to be changed in order to deduct the held balance from the ERC-20 balance. Any amount that is held must not be transferred. + +#### transferFrom + +The standard implementation of ERC-20 has to be changed in order to deduct the held balance from the ERC-20 balance. Any amount that is held must not be transferred. + +### Events + +#### HoldCreated + +Emitted when a hold has been created. + +| Parameter | Description | +| ---------|-------------| +| holdIssuer | The address of the hold issuer of the hold | +| operationId | The unique ID to identify the hold | +| from | The address of the payer, from whom the tokens are to be taken if executed | +| to | The address of the payee, to whom the tokens are to be paid if executed | +| notary | The address of the notary who is going to determine whether the hold is to be executed or released | +| value | The amount to be transferred. Must be less or equal than the balance of the payer. | +| expiration | The unix timestamp when the hold is expired | + +#### HoldExecuted + +Emitted when a hold has been executed. + +| Parameter | Description | +| ---------|-------------| +| holdIssuer | The address of the hold issuer of the hold | +| operationId | The unique ID to identify the hold | +| notary | The address of the notary who executed the hold | +| heldValue | The amount which was put on hold during creation | +| transferredValue | The amount which was used for the transfer | + +#### HoldReleased + +Emitted when a hold has been released. + +| Parameter | Description | +| ---------|-------------| +| holdIssuer | The address of the hold issuer of the hold | +| operationId | The unique ID to identify the hold | +| status | Can be one of the following values: `ReleasedByNotary`, `ReleasedByPayee`, `ReleasedOnExpiration` | + +#### HoldRenewed + +Emitted when a hold has been renewed. + +| Parameter | Description | +| ---------|-------------| +| holdIssuer | The address of the hold issuer of the hold | +| operationId | The unique ID to identify the hold | +| oldExpiration | The expiration time before the renewal | +| newExpiration | The expiration time after the renewal | + +#### AuthorizedHoldOperator + +Emitted when an operator has been approved to create holds on behalf of another account. + +| Parameter | Description | +| ---------|-------------| +| operator | The address to be a operator of holds | +| account | Address on which behalf holds will potentially be created | + +#### RevokedHoldOperator + +Emitted when an operator has been revoked from creating holds on behalf of another account. + +| Parameter | Description | +| ---------|-------------| +| operator | The address to be a operator of holds | +| account | Address on which behalf holds could potentially be created | + +## Rationale + +This standards provides a functionality, to guarantee future payments, which is needed for many business cases where transfers have to be guaranteed. + +It goes a step further than the ERC-20 `approve` function by ensuring that the held balance will be available when the transfer is done. Something that can not be done with `approve`, as the approved amount is only a maximum spending amount, but never guaranteed to be available. + +While not requiring it, the naming of the functions `authorizeHoldOperator`, `revokeHoldOperator` and `isHoldOperatorFor` follows the naming convention of [ERC-777](https://eips.ethereum.org/EIPS/eip-777). + +The `operationId` is a string and not something more gas efficient to allow easy traceability of the hold and allow human readable ids. It is up to the implementer if the string should be stored on-chain or only its hash, as it is enough to identify a hold. + +The `operationId` is a competitive resource. It is recommended, but nor required, that the hold issuers used a unique prefix to avoid collisions. + +## Backwards Compatibility +This EIP is fully backwards compatible as its implementation extends the functionality of ERC-20. + +## Implementation +The GitHub repository [IoBuilders/holdable-token](https://github.com/IoBuilders/holdable-token) contains the reference implementation. + +## Contributors +This proposal has been collaboratively implemented by [adhara.io](https://adhara.io/) and [io.builders](https://io.builders/). + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 53455c7d06112f25e8ed2892f058522c9ece5de4 Mon Sep 17 00:00:00 2001 From: Daniel Lehrner Date: Fri, 22 Nov 2019 23:52:36 +0100 Subject: [PATCH 33/47] EIP-2018: Clearable Token (#2018) --- EIPS/eip-2018.md | 261 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 EIPS/eip-2018.md diff --git a/EIPS/eip-2018.md b/EIPS/eip-2018.md new file mode 100644 index 00000000000000..75d72ee2b37389 --- /dev/null +++ b/EIPS/eip-2018.md @@ -0,0 +1,261 @@ +--- +eip: 2018 +title: Clearable Token +author: Julio Faura , Fernando Paris , Daniel Lehrner +discussions-to: https://github.com/ethereum/EIPs/issues/2104 +status: Draft +type: Standards Track +category: ERC +created: 2019-04-30 +requires: 1996 +--- + +## Simple Summary + +> "In banking and finance, clearing denotes all activities from the time a commitment is made for a transaction until it is settled." [[1]][Clearing-Wikipedia] + +## Actors + +#### Clearing Agent + +An account which processes, executes or rejects a clearable transfer. + +#### Operator +An account which has been approved by an account to order clearable transfers on its behalf. + +#### Orderer +The account which orders a clearable transfer. This can be the account owner itself, or any account, which has been approved as an operator for the account. + +## Abstract + +The clearing process turns the promise of a transfer into the actual movement of money from one account to another. A clearing agent decides if the transfer can be executed or not. The amount which should be transferred is not deducted from the balance of the payer, but neither is it available for another transfer and therefore ensures, that the execution of the transfer will be successful when it is executed. + +## Motivation + +A regulated token needs to comply with all the legal requirements, especially [KYC][KYC-Wikipedia] and [AML][AML-Wikipedia]. Some of these checks may not be able to be done on-chain and therefore a transfer may not be completed in one step. Currently there is no EIP to make such off-chain checks possible. This proposal allows a user to order a transfer, which can be checked by a clearing agent off-chain. Depending on the result of it, the clearing agent will either execute or cancel the transfer. To provide more information why a transfer is cancelled, the clearing agent can add a reason why it is not executed. + +## Specification + +```solidity +interface ClearableToken /* is ERC-1996 */ { + enum ClearableTransferStatusCode { Nonexistent, Ordered, InProcess, Executed, Rejected, Cancelled } + + function orderTransfer(string calldata operationId, address to, uint256 value) external returns (bool); + function orderTransferFrom(string calldata operationId, address from, address to, uint256 value) external returns (bool); + function cancelTransfer(string calldata operationId) external returns (bool); + function processClearableTransfer(string calldata operationId) external returns (bool); + function executeClearableTransfer(string calldata operationId) external returns (bool); + function rejectClearableTransfer(string calldata operationId, string calldata reason) external returns (bool); + function retrieveClearableTransferData(string calldata operationId) external view returns (address from, address to, uint256 value, ClearableTransferStatusCode status); + + function authorizeClearableTransferOperator(address operator) external returns (bool); + function revokeClearableTransferOperator(address operator) external returns (bool); + function isClearableTransferOperatorFor(address operator, address from) external view returns (bool); + + event ClearableTransferOrdered(address indexed orderer, string operationId, address indexed from, address indexed to, uint256 value); + event ClearableTransferInProcess(address indexed orderer, string operationId); + event ClearableTransferExecuted(address indexed orderer, string operationId); + event ClearableTransferRejected(address indexed orderer, string operationId, string reason); + event ClearableTransferCancelled(address indexed orderer, string operationId); + event AuthorizedClearableTransferOperator(address indexed operator, address indexed account); + event RevokedClearableTransferOperator(address indexed operator, address indexed account); +} +``` + +### Functions + +#### orderTransfer + +Orders a clearable transfer on behalf of the msg.sender in favor of `to`. A clearing agent is responsible to either execute or reject the transfer. The function must revert if the operation ID has been used before. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify the clearable transfer | +| to | The address of the payee, to whom the tokens are to be paid if executed | +| value | The amount to be transferred. Must be less or equal than the balance of the payer. | + +#### orderTransferFrom + +Orders a clearable transfer on behalf of the payer in favor of the `to`. A clearing agent is responsible to either execute or reject the transfer. The function must revert if the operation ID has been used before. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify the clearable transfer | +| from | The address of the payer, from whom the tokens are to be taken if executed | +| to | The address of the payee, to whom the tokens are to be paid if executed | +| value | The amount to be transferred. Must be less or equal than the balance of the payer. | + +#### cancelTransfer + +Cancels the order of a clearable transfer. Only the orderer can cancel their own orders. It must not be successful as soon as the transfer is in status `InProcess`. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify the clearable transfer | + +#### processClearableTransfer + +Sets a clearable transfer to status `InProcess`. Only a clearing agent can successfully execute this action. This status is optional, but without it the orderer can cancel the transfer at any time. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify the clearable transfer | + +#### executeClearableTransfer + +Executes a clearable transfer, which means that the tokens are transferred from the payer to the payee. Only a clearing agent can successfully execute this action. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify the clearable transfer | + +#### rejectClearableTransfer + +Rejects a clearable transfer, which means that the amount that is held is available again to the payer and no transfer is done. Only a clearing agent can successfully execute this action. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify the clearable transfer | +| reason | A reason given by the clearing agent why the transfer has been rejected | + +#### retrieveClearableTransferData + +Retrieves all the information available for a particular clearable transfer. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify the clearable transfer | + +#### authorizeClearableTransferOperator + +Approves an operator to order transfers on behalf of msg.sender. + +| Parameter | Description | +| ---------|-------------| +| operator | The address to be approved as operator of clearable transfers | + +#### revokeClearableTransferOperator + +Revokes the approval to order transfers on behalf of msg.sender. + +| Parameter | Description | +| ---------|-------------| +| operator | The address to be revoked as operator of clearable transfers | + +#### isClearableTransferOperatorFor + +Returns if an operator is approved to order transfers on behalf of `from`. + +| Parameter | Description | +| ---------|-------------| +| operator | The address to be an operator of clearable transfers | +| from | The address on which the holds would be created | + +#### transfer + +It is up to the implementer of the EIP if the `transfer` function of ERC-20 should always revert or is allowed under certain circumstances. + +#### transferFrom + +It is up to the implementer of the EIP if the `transferFrom` function of ERC-20 should always revert or is allowed under certain circumstances. + + +### Events + +#### ClearableTransferOrdered + +Must be emitted when a clearable transfer is ordered. + +| Parameter | Description | +| ---------|-------------| +| orderer | The address of the orderer of the transfer | +| operationId | The unique ID to identify the clearable transfer | +| from | The address of the payer, from whom the tokens are to be taken if executed | +| to | The address of the payee, to whom the tokens are to be paid if executed | +| value | The amount to be transferred if executed | + +#### ClearableTransferInProcess + +Must be emitted when a clearable transfer is put in status `ÌnProcess`. + +| Parameter | Description | +| ---------|-------------| +| orderer | The address of the orderer of the transfer | +| operationId | The unique ID to identify the clearable transfer | + +#### ClearableTransferExecuted + +Must be emitted when a clearable transfer is executed. + +| Parameter | Description | +| ---------|-------------| +| orderer | The address of the orderer of the transfer | +| operationId | The unique ID to identify the clearable transfer | + +#### ClearableTransferRejected + +Must be emitted when a clearable transfer is rejected. + +| Parameter | Description | +| ---------|-------------| +| orderer | The address of the orderer of the transfer | +| operationId | The unique ID to identify the clearable transfer | +| reason | A reason given by the clearing agent why the transfer has been rejected | + +#### ClearableTransferCancelled + +Must be emitted when a clearable transfer is cancelled by its orderer. + +| Parameter | Description | +| ---------|-------------| +| orderer | The address of the orderer of the transfer | +| operationId | The unique ID to identify the clearable transfer | + +#### AuthorizedClearableTransferOperator + +Emitted when an operator has been approved to order transfers on behalf of another account. + +| Parameter | Description | +| ---------|-------------| +| operator | The address which has been approved as operator of clearable transfers | +| account | Address on which behalf transfers will potentially be ordered | + +#### RevokedClearableTransferOperator + +Emitted when an operator has been revoked from ordering transfers on behalf of another account. + +| Parameter | Description | +| ---------|-------------| +| operator | The address which has been revoked as operator of clearable transfers | +| account | Address on which behalf transfers could potentially be ordered | + +## Rationale + +This EIP uses [EIP-1996][EIP-1996] to hold the money after a transfer is ordered. A clearing agent, whose implementation is not part of this proposal, acts as a predefined notary to decide if the transfer complies with the rules of the token or not. + +The `operationId` is a string and not something more gas efficient to allow easy traceability of the hold and allow human readable ids. It is up to the implementer if the string should be stored on-chain or only its hash, as it is enough to identify a hold. + +The `operationId` is a competitive resource. It is recommended, but not required, that the hold issuers used a unique prefix to avoid collisions. + +While not requiring it, the naming of the functions `authorizeClearableTransferOperator`, `revokeClearableTransferOperator` and `isClearableTransferOperatorFor` follows the naming convention of [ERC-777](https://eips.ethereum.org/EIPS/eip-777). + +## Backwards Compatibility + +This EIP is fully backwards compatible as its implementation extends the functionality of [EIP-1996][EIP-1996]. + +## Implementation + +The GitHub repository [IoBuilders/clearable-token](https://github.com/IoBuilders/clearable-token) contains the reference implementation. + +## Contributors +This proposal has been collaboratively implemented by [adhara.io](https://adhara.io/) and [io.builders](https://io.builders/). + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). + +[1] https://en.wikipedia.org/wiki/Clearing_(finance) + +[Clearing-Wikipedia]: https://en.wikipedia.org/wiki/Clearing_(finance) +[KYC-Wikipedia]: https://en.wikipedia.org/wiki/Know_your_customer +[AML-Wikipedia]: https://en.wikipedia.org/wiki/Money_laundering#Anti-money_laundering +[EIP-1996]: https://eips.ethereum.org/EIPS/eip-1996 From af677b348da866d41a58d8948a89d0b00d410e2b Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 22 Nov 2019 18:55:15 -0500 Subject: [PATCH 34/47] Use solidity/javascript highlighting in various EIPs (#2372) --- EIPS/eip-1062.md | 8 ++++---- EIPS/eip-1132.md | 18 +++++++++--------- EIPS/eip-137.md | 34 +++++++++++++++++----------------- EIPS/eip-1386.md | 2 +- EIPS/eip-1387.md | 2 +- EIPS/eip-1388.md | 2 +- EIPS/eip-1450.md | 4 ++-- EIPS/eip-1485.md | 2 +- EIPS/eip-1491.md | 8 ++++---- EIPS/eip-1504.md | 6 +++--- EIPS/eip-152.md | 2 +- EIPS/eip-1592.md | 2 +- EIPS/eip-1616.md | 14 +++++++------- EIPS/eip-1753.md | 2 +- EIPS/eip-1844.md | 2 +- EIPS/eip-1973.md | 3 +-- EIPS/eip-2045.md | 4 ++-- EIPS/eip-2157.md | 4 ++-- EIPS/eip-2255.md | 2 +- EIPS/eip-2266.md | 44 ++++++++++++++++++++++---------------------- EIPS/eip-2304.md | 9 ++++----- EIPS/eip-706.md | 6 +++--- EIPS/eip-779.md | 2 +- EIPS/eip-823.md | 36 ++++++++++++++++++------------------ EIPS/eip-875.md | 2 +- EIPS/eip-926.md | 6 +++--- EIPS/eip-927.md | 4 ++-- EIPS/eip-999.md | 4 ++-- README.md | 10 +++++----- 29 files changed, 121 insertions(+), 123 deletions(-) diff --git a/EIPS/eip-1062.md b/EIPS/eip-1062.md index 62ae1896156ca2..022467747dc0e0 100644 --- a/EIPS/eip-1062.md +++ b/EIPS/eip-1062.md @@ -36,13 +36,13 @@ When mapping the IPFS base58 string to ENS resolver, first we convert the Base58 ## Rationale To implement the specification, need two methods from ENS public resolver contract, when we want to store IPFS file fingerprint to contract, convert the Base58 string identifier to the hex format and invoke the `setMultihash` method below : -``` +```solidity function setMultihash(bytes32 node, bytes hash) public only_owner(node); ``` Whenever users need to visit the ENS content, we call the `multihash` method to get the IPFS hex data, transfer to the Base58 format, and return the IPFS resources to use. -``` +```solidity function multihash(bytes32 node) public view returns (bytes); ``` @@ -52,7 +52,7 @@ To implement the way to transfer from base58 to hex format and the reverse one, The library link : [https://www.npmjs.com/package/multihashes](https://www.npmjs.com/package/multihashes) To implement the method transfer from IPFS(Base58) to hex format : -``` +```javascript import multihash from 'multihashes' export const toHex = function(ipfsHash) { @@ -63,7 +63,7 @@ export const toHex = function(ipfsHash) { To implement the method transfer from hex format to IPFS(Base58) : -``` +```javascript import multihash from 'multihashes' export const toBase58 = function(contentHash) { diff --git a/EIPS/eip-1132.md b/EIPS/eip-1132.md index c5059281594930..d80c41c7332799 100644 --- a/EIPS/eip-1132.md +++ b/EIPS/eip-1132.md @@ -43,7 +43,7 @@ The intention with this proposal is to enhance the ERC20 standard with token-loc I’ve extended the ERC20 interface with the following enhancements: ### Locking of tokens -``` +```solidity /** * @dev Locks a specified amount of tokens against an address, * for a specified reason and time @@ -55,7 +55,7 @@ function lock(bytes32 _reason, uint256 _amount, uint256 _time) public returns (b ``` ### Fetching number of tokens locked under each utility -``` +```solidity /** * @dev Returns tokens locked for a specified address for a * specified reason @@ -67,7 +67,7 @@ function lock(bytes32 _reason, uint256 _amount, uint256 _time) public returns (b ``` ### Fetching number of tokens locked under each utility at a future timestamp -``` +```solidity /** * @dev Returns tokens locked for a specified address for a * specified reason at a specific time @@ -80,7 +80,7 @@ function lock(bytes32 _reason, uint256 _amount, uint256 _time) public returns (b ``` ### Fetching number of tokens held by an address -``` +```solidity /** * @dev @dev Returns total tokens held by an address (locked + transferable) * @param _of The address to query the total balance of @@ -89,7 +89,7 @@ function totalBalanceOf(address _of) view returns (uint256 amount) ``` ### Extending lock period -``` +```solidity /** * @dev Extends lock for a specified reason and time * @param _reason The reason to lock tokens @@ -99,7 +99,7 @@ function totalBalanceOf(address _of) view returns (uint256 amount) ``` ### Increasing number of tokens locked -``` +```solidity /** * @dev Increase number of tokens locked for a specified reason * @param _reason The reason to lock tokens @@ -108,7 +108,7 @@ function totalBalanceOf(address _of) view returns (uint256 amount) function increaseLockAmount(bytes32 _reason, uint256 _amount) public returns (bool) ``` ### Fetching number of unlockable tokens under each utility -``` +```solidity /** * @dev Returns unlockable tokens for a specified address for a specified reason * @param _of The address to query the the unlockable token count of @@ -117,7 +117,7 @@ function totalBalanceOf(address _of) view returns (uint256 amount) function tokensUnlockable(address _of, bytes32 _reason) public view returns (uint256 amount) ``` ### Fetching number of unlockable tokens -``` +```solidity /** * @dev Gets the unlockable tokens of a specified address * @param _of The address to query the the unlockable token count of @@ -125,7 +125,7 @@ function totalBalanceOf(address _of) view returns (uint256 amount) function getUnlockableTokens(address _of) public view returns (uint256 unlockableTokens) ``` ### Unlocking tokens -``` +```solidity /** * @dev Unlocks the unlockable tokens of a specified address * @param _of Address of user, claiming back unlockable tokens diff --git a/EIPS/eip-137.md b/EIPS/eip-137.md index cc873744bc4feb..d70e2cf45eec9b 100644 --- a/EIPS/eip-137.md +++ b/EIPS/eip-137.md @@ -53,14 +53,14 @@ Resolving a name in ENS is a two-step process. First, the ENS registry is called For example, suppose you wish to find the address of the token contract associated with 'beercoin.eth'. First, get the resolver: -``` +```javascript var node = namehash("beercoin.eth"); var resolver = ens.resolver(node); ``` Then, ask the resolver for the address for the contract: -``` +```javascript var address = resolver.addr(node); ``` @@ -112,43 +112,43 @@ Implementations should conform to the following test vectors for namehash: The ENS registry contract exposes the following functions: -``` +```solidity function owner(bytes32 node) constant returns (address); ``` Returns the owner (registrar) of the specified node. -``` +```solidity function resolver(bytes32 node) constant returns (address); ``` Returns the resolver for the specified node. -``` +```solidity function ttl(bytes32 node) constant returns (uint64); ``` Returns the time-to-live (TTL) of the node; that is, the maximum duration for which a node's information may be cached. -``` +```solidity function setOwner(bytes32 node, address owner); ``` Transfers ownership of a node to another registrar. This function may only be called by the current owner of `node`. A successful call to this function logs the event `Transfer(bytes32 indexed, address)`. -``` +```solidity function setSubnodeOwner(bytes32 node, bytes32 label, address owner); ``` Creates a new node, `sha3(node, label)` and sets its owner to `owner`, or updates the node with a new owner if it already exists. This function may only be called by the current owner of `node`. A successful call to this function logs the event `NewOwner(bytes32 indexed, bytes32 indexed, address)`. -``` +```solidity function setResolver(bytes32 node, address resolver); ``` Sets the resolver address for `node`. This function may only be called by the owner of `node`. A successful call to this function logs the event `NewResolver(bytes32 indexed, address)`. -``` +```solidity function setTTL(bytes32 node, uint64 ttl); ``` @@ -159,7 +159,7 @@ Resolvers may implement any subset of the record types specified here. Where a r Resolvers have one mandatory function: -``` +```solidity function supportsInterface(bytes4 interfaceID) constant returns (bool) ``` @@ -184,7 +184,7 @@ EIPs may define new interfaces to be added to this registry. Resolvers wishing to support contract address resources must provide the following function: -``` +```solidity function addr(bytes32 node) constant returns (address); ``` @@ -194,12 +194,12 @@ Clients resolving the `addr` record MUST check for a zero return value, and trea Changes to an address MUST trigger the following event: -``` +```solidity event AddrChanged(bytes32 indexed node, address a); ``` # Appendix A: Registry Implementation -``` +```solidity contract ENS { struct Record { address owner; @@ -261,7 +261,7 @@ contract ENS { The simplest possible resolver is a contract that acts as its own name resolver by implementing the contract address resource profile: -``` +```solidity contract DoSomethingUseful { // Other code @@ -285,7 +285,7 @@ Such a contract can be inserted directly into the ENS registry, eliminating the A basic resolver that implements the contract address profile, and allows only its owner to update records: -``` +```solidity contract Resolver { event AddrChanged(bytes32 indexed node, address a); @@ -325,7 +325,7 @@ After deploying this contract, use it by updating the ENS registry to reference Similar to the resolver above, this contract only supports the contract address profile, but uses the ENS registry to determine who should be allowed to update entries: -``` +```solidity contract PublicResolver { event AddrChanged(bytes32 indexed node, address a); event ContentChanged(bytes32 indexed node, bytes32 hash); @@ -364,7 +364,7 @@ contract PublicResolver { This registrar allows users to register names at no cost if they are the first to request them. -``` +```solidity contract FIFSRegistrar { ENS ens; bytes32 rootNode; diff --git a/EIPS/eip-1386.md b/EIPS/eip-1386.md index 94d678514fdcb5..481c0b18a207e1 100644 --- a/EIPS/eip-1386.md +++ b/EIPS/eip-1386.md @@ -40,7 +40,7 @@ The wine vendors smart contract validates the attestation, checks the payment am When the wine vendor shows up to her apartment with the wine, there is no need to prove her age again. ### Draft interface -``` +```solidity /* each attestation issuer should provide their own verify() for the * attestations they issued. There are two reasons for this. First, we * need to leave room for new attestation methods other than the diff --git a/EIPS/eip-1387.md b/EIPS/eip-1387.md index 8aceee77e8ee3e..360ab3de2b59a2 100644 --- a/EIPS/eip-1387.md +++ b/EIPS/eip-1387.md @@ -21,7 +21,7 @@ Unlike previous attempts, we assume that the attestation is signed and issued of This ERC provides an interface and reference implementation for smart contracts that need users to provide an attestation and validate it. ### Draft implementation -``` +```solidity contract MerkleTreeAttestationInterface { struct Attestation { diff --git a/EIPS/eip-1388.md b/EIPS/eip-1388.md index 6bf1ca4ec8bee5..1dba3a254f2e1a 100644 --- a/EIPS/eip-1388.md +++ b/EIPS/eip-1388.md @@ -21,7 +21,7 @@ Anyone can publish a list of issuers. Only the most trusted and carefully mainta This ERC provides a smart contract interface for anyone to manage a list of attestation issuers. A smart contract would explicitly trust a list, and therefore all attestations issued by the issuers on the list. ### Draft implementation - ``` +```solidity /* The purpose of this contract is to manage the list of attestation * issuer contracts and their capacity to fulfill requirements */ diff --git a/EIPS/eip-1450.md b/EIPS/eip-1450.md index ddbb8ba157f4a3..4be04e827cd141 100644 --- a/EIPS/eip-1450.md +++ b/EIPS/eip-1450.md @@ -52,7 +52,7 @@ For compliance reasons, the `ERC-1450` constructor must specify the issuer (the ### ERC-20 Extension `ERC-20` tokens provide the following functionality: -``` +```solidity contract ERC20 { function totalSupply() public view returns (uint256); function balanceOf(address who) public view returns (uint256); @@ -67,7 +67,7 @@ contract ERC20 { `ERC-20` is extended as follows: -``` +```solidity /** * ERC-1450 is an ERC-20 compatible token that facilitates compliance with one or more of Securities Act Regulations CF, D and A. * diff --git a/EIPS/eip-1485.md b/EIPS/eip-1485.md index 9dbdbcb3ef8114..52b1771cf73fa1 100644 --- a/EIPS/eip-1485.md +++ b/EIPS/eip-1485.md @@ -132,7 +132,7 @@ FNV Mix Algorithm Analysis for TEthashV1 You can compile it with simple in terminal. No additional library needs, -``` +```sh gcc -o fnvtest fnvcltest.c ``` diff --git a/EIPS/eip-1491.md b/EIPS/eip-1491.md index 66502ef07748b6..afdcb83d383dbc 100644 --- a/EIPS/eip-1491.md +++ b/EIPS/eip-1491.md @@ -41,7 +41,7 @@ The BDI software model is an attempt to solve a problem of plans and planning ch #### Main Interface -``` +```solidity pragma solidity ^0.4.25; pragma experimental ABIEncoderV2; @@ -327,7 +327,7 @@ interface IERC_HUCAP { -``` +```solidity interface IERC_HUCAP_TYPES { @@ -359,7 +359,7 @@ interface IERC_HUCAP_TYPES { -``` +```solidity pragma solidity ^0.4.25; pragma experimental ABIEncoderV2; @@ -451,7 +451,7 @@ interface IERC_HUCAP_KEYSIGNING_EXTENSION { ``` #### Human Capital Accounting Extension Interface -``` +```solidity pragma solidity ^0.4.25; pragma experimental ABIEncoderV2; diff --git a/EIPS/eip-1504.md b/EIPS/eip-1504.md index 036064b6b78d33..6746ed4e2763c8 100644 --- a/EIPS/eip-1504.md +++ b/EIPS/eip-1504.md @@ -51,7 +51,7 @@ Below is the specification of Handler interface. In the Handler interface we def Developers have to define their business-related functions as well. -``` +```solidity /// Handler interface. /// Handler defines business related functions. /// Use the interface to ensure that your external services are always supported. @@ -105,7 +105,7 @@ Below is the specification of Data contract. There are three parts in the Data c - **Resource Data**: all other resources that the contract needs to keep and manage. -``` +```solidity /// Data Contract contract DataContract { @@ -236,7 +236,7 @@ Note: - Function status() can be called at any time to show caller status of the upgrader. -``` +```solidity /// Handler upgrader contract Upgrader { // Data contract diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index 91a11d2d20e5db..9c09099b289988 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -202,7 +202,7 @@ For reference, further discussion on this EIP also occurred in the following PRs Assuming ecRecover precompile is perfectly priced, we executed a set of benchmarks comparing Blake2b F compression function precompile with ecRecover precompile. For benchmarks, we used 3.1 GHz Intel Core i7 64-bit machine. -``` +```sh $ sysctl -n machdep.cpu.brand_string Intel(R) Core(TM) i7-7920HQ CPU @ 3.10GHz ``` diff --git a/EIPS/eip-1592.md b/EIPS/eip-1592.md index 3c10b2b397bfaa..da3764bb7d83c1 100644 --- a/EIPS/eip-1592.md +++ b/EIPS/eip-1592.md @@ -105,7 +105,7 @@ To use rules within a token is as easy as having the token inherit from WithRule Below is a template for a rule. -``` +```solidity import "../interface/IRule.sol"; contract TemplateRule is IRule { diff --git a/EIPS/eip-1616.md b/EIPS/eip-1616.md index c22cdec233d9ab..bad066214035c6 100644 --- a/EIPS/eip-1616.md +++ b/EIPS/eip-1616.md @@ -38,7 +38,7 @@ This EIP proposes a light-weight abstraction layer for a standard account metada ## Specification The Attribute Registry interface contains four functions, outlined as follows: -``` +```solidity /** * @title EIP-1616 Attribute Registry Standard interface. EIP-165 ID: 0x5f46473f */ @@ -53,7 +53,7 @@ interface AttributeRegistryInterface { Contracts that comply with the Attribute Registry EIP MUST implement the above interface. As an additional requirement, the ERC-165 interface MUST be included: -``` +```solidity /** * @title EIP-165 interface. EIP-165 ID: 0x01ffc9a7 */ @@ -73,7 +73,7 @@ The implementation MUST follow the specifications described below. The view functions detailed below MUST be implemented. #### `hasAttribute` function -``` +```solidity function hasAttribute(address account, uint256 attributeTypeID) external view returns (bool) ``` @@ -86,7 +86,7 @@ _**NOTE**_: This function MUST return two equal values when performing two direc #### `getAttributeValue` function -``` +```solidity function getAttributeValue(address account, uint256 attributeTypeID) external view returns (uint256) ``` @@ -97,7 +97,7 @@ _**NOTE**_: This function MUST revert if a directly preceding or subsequent func _**NOTE**_: This function MUST return two equal values when performing two directly consecutive function calls with identical `account` and `attributeTypeID` parameters, regardless of differences in the caller's address, the transaction origin, or other out-of-band information. #### `countAttributeTypes` function -``` +```solidity function countAttributeTypes() external view returns (uint256) ``` @@ -108,7 +108,7 @@ _**NOTE**_: This function MUST return a positive integer value - i.e. calling t _**NOTE**_: This function MUST return a value that encompasses all indexes of attribute type IDs whereby a call to `hasAttribute` on some address with an attribute type ID at the given index would return `true`. #### `getAttributeTypeID` function -``` +```solidity function getAttributeTypeID(uint256 index) external view returns (uint256) ``` @@ -136,7 +136,7 @@ Targeted test cases with 100% code coverage can be found at [this repository](ht The basic implementation that follows can be found at [this repository](https://github.com/0age/AttributeRegistry) (see [here](https://github.com/TPL-protocol/tpl-contracts/blob/master/contracts/BasicJurisdiction.sol#L399) for an example of a more complex implementing contract): -``` +```solidity pragma solidity ^0.4.25; /** diff --git a/EIPS/eip-1753.md b/EIPS/eip-1753.md index 16e20a10316249..a4ea4cf71d051e 100644 --- a/EIPS/eip-1753.md +++ b/EIPS/eip-1753.md @@ -165,7 +165,7 @@ Smart contracts can be used to embed regulatory requirements with respect to the ## Interface ### Solidity Example -``` +```solidity interface EIP1753 { string public name; uint256 public totalSupply; diff --git a/EIPS/eip-1844.md b/EIPS/eip-1844.md index 5bb1c2d73ade41..1245ecd5ce6f94 100644 --- a/EIPS/eip-1844.md +++ b/EIPS/eip-1844.md @@ -24,7 +24,7 @@ For example, a token contract may not itself provide any kind of 'atomic swap' f ## Specification A new profile for ENS resolvers is defined, consisting of the following method: -``` +```solidity function interfaceImplementer(bytes32 node, bytes4 interfaceID) external view returns (address); ``` diff --git a/EIPS/eip-1973.md b/EIPS/eip-1973.md index 64c7a9cf15cb61..4f118bc16a596e 100644 --- a/EIPS/eip-1973.md +++ b/EIPS/eip-1973.md @@ -68,8 +68,7 @@ A pull system is required to keep the application completely decentralized and t `tokencontractAddress` : the contract address to which tokens will be minted, default is address(this) -``` -SOLIDITY +```solidity pragma solidity ^0.5.2; diff --git a/EIPS/eip-2045.md b/EIPS/eip-2045.md index 9836b9dbbaa617..ee3f998e59f1a9 100644 --- a/EIPS/eip-2045.md +++ b/EIPS/eip-2045.md @@ -23,7 +23,7 @@ Currently, computational opcode costs are already too close to the minimum unit A new gas counter `particlesUsed` is added to the EVM, in addition to the existing gas counter `gasUsed`. The unit 1 gas is equal to 10000 particles (`PARTICLES_PER_GAS`). The `particlesUsed` counter is only increased for opcodes priced in particles (i.e. opcodes that cost less than 1 gas). If increasing `particlesUsed` results in an excess of 1 gas, then 1 gas is added to `gasUsed` (and deducted from `particlesUsed`). Where the current gas logic looks like this: -``` +```python def vm_execute(ext, msg, code): # Initialize stack, memory, program counter, etc compustate = Compustate(gas=msg.gas) @@ -52,7 +52,7 @@ def vm_execute(ext, msg, code): ``` The new gas logic using particles might look like this: -``` +```python PARTICLES_PER_GAS = 10000 def vm_execute(ext, msg, code): diff --git a/EIPS/eip-2157.md b/EIPS/eip-2157.md index 63685d54a27d55..699c34ba956172 100644 --- a/EIPS/eip-2157.md +++ b/EIPS/eip-2157.md @@ -42,7 +42,7 @@ This pattern of separating data type definitions and storage allows developers t ERC-1900 defines a `contractAddress` field in the type metadata. For the limited purpose of ERC-1900, this field contains the value of the Ethereum type library in which the type definition exists. For the purpose of this ERC, the `contractAddress` will contain the Etherereum address of a `TypeRootContract`. -``` +```solidity contract TypeRootContract { address public libraryAddress; address public storageAddress; @@ -66,7 +66,7 @@ We propose a Solidity CRUD pattern, as described in https://medium.com/robhitche An stub implementation for the TypeStorageContract would look like: -``` +```solidity import './TypeALib.sol'; contract TypeAStorage { diff --git a/EIPS/eip-2255.md b/EIPS/eip-2255.md index 7789a4ea6a1cf4..6cb3a7455ae4f5 100644 --- a/EIPS/eip-2255.md +++ b/EIPS/eip-2255.md @@ -79,7 +79,7 @@ const response = await provider.send({ ``` Would return a value something like this: -``` +```json [ { invoker: 'ens://your-site.eth', diff --git a/EIPS/eip-2266.md b/EIPS/eip-2266.md index d9488ea0276da1..ee693b5c33022a 100644 --- a/EIPS/eip-2266.md +++ b/EIPS/eip-2266.md @@ -49,7 +49,7 @@ The Atomic Swap-based American Call Option smart contract should follow the synt This mapping stores the metadata of the swap contracts, including the parties and tokens involved. Each contract uses different `secretHash`, and is distinguished by `secretHash`. -``` +```solidity mapping(bytes32 => Swap) public swap; ``` @@ -57,7 +57,7 @@ mapping(bytes32 => Swap) public swap; This mapping stores the detail of the asset initiators want to sell, including the amount, the timelock and the state. It is associated with the swap contract with the same `secretHash`. -``` +```solidity mapping(bytes32 => InitiatorAsset) public initiatorAsset; ``` @@ -65,7 +65,7 @@ mapping(bytes32 => InitiatorAsset) public initiatorAsset; This mapping stores the details of the asset participants want to sell, including the amount, the timelock and the state. It is associated with the swap contract with the same `secretHash`. -``` +```solidity mapping(bytes32 => ParticipantAsset) public participantAsset; ``` @@ -73,7 +73,7 @@ mapping(bytes32 => ParticipantAsset) public participantAsset; This mapping stores the details of the premium initiators attach in the swap contract, including the amount, the timelock and the state. It is associated with the swap contract with the same `secretHash`. -``` +```solidity mapping(bytes32 => Premium) public premium; ``` @@ -84,7 +84,7 @@ mapping(bytes32 => Premium) public premium; This function sets up the swap contract, including the both parties involved, the tokens to exchanged, and so on. -``` +```solidity function setup(bytes32 secretHash, address payable initiator, address tokenA, address tokenB, uint256 initiatorAssetAmount, address payable participant, uint256 participantAssetAmount, uint256 premiumAmount) public payable ``` @@ -92,7 +92,7 @@ function setup(bytes32 secretHash, address payable initiator, address tokenA, ad The initiator invokes this function to fill and lock the token she/he wants to sell and join the contract. -``` +```solidity function initiate(bytes32 secretHash, uint256 assetRefundTime) public payable ``` @@ -100,7 +100,7 @@ function initiate(bytes32 secretHash, uint256 assetRefundTime) public payable The initiator invokes this function to fill and lock the premium. -``` +```solidity function fillPremium(bytes32 secretHash, uint256 premiumRefundTime) public payable ``` @@ -108,7 +108,7 @@ function fillPremium(bytes32 secretHash, uint256 premiumRefundTime) public payab The participant invokes this function to fill and lock the token she/he wants to sell and join the contract. -``` +```solidity function participate(bytes32 secretHash, uint256 assetRefundTime) public payable ``` @@ -116,7 +116,7 @@ function participate(bytes32 secretHash, uint256 assetRefundTime) public payable One of the parties invokes this function to get the token from the other party, by providing the preimage of the hash lock `secret`. -``` +```solidity function redeemAsset(bytes32 secret, bytes32 secretHash) public ``` @@ -124,7 +124,7 @@ function redeemAsset(bytes32 secret, bytes32 secretHash) public One of the parties invokes this function to get the token back after the timelock expires. -``` +```solidity function refundAsset(bytes32 secretHash) public ``` @@ -132,7 +132,7 @@ function refundAsset(bytes32 secretHash) public The participant invokes this function to get the premium. This can be invoked only if the participant has already invoked `participate` and the participant's token is redeemed or refunded. -``` +```solidity function redeemPremium(bytes32 secretHash) public ``` @@ -140,7 +140,7 @@ function redeemPremium(bytes32 secretHash) public The initiator invokes this function to get the premium back after the timelock expires. -``` +```solidity function refundPremium(bytes32 secretHash) public ``` @@ -151,7 +151,7 @@ function refundPremium(bytes32 secretHash) public This event indicates that one party has set up the contract using the function `setup()`. -``` +```solidity event SetUp(bytes32 secretHash, address initiator, address participant, address tokenA, address tokenB, uint256 initiatorAssetAmount, uint256 participantAssetAmount, uint256 premiumAmount); ``` @@ -159,7 +159,7 @@ event SetUp(bytes32 secretHash, address initiator, address participant, address This event indicates that `initiator` has filled and locked the token to be exchanged using the function `initiate()`. -``` +```solidity event Initiated(uint256 initiateTimestamp, bytes32 secretHash, address initiator, address participant, address initiatorAssetToken, uint256 initiatorAssetAmount, uint256 initiatorAssetRefundTimestamp); ``` @@ -167,7 +167,7 @@ event Initiated(uint256 initiateTimestamp, bytes32 secretHash, address initiator This event indicates that `participant` has filled and locked the token to be exchanged using the function `participate()`. -``` +```solidity event Participated(uint256 participateTimestamp, bytes32 secretHash, address initiator, address participant, address participantAssetToken, uint256 participantAssetAmount, uint256 participantAssetRefundTimestamp); ``` @@ -175,7 +175,7 @@ event Participated(uint256 participateTimestamp, bytes32 secretHash, address ini This event indicates that `initiator` has filled and locked `premium` using the function `fillPremium()`. -``` +```solidity event PremiumFilled(uint256 fillPremiumTimestamp, bytes32 secretHash, address initiator, address participant, address premiumToken, uint256 premiumAmount, uint256 premiumRefundTimestamp); ``` @@ -183,11 +183,11 @@ event PremiumFilled(uint256 fillPremiumTimestamp, bytes32 secretHash, address in These two events indicate that `asset` has been redeemed by the other party before the timelock by providing `secret`. -``` +```solidity event InitiatorAssetRedeemed(uint256 redeemTimestamp, bytes32 secretHash, bytes32 secret, address redeemer, address assetToken, uint256 amount); ``` -``` +```solidity event ParticipantAssetRedeemed(uint256 redeemTimestamp, bytes32 secretHash, bytes32 secret, address redeemer, address assetToken, uint256 amount); ``` @@ -195,11 +195,11 @@ event ParticipantAssetRedeemed(uint256 redeemTimestamp, bytes32 secretHash, byte These two events indicate that `asset` has been refunded by the original owner after the timelock expires. -``` +```solidity event InitiatorAssetRefunded(uint256 refundTimestamp, bytes32 secretHash, address refunder, address assetToken, uint256 amount); ``` -``` +```solidity event ParticipantAssetRefunded(uint256 refundTimestamp, bytes32 secretHash, address refunder, address assetToken, uint256 amount); ``` @@ -207,7 +207,7 @@ event ParticipantAssetRefunded(uint256 refundTimestamp, bytes32 secretHash, addr This event indicates that `premium` has been redeemed by `participant`. This implies that `asset` is either redeemed by `initiator` if it can provide the preimage of `secrectHash` before `asset` timelock expires; or refunded by `participant` if `asset` timelock expires. -``` +```solidity event PremiumRedeemed(uint256 redeemTimestamp,bytes32 secretHash,address redeemer,address token,uint256 amount); ``` @@ -215,7 +215,7 @@ event PremiumRedeemed(uint256 redeemTimestamp,bytes32 secretHash,address redeeme This event indicates that `premium` has been refunded back to `initiator`, because of `participant` doesn't participate at all, by the time of `premium` timelock expires. -``` +```solidity event PremiumRefunded(uint256 refundTimestamp, bytes32 secretHash, address refunder, address token, uint256 amount); ``` diff --git a/EIPS/eip-2304.md b/EIPS/eip-2304.md index a7e20fe103e927..73d4289c6db56c 100644 --- a/EIPS/eip-2304.md +++ b/EIPS/eip-2304.md @@ -22,8 +22,7 @@ With the increasing uptake of ENS by multi-coin wallets, wallet authors have req A new accessor function for resolvers is specified: -``` - +```solidity function addr(bytes32 node, uint coinType) external view returns(bytes memory); ``` @@ -37,7 +36,7 @@ The return value is the cryptocurency address in its native binary format. Detai A new event for resolvers is defined: -``` +```solidity event AddressChanged(bytes32 indexed node, uint coinType, bytes newAddress); ``` @@ -47,7 +46,7 @@ Resolvers MUST emit this event on each change to the address for a name and coin The following function provides the recommended interface for changing the addresses stored for a node. Resolvers SHOULD implement this interface for setting addresses unless their needs dictate a different interface. -``` +```solidity function setAddr(bytes32 node, uint coinType, bytes calldata addr); ``` @@ -125,7 +124,7 @@ For example, the BNB address `bnb1grpf0955h0ykzq3ar5nmum7y6gdfl6lxfn46h2` decode An example implementation of a resolver that supports this EIP is provided here: -``` +```solidity pragma solidity ^0.5.8; contract AddrResolver is ResolverBase { diff --git a/EIPS/eip-706.md b/EIPS/eip-706.md index 4211c23b75a42c..93e80d3d13e84d 100644 --- a/EIPS/eip-706.md +++ b/EIPS/eip-706.md @@ -94,7 +94,7 @@ You can verify that an encoded binary can be decoded into the proper plaintext u ### Go -``` +```sh $ go get https://github.com/golang/snappy ``` @@ -144,7 +144,7 @@ func main() { } ``` -``` +```sh $ go run main.go block.rlp block.go.snappy Yay, decompressed data matched provided plain text! @@ -182,7 +182,7 @@ else: print "Yay, decompressed data matched provided plain text!" ``` -``` +```sh $ python main.py block.rlp block.go.snappy Yay, decompressed data matched provided plain text! diff --git a/EIPS/eip-779.md b/EIPS/eip-779.md index 1d658b08547795..44deca5f094275 100644 --- a/EIPS/eip-779.md +++ b/EIPS/eip-779.md @@ -28,7 +28,7 @@ At block 1880000, the following accounts are encoded into a list `L`: At the beginning of block 1920000, all ether throughout all accounts in `L` will be transferred to a contract deployed at `0xbf4ed7b27f1d666546e30d74d50d173d20bca754`. The contract was created from the following Solidity code (compiler version `v0.3.5-2016-07-01-48238c9`): -``` +```solidity // Deployed on mainnet at 0xbf4ed7b27f1d666546e30d74d50d173d20bca754 contract DAO { diff --git a/EIPS/eip-823.md b/EIPS/eip-823.md index 49152b45decfce..f21a6ed20af317 100644 --- a/EIPS/eip-823.md +++ b/EIPS/eip-823.md @@ -26,13 +26,13 @@ This interface must be inherited by a ERC20 token contract that wants to exchang ##### exchnagedWith This mapping stores the number of tokens exchanged with another token, along with the latter’s address. Every time more tokens are exchanged the integer value is incremented consequently. This mapping acts as a record to denote which target contract holds our tokens. -``` js +```solidity mapping ( address => uint ) private exchangedWith; ``` ##### exchangedBy This mapping stores the address of the person who initiated the exchange and the amount of tokens exchanged. -``` js +```solidity mapping ( address => uint ) private exhangedBy; ``` @@ -43,14 +43,14 @@ NOTE: Callers MUST handle false from returns (bool success). Callers MUST NOT as ##### exchangeToken This function calls the intermediate exchange service contract that handles the exchanges. This function takes the address of the target contract and the amount we want to exchange as parameters and returns boolean `success` and `creditedAmount`. -``` js +```solidity function exchangeToken(address _targetContract, uint _amount) public returns(bool success, uint creditedAmount) ``` ##### exchangeAndSpend This function calls an intermediate exchange service contract that handles exchange and expenditure. This function takes the address of the target contract, the amount we want to spend in terms of target contract tokens and address of the receiver as parameters and returns boolean `success`. -``` js +```solidity function exchangeAndSpend(address _targetContract, uint _amount,address _to) public returns(bool success) ``` @@ -59,7 +59,7 @@ This function is called by the exchange service contract to our token contract t NOTE: It is required that only the exchange service contract has the authority to call this function. -``` js +```solidity function __exchangerCallback(address _targetContract,address _exchanger, uint _amount) public returns(bool success) ``` @@ -68,14 +68,14 @@ function __exchangerCallback(address _targetContract,address _exchanger, uint _a ##### Exchange This event logs any new exchanges that have taken place. -``` js +```solidity event Exchange(address _from, address _ targetContract, uint _amount) ``` ##### ExchangeSpent This event logs any new exchange that have taken place and have been spent immediately. -``` js +```solidity event ExchangeSpent(address _from, address _targetContract, address _to, uint _amount) ``` @@ -86,7 +86,7 @@ This interface must be inherited by a ERC20 token contract that wants to receive ##### exchangesRecieved This mapping stores the number of tokens received in terms of another token, along with its address. Every time more tokens are exchanged the integer value is incremented consequently. This mapping acts as a record to denote which tokens do this contract holds apart from its own. -``` js +```solidity mapping ( address => uint ) private exchnagesReceived; ``` #### Methods @@ -98,7 +98,7 @@ This function is called by the intermediate exchange service contract. This func NOTE: It is required that only the exchange service contract has the authority to call this function. -``` js +```solidity function __targetExchangeCallback (uint _to, uint _amount) public returns(bool success) ``` @@ -107,7 +107,7 @@ This function is called by the intermediate exchange service contract. This func NOTE: It is required that only the exchange service contract has the authority to call this function. -``` js +```solidity function __targetExchangeAndSpendCallback (address _from, address _to, uint _amount) public returns(bool success) ``` @@ -115,13 +115,13 @@ function __targetExchangeAndSpendCallback (address _from, address _to, uint _amo ##### Exchange This event logs any new exchanges that have taken place. -``` js +```solidity event Exchange(address _from, address _with, uint _amount) ``` ##### ExchangeSpent This event logs any new exchange that have taken place and have been spent immediately. -``` js +```solidity event ExchangeSpent(address _from, address _ targetContract, address _to, uint _amount) ``` @@ -135,7 +135,7 @@ This is an intermediate contract that provides a gateway for exchanges and expen This array stores all the tokens that are registered for exchange. Only register tokens can participate in exhanges. -``` js +```solidity address[] private registeredTokens; ``` @@ -147,7 +147,7 @@ This function is called by the owner of the token contract to get it’s tokens NOTE: Before any exchange it must be ensured that the token is registered. -``` js +```solidity function registerToken(address _token) public returns(bool success) ``` @@ -155,7 +155,7 @@ function registerToken(address _token) public returns(bool success) This function is called by the token holder who wants to exchange his token with the `_targetContract` tokens. This function queries the exchange rate, calculates the converted amount, calls `__exchangerCallback` and calls the `__targetExchangeCallback`. It takes address of the target contract and amount to exchange as parameter and returns boolean `success` and amount credited. -``` js +```solidity function exchangeToken(address _targetContract, uint _amount, address _from) public returns(bool success, uint creditedAmount) ``` @@ -163,7 +163,7 @@ function exchangeToken(address _targetContract, uint _amount, address _from) pub This function is called by the token holder who wants to exchange his token with the `_targetContract` tokens. This function queries the exchange rate, calculates the converted amount, calls `__exchangerCallback` and calls the `__targetExchangeAndSpendCallback`. It takes address of the target contract and amount to exchange as parameter and returns boolean `success` and amount credited. -``` js +```solidity function exchangeAndSpend(address _targetContract, uint _amount, address _from, address _to) public returns(bool success) ``` @@ -173,14 +173,14 @@ function exchangeAndSpend(address _targetContract, uint _amount, address _from, This event logs any new exchanges that have taken place. -``` js +```solidity event Exchange( address _from, address _by, uint _value ,address _target ) ``` ##### ExchangeAndSpent This event logs any new exchange that have taken place and have been spent immediately. -``` js +```solidity event ExchangeAndSpent ( address _from, address _by, uint _value ,address _target ,address _to) ``` diff --git a/EIPS/eip-875.md b/EIPS/eip-875.md index be9d5bdf63f242..4e6f2c1a5d57fd 100644 --- a/EIPS/eip-875.md +++ b/EIPS/eip-875.md @@ -63,7 +63,7 @@ Some protections need to be added to the message such as encoding the chain id, ## Interface -``` +```solidity contract ERC165 { /// @notice Query if a contract implements an interface diff --git a/EIPS/eip-926.md b/EIPS/eip-926.md index b84973769e80fe..1fe66569af2884 100644 --- a/EIPS/eip-926.md +++ b/EIPS/eip-926.md @@ -17,7 +17,7 @@ An increasing set of use cases require storage of metadata associated with an ad ## Specification The metadata registry has the following interface: -``` +```solidity interface AddressMetadataRegistry { function provider(address target) view returns(address); function setProvider(address _provider); @@ -34,7 +34,7 @@ Providers may implement any subset of the metadata record types specified here. Providers have one mandatory function: -``` +```solidity function supportsInterface(bytes4 interfaceID) constant returns (bool) ``` @@ -59,7 +59,7 @@ There are no backwards compatibility concerns. ## Implementation The canonical implementation of the metadata registry is as follows: -``` +```solidity contract AddressMetadataRegistry { mapping(address=>address) public provider; diff --git a/EIPS/eip-927.md b/EIPS/eip-927.md index b36910099f1c87..d24610b9f59df3 100644 --- a/EIPS/eip-927.md +++ b/EIPS/eip-927.md @@ -20,7 +20,7 @@ The pattern implemented here is inspired by [ds-auth](https://github.com/dapphub ## Specification The generalised authorisation interface is implemented as a metadata provider, as specified in EIP 926. The following mandatory function is implemented: -``` +```solidity function canCall(address owner, address caller, address callee, bytes4 func) view returns(bool); ``` @@ -39,7 +39,7 @@ As this standard uses EIP 926, the authorisation flow is as follows: Commonly, providers will wish to supply a standardised interface for users to set and unset their own authorisations. They SHOULD implement the following interface: -``` +```solidity function authoriseCaller(address owner, address caller, address callee, bytes4 func); function revokeCaller(address owner, address caller, address callee, bytes4 func); ``` diff --git a/EIPS/eip-999.md b/EIPS/eip-999.md index ce0389d978daeb..d1d75069aea30f 100644 --- a/EIPS/eip-999.md +++ b/EIPS/eip-999.md @@ -44,7 +44,7 @@ shall be replaced with a patched version of the as reviewed, tested, and approved in [parity-contracts/0x863df6bfa4](https://github.com/parity-contracts/0x863df6bfa4): -``` +```json { "object": "606060405234156200000d57fe5b5b6000808054806001018281620000259190620002d9565b916000526020600020900160005b6000909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506200012081805480602002602001604051908101604052809291908181526020018280548015620000fd57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311620000b2575b505050505060016000620001286401000000000262001d46176401000000009004565b5b5062000330565b600060015411156200013a5760006000fd5b6200015981620001806401000000000262001d71176401000000009004565b620001798383620001c26401000000000262001d9c176401000000009004565b5b5b505050565b60006001541115620001925760006000fd5b80600281905550620001b7620002c16401000000000262001bcf176401000000009004565b6004819055505b5b50565b600060006001541115620001d65760006000fd5b600082111515620001e75760006000fd5b81835110151515620001f95760006000fd5b8251600181905550600090505b8251811015620002b35782818151811015156200021f57fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff16600582600101610100811015156200025357fe5b0160005b508190555080600101610105600085848151811015156200027457fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b80600101905062000206565b816000819055505b5b505050565b60006201518042811515620002d257fe5b0490505b90565b815481835581811511620003035781836000526020600020918201910162000302919062000308565b5b505050565b6200032d91905b80821115620003295760008160009055506001016200030f565b5090565b90565b611ebf80620003406000396000f300606060405236156100ef576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063173825d91461016d5780632f54bf6e146101a35780634123cb6b146101f157806352375093146102175780635c52c2f51461023d578063659010e71461024f5780637065cb4814610275578063746c9171146102ab578063797af627146102d1578063b20d30a91461030d578063b61d27f61461032d578063b75c7dc61461039c578063ba51a6df146103c0578063c2cf7326146103e0578063c41a360a1461043b578063f00d4b5d1461049b578063f1736d86146104f0575b61016b5b6000341115610168577fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c3334604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a15b5b565b005b341561017557fe5b6101a1600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610516565b005b34156101ab57fe5b6101d7600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610659565b604051808215151515815260200191505060405180910390f35b34156101f957fe5b610201610691565b6040518082815260200191505060405180910390f35b341561021f57fe5b610227610697565b6040518082815260200191505060405180910390f35b341561024557fe5b61024d61069d565b005b341561025757fe5b61025f6106d7565b6040518082815260200191505060405180910390f35b341561027d57fe5b6102a9600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506106dd565b005b34156102b357fe5b6102bb610829565b6040518082815260200191505060405180910390f35b34156102d957fe5b6102f360048080356000191690602001909190505061082f565b604051808215151515815260200191505060405180910390f35b341561031557fe5b61032b6004808035906020019091905050610dcc565b005b341561033557fe5b61037e600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919080359060200190820180359060200191909192905050610e06565b60405180826000191660001916815260200191505060405180910390f35b34156103a457fe5b6103be60048080356000191690602001909190505061127d565b005b34156103c857fe5b6103de6004808035906020019091905050611392565b005b34156103e857fe5b61042160048080356000191690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061141a565b604051808215151515815260200191505060405180910390f35b341561044357fe5b610459600480803590602001909190505061149c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156104a357fe5b6104ee600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506114bf565b005b34156104f857fe5b610500611672565b6040518082815260200191505060405180910390f35b600060003660405180838380828437820191505092505050604051809103902061053f81611678565b156106535761010560008473ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549150600082141561057f57610652565b600160015403600054111561059357610652565b6000600583610100811015156105a557fe5b0160005b5081905550600061010560008573ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506105e6611890565b6105ee6119d0565b7f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da83604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15b5b5b505050565b6000600061010560008473ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541190505b919050565b60015481565b60045481565b6000366040518083838082843782019150509250505060405180910390206106c481611678565b156106d35760006003819055505b5b5b50565b60035481565b60003660405180838380828437820191505092505050604051809103902061070481611678565b156108245761071282610659565b1561071c57610823565b610724611890565b60fa600154101515610739576107386119d0565b5b60fa60015410151561074a57610823565b6001600081548092919060010191905055508173ffffffffffffffffffffffffffffffffffffffff1660056001546101008110151561078557fe5b0160005b508190555060015461010560008473ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c382604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15b5b5b5050565b60005481565b600060008261083d81611678565b15610dc45760006101086000866000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415806108c757506000610108600086600019166000191681526020019081526020016000206001015414155b80610906575060006101086000866000191660001916815260200190815260200160002060020180546001816001161561010002031660029004905014155b15610dc25760006101086000866000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610a5057610a496101086000866000191660001916815260200190815260200160002060010154610108600087600019166000191681526020019081526020016000206002018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a3f5780601f10610a1457610100808354040283529160200191610a3f565b820191906000526020600020905b815481529060010190602001808311610a2257829003601f168201915b5050505050611b37565b9150610b71565b6101086000856000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166101086000866000191660001916815260200190815260200160002060010154610108600087600019166000191681526020019081526020016000206002016040518082805460018160011615610100020316600290048015610b4a5780601f10610b1f57610100808354040283529160200191610b4a565b820191906000526020600020905b815481529060010190602001808311610b2d57829003601f168201915b505091505060006040518083038185876185025a03f1925050501515610b705760006000fd5b5b7fe3a3a4111a84df27d76b68dc721e65c7711605ea5eee4afd3a9c58195217365c338561010860008860001916600019168152602001908152602001600020600101546101086000896000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1661010860008a6000191660001916815260200190815260200160002060020187604051808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200186600019166000191681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015610d475780601f10610d1c57610100808354040283529160200191610d47565b820191906000526020600020905b815481529060010190602001808311610d2a57829003601f168201915b505097505050505050505060405180910390a16101086000856000191660001916815260200190815260200160002060006000820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160009055600282016000610db79190611be6565b505060019250610dc3565b5b5b5b5050919050565b600036604051808383808284378201915050925050506040518091039020610df381611678565b15610e0157816002819055505b5b5b5050565b60006000610e1333610659565b1561127357600084849050148015610e305750610e2f85611b51565b5b80610e3d57506001600054145b15610fed5760008673ffffffffffffffffffffffffffffffffffffffff161415610ea457610e9d8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050611b37565b9050610ef3565b8573ffffffffffffffffffffffffffffffffffffffff168585856040518083838082843782019150509250505060006040518083038185876185025a03f1925050501515610ef25760006000fd5b5b7f9738cd1a8777c86b011f7b01d87d484217dc6ab5154a9d41eda5d14af8caf292338688878786604051808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281038252858582818152602001925080828437820191505097505050505050505060405180910390a1611271565b6000364360405180848480828437820191505082815260200193505050506040518091039020915060006101086000846000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16148015611099575060006101086000846000191660001916815260200190815260200160002060010154145b80156110d85750600061010860008460001916600019168152602001908152602001600020600201805460018160011615610100020316600290049050145b1561118f57856101086000846000191660001916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550846101086000846000191660001916815260200190815260200160002060010181905550838361010860008560001916600019168152602001908152602001600020600201919061118d929190611c2e565b505b6111988261082f565b1515611270577f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328233878988886040518087600019166000191681526020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b5b5b5b5b50949350505050565b60006000600061010560003373ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054925060008314156112be5761138c565b8260020a9150610106600085600019166000191681526020019081526020016000209050600082826001015416111561138b5780600001600081548092919060010191905055508181600101600082825403925050819055507fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b3385604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182600019166000191681526020019250505060405180910390a15b5b50505050565b6000366040518083838082843782019150509250505060405180910390206113b981611678565b15611415576001548211156113cd57611414565b816000819055506113dc611890565b7facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da826040518082815260200191505060405180910390a15b5b5b5050565b600060006000600061010660008760001916600019168152602001908152602001600020925061010560008673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549150600082141561147f5760009350611493565b8160020a9050600081846001015416141593505b50505092915050565b6000600560018301610100811015156114b157fe5b0160005b505490505b919050565b60006000366040518083838082843782019150509250505060405180910390206114e881611678565b1561166b576114f683610659565b156115005761166a565b61010560008573ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549150600082141561153b5761166a565b611543611890565b8273ffffffffffffffffffffffffffffffffffffffff166005836101008110151561156a57fe5b0160005b5081905550600061010560008673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508161010560008573ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c8484604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15b5b5b50505050565b60025481565b600060006000600061010560003373ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054925060008314156116bb57611888565b6101066000866000191660001916815260200190815260200160002091506000826000015414156117455760005482600001819055506000826001018190555061010780548091906001016117109190611cae565b826002018190555084610107836002015481548110151561172d57fe5b906000526020600020900160005b5081600019169055505b8260020a90506000818360010154161415611887577fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda3386604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182600019166000191681526020019250505060405180910390a16001826000015411151561185e57610107610106600087600019166000191681526020019081526020016000206002015481548110151561180a57fe5b906000526020600020900160005b5060009055610106600086600019166000191681526020019081526020016000206000600082016000905560018201600090556002820160009055505060019350611888565b8160000160008154809291906001900391905055508082600101600082825417925050819055505b5b5b505050919050565b60006000610107805490509150600090505b818110156119bc576101086000610107838154811015156118bf57fe5b906000526020600020900160005b50546000191660001916815260200190815260200160002060006000820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905560018201600090556002820160006119269190611be6565b505060006001026101078281548110151561193d57fe5b906000526020600020900160005b5054600019161415156119b05761010660006101078381548110151561196d57fe5b906000526020600020900160005b505460001916600019168152602001908152602001600020600060008201600090556001820160009055600282016000905550505b5b8060010190506118a2565b61010760006119cb9190611cda565b5b5050565b6000600190505b600154811015611b33575b60015481108015611a095750600060058261010081101515611a0057fe5b0160005b505414155b15611a1b5780806001019150506119e2565b5b6001600154118015611a4557506000600560015461010081101515611a3d57fe5b0160005b5054145b15611a625760016000815480929190600190039190505550611a1c565b60015481108015611a8b57506000600560015461010081101515611a8257fe5b0160005b505414155b8015611aac5750600060058261010081101515611aa457fe5b0160005b5054145b15611b2e57600560015461010081101515611ac357fe5b0160005b505460058261010081101515611ad957fe5b0160005b508190555080610105600060058461010081101515611af857fe5b0160005b50548152602001908152602001600020819055506000600560015461010081101515611b2457fe5b0160005b50819055505b6119d7565b5b50565b600081516020830184f09050803b15610000575b92915050565b6000611b5c33610659565b15611bc957600454611b6c611bcf565b1115611b89576000600381905550611b82611bcf565b6004819055505b600354826003540110158015611ba55750600254826003540111155b15611bc3578160036000828254019250508190555060019050611bc8565b600090505b5b5b919050565b60006201518042811515611bdf57fe5b0490505b90565b50805460018160011615610100020316600290046000825580601f10611c0c5750611c2b565b601f016020900490600052602060002090810190611c2a9190611cfc565b5b50565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611c6f57803560ff1916838001178555611c9d565b82800160010185558215611c9d579182015b82811115611c9c578235825591602001919060010190611c81565b5b509050611caa9190611cfc565b5090565b815481835581811511611cd557818360005260206000209182019101611cd49190611d21565b5b505050565b5080546000825590600052602060002090810190611cf89190611d21565b5b50565b611d1e91905b80821115611d1a576000816000905550600101611d02565b5090565b90565b611d4391905b80821115611d3f576000816000905550600101611d27565b5090565b90565b60006001541115611d575760006000fd5b611d6081611d71565b611d6a8383611d9c565b5b5b505050565b60006001541115611d825760006000fd5b80600281905550611d91611bcf565b6004819055505b5b50565b600060006001541115611daf5760006000fd5b600082111515611dbf5760006000fd5b81835110151515611dd05760006000fd5b8251600181905550600090505b8251811015611e85578281815181101515611df457fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1660058260010161010081101515611e2757fe5b0160005b50819055508060010161010560008584815181101515611e4757fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b806001019050611ddd565b816000819055505b5b5050505600a165627a7a7230582016889f0740f073d397f9d00b0d19900fb050b957e3e2942f861085beb9baab180029", "opcodes": "PUSH1 0x60 PUSH1 0x40 MSTORE CALLVALUE ISZERO PUSH3 0xD JUMPI INVALID JUMPDEST JUMPDEST PUSH1 0x0 DUP1 DUP1 SLOAD DUP1 PUSH1 0x1 ADD DUP3 DUP2 PUSH3 0x25 SWAP2 SWAP1 PUSH3 0x2D9 JUMP JUMPDEST SWAP2 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP1 ADD PUSH1 0x0 JUMPDEST PUSH1 0x0 SWAP1 SWAP2 SWAP1 SWAP2 PUSH2 0x100 EXP DUP2 SLOAD DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND MUL OR SWAP1 SSTORE POP POP PUSH3 0x120 DUP2 DUP1 SLOAD DUP1 PUSH1 0x20 MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP1 SLOAD DUP1 ISZERO PUSH3 0xFD JUMPI PUSH1 0x20 MUL DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP1 JUMPDEST DUP2 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 PUSH1 0x1 ADD SWAP1 DUP1 DUP4 GT PUSH3 0xB2 JUMPI JUMPDEST POP POP POP POP POP PUSH1 0x1 PUSH1 0x0 PUSH3 0x128 PUSH5 0x100000000 MUL PUSH3 0x1D46 OR PUSH5 0x100000000 SWAP1 DIV JUMP JUMPDEST JUMPDEST POP PUSH3 0x330 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 SLOAD GT ISZERO PUSH3 0x13A JUMPI PUSH1 0x0 PUSH1 0x0 REVERT JUMPDEST PUSH3 0x159 DUP2 PUSH3 0x180 PUSH5 0x100000000 MUL PUSH3 0x1D71 OR PUSH5 0x100000000 SWAP1 DIV JUMP JUMPDEST PUSH3 0x179 DUP4 DUP4 PUSH3 0x1C2 PUSH5 0x100000000 MUL PUSH3 0x1D9C OR PUSH5 0x100000000 SWAP1 DIV JUMP JUMPDEST JUMPDEST JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 SLOAD GT ISZERO PUSH3 0x192 JUMPI PUSH1 0x0 PUSH1 0x0 REVERT JUMPDEST DUP1 PUSH1 0x2 DUP2 SWAP1 SSTORE POP PUSH3 0x1B7 PUSH3 0x2C1 PUSH5 0x100000000 MUL PUSH3 0x1BCF OR PUSH5 0x100000000 SWAP1 DIV JUMP JUMPDEST PUSH1 0x4 DUP2 SWAP1 SSTORE POP JUMPDEST JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x0 PUSH1 0x1 SLOAD GT ISZERO PUSH3 0x1D6 JUMPI PUSH1 0x0 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 DUP3 GT ISZERO ISZERO PUSH3 0x1E7 JUMPI PUSH1 0x0 PUSH1 0x0 REVERT JUMPDEST DUP2 DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH3 0x1F9 JUMPI PUSH1 0x0 PUSH1 0x0 REVERT JUMPDEST DUP3 MLOAD PUSH1 0x1 DUP2 SWAP1 SSTORE POP PUSH1 0x0 SWAP1 POP JUMPDEST DUP3 MLOAD DUP2 LT ISZERO PUSH3 0x2B3 JUMPI DUP3 DUP2 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH3 0x21F JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x5 DUP3 PUSH1 0x1 ADD PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH3 0x253 JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP DUP2 SWAP1 SSTORE POP DUP1 PUSH1 0x1 ADD PUSH2 0x105 PUSH1 0x0 DUP6 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH3 0x274 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 DUP2 SWAP1 SSTORE POP JUMPDEST DUP1 PUSH1 0x1 ADD SWAP1 POP PUSH3 0x206 JUMP JUMPDEST DUP2 PUSH1 0x0 DUP2 SWAP1 SSTORE POP JUMPDEST JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH3 0x15180 TIMESTAMP DUP2 ISZERO ISZERO PUSH3 0x2D2 JUMPI INVALID JUMPDEST DIV SWAP1 POP JUMPDEST SWAP1 JUMP JUMPDEST DUP2 SLOAD DUP2 DUP4 SSTORE DUP2 DUP2 ISZERO GT PUSH3 0x303 JUMPI DUP2 DUP4 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP2 DUP3 ADD SWAP2 ADD PUSH3 0x302 SWAP2 SWAP1 PUSH3 0x308 JUMP JUMPDEST JUMPDEST POP POP POP JUMP JUMPDEST PUSH3 0x32D SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH3 0x329 JUMPI PUSH1 0x0 DUP2 PUSH1 0x0 SWAP1 SSTORE POP PUSH1 0x1 ADD PUSH3 0x30F JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH2 0x1EBF DUP1 PUSH3 0x340 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x60 PUSH1 0x40 MSTORE CALLDATASIZE ISZERO PUSH2 0xEF JUMPI PUSH1 0x0 CALLDATALOAD PUSH29 0x100000000000000000000000000000000000000000000000000000000 SWAP1 DIV PUSH4 0xFFFFFFFF AND DUP1 PUSH4 0x173825D9 EQ PUSH2 0x16D JUMPI DUP1 PUSH4 0x2F54BF6E EQ PUSH2 0x1A3 JUMPI DUP1 PUSH4 0x4123CB6B EQ PUSH2 0x1F1 JUMPI DUP1 PUSH4 0x52375093 EQ PUSH2 0x217 JUMPI DUP1 PUSH4 0x5C52C2F5 EQ PUSH2 0x23D JUMPI DUP1 PUSH4 0x659010E7 EQ PUSH2 0x24F JUMPI DUP1 PUSH4 0x7065CB48 EQ PUSH2 0x275 JUMPI DUP1 PUSH4 0x746C9171 EQ PUSH2 0x2AB JUMPI DUP1 PUSH4 0x797AF627 EQ PUSH2 0x2D1 JUMPI DUP1 PUSH4 0xB20D30A9 EQ PUSH2 0x30D JUMPI DUP1 PUSH4 0xB61D27F6 EQ PUSH2 0x32D JUMPI DUP1 PUSH4 0xB75C7DC6 EQ PUSH2 0x39C JUMPI DUP1 PUSH4 0xBA51A6DF EQ PUSH2 0x3C0 JUMPI DUP1 PUSH4 0xC2CF7326 EQ PUSH2 0x3E0 JUMPI DUP1 PUSH4 0xC41A360A EQ PUSH2 0x43B JUMPI DUP1 PUSH4 0xF00D4B5D EQ PUSH2 0x49B JUMPI DUP1 PUSH4 0xF1736D86 EQ PUSH2 0x4F0 JUMPI JUMPDEST PUSH2 0x16B JUMPDEST PUSH1 0x0 CALLVALUE GT ISZERO PUSH2 0x168 JUMPI PUSH32 0xE1FFFCC4923D04B559F4D29A8BFC6CDA04EB5B0D3C460751C2402C5C5CC9109C CALLER CALLVALUE PUSH1 0x40 MLOAD DUP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 JUMPDEST JUMPDEST JUMP JUMPDEST STOP JUMPDEST CALLVALUE ISZERO PUSH2 0x175 JUMPI INVALID JUMPDEST PUSH2 0x1A1 PUSH1 0x4 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 POP POP PUSH2 0x516 JUMP JUMPDEST STOP JUMPDEST CALLVALUE ISZERO PUSH2 0x1AB JUMPI INVALID JUMPDEST PUSH2 0x1D7 PUSH1 0x4 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 POP POP PUSH2 0x659 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE ISZERO PUSH2 0x1F9 JUMPI INVALID JUMPDEST PUSH2 0x201 PUSH2 0x691 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE ISZERO PUSH2 0x21F JUMPI INVALID JUMPDEST PUSH2 0x227 PUSH2 0x697 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE ISZERO PUSH2 0x245 JUMPI INVALID JUMPDEST PUSH2 0x24D PUSH2 0x69D JUMP JUMPDEST STOP JUMPDEST CALLVALUE ISZERO PUSH2 0x257 JUMPI INVALID JUMPDEST PUSH2 0x25F PUSH2 0x6D7 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE ISZERO PUSH2 0x27D JUMPI INVALID JUMPDEST PUSH2 0x2A9 PUSH1 0x4 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 POP POP PUSH2 0x6DD JUMP JUMPDEST STOP JUMPDEST CALLVALUE ISZERO PUSH2 0x2B3 JUMPI INVALID JUMPDEST PUSH2 0x2BB PUSH2 0x829 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE ISZERO PUSH2 0x2D9 JUMPI INVALID JUMPDEST PUSH2 0x2F3 PUSH1 0x4 DUP1 DUP1 CALLDATALOAD PUSH1 0x0 NOT AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 POP POP PUSH2 0x82F JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE ISZERO PUSH2 0x315 JUMPI INVALID JUMPDEST PUSH2 0x32B PUSH1 0x4 DUP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 POP POP PUSH2 0xDCC JUMP JUMPDEST STOP JUMPDEST CALLVALUE ISZERO PUSH2 0x335 JUMPI INVALID JUMPDEST PUSH2 0x37E PUSH1 0x4 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP3 ADD DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP2 SWAP1 SWAP2 SWAP3 SWAP1 POP POP PUSH2 0xE06 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE ISZERO PUSH2 0x3A4 JUMPI INVALID JUMPDEST PUSH2 0x3BE PUSH1 0x4 DUP1 DUP1 CALLDATALOAD PUSH1 0x0 NOT AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 POP POP PUSH2 0x127D JUMP JUMPDEST STOP JUMPDEST CALLVALUE ISZERO PUSH2 0x3C8 JUMPI INVALID JUMPDEST PUSH2 0x3DE PUSH1 0x4 DUP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 POP POP PUSH2 0x1392 JUMP JUMPDEST STOP JUMPDEST CALLVALUE ISZERO PUSH2 0x3E8 JUMPI INVALID JUMPDEST PUSH2 0x421 PUSH1 0x4 DUP1 DUP1 CALLDATALOAD PUSH1 0x0 NOT AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 POP POP PUSH2 0x141A JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE ISZERO PUSH2 0x443 JUMPI INVALID JUMPDEST PUSH2 0x459 PUSH1 0x4 DUP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 POP POP PUSH2 0x149C JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE ISZERO PUSH2 0x4A3 JUMPI INVALID JUMPDEST PUSH2 0x4EE PUSH1 0x4 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 POP POP PUSH2 0x14BF JUMP JUMPDEST STOP JUMPDEST CALLVALUE ISZERO PUSH2 0x4F8 JUMPI INVALID JUMPDEST PUSH2 0x500 PUSH2 0x1672 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH1 0x0 PUSH1 0x0 CALLDATASIZE PUSH1 0x40 MLOAD DUP1 DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 SHA3 PUSH2 0x53F DUP2 PUSH2 0x1678 JUMP JUMPDEST ISZERO PUSH2 0x653 JUMPI PUSH2 0x105 PUSH1 0x0 DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 SLOAD SWAP2 POP PUSH1 0x0 DUP3 EQ ISZERO PUSH2 0x57F JUMPI PUSH2 0x652 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 SLOAD SUB PUSH1 0x0 SLOAD GT ISZERO PUSH2 0x593 JUMPI PUSH2 0x652 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x5 DUP4 PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH2 0x5A5 JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP DUP2 SWAP1 SSTORE POP PUSH1 0x0 PUSH2 0x105 PUSH1 0x0 DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 DUP2 SWAP1 SSTORE POP PUSH2 0x5E6 PUSH2 0x1890 JUMP JUMPDEST PUSH2 0x5EE PUSH2 0x19D0 JUMP JUMPDEST PUSH32 0x58619076ADF5BB0943D100EF88D52D7C3FD691B19D3A9071B555B651FBF418DA DUP4 PUSH1 0x40 MLOAD DUP1 DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 JUMPDEST JUMPDEST JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x0 PUSH2 0x105 PUSH1 0x0 DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 SLOAD GT SWAP1 POP JUMPDEST SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x1 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x4 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 CALLDATASIZE PUSH1 0x40 MLOAD DUP1 DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 SHA3 PUSH2 0x6C4 DUP2 PUSH2 0x1678 JUMP JUMPDEST ISZERO PUSH2 0x6D3 JUMPI PUSH1 0x0 PUSH1 0x3 DUP2 SWAP1 SSTORE POP JUMPDEST JUMPDEST JUMPDEST POP JUMP JUMPDEST PUSH1 0x3 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 CALLDATASIZE PUSH1 0x40 MLOAD DUP1 DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 SHA3 PUSH2 0x704 DUP2 PUSH2 0x1678 JUMP JUMPDEST ISZERO PUSH2 0x824 JUMPI PUSH2 0x712 DUP3 PUSH2 0x659 JUMP JUMPDEST ISZERO PUSH2 0x71C JUMPI PUSH2 0x823 JUMP JUMPDEST PUSH2 0x724 PUSH2 0x1890 JUMP JUMPDEST PUSH1 0xFA PUSH1 0x1 SLOAD LT ISZERO ISZERO PUSH2 0x739 JUMPI PUSH2 0x738 PUSH2 0x19D0 JUMP JUMPDEST JUMPDEST PUSH1 0xFA PUSH1 0x1 SLOAD LT ISZERO ISZERO PUSH2 0x74A JUMPI PUSH2 0x823 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x0 DUP2 SLOAD DUP1 SWAP3 SWAP2 SWAP1 PUSH1 0x1 ADD SWAP2 SWAP1 POP SSTORE POP DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x5 PUSH1 0x1 SLOAD PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH2 0x785 JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP DUP2 SWAP1 SSTORE POP PUSH1 0x1 SLOAD PUSH2 0x105 PUSH1 0x0 DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 DUP2 SWAP1 SSTORE POP PUSH32 0x994A936646FE87FFE4F1E469D3D6AA417D6B855598397F323DE5B449F765F0C3 DUP3 PUSH1 0x40 MLOAD DUP1 DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 JUMPDEST JUMPDEST JUMPDEST POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x0 DUP3 PUSH2 0x83D DUP2 PUSH2 0x1678 JUMP JUMPDEST ISZERO PUSH2 0xDC4 JUMPI PUSH1 0x0 PUSH2 0x108 PUSH1 0x0 DUP7 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x0 ADD PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO DUP1 PUSH2 0x8C7 JUMPI POP PUSH1 0x0 PUSH2 0x108 PUSH1 0x0 DUP7 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x1 ADD SLOAD EQ ISZERO JUMPDEST DUP1 PUSH2 0x906 JUMPI POP PUSH1 0x0 PUSH2 0x108 PUSH1 0x0 DUP7 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x2 ADD DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV SWAP1 POP EQ ISZERO JUMPDEST ISZERO PUSH2 0xDC2 JUMPI PUSH1 0x0 PUSH2 0x108 PUSH1 0x0 DUP7 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x0 ADD PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0xA50 JUMPI PUSH2 0xA49 PUSH2 0x108 PUSH1 0x0 DUP7 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x1 ADD SLOAD PUSH2 0x108 PUSH1 0x0 DUP8 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x2 ADD DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP1 ISZERO PUSH2 0xA3F JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xA14 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0xA3F JUMP JUMPDEST DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP1 JUMPDEST DUP2 SLOAD DUP2 MSTORE SWAP1 PUSH1 0x1 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0xA22 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP PUSH2 0x1B37 JUMP JUMPDEST SWAP2 POP PUSH2 0xB71 JUMP JUMPDEST PUSH2 0x108 PUSH1 0x0 DUP6 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x0 ADD PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH2 0x108 PUSH1 0x0 DUP7 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x1 ADD SLOAD PUSH2 0x108 PUSH1 0x0 DUP8 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x2 ADD PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP1 ISZERO PUSH2 0xB4A JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xB1F JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0xB4A JUMP JUMPDEST DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP1 JUMPDEST DUP2 SLOAD DUP2 MSTORE SWAP1 PUSH1 0x1 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0xB2D JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP SWAP2 POP POP PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP8 PUSH2 0x8502 GAS SUB CALL SWAP3 POP POP POP ISZERO ISZERO PUSH2 0xB70 JUMPI PUSH1 0x0 PUSH1 0x0 REVERT JUMPDEST JUMPDEST PUSH32 0xE3A3A4111A84DF27D76B68DC721E65C7711605EA5EEE4AFD3A9C58195217365C CALLER DUP6 PUSH2 0x108 PUSH1 0x0 DUP9 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x1 ADD SLOAD PUSH2 0x108 PUSH1 0x0 DUP10 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x0 ADD PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH2 0x108 PUSH1 0x0 DUP11 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x2 ADD DUP8 PUSH1 0x40 MLOAD DUP1 DUP8 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP7 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD DUP6 DUP2 MSTORE PUSH1 0x20 ADD DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH1 0x20 ADD DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP5 DUP2 DUP2 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP1 ISZERO PUSH2 0xD47 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0xD1C JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0xD47 JUMP JUMPDEST DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP1 JUMPDEST DUP2 SLOAD DUP2 MSTORE SWAP1 PUSH1 0x1 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0xD2A JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP SWAP8 POP POP POP POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 PUSH2 0x108 PUSH1 0x0 DUP6 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x0 PUSH1 0x0 DUP3 ADD PUSH1 0x0 PUSH2 0x100 EXP DUP2 SLOAD SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 SSTORE PUSH1 0x1 DUP3 ADD PUSH1 0x0 SWAP1 SSTORE PUSH1 0x2 DUP3 ADD PUSH1 0x0 PUSH2 0xDB7 SWAP2 SWAP1 PUSH2 0x1BE6 JUMP JUMPDEST POP POP PUSH1 0x1 SWAP3 POP PUSH2 0xDC3 JUMP JUMPDEST JUMPDEST JUMPDEST JUMPDEST POP POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 CALLDATASIZE PUSH1 0x40 MLOAD DUP1 DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 SHA3 PUSH2 0xDF3 DUP2 PUSH2 0x1678 JUMP JUMPDEST ISZERO PUSH2 0xE01 JUMPI DUP2 PUSH1 0x2 DUP2 SWAP1 SSTORE POP JUMPDEST JUMPDEST JUMPDEST POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x0 PUSH2 0xE13 CALLER PUSH2 0x659 JUMP JUMPDEST ISZERO PUSH2 0x1273 JUMPI PUSH1 0x0 DUP5 DUP5 SWAP1 POP EQ DUP1 ISZERO PUSH2 0xE30 JUMPI POP PUSH2 0xE2F DUP6 PUSH2 0x1B51 JUMP JUMPDEST JUMPDEST DUP1 PUSH2 0xE3D JUMPI POP PUSH1 0x1 PUSH1 0x0 SLOAD EQ JUMPDEST ISZERO PUSH2 0xFED JUMPI PUSH1 0x0 DUP7 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0xEA4 JUMPI PUSH2 0xE9D DUP6 DUP6 DUP6 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP POP POP POP POP PUSH2 0x1B37 JUMP JUMPDEST SWAP1 POP PUSH2 0xEF3 JUMP JUMPDEST DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP6 DUP6 DUP6 PUSH1 0x40 MLOAD DUP1 DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP SWAP3 POP POP POP PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP8 PUSH2 0x8502 GAS SUB CALL SWAP3 POP POP POP ISZERO ISZERO PUSH2 0xEF2 JUMPI PUSH1 0x0 PUSH1 0x0 REVERT JUMPDEST JUMPDEST PUSH32 0x9738CD1A8777C86B011F7B01D87D484217DC6AB5154A9D41EDA5D14AF8CAF292 CALLER DUP7 DUP9 DUP8 DUP8 DUP7 PUSH1 0x40 MLOAD DUP1 DUP8 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP7 DUP2 MSTORE PUSH1 0x20 ADD DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH1 0x20 ADD DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP6 DUP6 DUP3 DUP2 DUP2 MSTORE PUSH1 0x20 ADD SWAP3 POP DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP SWAP8 POP POP POP POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 PUSH2 0x1271 JUMP JUMPDEST PUSH1 0x0 CALLDATASIZE NUMBER PUSH1 0x40 MLOAD DUP1 DUP5 DUP5 DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP4 POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 SHA3 SWAP2 POP PUSH1 0x0 PUSH2 0x108 PUSH1 0x0 DUP5 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x0 ADD PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ DUP1 ISZERO PUSH2 0x1099 JUMPI POP PUSH1 0x0 PUSH2 0x108 PUSH1 0x0 DUP5 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x1 ADD SLOAD EQ JUMPDEST DUP1 ISZERO PUSH2 0x10D8 JUMPI POP PUSH1 0x0 PUSH2 0x108 PUSH1 0x0 DUP5 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x2 ADD DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV SWAP1 POP EQ JUMPDEST ISZERO PUSH2 0x118F JUMPI DUP6 PUSH2 0x108 PUSH1 0x0 DUP5 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x0 ADD PUSH1 0x0 PUSH2 0x100 EXP DUP2 SLOAD DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND MUL OR SWAP1 SSTORE POP DUP5 PUSH2 0x108 PUSH1 0x0 DUP5 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x1 ADD DUP2 SWAP1 SSTORE POP DUP4 DUP4 PUSH2 0x108 PUSH1 0x0 DUP6 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x2 ADD SWAP2 SWAP1 PUSH2 0x118D SWAP3 SWAP2 SWAP1 PUSH2 0x1C2E JUMP JUMPDEST POP JUMPDEST PUSH2 0x1198 DUP3 PUSH2 0x82F JUMP JUMPDEST ISZERO ISZERO PUSH2 0x1270 JUMPI PUSH32 0x1733CBB53659D713B79580F79F3F9FF215F78A7C7AA45890F3B89FC5CDDFBF32 DUP3 CALLER DUP8 DUP10 DUP9 DUP9 PUSH1 0x40 MLOAD DUP1 DUP8 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD DUP7 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP6 DUP2 MSTORE PUSH1 0x20 ADD DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP5 DUP5 DUP3 DUP2 DUP2 MSTORE PUSH1 0x20 ADD SWAP3 POP DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP SWAP8 POP POP POP POP POP POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 JUMPDEST JUMPDEST JUMPDEST JUMPDEST JUMPDEST POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x0 PUSH1 0x0 PUSH2 0x105 PUSH1 0x0 CALLER PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 SLOAD SWAP3 POP PUSH1 0x0 DUP4 EQ ISZERO PUSH2 0x12BE JUMPI PUSH2 0x138C JUMP JUMPDEST DUP3 PUSH1 0x2 EXP SWAP2 POP PUSH2 0x106 PUSH1 0x0 DUP6 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 SWAP1 POP PUSH1 0x0 DUP3 DUP3 PUSH1 0x1 ADD SLOAD AND GT ISZERO PUSH2 0x138B JUMPI DUP1 PUSH1 0x0 ADD PUSH1 0x0 DUP2 SLOAD DUP1 SWAP3 SWAP2 SWAP1 PUSH1 0x1 ADD SWAP2 SWAP1 POP SSTORE POP DUP2 DUP2 PUSH1 0x1 ADD PUSH1 0x0 DUP3 DUP3 SLOAD SUB SWAP3 POP POP DUP2 SWAP1 SSTORE POP PUSH32 0xC7FB647E59B18047309AA15AAD418E5D7CA96D173AD704F1031A2C3D7591734B CALLER DUP6 PUSH1 0x40 MLOAD DUP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP3 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 JUMPDEST JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x0 CALLDATASIZE PUSH1 0x40 MLOAD DUP1 DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 SHA3 PUSH2 0x13B9 DUP2 PUSH2 0x1678 JUMP JUMPDEST ISZERO PUSH2 0x1415 JUMPI PUSH1 0x1 SLOAD DUP3 GT ISZERO PUSH2 0x13CD JUMPI PUSH2 0x1414 JUMP JUMPDEST DUP2 PUSH1 0x0 DUP2 SWAP1 SSTORE POP PUSH2 0x13DC PUSH2 0x1890 JUMP JUMPDEST PUSH32 0xACBDB084C721332AC59F9B8E392196C9EB0E4932862DA8EB9BEAF0DAD4F550DA DUP3 PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 JUMPDEST JUMPDEST JUMPDEST POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x0 PUSH1 0x0 PUSH1 0x0 PUSH2 0x106 PUSH1 0x0 DUP8 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 SWAP3 POP PUSH2 0x105 PUSH1 0x0 DUP7 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 SLOAD SWAP2 POP PUSH1 0x0 DUP3 EQ ISZERO PUSH2 0x147F JUMPI PUSH1 0x0 SWAP4 POP PUSH2 0x1493 JUMP JUMPDEST DUP2 PUSH1 0x2 EXP SWAP1 POP PUSH1 0x0 DUP2 DUP5 PUSH1 0x1 ADD SLOAD AND EQ ISZERO SWAP4 POP JUMPDEST POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x5 PUSH1 0x1 DUP4 ADD PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH2 0x14B1 JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP SLOAD SWAP1 POP JUMPDEST SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x0 CALLDATASIZE PUSH1 0x40 MLOAD DUP1 DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY DUP3 ADD SWAP2 POP POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 SHA3 PUSH2 0x14E8 DUP2 PUSH2 0x1678 JUMP JUMPDEST ISZERO PUSH2 0x166B JUMPI PUSH2 0x14F6 DUP4 PUSH2 0x659 JUMP JUMPDEST ISZERO PUSH2 0x1500 JUMPI PUSH2 0x166A JUMP JUMPDEST PUSH2 0x105 PUSH1 0x0 DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 SLOAD SWAP2 POP PUSH1 0x0 DUP3 EQ ISZERO PUSH2 0x153B JUMPI PUSH2 0x166A JUMP JUMPDEST PUSH2 0x1543 PUSH2 0x1890 JUMP JUMPDEST DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x5 DUP4 PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH2 0x156A JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP DUP2 SWAP1 SSTORE POP PUSH1 0x0 PUSH2 0x105 PUSH1 0x0 DUP7 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 DUP2 SWAP1 SSTORE POP DUP2 PUSH2 0x105 PUSH1 0x0 DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 DUP2 SWAP1 SSTORE POP PUSH32 0xB532073B38C83145E3E5135377A08BF9AAB55BC0FD7C1179CD4FB995D2A5159C DUP5 DUP5 PUSH1 0x40 MLOAD DUP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 JUMPDEST JUMPDEST JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x2 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x0 PUSH1 0x0 PUSH1 0x0 PUSH2 0x105 PUSH1 0x0 CALLER PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 SLOAD SWAP3 POP PUSH1 0x0 DUP4 EQ ISZERO PUSH2 0x16BB JUMPI PUSH2 0x1888 JUMP JUMPDEST PUSH2 0x106 PUSH1 0x0 DUP7 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 SWAP2 POP PUSH1 0x0 DUP3 PUSH1 0x0 ADD SLOAD EQ ISZERO PUSH2 0x1745 JUMPI PUSH1 0x0 SLOAD DUP3 PUSH1 0x0 ADD DUP2 SWAP1 SSTORE POP PUSH1 0x0 DUP3 PUSH1 0x1 ADD DUP2 SWAP1 SSTORE POP PUSH2 0x107 DUP1 SLOAD DUP1 SWAP2 SWAP1 PUSH1 0x1 ADD PUSH2 0x1710 SWAP2 SWAP1 PUSH2 0x1CAE JUMP JUMPDEST DUP3 PUSH1 0x2 ADD DUP2 SWAP1 SSTORE POP DUP5 PUSH2 0x107 DUP4 PUSH1 0x2 ADD SLOAD DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x172D JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP1 ADD PUSH1 0x0 JUMPDEST POP DUP2 PUSH1 0x0 NOT AND SWAP1 SSTORE POP JUMPDEST DUP3 PUSH1 0x2 EXP SWAP1 POP PUSH1 0x0 DUP2 DUP4 PUSH1 0x1 ADD SLOAD AND EQ ISZERO PUSH2 0x1887 JUMPI PUSH32 0xE1C52DC63B719ADE82E8BEA94CC41A0D5D28E4AAF536ADB5E9CCCC9FF8C1AEDA CALLER DUP7 PUSH1 0x40 MLOAD DUP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP3 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 PUSH1 0x1 DUP3 PUSH1 0x0 ADD SLOAD GT ISZERO ISZERO PUSH2 0x185E JUMPI PUSH2 0x107 PUSH2 0x106 PUSH1 0x0 DUP8 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x2 ADD SLOAD DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x180A JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP1 ADD PUSH1 0x0 JUMPDEST POP PUSH1 0x0 SWAP1 SSTORE PUSH2 0x106 PUSH1 0x0 DUP7 PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x0 PUSH1 0x0 DUP3 ADD PUSH1 0x0 SWAP1 SSTORE PUSH1 0x1 DUP3 ADD PUSH1 0x0 SWAP1 SSTORE PUSH1 0x2 DUP3 ADD PUSH1 0x0 SWAP1 SSTORE POP POP PUSH1 0x1 SWAP4 POP PUSH2 0x1888 JUMP JUMPDEST DUP2 PUSH1 0x0 ADD PUSH1 0x0 DUP2 SLOAD DUP1 SWAP3 SWAP2 SWAP1 PUSH1 0x1 SWAP1 SUB SWAP2 SWAP1 POP SSTORE POP DUP1 DUP3 PUSH1 0x1 ADD PUSH1 0x0 DUP3 DUP3 SLOAD OR SWAP3 POP POP DUP2 SWAP1 SSTORE POP JUMPDEST JUMPDEST JUMPDEST POP POP POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x0 PUSH2 0x107 DUP1 SLOAD SWAP1 POP SWAP2 POP PUSH1 0x0 SWAP1 POP JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x19BC JUMPI PUSH2 0x108 PUSH1 0x0 PUSH2 0x107 DUP4 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x18BF JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP1 ADD PUSH1 0x0 JUMPDEST POP SLOAD PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x0 PUSH1 0x0 DUP3 ADD PUSH1 0x0 PUSH2 0x100 EXP DUP2 SLOAD SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 SSTORE PUSH1 0x1 DUP3 ADD PUSH1 0x0 SWAP1 SSTORE PUSH1 0x2 DUP3 ADD PUSH1 0x0 PUSH2 0x1926 SWAP2 SWAP1 PUSH2 0x1BE6 JUMP JUMPDEST POP POP PUSH1 0x0 PUSH1 0x1 MUL PUSH2 0x107 DUP3 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x193D JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP1 ADD PUSH1 0x0 JUMPDEST POP SLOAD PUSH1 0x0 NOT AND EQ ISZERO ISZERO PUSH2 0x19B0 JUMPI PUSH2 0x106 PUSH1 0x0 PUSH2 0x107 DUP4 DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x196D JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP1 ADD PUSH1 0x0 JUMPDEST POP SLOAD PUSH1 0x0 NOT AND PUSH1 0x0 NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 PUSH1 0x0 PUSH1 0x0 DUP3 ADD PUSH1 0x0 SWAP1 SSTORE PUSH1 0x1 DUP3 ADD PUSH1 0x0 SWAP1 SSTORE PUSH1 0x2 DUP3 ADD PUSH1 0x0 SWAP1 SSTORE POP POP JUMPDEST JUMPDEST DUP1 PUSH1 0x1 ADD SWAP1 POP PUSH2 0x18A2 JUMP JUMPDEST PUSH2 0x107 PUSH1 0x0 PUSH2 0x19CB SWAP2 SWAP1 PUSH2 0x1CDA JUMP JUMPDEST JUMPDEST POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 SWAP1 POP JUMPDEST PUSH1 0x1 SLOAD DUP2 LT ISZERO PUSH2 0x1B33 JUMPI JUMPDEST PUSH1 0x1 SLOAD DUP2 LT DUP1 ISZERO PUSH2 0x1A09 JUMPI POP PUSH1 0x0 PUSH1 0x5 DUP3 PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH2 0x1A00 JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP SLOAD EQ ISZERO JUMPDEST ISZERO PUSH2 0x1A1B JUMPI DUP1 DUP1 PUSH1 0x1 ADD SWAP2 POP POP PUSH2 0x19E2 JUMP JUMPDEST JUMPDEST PUSH1 0x1 PUSH1 0x1 SLOAD GT DUP1 ISZERO PUSH2 0x1A45 JUMPI POP PUSH1 0x0 PUSH1 0x5 PUSH1 0x1 SLOAD PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH2 0x1A3D JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP SLOAD EQ JUMPDEST ISZERO PUSH2 0x1A62 JUMPI PUSH1 0x1 PUSH1 0x0 DUP2 SLOAD DUP1 SWAP3 SWAP2 SWAP1 PUSH1 0x1 SWAP1 SUB SWAP2 SWAP1 POP SSTORE POP PUSH2 0x1A1C JUMP JUMPDEST PUSH1 0x1 SLOAD DUP2 LT DUP1 ISZERO PUSH2 0x1A8B JUMPI POP PUSH1 0x0 PUSH1 0x5 PUSH1 0x1 SLOAD PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH2 0x1A82 JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP SLOAD EQ ISZERO JUMPDEST DUP1 ISZERO PUSH2 0x1AAC JUMPI POP PUSH1 0x0 PUSH1 0x5 DUP3 PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH2 0x1AA4 JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP SLOAD EQ JUMPDEST ISZERO PUSH2 0x1B2E JUMPI PUSH1 0x5 PUSH1 0x1 SLOAD PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH2 0x1AC3 JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP SLOAD PUSH1 0x5 DUP3 PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH2 0x1AD9 JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP DUP2 SWAP1 SSTORE POP DUP1 PUSH2 0x105 PUSH1 0x0 PUSH1 0x5 DUP5 PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH2 0x1AF8 JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP SLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 DUP2 SWAP1 SSTORE POP PUSH1 0x0 PUSH1 0x5 PUSH1 0x1 SLOAD PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH2 0x1B24 JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP DUP2 SWAP1 SSTORE POP JUMPDEST PUSH2 0x19D7 JUMP JUMPDEST JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD PUSH1 0x20 DUP4 ADD DUP5 CREATE SWAP1 POP DUP1 EXTCODESIZE ISZERO PUSH2 0x0 JUMPI JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1B5C CALLER PUSH2 0x659 JUMP JUMPDEST ISZERO PUSH2 0x1BC9 JUMPI PUSH1 0x4 SLOAD PUSH2 0x1B6C PUSH2 0x1BCF JUMP JUMPDEST GT ISZERO PUSH2 0x1B89 JUMPI PUSH1 0x0 PUSH1 0x3 DUP2 SWAP1 SSTORE POP PUSH2 0x1B82 PUSH2 0x1BCF JUMP JUMPDEST PUSH1 0x4 DUP2 SWAP1 SSTORE POP JUMPDEST PUSH1 0x3 SLOAD DUP3 PUSH1 0x3 SLOAD ADD LT ISZERO DUP1 ISZERO PUSH2 0x1BA5 JUMPI POP PUSH1 0x2 SLOAD DUP3 PUSH1 0x3 SLOAD ADD GT ISZERO JUMPDEST ISZERO PUSH2 0x1BC3 JUMPI DUP2 PUSH1 0x3 PUSH1 0x0 DUP3 DUP3 SLOAD ADD SWAP3 POP POP DUP2 SWAP1 SSTORE POP PUSH1 0x1 SWAP1 POP PUSH2 0x1BC8 JUMP JUMPDEST PUSH1 0x0 SWAP1 POP JUMPDEST JUMPDEST JUMPDEST SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH3 0x15180 TIMESTAMP DUP2 ISZERO ISZERO PUSH2 0x1BDF JUMPI INVALID JUMPDEST DIV SWAP1 POP JUMPDEST SWAP1 JUMP JUMPDEST POP DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV PUSH1 0x0 DUP3 SSTORE DUP1 PUSH1 0x1F LT PUSH2 0x1C0C JUMPI POP PUSH2 0x1C2B JUMP JUMPDEST PUSH1 0x1F ADD PUSH1 0x20 SWAP1 DIV SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP1 DUP2 ADD SWAP1 PUSH2 0x1C2A SWAP2 SWAP1 PUSH2 0x1CFC JUMP JUMPDEST JUMPDEST POP JUMP JUMPDEST DUP3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP1 PUSH1 0x1F ADD PUSH1 0x20 SWAP1 DIV DUP2 ADD SWAP3 DUP3 PUSH1 0x1F LT PUSH2 0x1C6F JUMPI DUP1 CALLDATALOAD PUSH1 0xFF NOT AND DUP4 DUP1 ADD OR DUP6 SSTORE PUSH2 0x1C9D JUMP JUMPDEST DUP3 DUP1 ADD PUSH1 0x1 ADD DUP6 SSTORE DUP3 ISZERO PUSH2 0x1C9D JUMPI SWAP2 DUP3 ADD JUMPDEST DUP3 DUP2 GT ISZERO PUSH2 0x1C9C JUMPI DUP3 CALLDATALOAD DUP3 SSTORE SWAP2 PUSH1 0x20 ADD SWAP2 SWAP1 PUSH1 0x1 ADD SWAP1 PUSH2 0x1C81 JUMP JUMPDEST JUMPDEST POP SWAP1 POP PUSH2 0x1CAA SWAP2 SWAP1 PUSH2 0x1CFC JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST DUP2 SLOAD DUP2 DUP4 SSTORE DUP2 DUP2 ISZERO GT PUSH2 0x1CD5 JUMPI DUP2 DUP4 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP2 DUP3 ADD SWAP2 ADD PUSH2 0x1CD4 SWAP2 SWAP1 PUSH2 0x1D21 JUMP JUMPDEST JUMPDEST POP POP POP JUMP JUMPDEST POP DUP1 SLOAD PUSH1 0x0 DUP3 SSTORE SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 SHA3 SWAP1 DUP2 ADD SWAP1 PUSH2 0x1CF8 SWAP2 SWAP1 PUSH2 0x1D21 JUMP JUMPDEST JUMPDEST POP JUMP JUMPDEST PUSH2 0x1D1E SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH2 0x1D1A JUMPI PUSH1 0x0 DUP2 PUSH1 0x0 SWAP1 SSTORE POP PUSH1 0x1 ADD PUSH2 0x1D02 JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH2 0x1D43 SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH2 0x1D3F JUMPI PUSH1 0x0 DUP2 PUSH1 0x0 SWAP1 SSTORE POP PUSH1 0x1 ADD PUSH2 0x1D27 JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 SLOAD GT ISZERO PUSH2 0x1D57 JUMPI PUSH1 0x0 PUSH1 0x0 REVERT JUMPDEST PUSH2 0x1D60 DUP2 PUSH2 0x1D71 JUMP JUMPDEST PUSH2 0x1D6A DUP4 DUP4 PUSH2 0x1D9C JUMP JUMPDEST JUMPDEST JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 SLOAD GT ISZERO PUSH2 0x1D82 JUMPI PUSH1 0x0 PUSH1 0x0 REVERT JUMPDEST DUP1 PUSH1 0x2 DUP2 SWAP1 SSTORE POP PUSH2 0x1D91 PUSH2 0x1BCF JUMP JUMPDEST PUSH1 0x4 DUP2 SWAP1 SSTORE POP JUMPDEST JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x0 PUSH1 0x1 SLOAD GT ISZERO PUSH2 0x1DAF JUMPI PUSH1 0x0 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 DUP3 GT ISZERO ISZERO PUSH2 0x1DBF JUMPI PUSH1 0x0 PUSH1 0x0 REVERT JUMPDEST DUP2 DUP4 MLOAD LT ISZERO ISZERO ISZERO PUSH2 0x1DD0 JUMPI PUSH1 0x0 PUSH1 0x0 REVERT JUMPDEST DUP3 MLOAD PUSH1 0x1 DUP2 SWAP1 SSTORE POP PUSH1 0x0 SWAP1 POP JUMPDEST DUP3 MLOAD DUP2 LT ISZERO PUSH2 0x1E85 JUMPI DUP3 DUP2 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1DF4 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x5 DUP3 PUSH1 0x1 ADD PUSH2 0x100 DUP2 LT ISZERO ISZERO PUSH2 0x1E27 JUMPI INVALID JUMPDEST ADD PUSH1 0x0 JUMPDEST POP DUP2 SWAP1 SSTORE POP DUP1 PUSH1 0x1 ADD PUSH2 0x105 PUSH1 0x0 DUP6 DUP5 DUP2 MLOAD DUP2 LT ISZERO ISZERO PUSH2 0x1E47 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x20 ADD SWAP1 PUSH1 0x20 MUL ADD MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 SHA3 DUP2 SWAP1 SSTORE POP JUMPDEST DUP1 PUSH1 0x1 ADD SWAP1 POP PUSH2 0x1DDD JUMP JUMPDEST DUP2 PUSH1 0x0 DUP2 SWAP1 SSTORE POP JUMPDEST JUMPDEST POP POP POP JUMP STOP LOG1 PUSH6 0x627A7A723058 SHA3 AND DUP9 SWAP16 SMOD BLOCKHASH CREATE PUSH20 0xD397F9D00B0D19900FB050B957E3E2942F861085 0xbe 0xb9 0xba 0xab XOR STOP 0x29 ", @@ -58,7 +58,7 @@ To verify the byte-code above, a patched version is deployed at to be reviewed. The compiler settings used can be extracted from the following meta-data: -``` +```json {"compiler":{"version":"0.4.10+commit.f0d539ae"},"language":"Solidity","output":{"abi":[{"constant":false,"inputs":[{"name":"_owner","type":"address"}],"name":"removeOwner","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_addr","type":"address"}],"name":"isOwner","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"m_numOwners","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"m_lastDay","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"resetSpentToday","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"m_spentToday","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"}],"name":"addOwner","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"m_required","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_h","type":"bytes32"}],"name":"confirm","outputs":[{"name":"o_success","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_newLimit","type":"uint256"}],"name":"setDailyLimit","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"execute","outputs":[{"name":"o_hash","type":"bytes32"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_operation","type":"bytes32"}],"name":"revoke","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_newRequired","type":"uint256"}],"name":"changeRequirement","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_operation","type":"bytes32"},{"name":"_owner","type":"address"}],"name":"hasConfirmed","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"ownerIndex","type":"uint256"}],"name":"getOwner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"}],"name":"changeOwner","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"m_dailyLimit","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[],"payable":false,"type":"constructor"},{"payable":true,"type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"operation","type":"bytes32"}],"name":"Confirmation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"operation","type":"bytes32"}],"name":"Revoke","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"oldOwner","type":"address"},{"indexed":false,"name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newOwner","type":"address"}],"name":"OwnerAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"oldOwner","type":"address"}],"name":"OwnerRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newRequirement","type":"uint256"}],"name":"RequirementChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_from","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"to","type":"address"},{"indexed":false,"name":"data","type":"bytes"},{"indexed":false,"name":"created","type":"address"}],"name":"SingleTransact","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"operation","type":"bytes32"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"to","type":"address"},{"indexed":false,"name":"data","type":"bytes"},{"indexed":false,"name":"created","type":"address"}],"name":"MultiTransact","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"operation","type":"bytes32"},{"indexed":false,"name":"initiator","type":"address"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"to","type":"address"},{"indexed":false,"name":"data","type":"bytes"}],"name":"ConfirmationNeeded","type":"event"}],"devdoc":{"methods":{}},"userdoc":{"methods":{}}},"settings":{"compilationTarget":{"browser/WalletLibrary.sol":"WalletLibrary"},"libraries":{},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"browser/WalletLibrary.sol":{"keccak256":"0xf72fcdc85e15f93172878ca6a61fb81604d1052e9e724bc3896d65b3b4ab1bb0","urls":["bzzr://009bd59bd78f59804eaffb6111d341caea58888f8e5b5f75aebdf009fc6136c0"]}},"version":1} ``` diff --git a/README.md b/README.md index 9ffb99361a51f6..7e4772276c9f03 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ The canonical URL for a EIP that has achieved draft status at any point is at ht EIPs must pass some validation tests. The EIP repository ensures this by running tests using [html-proofer](https://rubygems.org/gems/html-proofer) and [eip_validator](https://rubygems.org/gems/eip_validator). It is possible to run the EIP validator locally: -``` +```sh gem install eip_validator eip_validator ``` @@ -58,7 +58,7 @@ The EIP repository contains an "auto merge" feature to ease the workload for EIP 2. Check whether you have Ruby 2.1.0 or higher installed: -``` +```sh $ ruby --version ``` @@ -66,13 +66,13 @@ $ ruby --version 4. Install Bundler: -``` +```sh $ gem install bundler ``` 5. Install dependencies: -``` +```sh $ bundle install ``` @@ -80,7 +80,7 @@ $ bundle install 1. Bundle assets and start the server: -``` +```sh $ bundle exec jekyll serve ``` From 1b734655e6a517f61a52544e50a0ac2cd323902e Mon Sep 17 00:00:00 2001 From: Daniel Lehrner Date: Sat, 23 Nov 2019 01:03:28 +0100 Subject: [PATCH 35/47] EIP-2019: Fundable Token (#2019) --- EIPS/eip-2019.md | 255 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 EIPS/eip-2019.md diff --git a/EIPS/eip-2019.md b/EIPS/eip-2019.md new file mode 100644 index 00000000000000..d4f05a2cff7957 --- /dev/null +++ b/EIPS/eip-2019.md @@ -0,0 +1,255 @@ +--- +eip: 2019 +title: Fundable Token +author: Fernando Paris , Julio Faura , Daniel Lehrner +discussions-to: https://github.com/ethereum/EIPs/issues/2105 +status: Draft +type: Standards Track +category: ERC +created: 2019-05-10 +requires: 20 +--- + +## Simple Summary +An extension to the [ERC-20] standard token that allows Token wallet owners to request a wallet to be funded, by calling the smart contract and attaching a fund instruction string. + +## Actors + +#### Token Wallet Owners +The person or company who owns the wallet, and will order a token fund request into the wallet. + +#### Token contract owner / agent +The entity, company responsible/owner of the token contract, and token issuing/minting. This actor is in charge of trying to fulfill all fund request(s), reading the fund instruction(s), and correlate the private payment details. + +#### Orderer +An actor who is enabled to initiate funding orders on behalf of a token wallet owner. + +## Abstract +Token wallet owners (or approved addresses) can order tokenization requests through blockchain. This is done by calling the ```orderFund``` or ```orderFundFrom``` methods, which initiate the workflow for the token contract operator to either honor or reject the fund request. In this case, fund instructions are provided when submitting the request, which are used by the operator to determine the source of the funds to be debited in order to do fund the token wallet (through minting). + +In general, it is not advisable to place explicit routing instructions for debiting funds on a verbatim basis on the blockchain, and it is advised to use a private communication alternatives, such as private channels, encrypted storage or similar, to do so (external to the blockchain ledger). Another (less desirable) possibility is to place these instructions on the instructions field in encrypted form. + +## Motivation +Nowadays most of the token issuing/funding request, based on any fiat based payment method need a previous centralized transaction, to be able to get the desired tokens issued on requester's wallet. +In the aim of trying to bring all the needed steps into decentralization, exposing all the needed steps of token lifecycle and payment transactions, a funding request can allow wallet owner to initiate the funding request via blockchain. +Key benefits: + +* Funding and payment traceability is enhanced bringing the initiation into the ledger. All payment stat +s can be stored on chain. +* Almost all money/token lifecycle is covered via a decentralized approach, complemented with private communications which is common use in the ecosystem. + +## Specification + +```solidity +interface IFundable /* is ERC-20 */ { + enum FundStatusCode { + Nonexistent, + Ordered, + InProcess, + Executed, + Rejected, + Cancelled + } + function authorizeFundOperator(address orderer) external returns (bool); + function revokeFundOperator(address orderer) external returns (bool) ; + function orderFund(string calldata operationId, uint256 value, string calldata instructions) external returns (bool); + function orderFundFrom(string calldata operationId, address walletToFund, uint256 value, string calldata instructions) external returns (bool); + function cancelFund(string calldata operationId) external returns (bool); + function processFund(string calldata operationId) external returns (bool); + function executeFund(string calldata operationId) external returns (bool); + function rejectFund(string calldata operationId, string calldata reason) external returns (bool); + + function isFundOperatorFor(address walletToFund, address orderer) external view returns (bool); + function retrieveFundData(address orderer, string calldata operationId) external view returns (address walletToFund, uint256 value, string memory instructions, FundStatusCode status); + + event FundOrdered(address indexed orderer, string indexed operationId, address indexed , uint256 value, string instructions); + event FundInProcess(address indexed orderer, string indexed operationId); + event FundExecuted(address indexed orderer, string indexed operationId); + event FundRejected(address indexed orderer, string indexed operationId, string reason); + event FundCancelled(address indexed orderer, string indexed operationId); + event FundOperatorAuthorized(address indexed walletToFund, address indexed orderer); + event FundOperatorRevoked(address indexed walletToFund, address indexed orderer); +} +``` + +### Functions + +#### authorizeFundOperator + +Wallet owner, authorizes a given address to be fund orderer. + +| Parameter | Description | +| ---------|-------------| +| orderer | The address of the orderer. + +#### revokeFundOperator + +Wallet owner, revokes a given address to be fund orderer. + +| Parameter | Description | +| ---------|-------------| +| orderer | The address of the orderer. + +#### orderFund + +Creates a fund request, that will be processed by the token operator. The function must revert if the operation ID has been used before. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify the request | +| value | The amount to be funded. | +| instruction | A string including the payment instruction. | + +#### orderFundFrom + +Creates a fund request, on behalf of a wallet owner, that will be processed by the token operator. The function must revert if the operation ID has been used before. + +| Parameter | Description | +| ---------|-------------| +| operationId |The unique ID to identify the request | +| walletToFund | The wallet to be funded on behalf. +| value | The amount to be funded. | +| instruction | A string including the payment instruction. | + +#### cancelFund + +Cancels a funding request. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify the request that is going to be cancelled. This can only be done by token holder, or the fund initiator. | + +#### processFund + +Marks a funding request as on process. After the status is on process, order cannot be cancelled. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify the request is in process. + +#### executeFund + +Issues the amount of tokens and marks a funding request as executed. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify the request that has been executed. + +#### rejectFund + +Rejects a given operation with a reason. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify the request that has been executed. +| reason | The specific reason that explains why the fund request was rejected. EIP 1066 codes can be used | + +#### isFundOperatorFor + +Checks that given player is allowed to order fund requests, for a given wallet. + +| Parameter | Description | +| ---------|-------------| +| walletToFund | The wallet to be funded, and checked for approval permission. +| orderer | The address of the orderer, to be checked for approval permission. + +#### retrieveFundData + +Retrieves all the fund request data. Only operator, tokenHolder, and orderer can get the given operation data. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify the fund order. + +### Events + +#### FundOrdered + +Emitted when an token wallet owner orders a funding request. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify the request | +| walletToFund | The wallet that the player is allowed to start funding requests | +| value | The amount to be funded. | +| instruction | A string including the payment instruction. | + +#### FundInProcess + +Emitted when an operator starts a funding request after validating the instruction, and the operation is marked as in process. + +| Parameter | Description | +| ---------|-------------| +| orderer | The address of the fund request orderer. | +| operationId | The unique ID to identify the fund. | + +#### FundExecuted + +Emitted when an operator has executed a funding request. + +| Parameter | Description | +| ---------|-------------| +| orderer | The address of the fund request orderer. | +| operationId | The unique ID to identify the fund. | + +#### FundRejected + +Emitted when an operator has rejected a funding request. + +| Parameter | Description | +| ---------|-------------| +| orderer | The address of the fund request orderer. | +| operationId | The unique ID to identify the fund. | +| reason | The specific reason that explains why the fund request was rejected. EIP 1066 codes can be used | + +#### FundCancelled + +Emitted when a token holder, orderer, has cancelled a funding request. This can only be done if the operator hasn't put the funding order in process. + +| Parameter | Description | +| ---------|-------------| +| orderer | The address of the fund request orderer. | +| operationId | The unique ID to identify the fund. | + +#### FundOperatorAuthorized + +Emitted when a given player, operator, company or a given persona, has been approved to start fund request for a given token holder. + +| Parameter | Description | +| ---------|-------------| +| walletToFund | The wallet that the player is allowed to start funding requests | +| orderer | The address that allows the the player to start requests. | + +#### FundOperatorRevoked + +Emitted when a given player has been revoked initiate funding requests. + +| Parameter | Description | +| ---------|-------------| +| walletToFund | The wallet that the player is allowed to start funding requests | +| orderer | The address that allows the the player to start requests. | + +## Rationale +This standards provides a functionality to allow token holders to start funding requests in a decentralized way. + +It's important to highlight that the token operator, need to process all funding request, updating the fund status based on the linked payment that will be done. + +Funding instruction format is open. ISO payment standard like is a good start point, + +The `operationId` is a string and not something more gas efficient to allow easy traceability of the hold and allow human readable ids. It is up to the implementer if the string should be stored on-chain or only its hash, as it is enough to identify a hold. + +The `operationId` is a competitive resource. It is recommended, but not required, that the hold issuers used a unique prefix to avoid collisions. + +## Backwards Compatibility +This EIP is fully backwards compatible as its implementation extends the functionality of [ERC-20]. + +## Implementation +The GitHub repository [IoBuilders/fundable-token](https://github.com/IoBuilders/fundable-token) contains the work in progress implementation. + +## Contributors +This proposal has been collaboratively implemented by [adhara.io](https://adhara.io/) and [io.builders](https://io.builders/). + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). + +[ERC-20]: https://eips.ethereum.org/EIPS/eip-20 From e0d5e27087e45407501c934277c6accad3f5468d Mon Sep 17 00:00:00 2001 From: Daniel Lehrner Date: Sat, 23 Nov 2019 01:15:28 +0100 Subject: [PATCH 36/47] EIP-2009: Compliance Service (#2009) --- EIPS/eip-2009.md | 300 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 300 insertions(+) create mode 100644 EIPS/eip-2009.md diff --git a/EIPS/eip-2009.md b/EIPS/eip-2009.md new file mode 100644 index 00000000000000..ffbd33bbfae9b3 --- /dev/null +++ b/EIPS/eip-2009.md @@ -0,0 +1,300 @@ +--- +eip: 2009 +title: Compliance Service +author: Daniel Lehrner +discussions-to: https://github.com/ethereum/EIPs/issues/2022 +status: Draft +type: Standards Track +category: ERC +created: 2019-05-09 +requires: 1066 +--- + +## Simple Summary + +This EIP proposes a service for decentralized compliance checks for regulated tokens. + +## Actors + +#### Operator +An account which has been approved by a token to update the tokens accumulated. + +#### Token +An account, normally a smart contract, which uses the `Compliance Service` to check if the an action can be executed or not. + +#### Token holder +An account which is in possession of tokens and on for which the checks are made. + +## Abstract + +A regulated token needs to comply with several legal requirements, especially [KYC][KYC-Wikipedia] and [AML][AML-Wikipedia]. If the necessary checks have to be made off-chain the token transfer becomes centralized. Further the transfer in this case takes longer to complete as it can not be done in one transaction, but requires a second confirmation step. The goal of this proposal is to make this second step unnecessary by providing a service for compliance checks. + +## Motivation + +Currently there is no proposal on how to accomplish decentralized compliance checks. [ERC-1462][ERC-1462] proposes a basic set of functions to check if `transfer`, `mint` and `burn` are allowed for a user, but not how those checks should be implemented. This EIP proposes a way to implement them fully on-chain while being generic enough to leave the actual implementation of the checks up to the implementers, as these may vary a lot between different tokens. + +The proposed `Compliance Service` supports more than one token. Therefore it could be used by law-makers to maintain the compliance rules of regulated tokens in one smart contract. This smart contract could be used by all of the tokens that fall under this jurisdiction and ensure compliance with the current laws. + +By having a standard for compliance checks third-party developers can use them to verify if token movements for a specific account are allowed and act accordingly. + +## Specification + +```solidity +interface CompliantService { + function checkTransferAllowed(bytes32 tokenId, address from, address to, uint256 value) external view returns (byte); + function checkTransferFromAllowed(bytes32 tokenId, address sender, address from, address to, uint256 value) external view returns (byte); + function checkMintAllowed(bytes32 tokenId, address to, uint256 value) external view returns (byte); + function checkBurnAllowed(bytes32 tokenId, address from, uint256 value) external view returns (byte); + + function updateTransferAccumulated(bytes32 tokenId, address from, address to, uint256 value) external; + function updateMintAccumulated(bytes32 tokenId, address to, uint256 value) external; + function updateBurnAccumulated(bytes32 tokenId, address from, uint256 value) external; + + function addToken(bytes32 tokenId, address token) external; + function replaceToken(bytes32 tokenId, address token) external; + function removeToken(bytes32 tokenId) external; + function isToken(address token) external view returns (bool); + function getTokenId(address token) external view returns (bytes32); + + function authorizeAccumulatedOperator(address operator) external returns (bool); + function revokeAccumulatedOperator(address operator) external returns (bool); + function isAccumulatedOperatorFor(address operator, bytes32 tokenId) external view returns (bool); + + event TokenAdded(bytes32 indexed tokenId, address indexed token); + event TokenReplaced(bytes32 indexed tokenId, address indexed previousAddress, address indexed newAddress); + event TokenRemoved(bytes32 indexed tokenId); + event AuthorizedAccumulatedOperator(address indexed operator, bytes32 indexed tokenId); + event RevokedAccumulatedOperator(address indexed operator, bytes32 indexed tokenId); +} +``` + +### Mandatory checks + +The checks must be verified in their corresponding actions. The action must only be successful if the check return an `Allowed` status code. In any other case the functions must revert. + +### Status codes + +If an action is allowed `0x11` (Allowed) or an issuer-specific code with equivalent but more precise meaning must be returned. If the action is not allowed the status must be `0x10` (Disallowed) or an issuer-specific code with equivalent but more precise meaning. + +### Functions + +#### checkTransferAllowed + +Checks if the `transfer` function is allowed to be executed with the given parameters. + +| Parameter | Description | +| ---------|-------------| +| tokenId | The unique ID which identifies a token | +| from | The address of the payer, from whom the tokens are to be taken if executed | +| to | The address of the payee, to whom the tokens are to be transferred if executed | +| value | The amount to be transferred | + +#### checkTransferFromAllowed + +Checks if the `transferFrom` function is allowed to be executed with the given parameters. + +| Parameter | Description | +| ---------|-------------| +| tokenId | The unique ID which identifies a token | +| sender | The address of the sender, who initiated the transaction | +| from | The address of the payer, from whom the tokens are to be taken if executed | +| to | The address of the payee, to whom the tokens are to be transferred if executed | +| value | The amount to be transferred | + +#### checkMintAllowed + +Checks if the `mint` function is allowed to be executed with the given parameters. + +| Parameter | Description | +| ---------|-------------| +| tokenId | The unique ID which identifies a token | +| to | The address of the payee, to whom the tokens are to be given if executed | +| value | The amount to be minted | + +#### checkBurnAllowed + +Checks if the `burn` function is allowed to be executed with the given parameters. + +| Parameter | Description | +| ---------|-------------| +| tokenId | The unique ID which identifies a token | +| from | The address of the payer, from whom the tokens are to be taken if executed | +| value | The amount to be burned | + +#### updateTransferAccumulated + +Must be called in the same transaction as `transfer` or `transferFrom`. It must revert if the update violates any of the compliance rules. It is up to the implementer which specific logic is executed in the function. + +| Parameter | Description | +| ---------|-------------| +| tokenId | The unique ID which identifies a token | +| from | The address of the payer, from whom the tokens are to be taken if executed | +| to | The address of the payee, to whom the tokens are to be transferred if executed | +| value | The amount to be transferred | + +#### updateMintAccumulated + +Must be called in the same transaction as `mint`. It must revert if the update violates any of the compliance rules. It is up to the implementer which specific logic is executed in the function. + +| Parameter | Description | +| ---------|-------------| +| tokenId | The unique ID which identifies a token | +| to | The address of the payee, to whom the tokens are to be given if executed | +| value | The amount to be minted | + +#### updateBurnAccumulated + +Must be called in the same transaction as `burn`. It must revert if the update violates any of the compliance rules. It is up to the implementer which specific logic is executed in the function. + +| Parameter | Description | +| ---------|-------------| +| tokenId | The unique ID which identifies a token | +| from | The address of the payer, from whom the tokens are to be taken if executed | +| value | The amount to be minted | + +#### addToken + +Adds a token to the service, which allows the token to call the functions to update the accumulated. If an existing token id is used the function must revert. It is up to the implementer if adding a token should be restricted or not. + +| Parameter | Description | +| ---------|-------------| +| tokenId | The unique ID which identifies a token | +| token | The address from which the update functions will be called | + +#### replaceToken + +Replaces the address of a added token with another one. It is up to the implementer if replacing a token should be restricted or not, but a token should be able to replace its own address. + +| Parameter | Description | +| ---------|-------------| +| tokenId | The unique ID which identifies a token | +| token | The address from which the update functions will be called | + +#### removeToken + +Removes a token from the service, which disallows the token to call the functions to update the accumulated. It is up to the implementer if removing a token should be restricted or not. + +| Parameter | Description | +| ---------|-------------| +| tokenId | The unique ID which identifies a token | + +#### isToken + +Returns `true` if the address has been added to the service, `false` if not. + +| Parameter | Description | +| ---------|-------------| +| token | The address which should be checked | + +#### getTokenId + +Returns the token id of a token. If the token has not been added to the service, '0' must be returned. + +| Parameter | Description | +| ---------|-------------| +| token | The address which token id should be returned | + +#### authorizeAccumulatedOperator + +Approves an operator to update accumulated on behalf of the token id of msg.sender. + +| Parameter | Description | +| ---------|-------------| +| operator | The address to be approved as operator of accumulated updates | + +#### revokeAccumulatedOperator + +Revokes the approval to update accumulated on behalf the token id the token id ofof msg.sender. + +| Parameter | Description | +| ---------|-------------| +| operator | The address to be revoked as operator of accumulated updates | + +#### isAccumulatedOperatorFor + +Retrieves if an operator is approved to create holds on behalf of `tokenId`. + +| Parameter | Description | +| ---------|-------------| +| operator | The address which is operator of updating the accumulated | +| tokenId | The unique ID which identifies a token | + +### Events + +#### TokenAdded + +Must be emitted after a token has been added. + +| Parameter | Description | +| ---------|-------------| +| tokenId | The unique ID which identifies a token | +| token | The address from which the update functions will be called | + +#### TokenReplaced + +Must be emitted after the address of a token has been replaced. + +| Parameter | Description | +| ---------|-------------| +| tokenId | The unique ID which identifies a token | +| previousAddress | The previous address which was used before | +| newAddress | The address which will be used from now on | + +#### TokenRemoved + +Must be emitted after the a token has been removed. + +| Parameter | Description | +| ---------|-------------| +| tokenId | The unique ID which identifies a token | + +#### AuthorizedAccumulatedOperator + +Emitted when an operator has been approved to update the accumulated on behalf of a token. + +| Parameter | Description | +| ---------|-------------| +| operator | The address which is operator of updating the accumulated | +| tokenId | Token id on which behalf updates of the accumulated will potentially be made | + +#### RevokedHoldOperator + +Emitted when an operator has been revoked from updating the accumulated on behalf of a token. + +| Parameter | Description | +| ---------|-------------| +| operator | The address which was operator of updating the accumulated | +| tokenId | Token id on which behalf updates of the accumulated could be made | + +## Rationale + +The usage of a token id instead of the address has been chosen to give tokens the possibility to update their smart contracts and keeping all their associated accumulated. If the address would be used, a migration process would needed to be done after a smart contract update. + +No event is emitted after updating the accumulated as those are always associated with a `transfer`, `mint` or `burn` of a token which already emits an event of itself. + +While not requiring it, the naming of the functions `checkTransferAllowed`, `checkTransferFromAllowed`, `checkMintAllowed` and `checkBurnAllowed` was adopted from [ERC-1462][ERC-1462]. + +While not requiring it, the naming of the functions `authorizeAccumulatedOperator`, `revokeAccumulatedOperator` and `isAccumulatedOperatorFor` follows the naming convention of [ERC-777][ERC-777]. + +Localization is not part of this EIP, but [ERC-1066][ERC-1066] and [ERC-1444][ERC-1444] can be used together to achieve it. + +## Backwards Compatibility + +As the EIP is not using any existing EIP there are no backwards compatibilities to take into consideration. + +## Implementation + +The GitHub repository [IoBuilders/compliance-service](https://github.com/IoBuilders/compliance-service) contains the work in progress implementation. + +## Contributors +This proposal has been collaboratively implemented by [adhara.io](https://adhara.io/) and [io.builders](https://io.builders/). + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). + +[KYC-Wikipedia]: https://en.wikipedia.org/wiki/Know_your_customer +[AML-Wikipedia]: https://en.wikipedia.org/wiki/Money_laundering#Anti-money_laundering +[ERC-777]: http://eips.ethereum.org/EIPS/eip-777 +[ERC-1066]: http://eips.ethereum.org/EIPS/eip-1066 +[ERC-1444]: http://eips.ethereum.org/EIPS/eip-1444 +[ERC-1462]: http://eips.ethereum.org/EIPS/eip-1462 From 05a85a9e3c7db933f2036971111a4f9df6b3cc11 Mon Sep 17 00:00:00 2001 From: Daniel Lehrner Date: Sat, 23 Nov 2019 01:28:38 +0100 Subject: [PATCH 37/47] EIP-2021: Payoutable Token (#2021) --- EIPS/eip-2021.md | 290 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 290 insertions(+) create mode 100644 EIPS/eip-2021.md diff --git a/EIPS/eip-2021.md b/EIPS/eip-2021.md new file mode 100644 index 00000000000000..416f7b5ae605fc --- /dev/null +++ b/EIPS/eip-2021.md @@ -0,0 +1,290 @@ +--- +eip: 2021 +title: Payoutable Token +author: Fernando Paris , Julio Faura , Daniel Lehrner +discussions-to: https://github.com/ethereum/EIPs/issues/2106 +status: Draft +type: Standards Track +category: ERC +created: 2019-05-10 +requires: 20, 1066, 1996 +--- + +## Simple Summary +An extension to the [ERC-20] standard token that allows Token wallet owners to request payout from their wallet, by calling the smart contract and attaching a payout instruction string. + +## Actors + +#### Token Wallet Owners +The person or company who owns the wallet, and will order payout. + +#### Token contract owner / agent +The entity, company responsible/owner of the token contract, and token issuing/minting. This actor is in charge of trying to fulfill all payout request(s), reading the payout instruction(s), and correlate the payout details. + +#### Orderer +An actor who is enabled to initiate payout orders on behalf of a token wallet owner. + +## Abstract +Token wallet owners (or approved addresses) can order payout requests through blockchain. This is done by calling the ```orderPayoutFrom``` or ```orderPayoutFrom``` methods, which initiate the workflow for the token contract operator to either honor or reject the payout request. In this case, payout instructions are provided when submitting the request, which are used by the operator to determine the destination of the funds. + +In general, it is not advisable to place explicit routing instructions for the payouts on a verbatim basis on the blockchain, and it is advised to use a private communication alternatives, such as private channels, encrypted storage or similar, to do so (external to the blockchain ledger). Another (less desirable) possibility is to place these instructions on the instructions field in encrypted form. + +## Motivation +Nowadays most of the token payout requests, need a previous centralized transaction, to be able to define the payout destination to be able to execute the payout (burn transaction). +In the aim of trying to bring all the needed steps into decentralization, exposing all the needed steps of token lifecycle and payment transactions, a payout request can allow wallet owner to initiate the payout order via blockchain. +Key benefits: + +* Payout, burning traceability is enhanced bringing the initiation into the ledger. All payment, payout statuses can be stored on chain. +* Almost all money/token lifecycle is covered via a decentralized approach, complemented with private communications which is common use in the ecosystem. + +In this case, the following movement of tokens are done as the process progresses: + +* Upon launch of the payout request, the appropriate amount of funds are placed on a hold with a predefined notary defined by the platform, and the payout is placed into a ```Ordered``` state +* The operator then can put the payout request ```InProcess```, which prevents the _orderer_ of the payout from being able to cancel the payout request +* After checking the payout is actually possible the operator then executes the hold, which moves the funds to a suspense wallet and places the payout into the ```FundsInSuspense``` state +* The operator then moves the funds offchain (usually from the omnibus account) to the appropriate destination account, then burning the tokens from the suspense wallet and rendering the payout into the ```Executed``` state +* Either before or after placing the request ```InProcess```, the operator can also reject the payout, which returns the funds to the payer and eliminates the hold. The resulting end state of the payout is ```Rejected``` +* When the payout is ```Ordered``` and before the operator places it into the ```InProcess``` state, the orderer of the payout can also cancel it, which frees up the hold and puts the payout into the final ```Cancelled``` state + +## Specification + +```solidity +interface IPayoutable /* is ERC-20 */ { + enum PayoutStatusCode { + Nonexistent, + Ordered, + InProcess, + FundsInSuspense, + Executed, + Rejected, + Cancelled + } + function authorizePayoutOperator(address orderer) external returns (bool); + function revokePayoutOperator(address orderer) external returns (bool); + function orderPayout(string calldata operationId, uint256 value, string calldata instructions) external returns (bool); + function orderPayoutFrom(string calldata operationId, address walletToBePaidOut, uint256 value, string calldata instructions) external returns (bool); + function cancelPayout(string calldata operationId) external returns (bool); + function processPayout(string calldata operationId) external returns (bool); + function putFundsInSuspenseInPayout(string calldata operationId) external returns (bool); + function executePayout(string calldata operationId) external returns (bool); + function rejectPayout(string calldata operationId, string calldata reason) external returns (bool); + + function isPayoutOperatorFor(address walletToDebit, address orderer) external view returns (bool); + function retrievePayoutData(string calldata operationId) external view returns (address walletToDebit, uint256 value, string memory instructions, PayoutStatusCode status); + + event PayoutOrdered(address indexed orderer, string indexed operationId, address indexed walletToDebit, uint256 value, string instructions); + event PayoutInProcess(address indexed orderer, string indexed operationId); + event PayoutFundsInSuspense(address indexed orderer, string indexed operationId); + event PayoutExecuted(address indexed orderer, string indexed operationId); + event PayoutRejected(address indexed orderer, string indexed operationId, string reason); + event PayoutCancelled(address indexed orderer, string indexed operationId); + event PayoutOperatorAuthorized(address indexed walletToBePaidOut, address indexed orderer); + event PayoutOperatorRevoked(address indexed walletToBePaidOut, address indexed orderer); +} +``` + +### Functions + +#### authorizePayoutOperator + +Wallet owner, allows a given address to be payout orderer. + +| Parameter | Description | +| ---------|-------------| +| orderer | The address of the orderer. | + +#### revokePayoutOperator + +Wallet owner, Revokes a given address to be payout orderer. + +| Parameter | Description | +| ---------|-------------| +| orderer | The address of the orderer. | + +#### orderPayout + +Creates a payout request, that will be processed by the token operator. The function must revert if the operation ID has been used before. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify the request | +| value | The amount to be paid out. | +| instruction | A string including the payment instruction. | + +#### orderPayoutFrom + +Creates a payout request, on behalf of a wallet owner, that will be processed by the token operator. The function must revert if the operation ID has been used before. + +| Parameter | Description | +| ---------|-------------| +| operationId |The unique ID to identify the request | +| walletToBePaidOut | The wallet to be paid out on behalf. | +| value | The amount to be paid out. | +| instruction | A string including the payment instruction. | + +#### cancelPayout + +Cancels a payout request. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify the request that is going to be cancelled. This can only be done by token holder, or the payout initiator/orderer. | +| reason | The specific reason that explains why the payout request was rejected. [EIP-1066] codes can be used. | + + +#### processPayout + +Marks a payout request as on process. After the status is on process, order cannot be cancelled. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify that the request is in process. | + +#### putFundsInSuspenseInPayout + +Put a given payout in suspense. Can only be done if it is in process. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify that the request is in process. | + +#### executePayout + +Burn the amount of tokens and marks a payout request as executed. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify the request that has been executed. | + +#### rejectPayout + +Rejects a given operation with a reason. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify the request that has been executed. | +| reason | The specific reason that explains why the payout request was rejected. [EIP-1066] codes can be used | + +#### isApprovedToOrderPayout + +Checks that given player is allowed to order payout requests, for a given wallet. + +| Parameter | Description | +| ---------|-------------| +| walletToBePaidOut | The wallet to be paid out, and checked for approval permission. | +| orderer | The address of the orderer, to be checked for approval permission. | + +#### retrievePayoutData + +Retrieves all the payout request data. Only operator, tokenHolder, and orderer can get the given operation data. + +| Parameter | Description | +| ---------|-------------| +| orderer | The address of the orderer, to correlate the right data. | +| operationId | The unique ID to identify the payout order. | + +### Events + +#### Payout Ordered + +Emitted when an token wallet owner orders a payout request. + +| Parameter | Description | +| ---------|-------------| +| operationId | The unique ID to identify the request | +| walletToBePaidOut | The wallet that is requested to be paid out | +| value | The amount to be funded. | +| instruction | A string including the payment instruction. | + +#### PayoutFundsInSuspense + +Emitted when an operator puts fund in suspense. + +| Parameter | Description | +| ---------|-------------| +| orderer | The address of the payout request orderer. | +| operationId | The unique ID to identify the payout. | + +#### PayoutInProcess + +Emitted when an operator accepts a payout request, and the operation is in process. + +| Parameter | Description | +| ---------|-------------| +| orderer | The address of the payout request orderer. | +| operationId | The unique ID to identify the payout. | + +#### PayoutExecuted + +Emitted when an operator has executed a payout request. + +| Parameter | Description | +| ---------|-------------| +| orderer | The address of the payout request orderer. | +| operationId | The unique ID to identify the payout. | + +#### PayoutRejected + +Emitted when an operator has rejected a payout request. + +| Parameter | Description | +| ---------|-------------| +| orderer | The address of the payout request orderer. | +| operationId | The unique ID to identify the payout. | +| reason | The specific reason that explains why the payout request was rejected. [EIP-1066] codes can be used | + +#### PayoutCancelled + +Emitted when a token holder, orderer, has cancelled a payout request. This can only be done if the operator hasn't put the payout order in process. + +| Parameter | Description | +| ---------|-------------| +| orderer | The address of the payout request orderer. | +| operationId | The unique ID per payout issuer to identify the payout. | + +#### PayoutOperatorAuthorized + +Emitted when a given player, operator, company or a given persona, has been approved to start payout request for a given token holder. + +| Parameter | Description | +| ---------|-------------| +| walletToBePaidOut | The wallet that the player is allowed to start payout requests | +| orderer |The address that allows the the player to start requests. | + +#### PayoutOperatorRevoked + +Emitted when a given player has been revoked initiate payout requests. + +| Parameter | Description | +| ---------|-------------| +| walletToBePaidOut | The wallet that the player is allowed to start payout requests | +| orderer |The address that allows the the player to start requests. | + +## Rationale +This standards provides a functionality to allow token holders to start payout requests in a decentralized way. + +It's important to highlight that the token operator, need to process all payout request, updating the payout status based on the linked payment that will be done. + +Payout instruction format is open. ISO payment standard like is a good start point. + +This EIP uses [EIP-1996] to hold the money after a payout is ordered. The token contract owner or agent, whose implementation is not part of this proposal, acts as a predefined notary to decide if the payout is executed or not. + +The `operationId` is a string and not something more gas efficient to allow easy traceability of the hold and allow human readable ids. It is up to the implementer if the string should be stored on-chain or only its hash, as it is enough to identify a hold. + +The `operationId` is a competitive resource. It is recommended, but not required, that the hold issuers used a unique prefix to avoid collisions. + +## Backwards Compatibility +This EIP is fully backwards compatible as its implementation extends the functionality of [ERC-20] and [ERC-1996]. + +## Implementation +The GitHub repository [IoBuilders/payoutable-token](https://github.com/IoBuilders/payoutable-token) contains the reference implementation. + +## Contributors +This proposal has been collaboratively implemented by [adhara.io](https://adhara.io/) and [io.builders](https://io.builders/). + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). + +[ERC-20]: https://eips.ethereum.org/EIPS/eip-20 +[EIP-1066]: https://eips.ethereum.org/EIPS/eip-1066 +[EIP-1996]: https://eips.ethereum.org/EIPS/eip-1996 From 26a8f1512cd095594400b28a008c85c89717d1cf Mon Sep 17 00:00:00 2001 From: Adam Schmideg Date: Sat, 23 Nov 2019 01:45:18 +0100 Subject: [PATCH 38/47] Automatically merged updates to draft EIP(s) 1767 (#2262) 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-1767.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-1767.md b/EIPS/eip-1767.md index c89b6fced5446e..84c83bc114ca6a 100644 --- a/EIPS/eip-1767.md +++ b/EIPS/eip-1767.md @@ -220,7 +220,7 @@ type Block { # Logs returns a filtered set of logs from this block. logs(filter: BlockFilterCriteria!): [Log!]! # Account fetches an Ethereum account at the current block's state. - account(address: Address!): Account! + account(address: Address!): Account # Call executes a local call operation at the current block's state. call(data: CallData!): CallResult # EstimateGas estimates the amount of gas that will be required for @@ -303,7 +303,7 @@ type Pending { # Transactions is a list of transactions in the current pending state. transactions: [Transaction!] # Account fetches an Ethereum account for the pending state. - account(address: Address!): Account! + account(address: Address!): Account # Call executes a local call operation for the pending state. call(data: CallData!): CallResult # EstimateGas estimates the amount of gas that will be required for From 4f4e1db38e43209a78e7911f331854ad060a58f0 Mon Sep 17 00:00:00 2001 From: James Hancock Date: Mon, 25 Nov 2019 02:43:31 -0800 Subject: [PATCH 39/47] Hard fork proposal to address the Ice age (#2387) --- EIPS/eip-2387.md | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 EIPS/eip-2387.md diff --git a/EIPS/eip-2387.md b/EIPS/eip-2387.md new file mode 100644 index 00000000000000..410c6e45d1b770 --- /dev/null +++ b/EIPS/eip-2387.md @@ -0,0 +1,67 @@ +--- +eip: 2387 +title: "Hardfork Meta: Mountain Glacier" +author: James Hancock (@madeoftin) +discussions-to: https://ethereum-magicians.org/t/hard-fork-to-address-the-ice-age-eip-2387 +type: Meta +status: Draft +created: 2019-11-22 +requires: 1679, 2384 +--- + +## Abstract + +This meta-EIP specifies the changes included in the Ethereum hard fork named Mountain Glacier. This hard fork addresses the impending Ice Age on Ethereum Mainnet and includes a commitment to solving the problems with the ice age more permanently. + +## Motivation + +Ethereum achieves a consistent block time due to its' difficulty retargeting algorithm. If a block-time is higher than 20 seconds, it reduces the difficulty, and if a block time is lower than 10 seconds, it increases the difficulty. This mechanism reaches typically an equilibrium of around 13-14 seconds. Included within this mechanism is something we refer to as the Difficulty Bomb or the Ice Age. It artificially adds to the difficulty in such a way that the retargeting mechanism, at some point, can not adapt to the increase, and we see increased block times throughout the network. The ice age increments every 100,000 blocks. It at first is barely noticeable, but once it is visible, there is a drastic effect on block-times in the network. + +The primary problem with the Ice Age is that it is included in the complex mechanism that targets block times, which is an entirely separate in purpose. What is worse is due to being intwined with that algorithm, it is very difficult to simulate or predict its effect on the network. To predict the impact of the ice age, you must both make assumptions about the difficulty of main-net in the future, and predict the effect of changes in difficulty to the impact on the ice age and thus block-times. + +This fork will push back the Iceage as far as far as is reasonable and will give us time to update the Iceage to no longer have these design problems. There are two solutions to consider with-in that time frame. + + - Update the mechanism so that behavior is predictable. + - Remove the Iceage entirely + +## Specification + +- Codename: Mountain Glacier + +### Activation + - `Block >= 9,200,000` on the Ethereum mainnet + - `Block >= tbd` on the Ropsten testnet + - `Block >= tbd` on the Kovan testnet + - `Block >= tbd` on the Rinkeby testnet + - `Block >= tbd` on the Görli testnet + +### Included EIPs + - [EIP-2384](https://eips.ethereum.org/EIPS/eip-2384): Istanbul/Berlin Difficulty Bomb Delay + +## Rationale + +I want to address the rationale for the intention of the Iceage and the implementation of the Iceage separately. + +**The original intentions of the ice age include:** + + - At the time of upgrades, inhibit unintentional growth of the resulting branching forks leading up to Eth 2.0. * + - Encourage a prompt upgrade schedule for the path to Eth 2.0. * + - Forces the community to come back into agreement repeatedly...and it gives whatever portion of the community that wants to a chance to fork off + - Is a check for the Core Devs in the case that a decision is made to freeze the code base of clients without the blessing of the community. + +*Note: Neither of these effects the Freedom to Fork. They are meant to encourage core-devs and the community to upgrade along with the network and prevent the case where sleeper forks remain dormant only later to be resurrected. The requirement for an active fork is to change a client in a way to respond to the ice age. This is in fact what Ethereum Classic as done. + +This is not meant to be exhaustive, but the ideas above capture much of what has been written on the original intentions and process of creating the fork. Any additions to this list that need to be made, I am happy to include. Regardless, to effectively implement an updated design for the ice age, all of the intentions need to be revisited and clarified as part of any updates. This clarification will give a clear expectation for the community and core developers moving forward. + +**The implementation** + +The existing implementation of the ice age, while it does work in practice, is unnecessarily complex to model and confusing to communicate to the community. Any updates to the design should be: + + - Easy to model the effect on the network + - Easy to predict when it occurs + +This fork would give us time to address the community to understand their priorities better as far as the intentions of the Ice Age, and give time for proposals for better mechanisms to achieve those goals. + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 6818ea9f0d8cbb2049ff7b80e822b93218e642e3 Mon Sep 17 00:00:00 2001 From: alet89 Date: Mon, 25 Nov 2019 20:24:39 +0100 Subject: [PATCH 40/47] Automatically merged updates to draft EIP(s) (#2397) 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 From 783fc89be3e4ffa5480f82cf6122a98160807309 Mon Sep 17 00:00:00 2001 From: Carl Beekhuizen Date: Mon, 25 Nov 2019 20:41:11 +0100 Subject: [PATCH 41/47] Draft: BLS12-381 Key Generation (#2333) Apply @MrChico's suggestions from code review Co-Authored-By: MrChico --- EIPS/eip-2333.md | 279 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 279 insertions(+) create mode 100644 EIPS/eip-2333.md diff --git a/EIPS/eip-2333.md b/EIPS/eip-2333.md new file mode 100644 index 00000000000000..9d0fe16c3233bd --- /dev/null +++ b/EIPS/eip-2333.md @@ -0,0 +1,279 @@ +--- +eip: 2333 +title: BLS12-381 Key Generation +author: Carl Beekhuizen (carl@ethereum.org) +discussions-to: https://github.com/ethereum/EIPs/issues/2337 +status: Draft +type: Standards Track +category: ERC +created: 2019-09-30 +--- + +## Simple Summary + +This EIP is a method based on a tree structure for deriving BLS private keys from a single source of entropy while providing a post-quantum cryptographic fallback for each key. + +## Abstract + +This standard is a method for deriving a tree-hierarchy of BLS12-381 keys based on an entropy seed. Starting with the aforementioned seed, a tree of keys is built out using only the parent node's private key and the index of the desired child. This allows for a practically limitless number of keys to be derived for many different purposes while only requiring knowledge of a single ancestor key in the tree. This allows for keys, or families thereof, to be provisioned for different purposes by further standards. + +In addition to the above, this method of deriving keys provides an emergency backup signature scheme that is resistant to quantum computers for in the event that BLS12-381 is ever deemed insecure. + +## A note on purpose + +This specification is designed not only to be an Ethereum 2.0 standard, but one that is adopted by the wider community who have adopted the BLS12-381 signature standard. It is therefore important also to consider the needs of the wider industry along with those specific to Ethereum. As a part of these considerations, it is the intention of the author that this standard eventually migrate to a more neutral repository in the future. + +## Motivation + +### Deficiencies of the existing mechanism + +The new curve (BLS12-381) used for signatures within Ethereum 2.0 (alongside many other projects) mandates a new key derivation scheme. The most commonly used scheme for key derivation at the within Ethereum 1.x is [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) (also known as HD derivation) which deems keys greater than the curve order invalid. Based on the order of the private key subgroup of BLS12-381 and the size of the entropy utilised, more than 54% of keys generated by BIP32 would be invalid. (secp256k1 keys derived by BIP32 are invalid with probability less than 1 in 2-127.) + +### Establishing a multi-chain standard early on + +By establishing a standard before the first users begin to generate their keys, the hope is that a single standard is highly pervasive and therefore can be assumed to be the method by which the majority of keys are provided. This is valuable for two reasons, firstly in order for a post-quantum backup mechanism to be effective, there needs to be an enshrined mechanism whereby users can switch to a post-quantum signature scheme with pre-shared public keys (something this EIP provides at 0 extra storage cost). Secondly, this unifies the inter- and intra-chain ecosystem by having common tooling ideally allowing users to switch between key-management systems. + +### A post-quantum backup + +This key derivation scheme has a Lamport key pair which is generated as a intermediate step in the key generation process. This key pair can be used to provide a Lamport signature which is a useful backup in the event of BLS12-381 no longer being considered secure (in the event of quantum computing making a sudden advancement, for example.). The idea is the Lamport signature will act as a bridge to a new signature scheme which is deemed to be secure. + +## Specification + +Keys are defined in terms of a tree structure where a key is determined by the tree's seed and a tree path. This is very useful as one can start with a single source of entropy and build out a practically unlimited number of keys. The specification can be broken into two sub-components: generating the master key, and constructing a child key from its parent. The master key is used as the root of the tree and then the tree is built in layers on top of this root. + +### The Tree Structure + +The key tree is defined purely through the relationship between a child-node and its ancestors. Starting with the root of the tree, the *master key*, a child node can be derived by knowing the parent's private key and the index of the child. The tree is broken up into depths which are indicated by `/` and the master node is described as `m`. The first child of the master node is therefore described as `m / 0` and `m / 0`'s siblings are `m / i` for all `0 <= i < 2**32`. + +```text + [m / 0] - [m / 0 / 0] + / \ + / [m / 0 / 1] +[m] - [m / 1] + \ + ... + [m / i] +``` + +### Key derivation + +Every key generated via the key derivation process derives a child key via a set of intermediate Lamport keys. The idea behind the Lamport keys is to provide a post-quantum backup in case BLS12-381 is no longer deemed secure. At a high level, the key derivation process works by using the parent node's privkey as an entropy source for the Lamport private keys which are then hashed together into a compressed Lamport public key, this public key is then hashed into BLS12-381's private key group. + +#### `IKM_to_lamport_SK` + +##### Inputs + +* `IKM`, a secret octet string +* `salt`, an octet string + +##### Outputs + +* `lamport_SK`, an array of 255 32-octet stings + +##### Definitions + +* `HKDF-Extract` is as defined in [RFC5869](https://tools.ietf.org/html/rfc5869), instantiated with SHA256 +* `HKDF-Expand` is as defined in [RFC5869](https://tools.ietf.org/html/rfc5869), instantiated with SHA256 +* `K = 32` is the digest size (in octets) of the hash function (SHA256) +* `L = K * 255` is the HKDF output size (in octets) +* `""` is the empty string +* `bytes_split` is a function takes in an octet string and splits it into `K`-byte chunks which are returned as an array + +##### Procedure + +``` text +0. PRK = HKDF-Extract(salt, IKM) +1. OKM = HKDF-Expand(PRK, "" , L) +2. lamport_SK = bytes_split(OKM, K) +3. return lamport_SK +``` + +#### `parent_SK_to_lamport_PK` + +##### Inputs + +* `parent_SK`, the BLS Secret Key of the parent node +* `index`, the index of the desired child node, an integer `0 <= index < 2^32` + +##### Outputs + +* `lamport_PK`, the compressed lamport PK, a 32 octet string + +##### Definitions + +* `I2OSP` is as defined in [RFC3447](https://ietf.org/rfc/rfc3447.txt) (Big endian decoding) +* `flip_bits` is a function that returns the bitwise negation of its input +* `""` is the empty string +* `a | b` is the concatenation of `a` with `b` + +##### Procedure + +```text +0. salt = I2OSP(index, 4) +1. IKM = I2OSP(parent_SK, 32) +2. lamport_0 = IKM_to_lamport_SK(IKM, salt) +3. not_IKM = flip_bits(IKM) +4. lamport_1 = IKM_to_lamport_SK(not_IKM, salt) +5. lamport_PK = "" +6. for i = 0 to 255 + lamport_PK = lamport_PK | SHA256(lamport_0[i]) +7. for i = 0 to 255 + lamport_PK = lamport_PK | SHA256(lamport_1[i]) +8. compressed_lamport_PK = SHA256(lamport_PK) +9. return compressed_lamport_PK +``` + +#### `HKDF_mod_r` + +`hkdf_mod_r()` is used to hash 32 random bytes into the subgroup of the BLS12-381 private keys. + +##### Inputs + +* `IKM`, a secret octet string. + +##### Outputs + +* `SK`, the corresponding secret key, an integer 0 <= SK < r. + +##### Definitions + +* `HKDF-Extract` is as defined in RFC5869, instantiated with hash H. +* `HKDF-Expand` is as defined in RFC5869, instantiated with hash H. +* `L` is the integer given by ceil((1.5 * ceil(log2(r))) / 8). +* `"BLS-SIG-KEYGEN-SALT-"` is an ASCII string comprising 20 octets. +* `""` is the empty string. +* `OS2IP` is as defined in [RFC3447](https://ietf.org/rfc/rfc3447.txt) (Big endian encoding) +* `r` is the order of the BLS 12-381 curve defined in [the draft IETF BLS signature scheme standard](https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-00) `r=52435875175126190479447740508185965837690552500527637822603658699938581184513` + +##### Procedure + +```text +1. PRK = HKDF-Extract("BLS-SIG-KEYGEN-SALT-", IKM) +2. OKM = HKDF-Expand(PRK, "", L) +3. SK = OS2IP(OKM) mod r +4. return SK +``` + +### `derive_child_SK` + +The child key derivation function takes in the parent's private key and the index of the child and returns the child private key. + +##### Inputs + +* `parent_SK`, the secret key of the parent node, a big endian encoded integer +* `index`, the index of the desired child node, an integer `0 <= index < 2^32` + +##### Outputs + +* `child_SK`, the secret key of the child node, a big endian encoded integer + +##### Procedure + +```text +0. compressed_lamport_PK = parent_SK_to_lamport_PK(parent_SK, index) +1. SK = HKDF_mod_r(compressed_lamport_PK) +2. return SK +``` + +### `derive_master_SK` + +##### Inputs + +* `seed`, the source entropy for the entire tree, a octet string >= 128 bits + +##### Outputs + +* `SK`, the secret key of master node within the tree, a big endian encoded integer + +##### Procedure + +```text +0. SK = HKDF_mod_r(seed) +1. return SK +``` + +## Rationale + +### Lamport signatures + +Lamport signatures are used as the backup mechanism because of their relative simplicity for a post-quantum signature scheme. Lamport signatures are very easy both to explain and implement as the sole cryptographic dependency is a secure hash function. This is important as it minimises the complexity of implementing this standard as well as the compute time for deriving a key. Lamport signatures have very large key sizes which make them impractical for many use cases, but this is not deemed to be an issue in this case as this scheme is only meant to be a once-off event to migrate to a new scheme. + +Revealing a the associated Lamport public key for a corresponding BLS key is done by verifying that the Lamport public key is the pre-image of the corresponding BLS private key (which in tern is verified against the BLS public key). This means that using a key's Lamport signature reveals the BLS private key rendering the BLS key pair unsafe. This has the upside of not requiring additional storage space for backup keys alongside BLS keys but does require that the Lamport signatures be used once and that the BLS key is no longer trusted after that point. + +The Lamport signatures used within this scheme have 255 bits worth of security, not 256. This is done because HKDF-SHA256, the mechanism used to stretch a key's entropy, has a length-limit of `255 * hash_function_digest_size`. The 1-bit reduction in security is deemed preferable over increasing the complexity of the entropy stretching mechanism. + +### SHA256 + +SHA256 is used as the hash function throughout this standard as it is the hash function chosen by the for the [IETF BLS12-381 standard](https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-00). Using a single hash function for everything decreases the number of cryptographic primitives required to implement the entire BLS standardised key-stack while reducing the surface for flaws in the overall system. + +### `hkdf_mod_r()` + +The function `hkdf_mod_r()` in this standard is the same as the `KeyGen` function described in the [draft IETF BLS standard](https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-00) and therefore the private key obtained from `KeyGen` is equal to that obtained from `hkdf_mod_r` for the same seed bytes. This means that common engineering can be done when implementing this function. Additionally because of its inclusion in an IETF standard, it has had much scrutiny by many cryptographers and cryptanalysts, thereby lending credence to its safety as a key derivation mechanism. + +While `hkdf_mod_r()` has modulo bias, the magnitude of this bias is minuscule (the output size of HKDF is set to 48 bytes which is greater 2128 time larger than the curve order). This bias is deemed acceptable in light of the simplicity of the constant time scheme. + +### Only using hardened keys + +Widely accepted standards that existed before this one ([BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) and [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki)) utilise the notion of hardened and non-hardened keys whereas this specification only offers the former. Non-hardened keys are primarily useful in a UTXO system in which having one's balance spilt amongst many accounts does not present much additionally complexity, but such keys are much less useful outside of this context. Further complicating matters is the problem of deriving non-hardened keys using a post-quantum signature scheme as non-hardened keys are made possible by the very group arithmetic quantum computers gain an advantage over. + +## Backwards Compatibility + +There are no major backwards compatibility issues brought upon by this EIP as it is not designed for use within Ethereum 1.0 as it currently stands. That said, this standard is not compatible with BIP32/ BIP44 style paths as paths specified by these systems make use of non-hardened keys, something that does not exist within this standard. + +## Test Cases + +### Test Case 0 + +```text +seed = 0xc55257c360c07c72029aebc1b53c05ed0362ada38ead3e3e9efa3708e53495531f09a6987599d18264c1e1c92f2cf141630c7a3c4ab7c81b2f001698e7463b04 +master_SK = 12513733877922233913083619867448865075222526338446857121953625441395088009793 +child_index = 0 +child_SK = 7419543105316279183937430842449358701327973165530407166294956473095303972104 +``` + +### Test Case 1 + +```text +seed = 0x3141592653589793238462643383279502884197169399375105820974944592 +master_SK = 46029459550803682895343812821003080589696405386150182061394330539196052371668 +child_index = 3141592653 +child_SK = 43469287647733616183478983885105537266268532274998688773496918571876759327260 +``` + +### Test Case 2 + +```text +seed = 0x0099FF991111002299DD7744EE3355BBDD8844115566CC55663355668888CC00 +master_SK = 45379166311535261329029945990467475187325618028073620882733843918126031931161 +child_index = 4294967295 +child_SK = 46475244006136701976831062271444482037125148379128114617927607151318277762946 +``` + +### Test Case 3 + +```text +seed = 0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3 +master_SK = 31740500954810567003972734830331791822878290325762596213711963944729383643688 +child_index = 42 +child_SK = 51041472511529980987749393477251359993058329222191894694692317000136653813011 +``` + +### Test Vector with Intermediate values + +```text +seed = 0xc55257c360c07c72029aebc1b53c05ed0362ada38ead3e3e9efa3708e53495531f09a6987599d18264c1e1c92f2cf141630c7a3c4ab7c81b2f001698e7463b04 +master_SK = 12513733877922233913083619867448865075222526338446857121953625441395088009793 +child_index = 0 +lamport_0 = [0x7b4a587eac94d7f56843e718a04965d4832ef826419b4001a3ad0ba77eb44a3b, 0x90f45a712112122429412921ece5c30eb2a6daf739dc9034fc79424daeb5eff6, 0xd061c2799de00b2be90eb1cc295f4c31e22d4b45c59a9b9b2554379bea7783cb, 0x3ad17e4cda2913b5180557fbe7db04b5ba440ce8bb035ae27878d66fbfa50d2c, 0xf5b954490933ad47f8bf612d4a4f329b3aa8914b1b83d59e15e271e2a087e002, 0x95d68d505bf4ff3e5149bc5499cf4b2f00686c674a29a8d903f70e569557d867, 0x1b59c76d9bb2170b220a87833582ede5970d4a336d91c99a812825afe963e056, 0x4310ff73cfbbf7b81c39ecbf1412da33e9388c1a95d71a75e51fe12256551ceb, 0xee696343f823e5716e16747f3bbae2fc6de233fe10eea8e45b4579018da0874f, 0xae12a437aaa7ae59f7d8328944b6a2b973a43565c55d5807dc2faf223a33aa73, 0x2a3ae0b47f145bab629452661ff7741f111272e33ec571030d0eb222e1ed1390, 0x1a3ea396e8cbd1d97733ef4753d6840b42c0795d2d693f18e6f0e7b3fff2beb2, 0x472429d0643c888bfdfe6e6ccfdeee6d345d60c6710859ac29fc289fd3656347, 0xa32d4d955949b8bed0eb20f586d8fd516d6ddec84fbbc36998d692633c349822, 0xe5ac8ac5ee1d40e53a7abf36e8269d5d5fce450a87feae8e59f432a44bcc7666, 0xddf9e497ed78032fbd72d9b8abd5204d81c3475f29afa44cdf1ded8ea72dd1dc, 0x945c62e88fb1e5f3c15ff57cd5eb1586ee93ec5ec80154c5a9c50241c5adae0a, 0xc8868b50fc8423c96b7efa1ede4d3203a6b835dbeb6b2ababc58397e6b31d9dd, 0x66de9bd86b50e2b6a755310520af655759c1753bff34b79a5cd63d6811fc8c65, 0x5b13786c6068df7735343e5591393bea8aee92ac5826d6132bf4f5ebf1098776, 0xa2038fc7d8e3cb2eda2bd303cfa76a9e5d8b88293918bec8b2fc03be75684f14, 0x47a13f6b2308a50eded830fdee7c504bf49d1fe6a95e337b0825d0d77a520129, 0xb534cdddcf1aa1c6b4cbba46d1db31b766d958e0a0306450bc031d1e3ed79d97, 0x54aa051b754c31658377f7bff00b7deaa861e74cb12e1eb84216666e19b23d69, 0x0220d57f63435948818eb376367b113c188e37451c216380f65d1ad55f73f527, 0xf9dd2e391565534a4db84980433bf5a56250f45fe294fce2679bcf115522c081, 0x1166591ee2ca59b9f4e525900f085141be8879c66ef18529968babeb87c44814, 0xf4fa2e8de39bdbeb29b64d8b440d3a6c9a6ca5bdce543877eaee93c11bd70ab8, 0x07f466d73b93db283b3f7bfaf9c39ae296adc376ab307ef12312631d0926790e, 0xb2ecff93acb4fa44c1dbf8464b81734a863b6d7142b02f5c008907ea4dc9aaa1, 0xa1d9c342f6c293ac6ef8b5013cba82c4bad6ed7024d782948cb23cd490039ba1, 0xc7d04a639ba00517ece4dbc5ef4aaf20e0ccde6e4a24c28936fabe93dec594db, 0xe3cbb9810472d9dd1cdb5eed2f74b67ea60e973d2d2e897bd64728c9b1aa0679, 0xe36884703413958ff2aba7a1f138a26d0ac0a371270f0169219beb00a5add5f0, 0xe5ea300a09895b3f98de5232d92a36d5611cbcf9aaf9e7bb20cf6d1696ad1cb4, 0xc136cda884e18175ab45148ed4f9d0d1a3c5e11ad0275058e61ae48eb151a81f, 0x3ee1101e944c040021187e93b6e0beb1048c75fb74f3fdd67756b1c8517a311f, 0x016964fd6fc32b9ad07a630949596715dee84d78230640368ff0929a280cf3a2, 0xe33865fc03120b94333bb754fd097dc0f90e69ff6fd221d6aae59fcf2d762d76, 0xe80bb3515a09ac6ecb4ec59de22701cdf954b1ae8a677fd85508c5b041f28058, 0x3889af7cd325141ec288021ede136652a0411d20364005b9d3ca9102cb368f57, 0x18dad0bc975cf8800addd54c7867389d3f7fe1b97d348bd8412a6cbfb75c520a, 0x09035218686061ee91bd2ad57dc6fb6da7243b8177a153484524b2b228da5314, 0x688fd7a97551c64eae33f91abb073a46eafbbacd5595c6bac2e57dd536acdfe2, 0x1fc164dce565a1d0da59cc8048b334cc5eb84bf04de2399ddb847c22a7e32ab7, 0xa2a340ba05c8a30dd1cab886a926b761758eba0e41b5c4c5dfd4a42f249655c1, 0xc43dffe01479db836a6a1a74564b297fad0d69c6b06cf593f6db9f26b4f307d5, 0x73cef7f3ff724a30a79e1dca74cef74954afeefa2e476c4dec65afe50c16c5c4, 0xa54002253ab7b95cc5b664b3f08976400475cc56f170b939f6792e730ff5170b, 0x9ade43053d41afebc002f09476dffd1b13ecbf67f810791540b92ca56d5e63e4, 0x234e7cbfbe45b22a871db26738fa05de09213a925439d7f3e5108132e521b280, 0x066b712417332c7cfca871fb1bb5839f0341acf9266229603a3eddbc8a93b59f, 0xb5857acdcf636330da2cfcc99c81d9fdbd20c506a3c0e4f4f6a139d2a64f051c, 0xe119908a150a49704b6bbba2c470cd619a0ae10dd9736e8d491890e3c8509fff, 0xb8a5c5dbb51e6cb73cca95b4ad63ea3c7399cd16b05ab6261535495b3af2ca51, 0x05624a1d4d2d2a31160bc48a6314bbf13eaddf56cddb0f0aa4ed3fb87f8b479f, 0x483daceff1c3baa0ed0f3be7e534eebf5f4aed424ecd804edfbf5c56b3476b50, 0x424d04694e7ae673707c77eb1c6d0996d250cfab6832ee3506a12e0384a3c5c9, 0xa11fed0ed8057966bfe7136a15a814d06a516fbc9d44aeef87c509137a26190e, 0x3694d22d1bc64658f3adbe2cc9f1716aee889066e0950e0b7a2fd576ed36bb76, 0x49a13000a87f39f93d0ae9c3a4cfccbf440c0a75cce4c9d70dac627b6d6958b3, 0xb3ff0cdd878d5ac1cb12e7d0b300d649fdd008800d498ae4f9fbf9510c74249a, 0xe52a867cfb87d2fe7102d23d8d64925f7b75ca3f7d6bb763f7337352c255e0be, 0x6513b372e4e557cca59979e48ec27620e9d7cdb238fcf4a9f19c3ba502963be0, 0x9f69d82d4d51736902a987c8b5c30c2b25a895f2af5d2c846667ff6768bcc774, 0x049a220dbe3340749f94643a429cb3cba3c92b561dc756a733d652d838728ab3, 0x4fa2cd877aa115b476082b11053309f3537fa03d9158085f5f3f4bab6083e6da, 0xed12db4069eb9f347735816afcee3fe43d4a6999fef8240b91bf4b05447d734f, 0x3ecbe5eda469278f68548c450836a05cc500864664c7dda9b7526f084a891032, 0x690d8f928fc61949c22e18cceaa2a446f8e1b65bd2e7af9e0a8e8284134ab3d2, 0x99e09167a09f8261e7e8571d19148b7d7a75990d0702d9d582a2e4a96ac34f8e, 0x6d33931693ed7c2e1d080b6a37da52c279a06cec5f534305819f7adf7db0afe3, 0xc4b735462a9a656e28a52b1d4992ea9dea826b858971d698453a4be534d6bb70, 0xedf92b10302dc41f8d362b360f4c2ef551d50e2ded012312c964002d2afc46d7, 0x58f6691cca081ae5c3661dd171b87cc49c90359bb03cc0e57e503f7fcf14aefc, 0x5d29b8b4ee295a73c4a8618927b3d14b76c7da049133a2257192b10be8c17a6a, 0x646802fa42801e0ae24011fb4f62e87219ef1da01f7fc14bf8d6bd2d9e7c21f1, 0x23abf45eee65cc4c1e95ccab42ad280a00bb3b14d243e2021a684075f900141e, 0x2b1ae95c975bf9c387eae506fdb5e58afd2d198f00a21cd3fddb5855e8021e4d, 0x0ef9f6e1c0583493d343e75f9c0c557fa6da0dc12b17a96c5757292916b72ee3, 0x04c7fc76195c64a3285af14161077c045ff6ddbb67c0ff91b080f98eb6781e5c, 0xba12679b97027d0e7076e6d19086c07792eaa7f78350842fbef8ddf5bcd3ecc0, 0xcead458e6799df4d2f6cbf7f13cb3afec3441a354816e3071856ed49cbdbb1a7, 0xbe6c56256556bb5c6727a1d9cb641d969677f56bb5ad7f8f7a7c9cfd128427b4, 0xc80f11963ff40cb1888054b83c0463d32f737f2e7d42098e639023db0dfc84d4, 0xac80006c1296bcfde86697efebb87fb0fddfb70dd34dd2ee4c152482af4687eb, 0xbb7d13ce184249df4576fc3d13351e1683500e48726cd4198423f14f9094068b, 0x1b2d9c40c55bd7362664fa46c1268e094d56c8193e3d991c08dc7a6e4ca14fa1, 0x9bd236254d0565f5b2d24552d4b4d732de43b0adaa64ecd8be3efc6508577591, 0x38078cefccc04e8312d79e0636e0e3157434c50a2ad4e3e87cc6584c41eec8b5, 0xb5d15a8527ff3fa254ba61ffceb02d2570b53361894f351a9e839c0bb716857d, 0x6763dad684bf2e914f40ae0a7ee0cdf12c97f41fc05a485d5991b4daad21a3f8, 0xc80363c20df589333ecbe05bd5f2c19942ebc2593626dc50d00835c40fb8d005, 0x48502b56ae93acd2794f847cbe825525d5d5f59f0f75c67aff84e5338776b3af, 0xfd8e033493ba8af264a855a78ab07f37d936351d2879b95928909ed8df1b4f91, 0x11f75bee9eac7356e65ebc7f004ccdc1da80807380d69143293d1421f50b1c97, 0x903a88a3ebe84ca1c52a752b1faffa9ca1daedac9cbf1aa70942efc9beb44b79, 0x2c0dcd68837f32a69da651045ad836b8cd6b48f2c8c5d73a3bd3bba6148d345a, 0x0aa0f49b3476f3fdb6393f2ab601e0009586090b72ee54a525734f51598960d5, 0xf7a789f013f702731656c562caa15b04cb7c9957376c4d80b8839167bb7fa626, 0x4e0be1b19e305d82db3fd8affd67b0d2559da3edbfb08d19632a5cc46a90ed07, 0x3caaccfc546d84d543eaf4f4c50c9c8fd831c12a8de56fdb9dfd04cc082882fe, 0x894f6a01fd34f0642077e22981752011678548eb70eb55e8072c1caffc16fe02, 0xae7eb54adaa68679348ea3537a49be669d1d61001fbab9fac259ba727dbc9a1a, 0x291a1cbdceff957b5a65440ab67fb8672de881230fe3108a15ca487c2662c2c7, 0x891d43b867137bf8beb9df4da2d951b5984a266a8cd74ec1593801d005f83f08, 0xc558407f6491b37a10835e0ad7ce74f4e368aa49157a28873f7229310cb2d7fd, 0x9ce061b0a072e1fe645f3479dac089b5bfb78cfa6cfbe5fd603bcdb504711315, 0xa8e30d07b09275115dd96472ecf9bc316581caf307735176ca226d4cd9022925, 0x918ee6d2efba7757266577691203f973cf4f4cac10f7d5f86acd2a797ff66583, 0xfa31ba95e15d1635d087522f3d0da9cf7acac4ed6d0ac672654032a3c39244a6, 0xf2952b58f015d6733af06938cd1f82fbddb3b796823bee7a3dbffa04efc117c2, 0x46f8f742d3683de010ede528128d1181e8819f4252474f51371a177bfa518fa4, 0x4ca1cc80094f2910cf83a9e65ad70e234690ffb9142793911ec7cf71663545b3, 0x381965037b5725c71bfa6989d4c432f6611de8e8ec387f3cfc0dcb1a15191b73, 0x2562b88ed3b86ba188be056805a3b7a47cb1a3f630d0e2f39647b0792ec6b7d8, 0x565f6d14e7f22724f06d40f54465ad40d265b6de072b34a09d6e37a97a118cd8, 0xc2982c861ad3278063b4a5f584eaf866db684cc4e712d64230fc9ee33bb4253b, 0xfd806c91927e549d8d400ab7aa68dbe60af988fbabf228483ab0c8de7dab7eee, 0xafae6ff16c168a3a3b5c2f1742d3f89fa4777c4bd0108f174014debf8f4d629c, 0xaf5a4be694de5e53632be9f1a49bd582bf76002259460719197079c8c4be7e66, 0xa8df4a4b4c5bf7a4498a11186f8bb7679137395f28e5c2179589e1c1f26504b5, 0xce8b77c64c646bb6023f3efaed21ca2e928e21517422b124362cf8f4d9667405, 0x62e67a8c423bc6c6c73e6cd8939c5c1b110f1a38b2ab75566988823762087693, 0x7e778f29937daaa272d06c62d6bf3c9c0112d45a3df1689c602d828b5a315a9f, 0xe9b5abd46c2377e602ff329050afa08afe152f4b0861db8a887be910ff1570bf, 0xa267b1b2ccd5d96ae8a916b0316f06fafb886b3bb41286b20763a656e3ca0052, 0xb8ed85a67a64b3453888a10dedf4705bd27719664deff0996a51bb82bc07194f, 0x57907c3c88848f9e27bc21dd8e7b9d61de48765f64d0e943e7a6bb94cc2021ab, 0xd2f6f1141a3b76bf9bf581d49091142944c7f9f323578f5bdd5522ba32291243, 0xc89f104200ed4c5d5f7046d99e68ae6f8ec31e2eeceb568eb05087e3aa546a74, 0xc9f367fae45c39299693b134229bb6dd0da112fd1a7d19b7f4772c01e5cbe479, 0x64e2d4ad51948764dd578d26357e29e8e4d076d65c05cffdf8211b624fefe9ac, 0xf9a9b4e6d5be7fc051df8ecd9c389d16b1af86c749308e6a23f7ff4871f0ba9a, 0x0d2b2a228b86ebf9499e1bf7674335087ced2eb35ce0eb90954a0f75751a2bf4, 0xff8531b45420a960d6e48ca75d77758c25733abde83cd4a6160beae978aa735e, 0xd6d412bd1cb96a2b568d30e7986b7e8994ca92fd65756a758295499e11ea52b6, 0xad8533fccbecdd4a0b00d648bfe992360d265f7be70c41d9631cefad5d4fe2f6, 0x31fbf2afb8d5cc896d517cfc5201ee24527e8d283f9c37ca10233bef01000a20, 0x2fd67b7365efc258131eb410f46bf3b1cbd3e9c76fd6e9c3e86c9ff1054116ff, 0xab6aa29f33d18244be26b23abadb39679a8aa56dafc0dd7b87b672df5f5f5db6, 0xbad3b0f401ca0a53a3d465de5cecd57769ec9d4df2c04b78f8c342a7ed35bbee, 0xbdc24d46e471835d83ce8c5b9ecbe675aab2fd8f7831c548e8efd268c2ee2232, 0x87265fabd7397d08f0729f13a2f3a25bbc8c874b6b50f65715c92b62f665f925, 0xa379fd268e7ff392c067c2dd823996f72714bf3f936d5eeded71298859f834cb, 0xf3ab452c9599ebfbb234f72a86f3062aed12ae1f634abbe542ff60f5cefc1fcf, 0x2b17ebb053a3034c07da36ed2ba42c25ad8e61dec87b5527f5e1c755eb55405a, 0x305b40321bd67bf48bfd121ee4d5d347268578bd4b8344560046594771a11129, 0xe7029c9bea020770d77fe06ca53b521b180ad6a9e747545aadc1c74beef7241c, 0xabc357cec0f4351a5ada22483d3b103890392f8d8f9cb8073a61969ed1be4e08, 0x97f88c301946508428044d05584dc41af2e6a0de946de7d7f5269c05468afe20, 0xbdc08fe8d6f9a05ad8350626b622ad8eec80c52331d154a3860c98676719cfbd, 0x161590fc9f7fcf4eaba2f950cf588e6da79e921f139d3c2d7ebe017003a4799e, 0x91b658db75bc3d1954bfde2ef4bc12980ff1688e09d0537f170c9ab47c162320, 0x76d995f121406a63ce26502e7ec2b653c221cda357694a8d53897a99e6ce731e, 0x3d6b2009586aceb7232c01259bb9428523c02b0f42c2100ec0d392418260c403, 0x14ca74ecbc8ec0c67444c6cb661a2bce907aa2a1453b11f16002b815b94a1c49, 0x553b4dc88554ebe7b0a3bd0813104fd1165a1f950ceace11f5841aa74b756d85, 0x4025bf4ad86751a156d447ce3cabafde9b688efcdafd8aa4be69e670f8a06d9e, 0x74260cf266997d19225e9a0351a9acfa17471fccdf5edc9ccc3bb0d23ef551c5, 0xf9dbca3e16d234e448cf03877746baeb62a8a25c261eff42498b1813565c752a, 0x2652ec98e05c1b6920fb6ddc3b57e366d514ffa4b35d068f73b5603c47f68f2f, 0x83f090efeb36db91eb3d4dfbb17335c733fce7c64317d0d3324d7caaaf880af5, 0x1e86257f1151fb7022ed9ed00fb961a9a9989e58791fb72043bb63ed0811791c, 0xd59e4dcc97cba88a48c2a9a2b29f79125099a39f74f4fb418547de8389cd5d15, 0x875a19b152fe1eb3fe1de288fa9a84864a84a79bac30b1dbd70587b519a9770e, 0x9c9dc2d3c8f2f6814cfc61b42ee0852bbaf3f523e0409dd5df3081b750a5b301, 0xf6f7f81c51581c2e5861a00b66c476862424151dd750efeb20b7663d552a2e94, 0x723fcb7ca43a42483b31443d4be9b756b34927176f91a391c71d0b774c73a299, 0x2b02d8acf63bc8f528706ed4d5463a58e9428d5b71d577fd5daa13ba48ac56cf, 0x2ff6911f574c0f0498fc6199da129446b40fca35ccbf362bc76534ba71c7ca22, 0x1ef4b959b11bc87b11e4a5f84b4d757c6bdcfad874acec9a6c9eee23dc4bbe1b, 0x68e2df9f512be9f64b7e3a2dee462149dac50780073d78b569a20256aea5f751, 0xd1a3682e12b90ae1eab27fc5dc2aef3b8e4dbb813925e9a91e58d6c9832767b6, 0x75778ccc102d98c5e0b4b83f7d4ef7fe8bc7263cc3317723001cb0b314d1e9e8, 0xc7f44e2cead108dc167f0036ac8a278d3549cc3dd5cc067d074ccad9b1d9f8d4, 0x4cba0223c5df2796b0ee9fbc084d69f10e6aedda8f0cf86171bebb156ede676c, 0x628deda825661f586a5713e43c806fdd55e1a53fbe90a4ddb5f3786570740954, 0xfc82a253bc7e0ac96252b238fbb411a54e0adf78d089f804a7fc83a4959b401e, 0x72a6491f5daae0ceb85b61a5ed69009dd2a167c64cb35cabf38b846e27268e9d, 0xee139a913d4fcf25ba54bb36fc8051b91f2ec73ba820cc193c46fb2f7c37a106, 0x7f75021f2b1d0c78859478e27f6f40646b5776c060f1a5f6f0944c840a0121f8, 0x5b60a1b78feca1d2602ac8110d263ad6b3663cbf49e6bdc1077b4b80af2feb6f, 0xd61f15d80b1e88469b6a76ed6a6a2b94143b6acc3bd717357264818f9f2d5c6d, 0xea85da1780b3879a4d81b685ba40b91c060866abd5080b30fbbb41730724a7dd, 0xb9b9da9461e83153f3ae0af59fbd61febfde39eb6ac72db5ed014797495d4c26, 0xf737762fe8665df8475ff341b3762aaeb90e52974fe5612f5efd0fc1c409d7f8, 0xaaa25d934a1d5aa6b2a1863704d7a7f04794ed210883582c1f798be5ca046cf7, 0x932f46d0b6444145221b647f9d3801b6cb8b1450a1a531a959abdaacf2b5656b, 0xf4a8b0e52f843ad27635c4f5a467fbf98ba06ba9a2b93a8a97170b5c41bf4958, 0x196ed380785ee2925307ec904161dc02a4596a55499e5b0a3897f95485b3e74a, 0x772e829a405219e4f8cd93a1ef15c250be85c828c1e29ef6b3f7b46958a85b44, 0xd66cfc9af9941515d788f9f5e3b56fddb92464173ddb67b83bf265e7ea502170, 0xf5b040bfc246425278e2423b1953d8ad518de911cf04d16c67d8580a09f90e62, 0xd2d18b2ae8a53dde14b4000e5e7e414505825f50401a3797dd8820cf510dc448, 0xc01dcc064e644266739cd0ec7edf92fc2ef8e92e0beedf0e8aa30efcff1644fe, 0x24720d325913ba137daf031924ad3bfaa1c8c00a53a2d048fe5667aef45efce3, 0x70a24e1c89b3ea78d76ef458d498dcb5b8561d484853b2a8b2adcd61869857df, 0x0ff3313997f14e1b1dcd80f1d62c58aaefb19efd7c0ea15dde21aa4e2a516e80, 0x960c1f50062a4df851638f42c0259b6e0a0217300884f13a3c5c8d94adb34f21, 0xb71ca7cc8578149da556131268f4625b51620dfc3a6e9fbd47f5df03afbd410e, 0xa1a3eeec0addec7b9e15f416a07608a1b5d94f0b42d5c203b8ced03a07484f5b, 0xa4bb8b059aa122ca4652115b83b17af80cfbea0d3e1e8979a396a667f94e85f3, 0x31c4d2f252167fe2a4d41944224a80b2f1afaf76f8dd6a3d52d71751849e44bb, 0x79642dd6a255f96c9efe569304d58c327a441448db0431aa81fe072d0d359b52, 0x42a4b504714aba1b67defe9458fff0c8cb1f216dcab28263cef67a65693b2036, 0xe3d2f6a9d882d0f026ef316940dfcbf131342060ea28944475fe1f56392c9ad2, 0x986af9aeff236394a0afa83823e643e76f7624e9bfd47d5468f9b83758a86caa, 0xafe2de6ede50ee351d63ed38d1f2ae5203174c731f41bbed95db467461ad5492, 0x9ad40f0785fe1c8a5e4c3342b3c91987cd47a862ece6573674b52fa0456f697a, 0xde4cde6d0fc6def3a89b79da0e01accdbec049f1c9471d13a5d59286bd679af1, 0xecd0d1f70116d6b3ae21c57fb06ad90eed33d040e2c5c3d12714b3be934fa5ce, 0x3c53c5bf2d1b1d4038e1f0e8a2e6d12e0d4613d5cd12562578b6909921224c10, 0x36087382b37e9e306642cc6e867e0fb2971b6b2b28b6caf2f9c96b790e8db70a, 0xa957496d6a4218a19998f90282d05bd93e6baabf55e55e8a5f74a933a4dec045, 0x077d6f094e8467a21f02c67753565ec5755156015d4e86f1f82a22f9cf21c869, 0x12dd3b1f29e1462ca392c12388a77c58044151154cf86f23873f92a99b6bb762, 0x7fdbcdedcc02ecf16657792bd8ef4fa4adeee497f30207d4cc060eb0d528b26b, 0x245554b12bf8edf9e9732d6e2fa50958376e355cb695515c94676e64c6e97009, 0xccd3b1841b517f7853e35f85471710777e437a8665e352a0b61c7d7083c3babc, 0xd970545a326dcd92e31310d1fdce3703dff8ef7c0f3411dfa74fab8b4b0763ac, 0xd24163068918e2783f9e79c8f2dcc1c5ebac7796ce63070c364837aac91ee239, 0x256a330055357e20691e53ca5be846507c2f02cfde09cafb5809106f0af9180e, 0xfa446a5d1876c2051811af2a341a35dbcd3f7f8e2e4f816f501139d27dd7cd82, 0xbafbc7a8f871d95736a41e5721605d37e7532e41eb1426897e33a72ed2f0bf1d, 0x8055af9a105b6cf17cfeb3f5320e7dab1a6480500ff03a16c437dfec0724c290, 0x1de6ee3e989497c1cc7ca1d16b7b01b2f336524aa2f75a823eaa1716c3a1a294, 0x12bb9508d646dda515745d104199f71276d188b3e164083ad27dfdcdc68e290b, 0x7ea9f9939ad4f3b44fe7b780e0587da4417c34459b2996b3a449bb5b3ff8c8cb, 0xa88d2f8f35bc669aa6480ce82571df65fea366834670b4084910c7bb6a735dde, 0x9486e045adb387a550b3c7a603c30e07ed8625d322d1158f4c424d30befe4a65, 0xb283a70ba539fe1945be096cb90edb993fac77e8bf53616bde35cdcaa04ab732, 0xab39a81558e9309831a2caf03e9df22e8233e20b1769f16e613debcdb8e2610f, 0x1fc12540473fbbad97c08770c41f517ce19dc7106aa2be2e9b77867046627509, 0xec33dbec9d655c4c581e07d1c40a587cf3217bc8168a81521b2d0021bd0ec133, 0xc8699e3b41846bc291209bbb9c06f565f66c6ccecbf03ebc27593e798c21fe94, 0x240d7eae209c19d453b666c669190db22db06279386aa30710b6edb885f6df94, 0xb181c07071a750fc7638dd67e868dddbeeee8e8e0dcbc862539ee2084674a89e, 0xb8792555c891b3cbfddda308749122a105938a80909c2013637289e115429625, 0xfe3e9e5b4a5271d19a569fee6faee31814e55f156ba843b6e8f8dc439d60e67a, 0x912e9ba3b996717f89d58f1e64243d9cca133614394e6ae776e2936cf1a9a859, 0xa0671c91a21fdfd50e877afa9fe3974aa3913855a2a478ae2c242bcdb71c73d7, 0x5b55d171b346db9ba27b67105b2b4800ca5ba06931ed6bd1bafb89d31e6472e6, 0x68438458f1af7bd0103ef33f8bc5853fa857b8c1f84b843882d8c328c595940d, 0x21fe319fe8c08c1d00f977d33d4a6f18aecaa1fc7855b157b653d2d3cbd8357f, 0x23cce560bc31f68e699ece60f21dd7951c53c292b3f5522b9683eb2b3c85fc53, 0x917fa32d172c352e5a77ac079df84401cdd960110c93aa9df51046d1525a9b49, 0x3fc397180b65585305b88fe500f2ec17bc4dccb2ec254dbb72ffb40979f14641, 0xf35fb569e7a78a1443b673251ac70384abea7f92432953ca9c0f31c356be9bd9, 0x7955afa3cd34deb909cd031415e1079f44b76f3d6b0aaf772088445aaff77d08, 0x45c0ca029356bf6ecfc845065054c06024977786b6fbfaea74b773d9b26f0e6c, 0xe5c1dac2a6181f7c46ab77f2e99a719504cb1f3e3c89d720428d019cb142c156, 0x677b0e575afcccf9ddefc9470e96a6cfff155e626600b660247b7121b17b030a, 0xbeed763e9a38277efe57b834a946d05964844b1f51dba2c92a5f3b8d0b7c67d0, 0x962b17ed1a9343d8ebfae3873162eef13734985f528ca06c90b0c1e68adfdd89] +lamport_1 = [0xb3a3a79f061862f46825c00fec4005fb8c8c3462a1eb0416d0ebe9028436d3a9, 0x6692676ce3b07f4c5ad4c67dc2cf1dfa784043a0e95dd6965e59dc00b9eaff2d, 0xbf7b849feb312db230e6e2383681b9e35c064e2d037cbc3c9cc9cd49220e80c9, 0xa54e391dd3b717ea818f5954eec17b4a393a12830e28fabd62cbcecf509c17dc, 0x8d26d800ac3d4453c211ef35e9e5bb23d3b9ede74f26c1c417d6549c3110314d, 0xbb8153e24a52398d92480553236850974576876c7da561651bc551498f184d10, 0x0d30e0e203dc4197f01f0c1aba409321fbf94ec7216e47ab89a66fb45e295eff, 0x01dc81417e36e527776bf37a3f9d74a4cf01a7fb8e1f407f6bd525743865791d, 0xa6318e8a57bec438245a6834f44eb9b7fb77def1554d137ea12320fc572f42c9, 0xd25db9df4575b595130b6159a2e8040d3879c1d877743d960bf9aa88363fbf9f, 0x61bb8baeb2b92a4f47bb2c8569a1c68df31b3469e634d5e74221bc7065f07a96, 0xb18962aee4db140c237c24fec7fd073b400b2e56b0d503f8bc74a9114bf183bf, 0x205473cc0cdab4c8d0c6aeceda9262c225b9db2b7033babfe48b7e919751a2c6, 0xc5aa7df7552e5bb17a08497b82d8b119f93463ccb67282960aee306e0787f228, 0x36da99e7d38ce6d7eab90ea109ba26615ad75233f65b3ae5056fba79c0c6682a, 0xd68b71bba6266b68aec0df39b7c2311e54d46a3eab35f07a9fe60d70f52eec58, 0xbbe56f1274ada484277add5cb8c90ef687d0b69a4c95da29e32730d90a2d059f, 0x0982d1d1c15a560339d9151dae5c05e995647624261022bbedce5dce8a220a31, 0x8ef54ad546d2c6144fc26e1e2ef92919c676d7a76cfdfb5c6a64f09a54e82e71, 0x1e3ac0133eef9cdbeb590f14685ce86180d02b0eea3ef600fd515c38992b1f26, 0x642e6b1c4bec3d4ba0ff2f15fbd69dcb57e4ba8785582e1bc2b452f0c139b590, 0xca713c8cf4afa9c5d0c2db4fc684a8a233b3b01c219b577f0a053548bedf8201, 0xd0569ba4e1f6c02c69018b9877d6a409659cb5e0aa086df107c2cc57aaba62da, 0x4ebe68755e14b74973e7f0fa374b87cee9c370439318f5783c734f00bb13e4b5, 0x788b5292dc5295ae4d0ea0be345034af97a61eec206fda885bbc0f049678c574, 0x0ebd88acd4ae195d1d3982038ced5af1b6f32a07349cf7fffbff3ce410c10df2, 0xc7faf0a49234d149036c151381d38427b74bae9bd1601fc71663e603bc15a690, 0xc5247bf09ebe9fa4e1013240a1f88c703f25a1437196c71ee02ca3033a61f946, 0x719f8c68113d9f9118b4281e1f42c16060def3e3eeef15f0a10620e886dc988f, 0x28da4f8d9051a8b4d6158503402bdb6c49ba2fb1174344f97b569c8f640504e6, 0x96f6773576af69f7888b40b0a15bc18cc9ec8ca5e1bb88a5de58795c6ddf678e, 0x8d80d188a4e7b85607deccf654a58616b6607a0299dd8c3f1165c453fd33d2e4, 0x9c08dcc4f914486d33aa24d10b89fd0aabcc635aa2f1715dfb1a18bf4e66692a, 0x0ff7045b5f6584cc22c140f064dec0692762aa7b9dfa1defc7535e9a76a83e35, 0x8e2dae66fa93857b39929b8fc531a230a7cfdd2c449f9f52675ab5b5176461d5, 0xf449017c5d429f9a671d9cc6983aafd0c70dd39b26a142a1d7f0773de091ac41, 0xed3d4cab2d44fec0d5125a97b3e365a77620db671ecdda1b3c429048e2ebdae6, 0x836a332a84ee2f4f5bf24697df79ed4680b4f3a9d87c50665f46edaeed309144, 0x7a79278754a4788e5c1cf3b9145edb55a2ba0428ac1c867912b5406bb7c4ce96, 0x51e6e2ba81958328b38fd0f052208178cec82a9c9abd403311234e93aff7fa70, 0x217ec3ec7021599e4f34410d2c14a8552fff0bc8f6894ebb52ec79bf6ec80dc9, 0x8a95bf197d8e359edabab1a77f5a6d04851263352aa46830f287d4e0564f0be0, 0x60d0cbfb87340b7c92831872b48997ce715da91c576296df215070c6c20046d4, 0x1739fbca476c540d081b3f699a97387b68af5d14be52a0768d5185bc9b26961b, 0xac277974f945a02d89a0f8275e02de9353e960e319879a4ef137676b537a7240, 0x959b7640821904ba10efe8561e442fbdf137ccb030aee7472d10095223e320ba, 0xdba61c8785a64cb332342ab0510126c92a7d61f6a8178c5860d018d3dad571c6, 0xc191fb6a92eb1f1fb9e7eb2bdecd7ec3b2380dd79c3198b3620ea00968f2bd74, 0x16ef4e88e182dfc03e17dc9efaa4a9fbf4ff8cb143304a4a7a9c75d306729832, 0x39080e4124ca577ff2718dfbcb3415a4220c5a7a4108729e0d87bd05adda5970, 0xa29a740eef233956baff06e5b11c90ed7500d7947bada6da1c6b5d9336fc37b6, 0x7fda7050e6be2675251d35376bacc895813620d245397ab57812391d503716ee, 0x401e0bf36af9992deb87efb6a64aaf0a4bc9f5ad7b9241456b3d5cd650418337, 0x814e70c57410e62593ebc351fdeb91522fe011db310fcf07e54ac3f6fefe6be5, 0x03c1e52ecbef0d79a4682af142f012dc6b037a51f972a284fc7973b1b2c66dcf, 0x57b22fb091447c279f8d47bdcc6a801a946ce78339e8cd2665423dfcdd58c671, 0x53aeb39ab6d7d4375dc4880985233cba6a1be144289e13cf0bd04c203257d51b, 0x795e5d1af4becbca66c8f1a2e751dcc8e15d7055b6fc09d0e053fa026f16f48f, 0x1cd02dcd183103796f7961add835a7ad0ba636842f412643967c58fe9545bee4, 0x55fc1550be9abf92cacb630acf58bad11bf734114ebe502978a261cc38a4dd70, 0x6a044e0ea5c361d3fb2ca1ba795301e7eb63db4e8a0314638f42e358ea9cfc3e, 0x57d9f15d4db199cbcb7cbd6524c52a1b799d52b0277b5a270d2985fcee1e2acb, 0x66c78c412e586bd01febc3e4d909cc278134e74d51d6f60e0a55b35df6fb5b09, 0x1076799e15a49d6b15c2486032f5e0b50f43c11bc076c401e0779d224e33f6fc, 0x5f70e3a2714d8b4483cf3155865ba792197e957f5b3a6234e4c408bf2e55119d, 0x9b105b0f89a05eb1ff7caed74cf9573dc55ac8bc4881529487b3700f5842de16, 0x1753571b3cfadca4277c59aee89f607d1b1e3a6aa515d9051bafb2f0d8ce0daa, 0x4014fff940b0950706926a19906a370ccbd652836dab678c82c539c00989201a, 0x0423fa59ee58035a0beb9653841036101b2d5903ddeabddabf697dbc6f168e61, 0x78f6781673d991f9138aa1f5142214232d6e3d6986acb6cc7fb000e1a055f425, 0x21b8a1f6733b5762499bf2de90c9ef06af1c6c8b3ddb3a04cce949caad723197, 0x83847957e909153312b5bd9a1a37db0bd6c72a417024a69df3e18512973a18b4, 0x948addf423afd0c813647cfe32725bc55773167d5065539e6a3b50e6ebbdab38, 0x0b0485d1bec07504a2e5e3a89addd6f25d497cd37a0c04bc38355f8bdb01cd48, 0x31be8bda5143d39ea2655e9eca6a294791ca7854a829904d8574bedc5057ddc4, 0x16a0d2d657fadce0d81264320e42e504f4d39b931dff9888f861f3cc78753f99, 0xb43786061420c5231bf1ff638cb210f89bf4cd2d3e8bafbf34f497c9a298a13b, 0x1f5986cbd7107d2a3cbc1826ec6908d976addbf9ae78f647c1d159cd5397e1bd, 0xa883ccdbfd91fad436be7a4e2e74b7796c0aadfe03b7eea036d492eaf74a1a6f, 0x5bc9eb77bbbf589db48bca436360d5fc1d74b9195237f11946349951f2a9f7f6, 0xb6bc86de74a887a5dceb012d58c62399897141cbcc51bad9cb882f53991f499c, 0xa6c3260e7c2dd13f26cf22bf4cd667688142ff7a3511ec895bc8f92ebfa694b6, 0xb97da27e17d26608ef3607d83634d6e55736af10cc7e4744940a3e35d926c2ad, 0x9df44067c2dc947c2f8e07ecc90ba54db11eac891569061a8a8821f8f9773694, 0x865cc98e373800825e2b5ead6c21ac9112ff25a0dc2ab0ed61b16dc30a4a7cd7, 0xe06a5b157570c5e010a52f332cacd4e131b7aed9555a5f4b5a1c9c4606caca75, 0x824eccb5cf079b5943c4d17771d7f77555a964a106245607cedac33b7a14922e, 0xe86f721d7a3b52524057862547fc72de58d88728868f395887057153bccaa566, 0x3344e76d79f019459188344fb1744c93565c7a35799621d7f4505f5b6119ac82, 0x401b3589bdd1b0407854565329e3f22251657912e27e1fb2d978bf41c435c3ac, 0xb12fd0b2567eb14a562e710a6e46eef5e280187bf1411f5573bb86ecbe05e328, 0xe6dc27bab027cbd9fbb5d80054a3f25b576bd0b4902527a0fc6d0de0e45a3f9f, 0x1de222f0e731001c60518fc8d2be7d7a48cc84e0570f03516c70975fdf7dc882, 0xb8ff6563e719fc182e15bbe678cf045696711244aacc7ce4833c72d2d108b1b9, 0x53e28ac2df219bcbbc9b90272e623d3f6ca3221e57113023064426eff0e2f4f2, 0x8a4e0776f03819e1f35b3325f20f793d026ccae9a769d6e0f987466e00bd1ce7, 0x2f65f20089a31f79c2c0ce668991f4440b576ecf05776c1f6abea5e9b14b570f, 0x448e124079a48f62d0d79b96d5ed1ffb86610561b10d5c4236280b01f8f1f406, 0x419b34eca1440c847f7bff9e948c9913075d8e13c270e67f64380a3f31de9bb2, 0x2f6e4fee667acaa81ba8e51172b8329ed936d57e9756fb31f635632dbc2709b7, 0xdd5afc79e8540fcee6a896c43887bd59c9de5d61b3d1b86539faeb41a14b251d, 0xc707bed926a46cc451a6b05e642b6098368dbdbf14528c4c28733d5d005af516, 0x153e850b606eb8a05eacecc04db4b560d007305e664bbfe01595cb69d26b8597, 0x1b91cc07570c812bb329d025e85ef520132981337d7ffc3d84003f81a90bf7a7, 0x4ca32e77a12951a95356ca348639ebc451170280d979e91b13316844f65ed42a, 0xe49ea1998e360bd68771bd69c3cd4cf406b41ccca4386378bec66ea210c40084, 0x01aaffbde1a672d253e0e317603c2dc1d0f752100d9e853f840bca96e57f314c, 0x170d0befcbbaafb317c8684213a4989368332f66e889824cc4becf148f808146, 0x56f973308edf5732a60aa3e7899ae1162c7a2c7b528c3315237e20f9125b34e0, 0x66c54fd5f6d480cab0640e9f3ec1a4eafbafc0501528f57bb0d5c78fd03068ef, 0xaca6c83f665c64d76fbc4858da9f264ead3b6ecdc3d7437bb800ef7240abffb9, 0xf1d4e02e7c85a92d634d16b12dc99e1d6ec9eae3d8dfbca77e7c609e226d0ce7, 0x094352545250e843ced1d3c6c7957e78c7d8ff80c470974778930adbe9a4ed1a, 0x76efa93070d78b73e12eb1efa7f36d49e7944ddcc3a043b916466ee83dca52ce, 0x1772a2970588ddb584eadf02178cdb52a98ab6ea8a4036d29e59f179d7ba0543, 0xe4bbf2d97d65331ac9f680f864208a9074d1def3c2433458c808427e0d1d3167, 0x8ccfb5252b22c77ea631e03d491ea76eb9b74bc02072c3749f3e9d63323b44df, 0x9e212a9bdf4e7ac0730a0cecd0f6cc49afc7e3eca7a15d0f5f5a68f72e45363b, 0x52e548ea6445aae3f75509782a7ab1f4f02c2a85cdd0dc928370f8c76ae8802d, 0xb62e7d73bf76c07e1a6f822a8544b78c96a6ba4f5c9b792546d94b56ca12c8b9, 0x595cb0e985bae9c59af151bc748a50923921a195bbec226a02157f3b2e066f5b, 0x1c7aa6b36f402cec990bafefbdbb845fc6c185c7e08b6114a71dd388fe236d32, 0x01ee2ff1a1e88858934a420258e9478585b059c587024e5ec0a77944821f798c, 0x420a963a139637bffa43cb007360b9f7d305ee46b6a694b0db91db09618fc2e5, 0x5a8e2ad20f8da35f7c885e9af93e50009929357f1f4b38a6c3073e8f58fae49e, 0x52a405fdd84c9dd01d1da5e9d1c4ba95cb261b53bf714c651767ffa2f9e9ad81, 0xa1a334c901a6d5adc8bac20b7df025e906f7c4cfc0996bfe2c62144691c21990, 0xb789a00252f0b34bded3cb14ae969effcf3eb29d97b05a578c3be8a9e479c213, 0xb9dbf7e9ddb638a515da245845bea53d07becdf3f8d1ec17de11d495624c8eab, 0xaf566b41f5ed0c026fa8bc709533d3fa7a5c5d69b03c39971f32e14ab523fa3d, 0x8121e0b2d9b106bb2aefd364fd6a450d88b88ee1f5e4aad7c0fcd8508653a112, 0x8581c1be74279216b93e0a0d7272f4d6385f6f68be3eef3758d5f68b62ee7b6c, 0x85386f009278f9a1f828404fa1bbfa02dfb9d896554f0a52678eb6ec8feadc55, 0xf483ed167d92a0035ac65a1cfdb7906e4952f74ae3a1d86324d21f241daffcb7, 0x3872485e2a520a350884accd990a1860e789dd0d0664ad14f50186a92c7be7be, 0xc6c1a3301933019105f5650cabcb22bfbf221965ffcfc1329315b24ea3d77fd4, 0xcee901330a60d212a867805ce0c28f53c6cc718f52156c9e74390d18f5df6280, 0xa67ae793b1cd1a828a607bae418755c84dbb61adf00833d4c61a94665363284f, 0x80d8159873b517aa6815ccd7c8ed7cfb74f84298d703a6c5a2f9d7d4d984ddde, 0x1de5a8b915f2d9b45c97a8e134871e2effb576d05f4922b577ade8e3cd747a79, 0x6ea17c5ece9b97dddb8b2101b923941a91e4b35e33d536ab4ff15b647579e1f5, 0xcb78631e09bc1d79908ce1d3e0b6768c54b272a1a5f8b3b52485f98d6bba9245, 0xd7c38f9d3ffdc626fe996218c008f5c69498a8a899c7fd1d63fbb03e1d2a073f, 0x72cdef54267088d466244a92e4e6f10742ae5e6f7f6a615eef0da049a82068f9, 0x60b3c490ba8c502656f9c0ed37c47283e74fe1bc7f0e9f651cbc76552a0d88eb, 0x56bd0c66987a6f3761d677097be9440ea192c1cb0f5ec38f42789abe347e0ea9, 0x3caac3e480f62320028f6f938ee147b4c78e88a183c464a0c9fb0df937ae30c1, 0x7a4d2f11bddda1281aba5a160df4b814d23aef07669affe421a861fac2b4ec0f, 0x9bb4d11299922dc309a4523959298a666ebe4063a9ee3bad1b93988ed59fb933, 0x957323fffbaf8f938354662452115ae5acba1290f0d3f7b2a671f0359c109292, 0x877624e31497d32e83559e67057c7a605fb888ed8e31ba68e89e02220eac7096, 0x8456546ae97470ff6ea98daf8ae632e59b309bd3ff8e9211f7d21728620ed1e5, 0xbacb26f574a00f466ce354e846718ffe3f3a64897d14d5ffb01afcf22f95e72b, 0x0228743a6e543004c6617bf2c9a7eba1f92ebd0072fb0383cb2700c3aed38ba0, 0x04f093f0f93c594549436860058371fb44e8daf78d6e5f563ba63a46b61ddbf0, 0x0ba17c1ec93429ceaff08eb81195c9844821b64f2b5363926c2a6662f83fb930, 0xd71605d8446878c677f146837090797e888416cfc9dc4e79ab11776cc6639d3f, 0x33dde958dc5a6796138c453224d4d6e7f2ae740cceef3b52a8b669eb4b9691a1, 0x3c39838295d1495e90e61ce59f6fcc693b31c292d02d31759719df6fe3214559, 0x8aecc66f38644296cf0e6693863d57a243a31a4929130e22ab44cb6157b1af41, 0xdf7153a7eab9521f2b37124067166c72de8f342249ac0e0f5350bd32f1251053, 0xa498840b58897cf3bed3981b94c86d85536dfebbc437d276031ebd9352e171eb, 0xb1df15a081042ab665458223a0449ffc71a10f85f3d977beb20380958fd92262, 0x15d3bdbdee2a61b01d7a6b72a5482f6714358eedf4bece7bb8458e100caf8fba, 0x0c96b7a0ea09c3ef758424ffb93654ce1520571e32e1f83aecbeded2388c3a7a, 0xb4a3a8023266d141ecd7c8a7ca5282a825410b263bc11c7d6cab0587c9b5446e, 0xf38f535969d9592416d8329932b3a571c6eacf1763de10fb7b309d3078b9b8d4, 0x5a1e7b1c3b3943158341ce6d7f9f74ae481975250d89ae4d69b2fcd4c092eb4e, 0xdad31e707d352f6cca78840f402f2ac9292094b51f55048abf0d2badfeff5463, 0x097e290170068e014ceda3dd47b28ede57ff7f916940294a13c9d4aa2dc98aad, 0x22e2dcedb6bb7f8ace1e43facaa502daa7513e523be98daf82163d2a76a1e0be, 0x7ef2b211ab710137e3e8c78b72744bf9de81c2adde007aef6e9ce92a05e7a2c5, 0x49b427805fc5186f31fdd1df9d4c3f51962ab74e15229e813072ec481c18c717, 0xe60f6caa09fa803d97613d58762e4ff7f22f47d5c30b9d0116cdc6a357de4464, 0xab3507b37ee92f026c72cc1559331630bc1c7335b374e4418d0d02687df1a9dd, 0x50825ae74319c9adebc8909ed7fc461702db8230c59975e8add09ad5e7a647ab, 0x0ee8e9c1d8a527a42fb8c2c8e9e51faf727cffc23ee22b5a95828f2790e87a29, 0x675c21c290ddb40bec0302f36fbcd2d1832717a4bc05d113c6118a62bc8f9aca, 0x580bafab24f673317b533148d7226d485e211eaa3d6e2be2529a83ca842b58a7, 0x540e474776cae597af24c147dc1ae0f70a6233e98cf5c3ce31f38b830b75c99a, 0x36eaf9f286e0f356eaaf8d81f71cc52c81d9ebc838c3b4859009f8567a224d16, 0x0e2cbbb40954be047d02b1450a3dbd2350506448425dc25fd5faf3a66ee8f5c4, 0x7eb0390cfe4c4eb120bbe693e87adc8ecab51d5fd8ce8f911c8ff07fad8cbe20, 0xbf77589f5c2ebb465b8d7936f6260a18a243f59bd87390ee22cf579f6f020285, 0x695b96bb28693f6928777591ef64146466d27521280a295936a52ec60707c565, 0x22a0d018cbd4274caa8b9e7fb132e0a7ed787874046ca683a7d81d1c7c8b8f15, 0x84092b122bb35e5ad85407b4b55f33707b86e0238c7970a8583f3c44308ed1d9, 0xea346067ca67255235f9cae949f06e4b6c93846a7abc7c8c8cd786e9c4b3e4bc, 0xa6df0716b125dc696b5d0e520cb49c1c089397c754efc146792e95bc58cc7159, 0x7377b5d3953029fc597fb10bb6479ee34133d38f08783fbb61c7d070f34ea66f, 0x7d79b00ffb976a10cd24476a394c8ed22f93837c51a58a3ddc7418153a5a8ea1, 0x01e55182e80dff26cc3e06bb736b4a63745bde8ae28c604fa7fb97d99de5f416, 0x062a2d5a207f8d540764d09648afecbf5033b13aec239f722b9033a762acf18b, 0x48be60a3221d98b4d62f0b89d3bef74c70878dd65c6f79b34c2c36d0ddaa1da0, 0x41e11f33543cf045c1a99419379ea31523d153bdf664549286b16207b9648c85, 0xeef4d30b4700813414763a199e7cc6ab0faec65ef8b514faa01c6aa520c76334, 0xea7cfe990422663417715e7859fc935ca47f47c943a1254044b6bc5934c94bc8, 0xbbd3c834e5403b98a0ca346c915a23310f3d58880786628bc6cfbe05ba29c3c5, 0xe216379f385bc9995ae0f37f1409a78d475c56b8aeb4ee434326724ec20124f7, 0xdd328a1eee19d09b6fef06e252f8ad0ae328fbf900ef745f5950896803a3899d, 0xa16fde34b0d743919feb0781eca0c525a499d279119af823cb3a8817000335db, 0x7a28d108c59b83b12c85cd9aabc1d1d994a9a0329ae7b64a32aadcd61ebe50e3, 0xb28bc82fceae74312eb837a805f0a8a01c0f669b99bb03fde31c4d58bedff89b, 0x1b0d8f37d349781e846900b51a90c828aa384afe9b8ee1f88aeb8dba4b3168f2, 0xbfd0301ff964c286c3331a30e09e0916da6f484e9c9596dbf1cae3cc902dbf9e, 0xbb8254cb9ef6b485b8fb6caeafe45f920affc30f6b9d671e9a454530536f4fef, 0xcad2317cf63dfa7147ded5c7e15f5f72e78f42d635e638f1ece6bc722ca3638b, 0xb6c6e856fd45117f54775142f2b38f31114539d8943bcbcf823f6c7650c001e4, 0x869f1baa35684c8f67a5bc99b294187852e6c85243a2f36481d0891d8b043020, 0x14c6ccf145ee40ff56e3810058d2fba9a943ffc7c7087c48a08b2451c13dc788, 0x263c1bcb712890f155b7e256cefa4abf92fe4380f3ffc11c627d5e4e30864d18, 0x69f4eaf655e31ad7f7a725cd415ce7e45dd4a8396ac416950d42ed33155c3487, 0x47e8eec2c5e33c9a54fe1f9b09e7744b614fb16531c36b862aa899424be13b05, 0x5c985de270e62c44f0b49157882e8e83641b906ce47959e337fe8423e125a2eb, 0x4e13b11e13202439bb5de5eea3bb75d2d7bf90f91411163ade06161a9cf424db, 0x583a8fa159bb74fa175d72f4e1705e9a3b8ffe26ec5ad6e720444b99288f1213, 0x903d2a746a98dfe2ee2632606d57a9b0fa6d8ccd895bb18c2245fd91f8a43676, 0xa35a51330316012d81ec7249e3f2b0c9d7fcbb99dd98c62fe880d0a152587f51, 0x33818a7beb91730c7b359b5e23f68a27b429967ea646d1ea99c314353f644218, 0x183650af1e0b67f0e7acb59f8c72cc0e60acc13896184db2a3e4613f65b70a8b, 0x857ff2974bef960e520937481c2047938a718cea0b709282ed4c2b0dbe2ef8fa, 0x95a367ecb9a401e98a4f66f964fb0ece783da86536410a2082c5dbb3fc865799, 0x56c606a736ac8268aedadd330d2681e7c7919af0fe855f6c1c3d5c837aa92338, 0x5c97f7abf30c6d0d4c23e762c026b94a6052a444df4ed942e91975419f68a3a4, 0x0b571de27d2022158a3128ae44d23a8136e7dd2dee74421aa4d6ed15ee1090a0, 0xa17f6bc934a2f3c33cea594fee8c96c1290feec934316ebbbd9efab4937bf9f9, 0x9ff57d70f27aad7281841e76435285fd27f10dad256b3f5cabde4ddc51b70eff, 0xafa3071a847215b3ccdf51954aa7cb3dd2e6e2a39800042fc42009da705508b2, 0x5e3bea33e4ac6f7c50a077d19571b1796e403549b1ce7b15e09905a0cc5a4acf, 0x0dc7ba994e632ab95f3ecb7848312798810cf761d1c776181882d17fd6dda075, 0xb4f7158679dad9f7370a2f64fbe617a40092849d17453b4f50a93ca8c6885844, 0x094564b00f53c6f27c121fd8adfe1685b258b259e585a67b57c85efb804c57b2, 0x9cd21a4249ba3fccffad550cdb8409dc12d8b74a7192874b6bafe2363886f318, 0xbb22e0dad55cb315c564c038686419d40ef7f13af2143a28455bf445f6e10393, 0x2a71d5e00821178c2cd39e7501e07da5cca6680eb7cdbe996f52dccafadb3735, 0x9619406093b121e044a5b403bb1713ae160aeb52ad441f82dc6c63e4b323b969, 0x3b8bd1d82c6d67ae707e19b889f1cb1f7bba912f12ae4284298f3a70c3644c79, 0xd7a70c50d47d48785b299dbea01bf03ef18b8495de3c35cb265bc8f3295c4e15, 0x8802ecce8dd6b6190af8ac79aafda3479c29f548d65e5798c0ca51a529b19108, 0x4b630e1df52ec5fd650f4a4e76b3eeddda39e1e9eab996f6d3f02eefdf690990, 0x0bfbff60fcf7f411d469f7f6f0a58ca305fd84eb529ee3ac73c00174793d723e, 0x535f78b5f3a99a1c498e2c19dc1acb0fbbaba8972ba1d7d66936c28ab3667ebe, 0x06ba92d8129db98fec1b75f9489a394022854f22f2e9b9450b187a6fc0d94a86, 0xb7ae275ba10f80fb618a2cf949d5ad2e3ae24eb2eb37dcf1ec8c8b148d3ba27f, 0xb275579bcf2584d9794dd3fc7f999902b13d33a9095e1980d506678e9c263de1, 0x843ccd52a81e33d03ad2702b4ef68f07ca0419d4495df848bff16d4965689e48, 0xde8b779ca7250f0eb867d5abdffd1d28c72a5a884d794383fc93ca40e5bf6276, 0x6b789a2befccb8788941c9b006e496b7f1b03dbb8e530ba339db0247a78a2850, 0xfccd4dca80bc52f9418f26b0528690255e320055327a34b50caf088235d2f660, 0x18479ebfbe86c1e94cd05c70cb6cace6443bd9fdac7e01e9c9535a9e85141f2f, 0x5350c8f3296441db954a261238c88a3a0c51ab418a234d566985f2809e211148, 0xa5636614135361d03a381ba9f6168e2fd0bd2c1105f9b4e347c414df8759dea3, 0xe7bb69e600992e6bd41c88a714f50f450153f1a05d0ddb4213a3fc4ba1f48c3f, 0x17b42e81bae19591e22aa2510be06803bcb5c39946c928c977d78f346d3ca86b, 0x30a10c07dc9646b7cbb3e1ab722a94d2c53e04c0c19efaaea7dccba1b00f2a20] +compressed_lamport_PK = 0x672ba456d0257fe01910d3a799c068550e84881c8d441f8f5f833cbd6c1a9356 +child_SK = 7419543105316279183937430842449358701327973165530407166294956473095303972104 +``` + +## Implementation + +* [Python](https://github.com/CarlBeek/eth2.0-deposit-tooling/blob/master/key_derivation/tree.py) + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 9d9a950d7de8f06d30982a4a756330a148321977 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Mon, 25 Nov 2019 21:42:39 -0500 Subject: [PATCH 42/47] Add name to metadata title (#2370) --- EIPS/eip-1450.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-1450.md b/EIPS/eip-1450.md index 4be04e827cd141..c7f17a73872b09 100644 --- a/EIPS/eip-1450.md +++ b/EIPS/eip-1450.md @@ -1,6 +1,6 @@ --- eip: 1450 -title: ERC-1450 +title: ERC-1450 A compatible security token for issuing and trading SEC-compliant securities author: John Shiple (@johnshiple), Howard Marks , David Zhang discussions-to: https://ethereum-magicians.org/t/erc-proposal-ldgrtoken-a-compatible-security-token-for-issuing-and-trading-sec-compliant-securities/1468 status: Draft From b8f75b6a0b154d17a945b79531636f071bee9c87 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 26 Nov 2019 09:03:13 +0100 Subject: [PATCH 43/47] Fix some URLs and require 2333 too --- EIPS/eip-2335.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-2335.md b/EIPS/eip-2335.md index 9bc5619e726ab8..3ade3673ac3039 100644 --- a/EIPS/eip-2335.md +++ b/EIPS/eip-2335.md @@ -7,7 +7,7 @@ status: Draft type: Standards Track category: ERC created: 2019-09-30 -requires: 2334 +requires: 2333, 2334 --- ## Simple Summary @@ -98,7 +98,7 @@ The `pubkey` is the public key associated with the the private key secured withi ## Path -The `path` indicates where in the key-tree a key originates from. It is a string defined by [EIP-2334](https://eips.ethereum.org/EIPS/eip-2333), if no path is known or the path is not relevant, the empty string, `""` indicates this. The `path` can specify an arbitrary depth within the tree and the deepest node within the tree indicates the depth of the key stored within this file. +The `path` indicates where in the key-tree a key originates from. It is a string defined by [EIP-2334](https://eips.ethereum.org/EIPS/eip-2334), if no path is known or the path is not relevant, the empty string, `""` indicates this. The `path` can specify an arbitrary depth within the tree and the deepest node within the tree indicates the depth of the key stored within this file. ## UUID From df922e04b5f30560e468ee4acf0c1b6ddad796f3 Mon Sep 17 00:00:00 2001 From: Carl Beekhuizen Date: Tue, 26 Nov 2019 09:24:22 +0100 Subject: [PATCH 44/47] Draft EIP: BLS12-381 Deterministic Account Hierarchy (#2334) --- EIPS/eip-2333.md | 2 +- EIPS/eip-2334.md | 102 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 EIPS/eip-2334.md diff --git a/EIPS/eip-2333.md b/EIPS/eip-2333.md index 9d0fe16c3233bd..a27d4e532f29b4 100644 --- a/EIPS/eip-2333.md +++ b/EIPS/eip-2333.md @@ -1,7 +1,7 @@ --- eip: 2333 title: BLS12-381 Key Generation -author: Carl Beekhuizen (carl@ethereum.org) +author: Carl Beekhuizen discussions-to: https://github.com/ethereum/EIPs/issues/2337 status: Draft type: Standards Track diff --git a/EIPS/eip-2334.md b/EIPS/eip-2334.md new file mode 100644 index 00000000000000..fa7e6b402b0e16 --- /dev/null +++ b/EIPS/eip-2334.md @@ -0,0 +1,102 @@ +--- +eip: 2334 +title: BLS12-381 Deterministic Account Hierarchy +author: Carl Beekhuizen +discussions-to: https://github.com/ethereum/EIPs/issues/2338 +status: Draft +type: Standards Track +category: ERC +created: 2019-09-30 +requires: 2333 +--- + +## Simple Summary + +This EIP defines the purpose of a given key, or family thereof, within a tree of keys. When combined with [EIP-2333](https://eips.ethereum.org/EIPS/eip-2333), the combination of a seed and knowledge of the desired purpose of a key is sufficient to determine a key pair. + +## Abstract + +A standard for allocating keys generated by [EIP-2333](https://eips.ethereum.org/EIPS/eip-2333) to a specific purpose. It defines a `path` which is a string that parses into the indices to be used when traversing the tree of keys that [EIP-2333](https://eips.ethereum.org/EIPS/eip-2333) generates. + +## A note on purpose + +This specification is designed not only to be an Ethereum 2.0 standard, but one that is adopted by the wider community who have adopted the BLS12-381 signature standard. It is therefore important also to consider the needs of the wider industry along with those specific to Ethereum. As a part of these considerations, it is the intention of the author that this standard eventually migrate to a more neutral repository in the future. + +## Motivation + +Ethereum 2.0 alongside many other projects will use BLS12-381 signatures. This new scheme requires a new key derivation mechanism, which is established within [EIP-2333](https://eips.ethereum.org/EIPS/eip-2333). This new scheme is incompatible with the current form of this specification ([BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki)) due to the: exclusive use of hardened keys, the increased number of keys per level, not using [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) for key derivation. It is therefore necessary to establish a new *path* for traversing the [EIP-2333](https://eips.ethereum.org/EIPS/eip-2333) key-tree. + +The path structure specified in this EIP aims to be more general than [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) by not having UTXO-centric features [which gave rise to the 4 different types of wallet paths being used within Ethereum 1.0](https://github.com/ethereum/EIPs/issues/84#issuecomment-292324521) and gave rise to (draft) EIPs [600](https://eips.ethereum.org/EIPS/eip-600) & [601](https://eips.ethereum.org/EIPS/eip-601) + +## Specification + +### Path + +The path traversed through the tree of keys is defined by integers (which indicate the sibling index) separated by `/` which denote ancestor relations. There are 4 levels (plus the master node) in the path and at least 4 (5 including the master node) MUST be used. + +```text +m / purpose / coin_type / account / use +``` + +#### Notation + +The notation used within the path is specified within the [EIP-2333](https://eips.ethereum.org/EIPS/eip-2333), but is summarized again below for convenience. + +* `m` Denotes the master node (or root) of the tree +* `/` Separates the tree into depths, thus `i / j` signifies that `j` is a child of `i` + +### Purpose + +The `purpose` is set to `12381` which is the name of the new curve (BLS12-381). In order to be in compliance with this standard, the [EIP-2333](https://eips.ethereum.org/EIPS/eip-2333) MUST be implemented as the KDF and therefore, the purpose `12381` MAY NOT be used unless this is the case. + +### Coin Type + +The `coin_type` here reflects the coin number for an individual coin thereby acting as a means of separating the keys used for different chains. + +### Account + +`account` is a field that provides the ability for a user to have distinct sets of keys for different purposes, if they so choose. This is the level at which different accounts for a single user SHOULD to be implemented. + +### Use + +This level is designed to provide a set of related keys that can be used for any purpose. The idea being that a single account has many uses which are related yet should remain separate for security reasons. It is required to support this level in the tree, although, for many purposes it will remain `0`. + +### Eth2 Specific Parameters + +#### Coin type + +The coin type used for the BLS12-381 keys in Ethereum 2 is `3600`. + +#### Validator keys + +Each Eth2 validator has two keys, one for withdrawals and transfers (called the *withdrawal key*), and the other for performing their duties as a validator (henceforth referred to as the *signing key*). + +The path for withdrawal keys is `m/12381/3600/i/0` where `i` indicates the `i`th set of validator keys. + +The path for the signing key is `m/12381/3600/i/0/0` where again, `i` indicates the `i`th set of validator keys. Another way of phrasing this is that the signing key is the `0`th child of the associated withdrawal key for that validator. + +## Rationale + +`purpose`, `coin_type`, and `account` are widely-adopted terms as per [BIP43](https://github.com/bitcoin/bips/blob/master/bip-0043.mediawiki) and [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) and therefore reusing these terms and their associated meanings makes sense. + +The purpose needs to be distinct from these standards as the KDF and path are not inter-compatible and `12381` is an obvious choice. + +`account` separates user activity into distinct categories thereby allowing users to separate their concerns however they desire. + +`use` will commonly be determined at the application level providing distinct keys for non-intersecting use cases. + +### Eth2 Specific Parameters + +A new coin type is chosen for Eth2 keys to help ensure a clean separation between Eth2 and Eth1 keys. Although the distinction between Eth1 ETH and Eth2 ETH is subtle, they are distinct entities and there are services which only distinguish between coins by their coin name (eg. [ENS' multichain address resolution](https://eips.ethereum.org/EIPS/eip-2304)). `3600` is chosen specifically because it is the square of the Eth1's `coin_type` (`3600==60^2`) thereby signaling that it is second instantiation of Ether the currency. + +The primary reason validators have separate signing and withdrawal keys is to allow for the different security concerns of actions within Eth2. The signing key is given to the validator client where it signs messages as per the requirements of being a validator, it is therefore a "hot key". If this key is compromised, the worst that can happen (locally) is that a slashable message is signed, resulting in the validator being slashed and forcibly exited. The withdrawal key is only needed when a validator wishes to perform an action not related to validating and has access to the full funds at stake for that validator. The withdrawal key therefore has higher security concerns and should be handled as a "cold key". By having the signing key be a child of the withdrawal key, secure storage of the withdrawal key is sufficient to recover the signing key should the need arise. + +## Backwards Compatibility + +[BIP43](https://github.com/bitcoin/bips/blob/master/bip-0043.mediawiki) and [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) are the commonly used standards for this purpose within Ethereum 1.0, however they have not been `Accepted` as standards as yet. Due to the use of a new KDF within [EIP-2333](https://eips.ethereum.org/EIPS/eip-2333), a new path standard is required. This EIP implements this, with minor changes. + +`purpose` `12381` paths do not support hardened keys and therefore the `'` character is invalid. + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From c74a31a18bda6b6e4ba83ce52d592d6b02c9559d Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 26 Nov 2019 09:25:06 +0100 Subject: [PATCH 45/47] Fix email address --- EIPS/eip-2335.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-2335.md b/EIPS/eip-2335.md index 3ade3673ac3039..502cbf52ec2280 100644 --- a/EIPS/eip-2335.md +++ b/EIPS/eip-2335.md @@ -1,7 +1,7 @@ --- eip: 2335 title: BLS12-381 Keystore -author: Carl Beekhuizen (carl@ethereum.org) +author: Carl Beekhuizen discussions-to: https://github.com/ethereum/EIPs/issues/2339 status: Draft type: Standards Track From 18b82e20953f27ac9c5dc90f64bf407a37b296cb Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 26 Nov 2019 12:26:27 +0100 Subject: [PATCH 46/47] Fix spelling --- EIPS/eip-2335.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-2335.md b/EIPS/eip-2335.md index 502cbf52ec2280..d930043cd826fa 100644 --- a/EIPS/eip-2335.md +++ b/EIPS/eip-2335.md @@ -94,7 +94,7 @@ The `cipher.function` encrypts the secret using the decryption key, thus to decr ## PubKey -The `pubkey` is the public key associated with the the private key secured within the keystore. It is stored here to improve user experience and security which is achieved by not requiring users to enter their password just to obtain their public keys. This field is required if the secret being stored within the keystore is a private key. The encoding of the `pubkey` is specified in the in the appropriate signature standard (eg. [BLS12-381 signature standard](https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-00)), but can be seen as a byte-string in the abstract and should be directly compatible with teh appropriate signature library. +The `pubkey` is the public key associated with the the private key secured within the keystore. It is stored here to improve user experience and security which is achieved by not requiring users to enter their password just to obtain their public keys. This field is required if the secret being stored within the keystore is a private key. The encoding of the `pubkey` is specified in the in the appropriate signature standard (eg. [BLS12-381 signature standard](https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-00)), but can be seen as a byte-string in the abstract and should be directly compatible with the appropriate signature library. ## Path From 537f2dc7068fff258634f33732e303576490b57e Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 26 Nov 2019 12:43:33 +0100 Subject: [PATCH 47/47] fix link to heading --- EIPS/eip-2335.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-2335.md b/EIPS/eip-2335.md index d930043cd826fa..46873a15221ce4 100644 --- a/EIPS/eip-2335.md +++ b/EIPS/eip-2335.md @@ -180,7 +180,7 @@ The keystore, at its core, is constructed with modules which allow for the confi ## Rationale -The rationale behind the design of this specification is largely the same as that behind the [Ethereum 1 keystore definition](https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition) except for the lack of support for Keccak (explained in [motivation above](##motivation)) and the notion of modules. +The rationale behind the design of this specification is largely the same as that behind the [Ethereum 1 keystore definition](https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition) except for the lack of support for Keccak (explained in [motivation above](#motivation)) and the notion of modules. Modules provide a very useful level of abstraction which allow the Key-Derivation-Function, Checksum, and Cipher to be thought of as instances of the same thing allowing for their substitution with minimal effort.