Tengo un contrato que llama a otro contrato que llama a otro. Si hay un lanzamiento (o un error de falta de gas) que ocurre en algún lugar del segundo contrato, ¿ se revierte toda la transacción o son solo las cosas en el segundo y tercer contrato las que lo hacen, mientras que la ejecución del primer contrato ¿sigue en pie?
En Solidity, por defecto, sí.
En el nivel de EVM, un lanzamiento (mal salto, sin gas o cualquier otra excepción) solo revierte la llamada en la que se encuentra. Solidity continúa útilmente la excepción en la pila hasta que todo se deshace.
Es posible, usando un código de nivel inferior (específicamente, address.call()), para evitar esto. Aquí hay un ejemplo de esto que se usa como una construcción improvisada de intento y captura.
Para complementar la respuesta de @Matthew, depende de cómo se realice la llamada en Solidity.
Si C
llama D.foo()
y foo
hace un throw
, entonces sí, se revierte toda la transacción.
Si C
hace una "llamada sin procesar de nivel inferior" como D.call(bytes4(sha3('foo()')))
, y foo
hace un throw
, entonces solo foo
y sus subllamadas se revierten. Esto se debe a que una llamada sin formato no propaga ninguna excepción: una llamada sin formato D.call
solo devuelve un valor booleano que indica si la llamada tuvo éxito o encontró una excepción.
En Solidity, a throw
provoca una excepción al generar un código de bytes que conduce a un destino de salto no válido . (Para los demás casos, consulte Todos los casos en los que Solidity se compila en un destino de salto no válido ).
Desde la perspectiva de Solidity, una excepción que no se trague o que no se detecte o no se controle hará que se revierta toda la transacción.
Actualmente no hay forma de detectar una excepción en Solidity, por lo que una excepción, como throw
, hará que se revierta toda la transacción.
Sin embargo, las llamadas sin procesar "tragan" excepciones: las llamadas sin procesar no propagan excepciones y es por eso que solo se revertirán las subllamadas.
Es toda la transacción la que se revierte.
Además, todo el gas adjunto a la transacción (incluido el restante) va al minero.
ZMitton
Mateo Schmidt
ZMitton