Skip to content

Commit

Permalink
docs: HIP-792 proofreading edits
Browse files Browse the repository at this point in the history
Signed-off-by: Brendan Graetz <bguiz@users.noreply.github.com>
  • Loading branch information
bguiz committed Aug 23, 2023
1 parent d3d0737 commit 652fa26
Showing 1 changed file with 66 additions and 45 deletions.
111 changes: 66 additions & 45 deletions HIP/hip-792.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,33 @@ 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
---

## Abstract

<!-- a short (~200 word) description of the technical issue being addressed. -->

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

<!-- The motivation is critical for HIPs that want to change the Hedera codebase or ecosystem. It should clearly explain why the existing specification is inadequate to address the problem that the HIP solves. HIP submissions without sufficient motivation may be rejected outright. -->

`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.
<!-- TODO links/ references that demonstrate this in HTS -->

> NOTE:
Expand All @@ -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.
Expand All @@ -114,18 +120,20 @@ to verify authorization of a transaction that will work in the above scenarios.

<!-- Provide a list of “user stories” to express how this feature, functionality, improvement, or tool will be used by the end user. Template for user story: “As (user persona), I want (to perform this action) so that (I can accomplish this goal).” -->

(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

Expand All @@ -137,19 +145,24 @@ 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

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)
- 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:

Expand All @@ -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:

Expand All @@ -180,30 +195,36 @@ 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

<!-- All HIPs that introduce backward incompatibilities must include a section describing these incompatibilities and their severity. The HIP must explain how the author proposes to deal with these incompatibilities. HIP submissions without a sufficient backward compatibility treatise may be rejected outright. -->

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

<!-- If there are security concerns in relation to the HIP, those concerns should be explicitly addressed to make sure reviewers of the HIP are aware of them. -->

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
Expand All @@ -221,12 +242,12 @@ These could imply the user has given their authorization for all such combinatio
<!-- For a HIP that adds new functionality or changes interface behaviors, it is helpful to include a section on how to teach users, new and experienced, how to apply the HIP to their work. -->

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
Expand Down

0 comments on commit 652fa26

Please sign in to comment.