¿Por qué no usaría require()?

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.

Tu código es mejor. No, no hay límites.
Debo agregar que require(amount > 0)es técnicamente incorrecto. ERC20 dice que un Transferevento aún debe dispararse cuando amountes 0.

Respuestas (1)

Hay dos escenarios en los que desearía abortar una transacción:

  1. Error en el código
  2. Entrada de usuario ilegal

El primer escenario nunca debería ocurrir, por supuesto.

Sin embargo, para asegurarnos de que nunca suceda, usamos asserton 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).

De acuerdo, ¿afirme () genera errores detallados destinados a ser detectados por las herramientas de control de calidad?
Ambos assertgeneran requireuna 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 requirerevierte el gas usado, assertno 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.