-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from flow-hydraulics/access-checks
Access checks
- Loading branch information
Showing
28 changed files
with
684 additions
and
157 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,104 @@ | ||
<!-- markdownlint-configure-file { "MD013": { "line_length": 120 } } --> | ||
|
||
# OnChainMultiSig | ||
|
||
This repo is the source code for the `OnChainMultiSig` contract. | ||
Its usage is demonstrated with the `MultiSigFlowToken` contract. | ||
This repository is the source code for the `OnChainMultiSig` contract. | ||
|
||
The `OnChainMultiSig` contract is designed to address the need for | ||
multiple signature to authorise transactions without [time constraint] or [gas balance]. | ||
|
||
## Motivation | ||
|
||
The motivation for this contract is in three parts: | ||
|
||
1. **Limited Time Constraint** Natively, Flow suports multiple signers to authorise account transaction | ||
with the innovative [`Weighted Keys`] in the [`Accounts`] system. | ||
However, transactions all have expiration window (measured in blocks). | ||
This is about [10 minutes] on the Mainnet. | ||
It may not always be feasible or user friendly to require multisig key holder to be | ||
present to sign everytime a transaction is required. | ||
|
||
2. **Standardisation** It is common for an account to have multiple resources in their storage path and that | ||
these resources all require the multisig feature. It will be easier for frontend developers or users to compose | ||
signatures that captures the intention of the signer securely. | ||
|
||
3. **Gas requirement** It should not be required that the signers of a multisig resource must | ||
all have balance in an account, the signatures themselves should be enough to authorise | ||
transactions of which some other [`payer`] (or themselves) can pay for. | ||
|
||
## Solution | ||
|
||
To address the time constraint, as the name suggests, the signatures are temporarily stored on chain. | ||
Once all required signatures are ready, anyone can call the public method to execute the transaction. | ||
|
||
Interfaces are defined to facilitate standardising this onchain signature storage across different resources. | ||
|
||
Finally, following Flow's decoupling principle between account and keys, | ||
the signature for a multisig transaction can be sumbitted by a trusted [`payer`], | ||
independent to the account that owns the resource[^1] or the key. | ||
This allows signers to simply be some entity that holds some private key where the corresponding public | ||
key has been added as part of the resource's multisig public key list with some weight. | ||
|
||
### Method Details | ||
|
||
`OnChainMultiSig` contract provides a `Manager` resource which is intended to be created and stored by resources that | ||
supports onchain multisig. | ||
In addition, `PublicSigner` interface is provided for the resources as a standard interface for transactions to: | ||
|
||
1. `addNewPayload`: Create a new payload and signature for it to be stored. | ||
The `TxIndex` must be the current index incremented by one and is included in the signature. | ||
Signature must be produced by the public key in `@Manager.keyList` | ||
2. `addPayloadSignature`: Submit a signature for a payload that was added. | ||
Signature must be produced by the public key in `@Manager.keyList` | ||
3. `executeTx`: Execute a transaction (if all signatures required have been submitted) | ||
|
||
and queries for: | ||
|
||
1. `UUID`: gets the uuid of the multisig resource | ||
2. `getTxIndex`: gets the sequentially assigned current txIndex of multisig pending tx of this resource | ||
3. `getSignerKeys`: gets the list of public keys for the resource's multisig signers | ||
4. `getSignerKeyAttr`: gets the stored key attributes | ||
|
||
Internal to the `Manager` resource, it implements the `SignatureManager` interface which allows the implementation of `PublicSigner` | ||
functions on the multisig supported resources to work with the `Manager`. | ||
|
||
#### Usage | ||
|
||
We will use a simple `Vault` resource in the `MultiSigFlowToken` contract to demonstrate the usage of the `PublicSigner`, | ||
how to form a [onchain-multisig signature], | ||
transacting with the `MultiSigFlowToken` contract and [resource owner account management]. | ||
|
||
TODO code walk through | ||
|
||
### Signatures | ||
|
||
The message in the signature verified by the `Manager` resource are as such: | ||
**TODO details** | ||
|
||
- `OnChainMultiSig.PayloadDetails` | ||
- only a few types are supported at the moment | ||
- only certain `signatureAlgorithm` and `hashAlgorithm` are supported at the moment | ||
|
||
### Resource Owner Account Management | ||
|
||
Whilst it is possible to allow for onchain multisig feature to be available for resources, | ||
to limit the use to *just* be in that way will ultimately depend on the account that owns the resources. | ||
|
||
As such, the account with such a resource should itself have all the keys added so that the `weights` | ||
of each authorizer is consistent for the resource and the account. This is because if one key | ||
is added to the account, that key has the ability to directly call functions in `Manager` to alter the states. | ||
|
||
Another approach may be that once the resource has been added, all keys for the owner account is revoked. | ||
This limits the flexibility of the account but it may be neccessary, similar to [immutable contracts] in Flow. | ||
|
||
[onchain-multisig signature]: (#signatures) | ||
[immutable contracts]: <https://docs.onflow.org/concepts/accounts-and-keys/#account-creation> | ||
[decoupled]: <https://docs.onflow.org/concepts/accounts-and-keys/#account-creation> | ||
[10 minutes]: <https://docs.onflow.org/flow-go-sdk/building-transactions/#reference-block> | ||
[`payer`]: <https://docs.onflow.org/flow-go-sdk/building-transactions/#payer> | ||
[gas balance]: <https://docs.onflow.org/flow-go-sdk/building-transactions/#payer> | ||
[time constrains]: <https://docs.onflow.org/flow-go-sdk/building-transactions/#reference-block> | ||
[`Accounts`]: <https://docs.onflow.org/concepts/accounts-and-keys/#accounts> | ||
[`Weighted Keys`]: <https://docs.onflow.org/concepts/accounts-and-keys/#weighted-keys> | ||
[resource owner account management]: (#resource-owner-account-management) | ||
[^1]: Please see [resource owner account management] for details |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.