NOTE: This repository is currently not maintained.
This repository is the source code for the
OnChainMultiSig contract is designed to address the need for
multiple signature to authorise transactions without [time constraint] or gas balance.
The motivation for this contract is in three parts:
Limited Time Constraint Natively, Flow suports multiple signers to authorise account transaction with the innovative
Weighted Keysin the
Accountssystem. 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.
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.
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.
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
independent to the account that owns the resource1 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.
OnChainMultiSig contract provides a
Manager resource which is intended to be created and stored by resources that
supports onchain multisig.
PublicSigner interface is provided for the resources as a standard interface for transactions to:
addNewPayload: Create a new payload and signature for it to be stored. The
TxIndexmust be the current index incremented by one and is included in the signature. Signature must be produced by the public key in
addPayloadSignature: Submit a signature for a payload that was added. Signature must be produced by the public key in
executeTx: Execute a transaction (if all signatures required have been submitted)
and queries for:
UUID: gets the uuid of the multisig resource
getTxIndex: gets the sequentially assigned current txIndex of multisig pending tx of this resource
getSignerKeys: gets the list of public keys for the resource's multisig signers
getSignerKeyAttr: gets the stored key attributes
Internal to the
Manager resource, it implements the
SignatureManager interface which allows the implementation of
functions on the multisig supported resources to work with the
We have used a simple
Vault resource in the
MultiSigFlowToken contract to demonstrate the usage of the
how to form a onchain-multisig signature,
transacting with the
MultiSigFlowToken contract and resource owner account management.
The message in the signature verified by the
Manager resource are as such, in order:
txIndex: UInt64: The txIndex of the payload. For a new payload, this must be the latest txIndex + 1
method: String: The name of the method the multisig supported resource uses
arg: AnyStructure: The arguments that are needed (currently supports:
Example of how the signer may construct their message to ensure the encoding to bytes align with the cadence
encoding in the contract can be found in
which uses the script in
The signing example can be found in
Note: The current version only supports
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
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.