Advertencia de remezcla: no se especificó visibilidad, violar el patrón de controles-efectos-interacción, la mutabilidad del estado de la función se puede restringir a puro: ¿se puede ignorar?

Hace dos meses, escribí un contrato inteligente con Remix.ethereum.org. La línea 1 de mi código tiene:

pragma solidity ^0.4.11;

Compiló bien sin errores ni advertencias. Probé cada función en Ropsten y funcionó bien.

Ahora, estoy cada vez más cerca de implementarlo en la red principal. Veo que Remix ha cambiado. Ahora, dice:

Static Analysis generó 50 advertencias que requieren su atención.

En la pestaña Análisis, hay muchas advertencias que no sé cómo resolver. Un ejemplo es,

Posible violación del patrón de controles-efectos-interacción en TestContract.testFunction(dirección): podría generar una vulnerabilidad de reingreso. Nota: Actualmente, este análisis estático no considera los modificadores.

Otro ejemplo es,

Requisito de gas de la función browser/TestContract 8.sol:MintableToken.transferFrom(address,address,uint256) desconocido o no constante. Si el requisito de gas de una función es superior al límite de gas del bloque, no se puede ejecutar. Evite bucles en sus funciones o acciones que modifiquen grandes áreas de almacenamiento (esto incluye borrar o copiar arreglos en almacenamiento)

Otro ejemplo es,

Función alternativa del navegador de contratos/TestContract 8.sol: la prueba requiere demasiada gasolina (nula). Si la función de reserva requiere más de 2300 de gas, el contrato no puede recibir Ether.

Otro ejemplo es,

Test.transferFrom(address,address,uint256): Potencialmente debería ser constante pero no lo es. Nota: Actualmente, este análisis estático no considera los modificadores.

Hay múltiples ocurrencias de cada uno de los ejemplos anteriores. ¿Puedo ignorar todas estas advertencias? Si no, ¿cómo los resuelvo?

En Configuración, estaba usando Solidity versión 0.4.11. Si cambio esto a 0.4.17, también recibo docenas de advertencias en la pestaña Compilar. Un ejemplo es,

browser/TestContract 8.sol:15:3 Advertencia: No se especificó visibilidad. Predeterminado a "público":

registro de función (clave de cadena) {

^

Abarcando varias líneas.

Puedo agregar "público" después del paréntesis de cierre para los parámetros en cada una de las funciones para resolver las advertencias anteriores, pero no estoy seguro de si eso es lo correcto.

Otro ejemplo de advertencia es,

browser/TestContract 8.sol:100:3 Advertencia: la mutabilidad del estado de la función se puede restringir a puro

function mil(uint256 a, uint256 b) rendimientos constantes internos (uint256) {

^

Abarcando varias líneas.

No tengo idea de cómo resolver la advertencia anterior.

¿Estoy en lo correcto al suponer que puedo ignorar 0.4.17 y volver a 0.4.11?

0.4.11 hasta 0.4.16 no mostrarán estas advertencias en la pestaña Compilador. ¿Debo usar 0.4.16?

Mi código se puede ver aquí

Respuestas (2)

En general

Puede dejar que se ejecute el código, ignorando las advertencias del compilador, pero siempre es bueno no hacerlo. La mayoría de las veces, las advertencias del compilador le advierten sobre algo que puede causar un error en su código. En comparación con los errores del compilador, la diferencia es que su código es sintácticamente correcto, por lo tanto, puede compilarse, pero puede generar problemas, especialmente cuando alguien intenta hacer algo que no espera que hagan los demás.

Las advertencias del compilador indican cosas que pueden causar problemas o pueden tener efectos no deseados que el programador no conocía.

Puede encontrar una buena lectura sobre esto aquí , y también puede consultar esta pregunta . Y lo más importante, lea las consideraciones de seguridad de los documentos de Solidity. ¡Eso puede salvar tu vida!

De todos modos, el compilador no es tan inteligente como usted y reclama lo que le falta en declaraciones de Note:la siguiente manera:

Nota: Actualmente, este análisis estático no considera los modificadores.

A veces, estas notas pueden indicar las ocasiones en que puede ignorar estas advertencias con seguridad.


Ejemplo

Una advertencia de error que ha mencionado es:

browser/TestContract 8.sol:15:3 Advertencia: No se especificó visibilidad. Predeterminado a "público":

Digamos que tienes function A(uint val) {}. Desea que se use solo dentro del contrato debido a algunas validaciones previas que debe hacer (Esto es solo un ejemplo;)). Y si la función se llama sin validación, eso puede causar algunas ejecuciones no deseadas. Y el único uso de function Aes usarlo dentro de algunas otras funciones dentro del contrato.

pragma solidity ^0.4.0;

contract Example {


    function A(uint val) {
       //do something with val 
    }

    function B(uint val){
        //validation of val
        A(val);
    }

}

Ahora, si mantiene el contrato como el anterior, ya function A()que también está configurado como público de forma predeterminada, cualquier persona que use su contrato puede usarlo function Acon cualquier uintvalor y eso puede causar problemas. Pero si tenía el modificador de acceso function Adeclarado como private, este problema no aparecerá ya function Aque no se puede acceder públicamente. Y como su requisito también es usar function Asolo dentro de las otras funciones dentro del contrato, también se logra su objetivo.

Como cuando no se declara ningún modificador de acceso, el compilador asume que una función es pública y le advierte que está configurando la función para que sea pública y le pide que verifique si realmente debería ser pública. En el caso anterior, recibirá advertencias con respecto a las funciones y la configuración function Apara que sea privado y function Bpúblico eliminará las advertencias porque ahora el compilador sabe que está haciendo function Bpúblico y function Aprivado intencionalmente.

pragma solidity ^0.4.0;

contract Example {


    function A(uint val) private {
       //do something with val 
    }

    function B(uint val)public {
        //validation of val
        A(val);
    }

}

La advertencia sobre function Bla configuración pública es un tipo de advertencia que puede ignorar con seguridad ya que su intención también es la misma, pero la advertencia sobre function Aes algo que realmente debe considerar.


lo que sugiero ,

  • no ignorar la advertencia, sino revisarlas y verificar si realmente importan, cómo espera que se comporte el código e intentar resolverlas.

  • intente usar la última versión del compilador (atm 0.4.17), ya que las versiones estables más nuevas tienden a tener menos errores y más funciones (por lo tanto, genera nuevas advertencias).


Información sobre otras advertencias que recibe

browser/TestContract 8.sol:100:3 Advertencia: la mutabilidad del estado de la función se puede restringir a puro

Puede consultar esta respuesta y esta pregunta con respecto a la introducción viewy el puretipo de funciones.

Violación potencial del patrón de controles-efectos-interacción en TestContract.testFunction (dirección):

Esto es por no seguir el patrón de Comprobaciones-Efectos-Interacciones como se describe aquí en los documentos. Consulte la función que recibe esta advertencia y siga el patrón definido en los documentos para evitar la advertencia.

Y según el código que se encuentra en el enlace que publicó, creo que la closeSale()advertencia probablemente debería deberse a que el compilador asume que puede haber una posibilidad de reingreso , ya que está llamando al evento miembro LogSaleClosed(uint256 issuedSupply, uint256 restrictedTokens)después de las interacciones con el contrato de token.

Lo que puedo sugerir es tener ese evento dentro del contrato token. Puede ver aquí la vulnerabilidad de reingreso. Solo dice que si el código incorrecto allí permite que otro contrato retire dinero varias veces porque cambian las acciones de la variable de estado después de enviar la transacción, lo que puede llevar algún tiempo dejando que el otro contrato llame a la misma función varias veces porque mantiene el msg.sendervalor distinto de cero hasta la transacción se ejecuta. Si ve el código bueno allí, primero se establece shares[msg.sender]en cero primero. Dado que usted es quien desarrolló esto, conoce el flujo de eventos esperados y puede estar seguro de que no ocurrirá una nueva entrada, es seguro ignorarlo.

Test.transferFrom(address,address,uint256): Potencialmente debería ser constante pero no lo es. Nota: Actualmente, este análisis estático no considera los modificadores.

Lo que significa constante es que no estaría cambiando el estado. Esa no es una variable de estado cambiada. Entonces, normalmente, esas funciones se denominan funciones constantes y se definen con la palabra clave de constante. Puedes leer esto .

Entonces, si sus funciones no cambian ninguna variable de estado, puede declararlas constantes. La solidez te está recordando esto.

Tengo "contrato Contract1 es Contract2". Si las funciones de Contract1 llaman a funciones de Contract2, pero no se llaman desde otros contratos o transacciones, ¿las funciones de Contract2 deben ser "internas" o "privadas"? ¿Qué pasa con las otras advertencias como "Violación potencial de comprobaciones-Efectos-Interacción..." o "Requisito de funcionamiento de gas..."? ¿Cómo los resuelvo? Con esta advertencia: “[función]: Potencialmente debería ser constante pero no lo es”, la función es transferir tokens. No veo cómo esto puede ser una constante. ¿Cómo resuelvo esta advertencia? FYI, agregué un enlace a mi código en mi publicación original.
Gracias por su respuesta. Remix solía proporcionar el código de interfaz ABI/JSON. Ahora, no lo veo. ¿Cómo conseguimos esto?
sí, tiene que ser un control interno aquí .
Actualicé la respuesta con respecto checks-effects-interactional final de la respuesta .
¡Gracias por tu ayuda! Me estoy acercando. Resolví la advertencia Checks-Effects-Interaction para 2 de las 3 funciones. No puedo para la función TestSale.closeSale. Consulte el código en gist.github.com/anonymous/3497e6b4e09953a009a4fdbacd11946a . No creo que esto se pueda resolver. ¿Qué piensas? También recibo la advertencia "Potencialmente debería ser constante pero no lo es" en 3 funciones: TestToken.transfer, TestToken.transferFrom y TestSale.selfDestruct. ¿Sabes cómo resolver?
También da advertencias para variables con nombres similares, pero creo que ignoraré estas advertencias. Tengo 28 advertencias de "Requerimiento de gas de la función _____ desconocido o no constante. Si el requerimiento de gas de una función es superior al límite de gas del bloque, no se puede ejecutar. Evite bucles en sus funciones o acciones que modifiquen grandes áreas de almacenamiento (esto incluye borrar o copiar arreglos en el almacenamiento)" ¿Cómo resuelvo estas advertencias?

browser/TestContract 8.sol:100:3 Advertencia: la mutabilidad del estado de la función se puede restringir a puro

Respuesta: Las funciones se pueden declarar puras, en cuyo caso prometen no leer ni modificar el estado.

. http://solidity.readthedocs.io/en/develop/contracts.html#pure-functions