Please tell me how can smart contract call it's own function if this is not in smart contract code? Here is an example: https://github.com/gnosis/MultiSigWallet/blob/master/contracts/MultiSigWallet.sol. It has onlyWallet modifier applied to addOwner function, but addOwner is not called in the code. Thanks.
1 Answer
The line require(msg.sender == address(this))
in onlyWallet
can be a bit of a head scratcher, so let's first look at some snippets from the MultiSig wallet tests to see how you'd interact with the contract:
var owners = [accounts[0], accounts[1], accounts[2]]
var multisigInstance = await MultiSigWallet.new(owners, confirmations)
var addOwnerData = multisigInstance.contract.addOwner.getData(accounts[3])
await multisigInstance.submitTransaction(multisigInstance.address, 0, addOwnerData, {from: accounts[0]})
As you can see, one of the contract owners can invoke submitTransaction
passing along the encoded data that makes up the addOwner
method call.
Inside the submitTransaction
smart contract method there is a call to the addTransaction
method which stores the transaction data (addOwners call data) into a mapping.
transactions[transactionId] = Transaction({
destination: destination,
value: value,
data: data,
executed: false
});
Then an owner calls the confirmTransaction
method to confirm the transaction which then invokes executeTransaction(transactionId)
:
Finally, inside executeTransaction
you can see that it's executing the encoded data (addOwner call data) which makes the contract address the sender:
txn.destination.call.value(txn.value)(txn.data)
So essentially, the MultiSig wallet allows owners to submit a transaction which gets stored until another owner approves of it and executes it.
-
General scheme of the function calls is clear. In this particular example we have onlyWallet modifier for the method addOwner. This modifier requires the caller to be the contract. So how contract can call it's own function if it's not called in the contract code?– Max FLFeb 2, 2018 at 4:36
-
-
-
1@Ender yes it’s safe; basically it’s used when you don’t know or have the interface of the contract you’re calling but just know that that method exists. Apr 1, 2019 at 15:32