No puedo deshacerme del error "Error de referencia no detectado: web3js no está definido"

He estado tratando de deshacerme de este error, pero no importa cuánto lo intente, simplemente no puedo resolverlo. Terminé los tutoriales de cryptoZombies, y todo lo que sé sobre web3 lo obtuve de allí. Creé la aplicación más simple posible para mostrar el error que recibo. Este es mi contrato, desplegado en Ropsten:

pragma solidity ^0.4.24;

contract SimpleRegister {
   string name;

   function setName(string _name) external {
      name = _name;
   }

   function getName() external view returns (string) {
      return (name);
   }
}

Mi interfaz es la siguiente:

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <meta http-equiv="X-UA-Compatible" content="ie=edge">
   <title>Document</title>

   <script src="./web3.min.js"></script>
   <script language="javascript" type="text/javascript" src="abi.js"></script>
</head>
<body>
   <div class="container">
   <h1>Simple Register</h1>
   <h2 id="display"></h2>     
   <button type="submit" onclick="getName();return false;">Get Name</button>
</div>

<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>

<script>
    window.addEventListener('load', function() {  
        if (typeof web3 !== 'undefined') {     
            web3js = new Web3(web3.currentProvider); 
        } 
        else {
            this.alert("Install Metamask.");         
        }
        startApp();
    });

    function startApp() {
        var contractAddress = "0x715e99e73deefdb06f9d1e55172cbc52307eda5b";   
        simpleRegister = new web3js.eth.Contract(contractABI, contractAddress);
    }

    function _getName() {
        return simpleRegister.methods.getName().call();
    }

    function getName() {           
        _getName().then(function(result) {
            $("#display").html(result[0]);
            console.log(result);
        });
    }
</script>
</body>
</html>

¿Alguien tiene una idea de lo que está pasando y cómo solucionarlo? Gracias.

Respuestas (3)

No puede simplemente abrir el archivo html y hacer que MetaMask inyecte su instancia web3.

De la documentación de MetaMask :

Debido a las restricciones de seguridad del navegador, no podemos comunicarnos con dapps que se ejecutan en file://. Utilice un servidor local para el desarrollo.

La forma más fácil de evitar esto es usar SimpleHTTPServer de Python desde el directorio raíz del proyecto:

python3 -m http.server

Luego puede visitar http://localhost:8000 en el navegador web con la extensión MetaMask instalada.

Según su código, hay un pequeño error en su código.

<script>
    window.addEventListener('load', function() {  
        if (typeof web3 !== 'undefined') {     
            web3js = new Web3(web3.currentProvider); 
        } 
        else {
            this.alert("Install Metamask.");  
            return;
        }
        startApp();
    });

    function startApp() {
        var contractAddress = "0x715e99e73deefdb06f9d1e55172cbc52307eda5b";   
        simpleRegister = new web3js.eth.Contract(contractABI, contractAddress);
    }

    function _getName() {
        return simpleRegister.methods.getName().call();
    }

    function getName() {           
        _getName().then(function(result) {
            $("#display").html(result[0]);
            console.log(result);
        });
    }
</script>

Si no se encuentra metamask, sigue llamando a web3js startApp(). Según su código, si no se encuentra metamask, entonces web3js no está definido, en web3js no está definido.

Absolutamente, si no hay un web3 inyectado, generalmente recurrirá a una instancia web3 local conectada a un nodo, por ejemplo, Infura. Ver: github.com/MetaMask/faq/blob/master/DEVELOPERS.md

Debe asegurarse de tener el archivo web3.min.js en la misma carpeta que el código HTML que tiene.

Puede descargar una copia desde aquí (nota: estará en la carpeta /dist).

Gracias, pero ya tenía el archivo en la misma carpeta. También lo descargué del enlace que enviaste (tal vez el que usé antes estaba roto), pero no funcionó tan bien.