Динамический вызов внешнего контракта в 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.