В солидности,call
иdelegatecall
— это два низкоуровневых инструмента для взаимодействия между контрактамифункция。Они все могут позвонить по контрактуфункция,Но их способ ииспользовать отличается.
call
Это низкий уровеньфункция,Он может вызывать любую функцию контракта.,в том числе непубличныефункция。call
функцияполучитьфункциязнакинекоторые параметры,Затем выполните это на целевом контрактефункция。call
функция Будет создана новая среда выполнения.,Это означает вызовфункция Иметь свой собственныйthis
иmsg.sender
。
delegatecall
иcall
похожий,Также можно вызвать любую функцию контракта. Однако,delegatecall
Нет Будет создана новая среда выполнения.,Вместо этого он выполняется в контексте вызывающего контракта. это означает,Вызываемая функция может получать доступ к хранилищу вызывающего контракта и изменять его.
delegatecall
Обновление контрактаи Библиотека реализациифункция Очень полезно в таких сценариях, как,Потому что это позволяет одному контракту заимствовать код другого контракта.,сохраняя при этом свой статус。
call
иdelegatecall
функция В солидностииспользуются для вызова контрактовфункция,Но у них есть некоторые ключевые различия в способе их выполнения:
1.контекст выполнения:при использованииcall
функциячас,Вызванная функция выполняется в контексте вызываемого контракта.,это означаетэто Иметь свой собственныйthis
иmsg.sender
。иdelegatecall
функция Затем вызываемая функция выполняется в контексте вызывающего контракта.функция,это означаетthis
иmsg.sender
будучи вызваннымфункциясерединаи Контракт вызова тот же。2.государственное хранилище:call
функцияв исполнениичас Нет会改变调用合约的状态,Он только меняет состояние вызываемого контракта。иdelegatecall
функция Вы можете изменить статус контракта звонка,Поскольку он выполняется в контексте вызывающего контракта。3.использовать:call
функция Обычно используется для вызова других контрактовфункция,иdelegatecall
функция Он часто используется для реализации обновлений контракта.и Библиотекафункция。delegatecall
Позволяет одному контракту заимствовать код из другого контракта.,сохраняя при этом свой статус,Это очень полезно в таких сценариях, как обновление контрактов и библиотек реализации.
В солидности,call
иdelegatecall
функцияиспользуются для взаимодействия между контрактами,Но их Сценарии использование разное.
Использование вызова
call
функция Обычно используется для вызова другого контрактафункция。Когда из одного контракта нужно вызвать другой контрактфункция,и нет необходимости менять статус текущего договора,Можно использоватьcall
функция。Например,Возможно, вам придется запросить статус другого контракта.,Или вызовите одну из его функций для выполнения какой-либо операции.
Случаи использования делегированного вызова
delegatecall
функция Обычно используется для реализации обновлений контракта.и Библиотекафункция。Когда из одного контракта нужно вызвать другой контрактфункция,И когда нужно изменить статус текущего договора,Можно использоватьdelegatecall
функция。delegatecall
Позволяет одному контракту выполнять код другого контракта в своем собственном контексте.,это означает Вызываемая функция может получать доступ к хранилищу вызывающего контракта и изменять его.
Следует отметить, что,call
иdelegatecall
Они все низкого уровняфункция,Используйте их с большой осторожностью,Потому что они могут вызвать неожиданные побочные эффекты. Например,При вызове функция выдает аномальный,Тогда вся транзакция будет отменена. также,Если вы используете его неправильноdelegatecall
,Вы можете непреднамеренно изменить состояние контракта. поэтому,Если вы полностью не понимаете их принципы работы.,В противном случае лучше избегать их прямого использования.
В солидности,call
иdelegatecall
Они все низкого уровняфункция,Хотя они могут быть очень полезны в определенных ситуациях.,Однако вам следует избегать их непосредственного использования в следующих ситуациях:
1.вопросы безопасности:call
иdelegatecall
может привести к повторным атакам。Если после вызова внешнего контракта остались незавершенные работы Работа(Например,обновить переменные состояния),и не принял соответствующих мер защиты,Затем вызываемый контракт может снова вызвать исходный контракт.,Это приводит к повторным атакам.
2.Обработка исключений:call
иdelegatecall
Не будет автоматически обрабатывать вызовфункцияброшенныйаномальный。При вызове функция выдает аномальный,Тогда вся транзакция будет отменена,Если только ты не позвонишьcall
илиdelegatecall
час Проверено。
3.Изменение статуса:delegatecall
Можно изменить статус контракта вызова,Это может быть полезно в некоторых случаях,Но если случайно использовать,Может привести к неожиданным результатам. Например,Если вы случайно вызвали функцию, которая изменяет переменную состояния, которую вы не собирались изменять,Это может привести к потере статуса контракта.
4.видимость функции:call
иdelegatecall
Могу позвонить в любойфункция,Включает закрытую функцию. Это может вызвать неожиданное поведение,Если вы случайно вызвали функцию, которую не следует,Может вызвать проблемы.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;
// договор получателя
contract Receiver {
// Определите событие, которое будет инициироваться при поступлении средств.
event Received(address caller, uint256 amount, string message);
// Receiveфункция для получения ETH
receive() external payable {}
// резервная функция, срабатывающая при вызове несуществующей функции
fallback() external payable {
emit Received(msg.sender, msg.value, "Fallback was called");
}
// fooфункция, получает сообщение и значение, возвращает значение плюс один
function foo(string memory _message, uint256 _x)
public
payable
returns (uint256)
{
emit Received(msg.sender, msg.value, _message);
return _x + 1;
}
}
// контракт вызывающего абонента
contract Caller {
// Определите событие, которое будет срабатывать при получении ответа
event Response(bool success, bytes data);
// гипотезаконтракт вызывающего абонентапонятия не имеюдоговор Исходный код получателя,
// Но мы знаем договор Адрес получателя и вызываемая функция.
function testCallFoo(address payable _addr) public payable {
// Вы можете отправить эфир и указать индивидуальное количество газа.
(bool success, bytes memory data) = _addr.call{
value: msg.value,
gas: 5000
}(abi.encodeWithSignature("foo(string,uint256)", "call foo", 123));
emit Response(success, data);
}
// Вызов несуществующей функции запускает резервную функцию.
function testCallDoesNotExist(address payable _addr) public payable {
(bool success, bytes memory data) = _addr.call{value: msg.value}(
abi.encodeWithSignature("doesNotExist()")
);
emit Response(success, data);
}
}
Отказ от ответственности: эта работа распространяется под лицензией Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)[1]. Пожалуйста, укажите источник при ее использовании. Автор: мэнбин[2] блог: мэнбин[3] Гитхаб: mengbin92[4] cnblogs: Непреднамеренно полюбила воду[5] Сообщество разработчиков облачных технологий Tencent: Мюнстер[6]
[1]
С указанием авторства-Некоммерческая-ShareAlike 4.0 интернациональность (CC BY-NC-SA 4.0): https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh
[2]
mengbin: mengbin1992@outlook.com
[3]
mengbin: https://mengbin.top
[4]
mengbin92: https://mengbin92.github.io/
[5]
Влюбляюсь в воду нечаянно: https://www.cnblogs.com/lianshuiwuyi/
[6]
Мюнстер: https://cloud.tencent.com/developer/user/6649301