I am trying to make a contract have a function that is capable of calling functions of another contract. The key part of my goal is that the contract should not be able to be deployed without any import statements and will not know the name of the contract by default. In other words the user of this contract would input the called contracts data (i.e. address, name) as parameters. What is the best way to accomplish this?
Not sure why this was downvoted.
If I understand the question correctly, you want to deploy the contract without knowledge of the specific details of the contracts it will have to communicate with.
You can greatly simplify this by assuming knowledge of their interfaces.
You can define interfaces without importing contract code. Define the function interfaces and leave the function definitions empty:
contract WidgetInterface {
function doSomething() returns(uint) {}
function somethingElse() returns(bool isTrue) {}
}
Use that Interface contract to talk to actual contracts:
WidgetInterface w = WidgetInterface(actualContractAddress);
In my opinion it will usually be possible and advisable to register authorized/valid contracts as you go. Maintain a list of the contracts it can safely talk to, along these lines:
if(!isAuthorized(actualContractAddress)) throw;
where actualContractAddress
is supplied by sender and isAuthorized()
is a function you have worked out to query an internal registry.
Hope it helps.
You can do this by using an interface, as suggested by Rob Hitchens, or you could define the interface dynamically and execute a method by using .call, .callcode, .delegatecall.
Here's an example:
contract ContractsCaller {
function execute(address contractAt, uint _i, bytes32 _b) returns (bool) {
return contractAt.call(bytes4(sha3("testMethod(uint256,bytes32)")), _i, _b);
}
}
contract Test {
uint256 public i;
bytes32 public b;
function testMethod(uint256 _i, bytes32 _b) {
i = _i;
b = _b;
}
}
Test can be defined in a separate file. ContractsCaller doesn't need to know anything about Test besides its address and the signature of the method it's calling.
The signature of the method is the first 4 bytes of the method name and the types of its parameters:
bytes4(sha3("testMethod(uint256,bytes32)"))
More information about .call, .callcode, .delegatecall.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With