У меня есть два контракта Solidity, где контракт Caller
зависит от второго контракта Callee
. Контракт Callee
предоставляет функцию публичного просмотра, которая проверяет правильность строки (например, пароля) в соответствии с некоторыми внутренними правилами. Caller
должен проверить строку в своей собственной функции, вызвав Callee
, прежде чем он сможет продолжить обработку. Кроме того, Caller
необходимо вызвать функцию с Callee
помощью delegatecall
, потому что внутренняя проверка правильности учитывает адрес вызывающего абонента.
contract Caller {
function doSomething(string _text, address _callee) public {
bool valid = bool(_callee.delegatecall(
bytes4(keccak256("check(string _text)")), _text)
);
require(valid == true);
/* further process if text is valid */
}
}
contract Callee {
function check(string _text) public view returns(bool){
/* validity check */
return true;
}
}
Проблема с этим кодом в том, что вызов функции check
кажется асинхронным, и поэтому require
оператор в функции doSomething
всегда будет терпеть неудачу. Это проблема delegatecall
? Есть ли способ синхронно вызвать внешнюю функцию?
Наконец-то я нашел ответ на свою проблему: к сожалению, нельзя получить значения из вызовов функции delegatecall.
Нулик
DELEGATECALL
коде операции:func opDelegateCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error)
Себастьян Дайн
Нулик
ret
содержит[]byte
массив, возвращенный DELEGATECALL. Возможно, вы можете написать небольшую часть своего контракта на ассемблере, поэтому вы вызываете DELEGATECALL и перехватываете это возвращаемое значение. Это возвращаемое значение помещается в память вoutOffset
позицию.Себастьян Дайн
ret
переменная указывает, была ли обработка вызванной функции успешной.Нулик
ret
это вывод, возвращаемый EVM. Если произошла какая-либо ошибка, он возвращает файлerror
. Этот вывод кодируется в соответствии с ABI. Если вы вызовете abi.Unpack(),ret
вы получите значение в соответствии с его типом. Например, все целые числа хранятся в массивах по 32 байта, все строки имеют первую длину строки, затем следуют строковые данные и так далее...