Multi Signature Wallet lets you execute one of its functions only when a threshold of agreements is met.
Let’s create a multiSig wallet, which is a smart contract by the way, and deploy it on ethereum. Let ‘s assume that this smart contract address is 0x3471aa..
When we deployed the contract we stored the address of 5 administrators and set a threshold of 3 in the smart contract state. This means that if 3 out of 5 administrators agree, they can execute a function of this MultiSig smart contract.
So what are these functions ?
- We can add or remove administrators along with modifying the threshold. For instance if you want to go through a 3 out of 5 to a 2 out of 3 administrator agreement threshold. Note that this function can be executed only by the MultiSig Smart contract itself …Don’t worry we will talk more about that later.
- Submit and execute a transaction. A transaction can be everything from a plain ether transfer to calling another smart contract function like transferring an ERC20 for instance. Actually Everybody is allowed to submit and trigger the execution of a transaction. Indeed the execution will be triggered only if the threshold is met hence no need to restrict it to only the administrators. In our example for somebody to trigger the execution of a transaction will require the agreement of at least 3 out of 5 administrators.
- Provide or revoke an agreement. Each administrator can give and revoke their agreement on a proposed transaction. Of course administrators only can execute that function.
You have to keep in mind that if the MultiSig smart contract sends a transaction of 1 ether to another address this ether will come from the MultiSig balance. In the same way if the MultiSig smart contract executes a transaction of another smart contract the message sender of that smart contract will be the address of the MultiSig 0x3471aa...
Here is an example where the write() function of the Private Diary Smart Contract is restricted to Ben. If Jan tries to call that write function his transaction will fail. Jan cannot execute that function because the message sender of the transaction must be the address 0x42be5.. otherwise it will fail.
Now instead of restricting it to address 0x42be5.. we restrict it to the address 0x3471aa.. the MultiSig address. If Jan tries to call that write function his transaction will fail again. Only the MultiSig Smart Contract can execute that function , but what does it mean ?
For the MultiSig to be able to call the write function we must propose that transaction and gather all the requirements from administrators and then execute it.
- Call the submit transaction function on the MultiSig with the right parameter. We should encode a call with the function name, write(), the values and the destination address which is the private diary smart contract in that example. This function will return a transaction ID.
- At least 3 out of 5 administrators must call the provide agreement function on the MultiSig with the transaction ID they agree upon.
- Call the execute transaction function on the MultiSig for this specific transaction ID. It will verify that the threshold of agreement is met and then call the write() function.
In order to call the add or remove administrators function on the MultiSig we should go through the same steps as these functions are only accessible to the MultiSig address.
Let’s take a look at a more complicated example where we want to have a proxy smart contract in front of our private diary smart contract for upgradability reasons. We want to use a MultiSig to be the admin of the proxy and also to access the write() function. Can it be the same MultiSig smart contract ?
We have to know that a proxy will transfer the transaction without modifying the message sender (thanks to the delegate call property). This means that the transaction issued by the MultiSig to the write() function of the diary contract will still succeed even though it goes through the proxy.
The drawback is that we can’t use the same MultiSig to use as a proxy admin. Indeed if ,like Openzeppelin , you use the transparent proxy pattern to avoid function clashes the proxy will decide which calls are delegated to the underlying logic contract based on the caller address. In our example the Admin MultiSig will never be able to call the write() function and the MultiSig 0x3471aa.. will never be able to execute the admin functions of the proxy.