SPOILER de CodeWars
Estoy tratando de aprender haciendo, y estoy bastante confundido. Estoy trabajando en un kata para hacer una moneda y enviarla a otros. Mi solución falla la prueba porque dice que no estoy revisando el saldo, pero tengo esta línea como el primer comando en la función:
require( (amount > 0) && (balanceOf(msg.sender) >= amount) );
Miré las otras soluciones que pasaron y todas usan una declaración if:
if(balanceOf(msg.sender) < amount) return;
¿Hay límites para la cantidad de declaraciones require() que tengo en un contrato o función?
Por lo que he leído, pensé que require() siempre se prefiere como la forma más económica (menos gas) de verificar algo y fallar con gracia. Obviamente puedo escribir una declaración if...
Solo necesito saber si me estoy perdiendo algo o si la prueba de kata está mal.
Hay dos escenarios en los que desearía abortar una transacción:
El primer escenario nunca debería ocurrir, por supuesto.
Sin embargo, para asegurarnos de que nunca suceda, usamos assert
on variables o expresiones cuya corrección queremos... afirmar.
Si de alguna manera no detectamos un error en nuestro código durante el control de calidad, esto garantiza que la "transacción con errores" no se llevará a cabo.
En este escenario, aunque la transacción no se completa, el usuario paga el gas consumido en el camino hasta la aserción (fallida).
El segundo escenario bien puede suceder, ya que no controlamos la entrada del usuario.
Para garantizar la entrada del usuario, usamos require
, ya sea directamente en la entrada o en cualquier expresión que se derive de ella.
En este escenario, la transacción no se llevará a cabo y el usuario conservará todos los gastos de gas.
Técnicamente, una vez que está seguro de que una determinada pieza de código es perfecta, puede eliminar todas las afirmaciones restantes antes de implementarla (a menos que no le importe el poco gas adicional que se usa).
assert
generan require
una excepción, que puede ser detectada por cualquier entidad de capa superior (cualquier función en el árbol de llamadas) o por su cliente web3. Pero mientras require
revierte el gas usado, assert
no lo hace. Por lo tanto, es totalmente su decisión cuál de ellos usar y si detectar o no alguna excepción emitida en el camino.
usuario19510
usuario19510
require(amount > 0)
es técnicamente incorrecto. ERC20 dice que unTransfer
evento aún debe dispararse cuandoamount
es 0.