I have a contract which inherits from contract Claimable
by OpenZeppelin (see here):
pragma solidity ^0.4.24;
import "./Claimable.sol";
contract MyTestContract is Claimable {
uint256 public id;
function set(uint256 _id) external onlyOwner {id = _id;}
}
The purpose of course is to restrict the calling permission for function set
.
This function can be called only from the account which I use in order to deploy the contract.
After deployment, I would like to transfer ownership from this account to another contract.
The reason for this is not a part of my question, but for all it matters, I need to enforce multiple-signature on the function, and allow it to be executed only after X out of Y permitted users have submitted a request. Hence I need to transfer the ownership of the contract from my account to a MultiSig contract by Gnosis (see here), which I deploy myself.
The issue which I am having a problem with and cannot really wrap my head around, is how to transfer ownership to something which is "not exactly an account".
When I transfer ownership from my account to another account on the network, it works fine.
For example, I set up a Ganache network with 8 accounts, and then run this Truffle test:
contract('MyTestContract', (accounts) => {
it('Transfer Ownership', async () => {
let myTestContract = await artifacts.require('MyTestContract').new();
let owner = await myTestContract.owner();
assert(owner === accounts[0]);
await myTestContract.transferOwnership(accounts[1]);
await myTestContract.claimOwnership({from: accounts[1]});
let newOwner = await myTestContract.owner();
assert(newOwner === accounts[1]);
});
});
But when I transfer ownership from my account to the address of a contract which I deploy into the network, Truffle reports:
Error: sender account not recognized
Now, the error by itself makes sense, because there is no such account on the network.
So my question here - is it even possible to do what I'm trying to achieve?
I feel that I have some fundamental misunderstanding of the difference between accounts and contracts, which I'd be very grateful if someone could clarify for me.
Thank you very much!
UPDATE:
To clarify, this is how I transfer ownership to the MultiSig contract:
await myTestContract.transferOwnership(multiSigContract.address);
await myTestContract.claimOwnership({from: multiSigContract.address});
And by the way, when I use Ownable
instead of Claimable
, i.e.:
On-Chain Code:
contract MyTestContract is Ownable {...}
Off-Chain Code:
await myTestContract.transferOwnership(multiSigContract.address);
The ownership-transfer completes successfully, and the MultiSig contract is the only one which can call the set
function.
So the problem is essentially at:
await myTestContract.claimOwnership({from: multiSigContract.address});
address
can contain any value of 20 bytes you want.myTestContract.claimOwnership({from: myMultiSigContract.address})
?Claimable
contract test (also on OpenZeppelin's GitHub repository), this is what I'm supposed to do. Am I wrong here?