Я попытался использовать функцию «Вызов», как описано здесь: Функция вызова из развернутого контракта
Но кажется, что он вообще не работает.
Как я могу вызвать функцию из существующего развернутого смарт-контракта?
Я пытаюсь вызвать простую функцию из существующего адреса, которая получает адрес в качестве параметра.
Это код, который я использую для вызова внешней функции:
Контракт А:
function CallExternalFunction(address externalContractAddress)
{
externalContractAddress.call(bytes4(sha3("FunctionX(address)")),0xfffff);
//sends 0xfffff as input parameter to the external contract
}
Исходный код уже развернутого контракта выглядит так:
Контракт Б:
contract test {
mapping (address => uint256) public balanceOf;
function test() {
}
function FunctionX(address _address)
{
balanceOf[_address] = 50000;
}
}
Попробуй это. Разверните вызывающую программу, и она развернет тестовый контракт, чтобы упростить задачу.
contract Caller {
test public t;
function Caller() {
t = new test();
}
function callIt(address theAddress)
public
returns(bool success)
{
t = test(t); <===== here the other contract address can be called t = test([OtherContractAddress]); example: test(0x12345);
bool result = t.FunctionX(theAddress);
return result;
}
}
contract test {
mapping (address => uint256) public balanceOf;
function FunctionX(address _address) public returns(bool success)
{
balanceOf[_address] = 50000;
return true;
}
}
В Remix, чтобы показать, что это работает.
Вы можете использовать аналогичную структуру для контракта, который уже есть, если у вас есть исходный код, используя и интерфейсный контракт. Здесь компилятор «вызывающий» может видеть достаточно теста {} для управления интерфейсом.
contract Caller {
test public t;
// where test is deployed and the address is known
// Pass in the address for test {}.
function Caller(address tAddress) {
t = test(tAddress); // address of contract t
}
function callIt(address theAddress)
public
returns(uint bal)
{
return t.FunctionX(theAddress);
}
}
// This interface constant includes the function interfaces (exactly as in the "real" contract" with the fynctions undefined
// This tells the compiler how to communicate with the ABI in test{}.
contract test {
function FunctionX(address _address) public returns(uint balanceOf) {}
}
t = new test();
развертывает новый экземпляр test. Для уже развернутого test{} вы можете передать адрес или жестко закодировать адрес. Вызывающий должен знать его, чтобы позвонить. Единственный исходный файл дает компилятору представление о тестовом контракте, поэтому он понимает интерфейс test{} и имеет байт-код, необходимый для развертывания нового теста{}.
Роб Хитченс
Рестен
Гарен Вартанян
call
ваш газ (минус ~ 30 тыс.) будет перенаправлен внешнему контракту, чтобы делать с ним все, что ему заблагорассудится, что является уязвимостью, особенно если вызов завершается сбоем и по умолчанию используется резервная функция.call
также нарушает безопасность типов для аргументов функции и по-прежнему будет передавать эфир, если при выполнении генерируется исключение, поэтому обязательно поместите вызов в arequire()
, чтобы отменить транзакции, которые ведут себя не так, как ожидалось.