From 34debd1e8d61b00644530a70532da72838d9eef5 Mon Sep 17 00:00:00 2001 From: Brendan Graetz Date: Tue, 22 Aug 2023 16:13:19 +0800 Subject: [PATCH 01/10] docs: (WIP) HIP-XYZ Extend isAuthorized to process current transaction in HAS System Contract Signed-off-by: Brendan Graetz --- HIP/hip-XYZ.md | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 HIP/hip-XYZ.md diff --git a/HIP/hip-XYZ.md b/HIP/hip-XYZ.md new file mode 100644 index 000000000..a19a7bf8b --- /dev/null +++ b/HIP/hip-XYZ.md @@ -0,0 +1,94 @@ +--- +hip: \${XYZ} +title: Extend isAuthorized to process current transaction in HAS System Contract +author: Brendan Graetz <@bguiz> +working-group: Nana Essilfie-Conduah <@nana-ec>, Luke Lee <@lukelee-sl> +type: Standards Track +category: Service +needs-council-approval: Yes +status: Draft +last-call-date-time: 2023-\${MM}-\${DD}T16:00:00Z +created: 2023-08-21 +discussions-to: https://github.com/hashgraph/hedera-improvement-proposal/discussions/\${XYZ} +updated: 2023-08-21 +requires: 632 +--- + +## Abstract + + + +HIP-632 adds a new system contract, `hederaAccountService` that exposes a method `isAuthorized(address, messageHash, signatureBlob)`. This HIP proposes a similar version of that which implements the same functionality, but restricted for use *only* on the current (in flight) transaction. This would expose a method `isAuthorizedCurrentTransaction()`. + +## Motivation + + + +`hederaAccountService.isAuthorized(address, messageHash, signatureBlob)` works for the following scenarios: + +- When an account's admin key is "simple", and is comprised of either a single EdDSA key, or a single ECDSA key +- When an account's admin key is "complex", and is comprised of multiple EdDSA keys and/or ECDSA keys, combined using one or more `KeyList`s or `ThresholdKey`s. + +`hederaAccountService.isAuthorized(address, messageHash, signatureBlob)` does **not** work for the following scenarios: + +- When an account's admin key is "complex", and is comprised of multiple EdDSA keys and/or ECDSA keys and/or smart contract IDs, combined using one or more `KeyList`s or `ThresholdKey`s. + +The proposed `hederaAccountService.isAuthorizedCurrentTransaction()` method aims to fulfil the above scenario, and specific use cases pertaining to this scenario will be elaborated upon in the [use cases section](#use-cases) below. + +Furthermore, Hedera Token Service exposes an authorization mechanism already, +which is capable of handling this scenario that is presently unfulfilled by Hedera Account Service. + + +> NOTE: +> "EdDSA" refers to **EdDSA ED25519**, and +> "ECDSA" refers to **ECDSA secp256k1** throughout this HIP, unless otherwise stated. +> These are the only types of cryptographic keys currently supported by Hedera's account system. + +## Rationale + + + +## User stories + + + +## Specification + + + +## Backwards compatibility + + + +## Security implications + + + +## How to teach this + + + +## Reference Implementations + + + +## Rejected Ideas + + + +## Open Issues + + + +Nil + +## References + + + +- [HIP-632 - Hedera Account Service (HAS) System Contract](../hip-632) +- [`ecrecover` Precompiled Contract](https://ethereum.github.io/execution-specs/autoapi/ethereum/frontier/vm/precompiled_contracts/ecrecover/index.html) + +## Copyright/license + +This document is licensed under the Apache License, Version 2.0 -- see [LICENSE](../LICENSE) or [`https://www.apache.org/licenses/LICENSE-2.0`](https://www.apache.org/licenses/LICENSE-2.0) From c26b90c2b2dd8bf6758066de25576aad53d1af42 Mon Sep 17 00:00:00 2001 From: Brendan Graetz Date: Tue, 22 Aug 2023 16:21:02 +0800 Subject: [PATCH 02/10] proj: HIP-792 assigned HIP-number Signed-off-by: Brendan Graetz --- HIP/{hip-XYZ.md => hip-792.md} | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename HIP/{hip-XYZ.md => hip-792.md} (98%) diff --git a/HIP/hip-XYZ.md b/HIP/hip-792.md similarity index 98% rename from HIP/hip-XYZ.md rename to HIP/hip-792.md index a19a7bf8b..c572f0837 100644 --- a/HIP/hip-XYZ.md +++ b/HIP/hip-792.md @@ -1,5 +1,5 @@ --- -hip: \${XYZ} +hip: 792 title: Extend isAuthorized to process current transaction in HAS System Contract author: Brendan Graetz <@bguiz> working-group: Nana Essilfie-Conduah <@nana-ec>, Luke Lee <@lukelee-sl> @@ -7,10 +7,10 @@ type: Standards Track category: Service needs-council-approval: Yes status: Draft -last-call-date-time: 2023-\${MM}-\${DD}T16:00:00Z +last-call-date-time: 2023-10-22T16:00:00Z created: 2023-08-21 -discussions-to: https://github.com/hashgraph/hedera-improvement-proposal/discussions/\${XYZ} -updated: 2023-08-21 +discussions-to: https://github.com/hashgraph/hedera-improvement-proposal/discussions/792 +updated: 2023-08-22 requires: 632 --- From 0e6ad8059d4af7287f8179029c335603c06242ff Mon Sep 17 00:00:00 2001 From: Brendan Graetz Date: Tue, 22 Aug 2023 16:48:02 +0800 Subject: [PATCH 03/10] docs: HIP-792 add specification and backwards compatibility sections Signed-off-by: Brendan Graetz --- HIP/hip-792.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/HIP/hip-792.md b/HIP/hip-792.md index c572f0837..366166da5 100644 --- a/HIP/hip-792.md +++ b/HIP/hip-792.md @@ -56,10 +56,32 @@ which is capable of handling this scenario that is presently unfulfilled by Hede +An augmentation of the existing system contract specified in HIP-632, `hederaAccountService`, with 1 new function to expand authorization checks is proposed. + +This will aid developers who were limited to `ECRECOVER` authorization flows, and `hederaAccountService.isAuthorized(address, messageHash, signatureBlob)` flows, who will now be able to expand authorization checks to include smart contract ID based authorization. + +| hash | signature | return | description | +| --- | --- | --- | --- | +| | isAuthorizedCurrentTransaction() | bool | `true`` if account is authorized to carry out transaction execution on account. Accepts protobuf key signature blobs. May be used for ECDSA, EdDSA simple key flows, and complex key flows which include any of ECDSA keys, EdDSA keys, and smart contract IDs. | + +### `isAuthorizedCurrentTransaction()` Function Usage + +This function behaves identically to `isAuthorized(address, messageHash, signatureBlob)` as defined in HIP-632, with the following key differences: + +- It is called without specifying any parameters +- This function extracts the values that it needs in order to validate if a transaction is authorized from the current transaction +- Therefore it designed to be used exclusively on the current transaction, which is still in-flight (as clearly communicated by the `CurrentTransaction` suffix in the function name) + +No new protocol buffer schema definitions are needed as there are no parameters. Internal protocol buffers schema definitions that need to be used to process this function would be existing ones already present in Hedera's base account system, such as `Key`, `ContractID`, `KeyList` and `ThresholdKey`. Potentially this function may also use `SignatureMap` and `SignaturePair` as defined in HIP-632, if necessary. + ## Backwards compatibility +This functionality is newly proposed and thus does not overwrite or alter existing functionality. + +Notably, this HIP proposes changes to neither `isAuthorized(address, messageHash, signatureBlob)` nor `isAuthorizedRaw(address, messageHash, signatureBlob)`. + ## Security implications From 76390b8f4592efce4aaf735ed8af6ba1e2c4f39b Mon Sep 17 00:00:00 2001 From: Brendan Graetz Date: Tue, 22 Aug 2023 17:05:57 +0800 Subject: [PATCH 04/10] docs: HIP-792 add users stories section Signed-off-by: Brendan Graetz --- HIP/hip-792.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/HIP/hip-792.md b/HIP/hip-792.md index 366166da5..b7bd1d123 100644 --- a/HIP/hip-792.md +++ b/HIP/hip-792.md @@ -52,6 +52,19 @@ which is capable of handling this scenario that is presently unfulfilled by Hede +As a smart contract developer, +I want to code a smart contract in solidity which is able to identify whether a transaction is authorized when sent from an account with a complex key where a smart contract ID is among its components, +so that I can implement advanced use cases including: + +- implement flexible and customisable authorisation rules +- implement advanced multisig use cases without the need to split across multiple transactions +- implement atomic multisig uses cases +- implement batch processing of multiple transactions + +As a user of Hedera networks, +I want to create an 1-of-2 threshold key on my Hedera account where 1 component of my complex key is either an EdDSA key or an ECDSA key and the other component is a specified smart contract ID, +so that when this smart contract specified in my threshold key can perform actions on behalf of my account. + ## Specification From 917086bb523ff87f2c982c200aaf5dc1f71e4d7e Mon Sep 17 00:00:00 2001 From: Brendan Graetz Date: Tue, 22 Aug 2023 17:34:49 +0800 Subject: [PATCH 05/10] docs: HIP-792 add security implications and how to teach this sections Signed-off-by: Brendan Graetz --- HIP/hip-792.md | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/HIP/hip-792.md b/HIP/hip-792.md index b7bd1d123..02cadabdb 100644 --- a/HIP/hip-792.md +++ b/HIP/hip-792.md @@ -99,10 +99,34 @@ Notably, this HIP proposes changes to neither `isAuthorized(address, messageHash +Ensure that this proposal considers +the [new model (v2) boundaries](https://docs.hedera.com/hedera/core-concepts/smart-contracts/security#new-model-v2-boundaries) +and does not break its stipulations. +Specifically: + +- Consider that top-level signatures are not supported +- Consider that `delegatecall` on the system contract is not supported + +Consider that smart contract developers may do the following: + +- Multiple smart contracts utilize the `isAuthorizedCurrentTransaction` call to do multiple things +- Authorize all potential uses of a user's signature in the parent transaction + +These could imply the user has given their authorization for all such combinations. Therefore sufficient warnings should be embedded in any [educational materials](#how-to-teach-this) related to this. + ## How to teach this +Provide a [short, self contained, correct code example](http://sscce.org/) +which demonstrates this HIP, with both error-path and happy-path examples. +This will be in the style of existing work: + +- [Multisig Account](https://github.com/hedera-dev/hedera-code-snippets/tree/main/multisig-account) + +Provide sufficient warnings about improper use of `isAuthorizesCurrentTransaction` in a tutorial, +at minimum including a list of "Do's and Don'ts". + ## Reference Implementations @@ -111,6 +135,11 @@ Notably, this HIP proposes changes to neither `isAuthorized(address, messageHash +- Allow `delegatecall` on the `hederaAccountService` system contract + - Rejected becuase: Contradiction of v2 smart contract security model + - If there is indeed a community request that asks from specific exemption, we can ask them to submit a HIP that would specifically whitelist those specific flows, and then consider those. + - This path has already been trodden with HTS - "System smart contracts may not be delegate called, except from the Token proxy/facade flow, e.g., HIP 719. In such cases, HTS tokens are represented as smart contracts (see HIP 218) for common ERC methods." + ## Open Issues @@ -122,7 +151,8 @@ Nil - [HIP-632 - Hedera Account Service (HAS) System Contract](../hip-632) -- [`ecrecover` Precompiled Contract](https://ethereum.github.io/execution-specs/autoapi/ethereum/frontier/vm/precompiled_contracts/ecrecover/index.html) +- [Hedera - Smart Contract Security - Security Model - New model (v2) boundaries](https://docs.hedera.com/hedera/core-concepts/smart-contracts/security#new-model-v2-boundaries) +- [Ethereum - `ecrecover` Precompiled Contract](https://ethereum.github.io/execution-specs/autoapi/ethereum/frontier/vm/precompiled_contracts/ecrecover/index.html) ## Copyright/license From bbf013672886c7579637a9e8b11e8d3f2360af12 Mon Sep 17 00:00:00 2001 From: Brendan Graetz Date: Tue, 22 Aug 2023 19:09:41 +0800 Subject: [PATCH 06/10] docs: HIP-792 add rationale section Signed-off-by: Brendan Graetz --- HIP/hip-792.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/HIP/hip-792.md b/HIP/hip-792.md index 02cadabdb..eb3d63b70 100644 --- a/HIP/hip-792.md +++ b/HIP/hip-792.md @@ -48,6 +48,46 @@ which is capable of handling this scenario that is presently unfulfilled by Hede +In existing code examples where `ecrecover` is used, +a smart contract function is passed in the transaction data in its parameters. +The design of both `isAuthorized(address, messageHash, signatureBlob)` +and `isAuthorizedRaw(address, messageHash, signatureBlob)`, +in HIP-632 mimics this approach. + +This approach is fine in in cases where we assume that: + +(1) All authorization is performed using cryptographic signatures (EdDSA and/or ECDSA in the case of Hedera). + +(2) All authorization is performed "off-chain", that is among clients, and not within or by smart contracts. + +While this approach is sufficient on Ethereum and other EVM-compatible networks, +because Externally Owned Acounts (EOAs) are the only type of account +that exists on, and is supported by the network, +this is **not** the case for Hedera. +Hedera, while EVM-compatible, has an account system that supports "simple" keys +(which are approximately analogous to EOAs), **and** +simultaneously supports "complex" keys on accounts. +These complex accounts require special consideration as they support +`KeyList`, `ThresholdKey` (which may be recursively nested), +and whose "leaf nodes" may be comprised of any of +EdDSA keys, ECDSA keys, and even smart contract IDs. + +The authorization methods described in HIP-632 are sufficient to support +the "complex" keys on accounts, as described above, with one exception: +when the "leaf nodes" are smart contract IDs. +In this scenario, both (1) and (2) listed above cannot be met: + +(1) Smart contracts do not have cryptographic keys, +and therefore cannot sign a transaction in order to authorize it. + +(2) Smart contract execution occurs exclusively "on-chain", +and therefore a smart contract may not provide its authorisation of a transaction +by any means other than its own execution when invoked within a transaction; +in other words smart contract authorization must necessarily occur while a transaction is "in flight". + +Therefore this HIP proposes a means, via the `hederaAccountSystem` system contract, +to verify authorization of a transaction that will work in the above scenarios. + ## User stories From d3d07375e8105b060091b2d56ecf5cf316bee98a Mon Sep 17 00:00:00 2001 From: Brendan Graetz Date: Wed, 23 Aug 2023 12:53:44 +0800 Subject: [PATCH 07/10] docs: HIP-792 - add examples subsection to specification section Signed-off-by: Brendan Graetz --- HIP/hip-792.md | 80 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 75 insertions(+), 5 deletions(-) diff --git a/HIP/hip-792.md b/HIP/hip-792.md index eb3d63b70..a36062ada 100644 --- a/HIP/hip-792.md +++ b/HIP/hip-792.md @@ -18,7 +18,7 @@ requires: 632 -HIP-632 adds a new system contract, `hederaAccountService` that exposes a method `isAuthorized(address, messageHash, signatureBlob)`. This HIP proposes a similar version of that which implements the same functionality, but restricted for use *only* on the current (in flight) transaction. This would expose a method `isAuthorizedCurrentTransaction()`. +HIP-632 adds a new system contract, `hederaAccountService` that exposes a method `isAuthorized(address, messageHash, signatureBlob)`. This HIP proposes a similar version of that which implements the same functionality, but restricted for use *only* on the current (in flight) transaction. This would expose a new method `isAuthorizedCurrentTransaction()`. ## Motivation @@ -40,8 +40,10 @@ which is capable of handling this scenario that is presently unfulfilled by Hede > NOTE: -> "EdDSA" refers to **EdDSA ED25519**, and -> "ECDSA" refers to **ECDSA secp256k1** throughout this HIP, unless otherwise stated. +> +> - "EdDSA" refers to **EdDSA ED25519**, and +> - "ECDSA" refers to **ECDSA secp256k1** throughout this HIP, unless otherwise stated. +> > These are the only types of cryptographic keys currently supported by Hedera's account system. ## Rationale @@ -85,9 +87,29 @@ and therefore a smart contract may not provide its authorisation of a transactio by any means other than its own execution when invoked within a transaction; in other words smart contract authorization must necessarily occur while a transaction is "in flight". +However the latter scenario **should** be supported, +as noted in [Hedera's documentation on Keys](https://docs.hedera.com/hedera/sdks-and-apis/hedera-api/basic-types/key): + +> Note that when a Key is a smart contract ID, +> it doesn't mean the contract with that ID will actually create a cryptographic signature. +> It only means that when the contract calls a precompiled contract, +> the resulting "child transaction" will be authorized to perform any action controlled by the Key. + Therefore this HIP proposes a means, via the `hederaAccountSystem` system contract, to verify authorization of a transaction that will work in the above scenarios. +> NOTE: +> +> Hedera Token Service already exposes a system contract `hederaTokenService`, +> and its function already performs the same authorization as proposed +> for `hederaAccountService.isAuthorizedCurrentTransaction()` +> +> This works as system contracts, including `hederaTokenService`, +> are passed in a [`TxnAwareEvmSigsVerifier`](https://github.com/hashgraph/hedera-services/blob/810971de2b/hedera-node/hedera-mono-service/src/main/java/com/hedera/node/app/service/mono/contracts/sources/TxnAwareEvmSigsVerifier.java#L60), +> which has a [`TransactionContext`](https://github.com/hashgraph/hedera-services/blob/810971de2b/hedera-node/hedera-mono-service/src/main/java/com/hedera/node/app/service/mono/contracts/sources/TxnAwareEvmSigsVerifier.java#L70) +> that contains the necessary information in [`JKey`](https://github.com/hashgraph/hedera-services/blob/810971de2b/hedera-node/hedera-mono-service/src/main/java/com/hedera/node/app/service/mono/legacy/core/jproto/JKey.java#L37). +> + ## User stories @@ -127,6 +149,46 @@ This function behaves identically to `isAuthorized(address, messageHash, signatu No new protocol buffer schema definitions are needed as there are no parameters. Internal protocol buffers schema definitions that need to be used to process this function would be existing ones already present in Hedera's base account system, such as `Key`, `ContractID`, `KeyList` and `ThresholdKey`. Potentially this function may also use `SignatureMap` and `SignaturePair` as defined in HIP-632, if necessary. +### Examples + +Happy path example: + +- Account `0.0.12345` has a `ThresholdKey` of ([`customSc`, `edDsaKey`, `ecDsaKey`], 3) --> transactions need to be authorised by all 3. +- `customSc` is a smart contract that has been deployed to HSCS +- `customSc` contains a function `foo` which invokes `hederaAcountService.isAuthorizedCurrentTransaction()` +- Transaction `tx` with `customSc.foo` invocation is instantiated, client-side +- `tx` is signed by `edDsaKey`, client-side +- `tx` is also subsequently signed by `ecDsaKey`, client-side +- `tx` is executed by submitting it to the network +- HSCS' EVM parses `tx` and invokes the function `customSc.foo` +- This in tun invokes `hederaAcountService.isAuthorizedCurrentTransaction()` +- `hederaAcountService` invokes the system contract implementation +- The system contract uses `TxnAwareEvmSigsVerifier` to determine that `tx` is authorised, because: + - `tx` has been signed by `edDsaKey`, which is a member of account `0.0.12345`'s `ThresholdKey` + - `tx` has also been signed by `ecDsaKey`, which is a member of account `0.0.12345`'s `ThresholdKey` + - `tx` invokes `customSc`, which is a member of account `0.0.12345`'s `ThresholdKey` +- A `true` return value from `hederaAcountService.isAuthorizedCurrentTransaction()` is obtained within `customSc.foo` +- `customSc.foo` uses this return value to determine that the transaction is authorized, and therefore should execute the happy path for the remainder of its function + +Error path example: + +- Account `0.0.12345` has a `ThresholdKey` of ([`customSc`, `edDsaKey`, `ecDsaKey`], 3) --> transactions need to be authorised by all 3. +- `customScOther` is a smart contract that has been deployed to HSCS +- `customScOther` contains a function `foo` which invokes `hederaAcountService.isAuthorizedCurrentTransaction()` +- Transaction `tx` with `customScOther.foo` invocation is instantiated, client-side +- `tx` is signed by `edDsaKey`, client-side +- `tx` is also subsequently signed by `ecDsaKey`, client-side +- `tx` is executed by submitting it to the network +- HSCS' EVM parses `tx` and invokes the function `customScOther.foo` +- This in tun invokes `hederaAcountService.isAuthorizedCurrentTransaction()` +- `hederaAcountService` invokes the system contract implementation +- The system contract uses `TxnAwareEvmSigsVerifier` to determine that `tx` is **not** authorised, because: + - `tx` has been signed by `edDsaKey`, which is a member of account `0.0.12345`'s `ThresholdKey` + - `tx` has also been signed by `ecDsaKey`, which is a member of account `0.0.12345`'s `ThresholdKey` + - `tx` invokes `customScOther`, which is **not** a member of account `0.0.12345`'s `ThresholdKey` +- A `false` return value from `hederaAcountService.isAuthorizedCurrentTransaction()` is obtained within `customScOther.foo` +- `customScOther.foo` uses this return value to determine that the transaction is **not** authorized, and therefore should execute the error path for the remainder of its function + ## Backwards compatibility @@ -171,14 +233,18 @@ at minimum including a list of "Do's and Don'ts". +Nil + + + ## Rejected Ideas - Allow `delegatecall` on the `hederaAccountService` system contract - - Rejected becuase: Contradiction of v2 smart contract security model + - Rejected because: Contradiction of v2 smart contract security model - If there is indeed a community request that asks from specific exemption, we can ask them to submit a HIP that would specifically whitelist those specific flows, and then consider those. - - This path has already been trodden with HTS - "System smart contracts may not be delegate called, except from the Token proxy/facade flow, e.g., HIP 719. In such cases, HTS tokens are represented as smart contracts (see HIP 218) for common ERC methods." + - This path has already been trodden with HTS - "System smart contracts may not be delegate called, except from the Token proxy/facade flow, e.g., HIP 719. In such cases, HTS tokens are represented as smart contracts (see HIP 218) for common ERC methods." ## Open Issues @@ -191,7 +257,11 @@ Nil - [HIP-632 - Hedera Account Service (HAS) System Contract](../hip-632) +- [Hedera - Basic Types - Key](https://docs.hedera.com/hedera/sdks-and-apis/hedera-api/basic-types/key) - [Hedera - Smart Contract Security - Security Model - New model (v2) boundaries](https://docs.hedera.com/hedera/core-concepts/smart-contracts/security#new-model-v2-boundaries) +- [Github - hedera-services `TxnAwareEvmSigsVerifier`](https://github.com/hashgraph/hedera-services/blob/810971de2b/hedera-node/hedera-mono-service/src/main/java/com/hedera/node/app/service/mono/contracts/sources/TxnAwareEvmSigsVerifier.java#L60) +- [Github - hedera-services `TransactionContext`](https://github.com/hashgraph/hedera-services/blob/810971de2b/hedera-node/hedera-mono-service/src/main/java/com/hedera/node/app/service/mono/contracts/sources/TxnAwareEvmSigsVerifier.java#L70) +- [Github - hedera-services `TransactionContext`](https://github.com/hashgraph/hedera-services/blob/810971de2b/hedera-node/hedera-mono-service/src/main/java/com/hedera/node/app/service/mono/legacy/core/jproto/JKey.java#L37) - [Ethereum - `ecrecover` Precompiled Contract](https://ethereum.github.io/execution-specs/autoapi/ethereum/frontier/vm/precompiled_contracts/ecrecover/index.html) ## Copyright/license From 652fa26bb7ecaf525eeb003496153918717ae9cc Mon Sep 17 00:00:00 2001 From: Brendan Graetz Date: Wed, 23 Aug 2023 16:34:30 +0800 Subject: [PATCH 08/10] docs: HIP-792 proofreading edits Signed-off-by: Brendan Graetz --- HIP/hip-792.md | 111 +++++++++++++++++++++++++++++-------------------- 1 file changed, 66 insertions(+), 45 deletions(-) diff --git a/HIP/hip-792.md b/HIP/hip-792.md index a36062ada..9f60f8903 100644 --- a/HIP/hip-792.md +++ b/HIP/hip-792.md @@ -10,7 +10,7 @@ status: Draft last-call-date-time: 2023-10-22T16:00:00Z created: 2023-08-21 discussions-to: https://github.com/hashgraph/hedera-improvement-proposal/discussions/792 -updated: 2023-08-22 +updated: 2023-08-23 requires: 632 --- @@ -18,25 +18,25 @@ requires: 632 -HIP-632 adds a new system contract, `hederaAccountService` that exposes a method `isAuthorized(address, messageHash, signatureBlob)`. This HIP proposes a similar version of that which implements the same functionality, but restricted for use *only* on the current (in flight) transaction. This would expose a new method `isAuthorizedCurrentTransaction()`. +HIP-632 adds a new system contract, `hederaAccountService` that exposes a method `isAuthorized(address, messageHash, signatureBlob)`. This HIP proposes a similar version of that function, which implements the same functionality, but restricted for use *only* on the current (in flight) transaction. This exposes a new method `isAuthorizedCurrentTransaction()`. ## Motivation -`hederaAccountService.isAuthorized(address, messageHash, signatureBlob)` works for the following scenarios: +`hederaAccountService.isAuthorized(address, messageHash, signatureBlob)` does work for the following scenarios: - When an account's admin key is "simple", and is comprised of either a single EdDSA key, or a single ECDSA key - When an account's admin key is "complex", and is comprised of multiple EdDSA keys and/or ECDSA keys, combined using one or more `KeyList`s or `ThresholdKey`s. `hederaAccountService.isAuthorized(address, messageHash, signatureBlob)` does **not** work for the following scenarios: -- When an account's admin key is "complex", and is comprised of multiple EdDSA keys and/or ECDSA keys and/or smart contract IDs, combined using one or more `KeyList`s or `ThresholdKey`s. +- When an account's admin key is "complex", and is comprised of multiple EdDSA keys and/or ECDSA keys and/or **smart contract IDs**, combined using one or more `KeyList`s or `ThresholdKey`s. The proposed `hederaAccountService.isAuthorizedCurrentTransaction()` method aims to fulfil the above scenario, and specific use cases pertaining to this scenario will be elaborated upon in the [use cases section](#use-cases) below. Furthermore, Hedera Token Service exposes an authorization mechanism already, -which is capable of handling this scenario that is presently unfulfilled by Hedera Account Service. +which is capable of handling this scenario that is presently unfulfilled by Hedera Account Service as described in HIP-632. > NOTE: @@ -52,43 +52,49 @@ which is capable of handling this scenario that is presently unfulfilled by Hede In existing code examples where `ecrecover` is used, a smart contract function is passed in the transaction data in its parameters. -The design of both `isAuthorized(address, messageHash, signatureBlob)` -and `isAuthorizedRaw(address, messageHash, signatureBlob)`, +The design of both `hederaAcountService.isAuthorized(address, messageHash, signatureBlob)` +and `hederaAcountService.isAuthorizedRaw(address, messageHash, signatureBlob)` in HIP-632 mimics this approach. -This approach is fine in in cases where we assume that: +This approach is adequate in situations where we assume that: (1) All authorization is performed using cryptographic signatures (EdDSA and/or ECDSA in the case of Hedera). -(2) All authorization is performed "off-chain", that is among clients, and not within or by smart contracts. +(2) All authorization is performed "off-chain", that is among clients, and not within (or by) smart contracts. -While this approach is sufficient on Ethereum and other EVM-compatible networks, -because Externally Owned Acounts (EOAs) are the only type of account -that exists on, and is supported by the network, -this is **not** the case for Hedera. -Hedera, while EVM-compatible, has an account system that supports "simple" keys -(which are approximately analogous to EOAs), **and** -simultaneously supports "complex" keys on accounts. +On Ethereum and other EVM-compatible networks, +this approach is sufficient because Externally Owned Acounts (EOAs) +are the only type of account that exists on, +and is supported by the network. + +However, this is **not** the case for Hedera. +While EVM-compatible, +Hedera has an account system that supports "simple" keys on acounts +(which are approximately analogous to EOAs). +Hedera simultaneously supports "complex" keys on accounts +(which have no analogue on EVM-compatible networks). These complex accounts require special consideration as they support -`KeyList`, `ThresholdKey` (which may be recursively nested), -and whose "leaf nodes" may be comprised of any of -EdDSA keys, ECDSA keys, and even smart contract IDs. +`KeyList`s and `ThresholdKey`s (which may be recursively nested), +and whose "leaf nodes" may be comprised of any of: +EdDSA keys, ECDSA keys, and even **smart contract IDs**. The authorization methods described in HIP-632 are sufficient to support the "complex" keys on accounts, as described above, with one exception: -when the "leaf nodes" are smart contract IDs. -In this scenario, both (1) and (2) listed above cannot be met: +When the "leaf nodes" of a "complex" key include one or more **smart contract IDs**. +In this situation, both assumptions (1) and (2) listed above can no longer be held true: (1) Smart contracts do not have cryptographic keys, and therefore cannot sign a transaction in order to authorize it. (2) Smart contract execution occurs exclusively "on-chain", -and therefore a smart contract may not provide its authorisation of a transaction -by any means other than its own execution when invoked within a transaction; -in other words smart contract authorization must necessarily occur while a transaction is "in flight". +and therefore a smart contract may not provide its authorization of a transaction +by any means other than its own execution when invoked within a transaction. +In other words smart contract authorization must necessarily occur while a transaction is "in flight", +and therefore cannot occur client-side before being submitted to the network. -However the latter scenario **should** be supported, -as noted in [Hedera's documentation on Keys](https://docs.hedera.com/hedera/sdks-and-apis/hedera-api/basic-types/key): +However the latter scenario with smart contract IDs +within "complex" keys **should** be supported, as noted in +[Hedera's documentation on Keys](https://docs.hedera.com/hedera/sdks-and-apis/hedera-api/basic-types/key): > Note that when a Key is a smart contract ID, > it doesn't mean the contract with that ID will actually create a cryptographic signature. @@ -114,18 +120,20 @@ to verify authorization of a transaction that will work in the above scenarios. +(1) As a smart contract developer, -I want to code a smart contract in solidity which is able to identify whether a transaction is authorized when sent from an account with a complex key where a smart contract ID is among its components, +I want to code a smart contract in solidity which is able to identify whether a transaction is authorized when sent from an account with a complex key which contains a smart contract ID, so that I can implement advanced use cases including: - implement flexible and customisable authorisation rules - implement advanced multisig use cases without the need to split across multiple transactions -- implement atomic multisig uses cases +- implement atomic multisig use cases - implement batch processing of multiple transactions +(2) As a user of Hedera networks, I want to create an 1-of-2 threshold key on my Hedera account where 1 component of my complex key is either an EdDSA key or an ECDSA key and the other component is a specified smart contract ID, -so that when this smart contract specified in my threshold key can perform actions on behalf of my account. +so that the particular smart contract specified in my threshold key can perform actions on behalf of my account. ## Specification @@ -137,7 +145,7 @@ This will aid developers who were limited to `ECRECOVER` authorization flows, an | hash | signature | return | description | | --- | --- | --- | --- | -| | isAuthorizedCurrentTransaction() | bool | `true`` if account is authorized to carry out transaction execution on account. Accepts protobuf key signature blobs. May be used for ECDSA, EdDSA simple key flows, and complex key flows which include any of ECDSA keys, EdDSA keys, and smart contract IDs. | +| | isAuthorizedCurrentTransaction() | bool | `true` if account is authorized to carry out transaction execution on account. Accepts protobuf key signature blobs. May be used for ECDSA, EdDSA simple key flows, and complex key flows which include any of ECDSA keys, EdDSA keys, and smart contract IDs. | ### `isAuthorizedCurrentTransaction()` Function Usage @@ -145,11 +153,16 @@ This function behaves identically to `isAuthorized(address, messageHash, signatu - It is called without specifying any parameters - This function extracts the values that it needs in order to validate if a transaction is authorized from the current transaction -- Therefore it designed to be used exclusively on the current transaction, which is still in-flight (as clearly communicated by the `CurrentTransaction` suffix in the function name) +- Therefore it designed to be used exclusively on the current transaction, which is still in-flight + - This is clearly communicated by the `CurrentTransaction` suffix in the function name -No new protocol buffer schema definitions are needed as there are no parameters. Internal protocol buffers schema definitions that need to be used to process this function would be existing ones already present in Hedera's base account system, such as `Key`, `ContractID`, `KeyList` and `ThresholdKey`. Potentially this function may also use `SignatureMap` and `SignaturePair` as defined in HIP-632, if necessary. +No new protocol buffer schema definitions are needed as there are no parameters for this function. +Internal protocol buffer schema definitions that need to be used to process this function +would be the existing ones already present in Hedera's base account system, +such as `Key`, `ContractID`, `KeyList` and `ThresholdKey`. Potentially, this function may also use `SignatureMap` and `SignaturePair`, +as defined in HIP-632, if deemed necessary during implementation. -### Examples +### Example usage flows Happy path example: @@ -161,14 +174,16 @@ Happy path example: - `tx` is also subsequently signed by `ecDsaKey`, client-side - `tx` is executed by submitting it to the network - HSCS' EVM parses `tx` and invokes the function `customSc.foo` -- This in tun invokes `hederaAcountService.isAuthorizedCurrentTransaction()` -- `hederaAcountService` invokes the system contract implementation -- The system contract uses `TxnAwareEvmSigsVerifier` to determine that `tx` is authorised, because: +- This in turn invokes the system contract function + `hederaAcountService.isAuthorizedCurrentTransaction()` +- `hederaAcountService` invokes the system contract implementation, + which uses `TxnAwareEvmSigsVerifier` to determine that `tx` is authorised, because: - `tx` has been signed by `edDsaKey`, which is a member of account `0.0.12345`'s `ThresholdKey` - `tx` has also been signed by `ecDsaKey`, which is a member of account `0.0.12345`'s `ThresholdKey` - `tx` invokes `customSc`, which is a member of account `0.0.12345`'s `ThresholdKey` + - Put together, all 3 out of the required threshold of 3 have been met - A `true` return value from `hederaAcountService.isAuthorizedCurrentTransaction()` is obtained within `customSc.foo` -- `customSc.foo` uses this return value to determine that the transaction is authorized, and therefore should execute the happy path for the remainder of its function +- `customSc.foo` uses this return value to determine that the transaction is indeed **authorized**, and therefore should execute the **happy path** for the remainder of its function Error path example: @@ -180,14 +195,16 @@ Error path example: - `tx` is also subsequently signed by `ecDsaKey`, client-side - `tx` is executed by submitting it to the network - HSCS' EVM parses `tx` and invokes the function `customScOther.foo` -- This in tun invokes `hederaAcountService.isAuthorizedCurrentTransaction()` -- `hederaAcountService` invokes the system contract implementation -- The system contract uses `TxnAwareEvmSigsVerifier` to determine that `tx` is **not** authorised, because: +- This in turn invokes the system contract function + `hederaAcountService.isAuthorizedCurrentTransaction()` +- `hederaAcountService` invokes the system contract implementation, + which uses `TxnAwareEvmSigsVerifier` to determine that `tx` is **not** authorised, because: - `tx` has been signed by `edDsaKey`, which is a member of account `0.0.12345`'s `ThresholdKey` - `tx` has also been signed by `ecDsaKey`, which is a member of account `0.0.12345`'s `ThresholdKey` - `tx` invokes `customScOther`, which is **not** a member of account `0.0.12345`'s `ThresholdKey` + - Put together, only 2 out of the required threshold of 3 have been met - A `false` return value from `hederaAcountService.isAuthorizedCurrentTransaction()` is obtained within `customScOther.foo` -- `customScOther.foo` uses this return value to determine that the transaction is **not** authorized, and therefore should execute the error path for the remainder of its function +- `customScOther.foo` uses this return value to determine that the transaction is indeed **unauthorized**, and therefore should execute the **error path** for the remainder of its function. ## Backwards compatibility @@ -195,15 +212,19 @@ Error path example: This functionality is newly proposed and thus does not overwrite or alter existing functionality. -Notably, this HIP proposes changes to neither `isAuthorized(address, messageHash, signatureBlob)` nor `isAuthorizedRaw(address, messageHash, signatureBlob)`. +Notably, this HIP proposes changes to +neither `isAuthorized(address, messageHash, signatureBlob)` +nor `isAuthorizedRaw(address, messageHash, signatureBlob)` +from HIP-632. ## Security implications -Ensure that this proposal considers +It vital that this proposal considers the [new model (v2) boundaries](https://docs.hedera.com/hedera/core-concepts/smart-contracts/security#new-model-v2-boundaries) and does not break its stipulations. + Specifically: - Consider that top-level signatures are not supported @@ -221,12 +242,12 @@ These could imply the user has given their authorization for all such combinatio Provide a [short, self contained, correct code example](http://sscce.org/) -which demonstrates this HIP, with both error-path and happy-path examples. +which demonstrates this HIP, with both happy path and error path examples. This will be in the style of existing work: - [Multisig Account](https://github.com/hedera-dev/hedera-code-snippets/tree/main/multisig-account) -Provide sufficient warnings about improper use of `isAuthorizesCurrentTransaction` in a tutorial, +Provide sufficient warnings about improper use of `isAuthorizedCurrentTransaction` in a tutorial, at minimum including a list of "Do's and Don'ts". ## Reference Implementations From 1fbe55c842989632db9c23556743a8ac9434def4 Mon Sep 17 00:00:00 2001 From: Brendan Graetz Date: Thu, 24 Aug 2023 09:51:35 +0800 Subject: [PATCH 09/10] docs: HIP-792 - add discussions-to link for newly created discussion --- HIP/hip-792.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HIP/hip-792.md b/HIP/hip-792.md index 9f60f8903..3ce1bc23f 100644 --- a/HIP/hip-792.md +++ b/HIP/hip-792.md @@ -9,7 +9,7 @@ needs-council-approval: Yes status: Draft last-call-date-time: 2023-10-22T16:00:00Z created: 2023-08-21 -discussions-to: https://github.com/hashgraph/hedera-improvement-proposal/discussions/792 +discussions-to: https://github.com/hashgraph/hedera-improvement-proposal/discussions/793 updated: 2023-08-23 requires: 632 --- From 8324ccf1258a89ac309accde50868b13373c8e8a Mon Sep 17 00:00:00 2001 From: Brendan Graetz Date: Wed, 7 Feb 2024 16:35:22 +0800 Subject: [PATCH 10/10] docs: minor - accept suggested edits Co-authored-by: Nana Essilfie-Conduah <56320167+Nana-EC@users.noreply.github.com> Signed-off-by: Brendan Graetz --- HIP/hip-792.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/HIP/hip-792.md b/HIP/hip-792.md index 3ce1bc23f..01971ef40 100644 --- a/HIP/hip-792.md +++ b/HIP/hip-792.md @@ -98,7 +98,7 @@ within "complex" keys **should** be supported, as noted in > Note that when a Key is a smart contract ID, > it doesn't mean the contract with that ID will actually create a cryptographic signature. -> It only means that when the contract calls a precompiled contract, +> It only means that when the contract calls a system contract function, > the resulting "child transaction" will be authorized to perform any action controlled by the Key. Therefore this HIP proposes a means, via the `hederaAccountSystem` system contract, @@ -246,6 +246,7 @@ which demonstrates this HIP, with both happy path and error path examples. This will be in the style of existing work: - [Multisig Account](https://github.com/hedera-dev/hedera-code-snippets/tree/main/multisig-account) +- [Multisig Smart Contract Account](https://github.com/hedera-dev/hedera-code-snippets/tree/main/multisig-sc-account) Provide sufficient warnings about improper use of `isAuthorizedCurrentTransaction` in a tutorial, at minimum including a list of "Do's and Don'ts".