Динамический вызов внешнего контракта в solidity
Я пытаюсь сделать контракт функцией, способной вызывать функции другого контракта. Ключевой частью моей цели является то, что контракт не должен быть развернут без каких-либо инструкций импорта и не будет знать имя контракта по умолчанию. Другими словами, пользователь этого контракта вводит в качестве параметров вызываемые данные контрактов (т. е. адрес, имя). Как лучше всего этого добиться?
2 ответов
не уверен, почему это было правда.
если я правильно понял вопрос, вы хотите развернуть контракт без знания конкретных деталей контрактов, с которыми ему придется общаться.
вы можете значительно упростить это, предполагая знание их интерфейсов.
вы можете определить интерфейсы без импорта кода контракта. Определите интерфейсы функций и оставьте определения функций пусто:
contract WidgetInterface {
function doSomething() returns(uint) {}
function somethingElse() returns(bool isTrue) {}
}
используйте этот контракт интерфейса, чтобы поговорить с фактическими контрактами:
WidgetInterface w = WidgetInterface(actualContractAddress);
по-моему как правило, можно и целесообразно регистрировать авторизованные / действительные контракты, как вы идете. Ведите список контрактов, с которыми он может безопасно разговаривать, по следующим строкам:
if(!isAuthorized(actualContractAddress)) throw;
здесь actualContractAddress
поставляется отправителем и isAuthorized()
это функция, которую вы разработали для запроса внутреннего реестра.
надеюсь, что это помогает.
вы можете сделать это с помощью интерфейса, как предложил Роб Хитченс, или вы можете определить интерфейс динамически и выполнить метод с помощью .призывать. ,callcode,.delegatecall.
вот пример:
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 можно определить в отдельном файле. ContractsCaller не нужно ничего знать о тесте, кроме его адреса и подписи метода, который он вызывает.
сигнатура метода-это первые 4 байта имени метода и типы его параметров:
bytes4(sha3("testMethod(uint256,bytes32)"))
дополнительная информация о .призывать. ,callcode,.delegatecall.