Содержание

Внешние вызовы функций

Выражения this.g(8); и c.g(2); (где c — это экземпляр контракта) — это вызовы функций. Функция при такой записи вызывается “внешне” через message call, а не напрямую. Вызов функции через this невозможен в конструкторе, так как контракт еще не создан.

Внешне можно вызывать функции других контрактов. Для внешнего вызова, все аргументы функции должны быть скопированы в memory.

При вызове функций других контрактов, количество Wei, отправляемых с вызовом, и газа можно указать через .value() и .gas(), например:

pragma solidity ^0.4.0;

contract InfoFeed {
    function info() public payable returns (uint ret) { return 42; }
}

contract Consumer {
    InfoFeed feed;
    function setFeed(address addr) public { feed = InfoFeed(addr); }
    function callFeed() public { feed.info.value(10).gas(800)(); }
}

Модификатор payable должен быть использован для info, потому что в противном случае .value() будет недоступна.

Выражение InfoFeed(addr) выполняет явное преобразование типа, как бы объявляя, что тип контракта по данному адресу — InfoFeed. И этого не выполняет конструктор. Явные преобразования типов необходимо выполнять с особой осторожностью. Не стоит вызывать функцию контракта, если неизвестен ее тип.

Можно также использовать функцию function setFeed(InfoFeed _feed) { feed = _feed; } напрямую.

Вызовы функций выбрасывают исключения, если вызываемый контракт не существует (в том смысле, что аккаунт не содержит кода), или если сам вызываемый контракт выбрасывает исключение или приводит к Out-of-Gas.

Предупреждение

Любое взаимодействие с другим контрактом потенциально опасно, особенно, если исходный код контракта заранее неизвестен. Текущий контракт передает контроль вызываемому контракту, который потенциально может сделать что угодно. Даже, если вызываемый контракт наследует от известного контракта, родительский контракт требуется только для правильного интерфейса. Однако, реализация контракта может быть полностью произвольной, и таким образом, представлять опасность. Вдобавок, контракт может вызывать другие контракты, или даже вернутся в вызывающий контракт первых возвратов вызовов. Это означает, что вызываемый контракт может изменить глобальный переменные вызывающего контракта через его функции. Нужно писать функции таким образом, чтобы, например, вызовы внешних функций происходили после любых изменений глобальных переменных. Так, контракт будет неуязвим к повторным вызовам.

Материал был полезен? Поделитесь в соц. сетях:
Логотип echain.ru

Добавить комментарий

Ваш e-mail не будет опубликован.