Quiero recuperar un resultado devuelto por una llamada a una función de otro contrato en mi contrato. Mi código de solidez está abajo, tengo
contract A {
function verifyUser(address userAddress) public returns(bool) {
bool verified = false;
uint id = userId[userAddress];
if (id != 0) {
verified = true;
}
return verified;
}
}
Utilicé el código ensamblador para obtener el valor devuelto por el método de verificación del usuario del contrato A.
contract B {
function verifAtt(uint idRequiredData, uint P, address userAddress) public returns (bool answer){
answer=false;
if(P==1) {
bytes4 sig = bytes4(keccak256("verifyUser(address)"));
assembly {
// move pointer to free memory spot
let ptr := mload(0x40)
// put function sig at memory spot
mstore(ptr,sig)
// append argument after function sig
mstore(add(ptr,0x04), userAddress)
let result := call(
15000, // gas limit
sload(dc), // to addr. append var to _slot to access storage variable
0, // not transfer any ether
ptr, // Inputs are stored at location ptr
0x24, // Inputs are 36 bytes long
ptr, //Store output over input
0x20) //Outputs are 32 bytes long
if eq(result, 0) {
revert(0, 0)
}
answer := mload(ptr) // Assign output to answer var
mstore(0x40,add(ptr,0x24)) // Set storage pointer to new space
}
}
}
return answer
}
Probé la función verificar usuario del contrato B y el resultado siempre es verdadero, incluso si el resultado debe ser falso. Quiero estar seguro de que el código ensamblador es correcto.
trabajo con remix y solidity 0.4.16
Sería mejor que hicieras:
verified = A(dc).verifyUser(userAddress);
El A(dc)
no está creando una nueva instancia. Es arrojar la dc
dirección a un A
contrato.
Tienes que hacerlo así porque call
devolverá el success
de la llamada, por ejemplo, si terminó con un return
o un revert/assert
. Puede obtener los datos de retorno si hace un call
, pero requiere el uso de un ensamblaje de solidez.
Además de eso, debe pensar dos veces sobre lo que está haciendo con el archivo for
. Esto es algo muy peligroso de hacer. Su transacción no puede usar más gas que el límite de gas del bloque. Entonces, si su matriz es demasiado grande, la llamada a la función siempre fallará.
Como regla general, todas sus funciones deben completarse en O(1)
.