1

Just cannot get what seems like a simple input from html page to interact with a very simple contract to input data.

Started off trying to make this tutorial work: Interacting with a Smart Contract through Web3.js

Have been around the horn with old, current, workaround info on web3 installs. Getting tired and finally have given in and need some help. What am I missing or not seeing?

Contract works in remix by itself but cannot get the web page to interact.

code being used below -

pragma solidity ^0.5.0;

contract Coursetro {

   string fName;
   uint age;

   function setInstructor(string memory _fName, uint _age) public {
       fName = _fName;
       age = _age;
   }

   function getInstructor() public view returns (string memory, uint) {
       return (fName, age);
   }   
}  
<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>
    <link rel="stylesheet" type="text/css" href="main.css">
    <script src="node_modules/web3/dist/web3.min.js"></script>
</head>
<body>
    <div class="container">
        <h1>Course Info Instructor</h1>
        <h2 id="instructor"></h2>
        <label for="name" class="col-lg-2 control-label">Instructor Name</label>
        <input id="name" type="text">
        <label for="name" class="col-lg-2 control-label">Instructor Age</label>
        <input id="age" type="text">
        <button id="button">Update Instructor</button>
    </div>
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
    <script>
       // Our future code here..

    if (typeof web3 !== 'undefined') {
            web3 = new Web3(web3.currentProvider);
        } else {
            // set the provider you want from Web3.providers
            web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
        }
    web3.eth.defaultAccount = web3.eth.accounts[0];
    var CoursetroContract = new web3.eth.Contract(
 [
    {
        "constant": false,
        "inputs": [
            {
                "name": "_fName",
                "type": "string"
            },
            {
                "name": "_age",
                "type": "uint256"
            }
        ],
        "name": "setInstructor",
        "outputs": [],
        "payable": false,
        "stateMutability": "nonpayable",
        "type": "function"
    },
    {
        "constant": true,
        "inputs": [],
        "name": "getInstructor",
        "outputs": [
            {
                "name": "",
                "type": "string"
            },
            {
                "name": "",
                "type": "uint256"
            }
        ],
        "payable": false,
        "stateMutability": "view",
        "type": "function"
    }
], '0xD3a07D67D352AD9543ab46CA07931f2c1F8b1822'
//'0x1e37941619bfb66fa436e345b8ff7bfb4603ac2e'
);
//  var Coursetro = new CoursetroContract.at('0x1e37941619bfb66fa436e345b8ff7bfb4603ac2e');
    console.log
 </script>
</body>
</html>
1

I deployed your contract to rinkeby network and it's working with MetaMask provider https://rinkeby.etherscan.io/address/0x18c1b1da1f3d03e1e2cbd9d28fdf3cc5512cbe65. If you want to use another provider you can head to https://infura.io/.

Here is my working example:

<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>
    <link rel="stylesheet" type="text/css" href="main.css">
    <script src="node_modules/web3/dist/web3.min.js"></script>
</head>
<body>
<div class="container">
    <h1>Course Info Instructor</h1>
    <h2 id="instructor"></h2>
    <label for="name" class="col-lg-2 control-label">Instructor Name</label>
    <input id="name" type="text">
    <label for="name" class="col-lg-2 control-label">Instructor Age</label>
    <input id="age" type="text">
    <button id="button">Update Instructor</button>
</div>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script>
    // Our future code here..

    if (typeof web3 !== 'undefined') {
        web3 = new Web3(web3.currentProvider);
    } else {
        // set the provider you want from Web3.providers
        web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
    }

    var CoursetroContract = new web3.eth.Contract(
        [{"constant":false,"inputs":[{"name":"_fName","type":"string"},{"name":"_age","type":"uint256"}],"name":"setInstructor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getInstructor","outputs":[{"name":"","type":"string"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}], '0x18c1b1da1f3d03e1e2cbd9d28fdf3cc5512cbe65'
    );

    async function initContractLogic() {
        var currentAccounts = await web3.eth.getAccounts();

        $('#button').on('click', function() {
            CoursetroContract.methods.setInstructor($('#name').val().trim(), $('#age').val().trim()).send({from: currentAccounts[0]}).on('transactionHash', function(hash){
                console.log('hash', hash);
            }).on('confirmation', function(confirmationNumber, receipt) {
                updateHtmlData();
            }).catch(function(error) {
                console.log(error, 'error');
            });
        });

        function updateHtmlData() {
            CoursetroContract.methods.getInstructor().call(function(error, result){
                if (error) {
                    console.log(error, 'error')
                } else {
                    console.log(result, 'result');
                    $('#name').val(result[0]);
                    $('#age').val(result[1]);
                }
            });
        }
        updateHtmlData();
    }
    initContractLogic();
</script>
</body>
</html>

Have in mind that if you are using newer version of MetaMask you need to allow your MetaMask to provide accounts data the site where is your dapp located. You can do this manually from MetaMask -> Settings -> Connections or place this at the very top of your code await ethereum.enable();.

| improve this answer | |
  • Thanks Miroslav. Still get: ''''Error: Returned values aren't valid, did it run Out of Gas? You might also see this error if you are not using the correct ABI for the contract you are retrieving data from, requesting data from a block number that does not exist, or querying a node which is not fully synced. at a.decodeParameters (web3.min.js:1) at h.o._decodeMethodReturn (web3.min.js:1) at x.outputFormatter (web3.min.js:1) at x.formatOutput (web3.min.js:1) at u (web3.min.js:1) at web3.min.js:1 at XMLHttpRequest.i.onreadystatechange (web3.min.js:1) "error"'''' – etzz2c Feb 2 at 15:06
  • Ok I need you to tell me on which network is your contract is deployed, what is the contract address and what is your web3 version. – Miroslav Nedelchev Feb 2 at 15:28
  • You hit it on the head. Found that after recompiling I ended up at a different address. Thanks again. Was using this as an example to learn how to integrate the web interface but still do not see the ability to enter/modify data using the "update' button. I can only view it after being added from Remix. – etzz2c Feb 2 at 16:18
  • I am using a ganache local instance and a chrome browser with metamask. not sure how to tell what version of web3 I'm using (there were so many different installs to try and get rid of errors) but believe I'm at 1.0 because of the "new" entries (ex:''''web3 = new Web3(new Web3.providers.HttpProvider("localhost:8545"));'''' – etzz2c Feb 2 at 16:23
  • Yes, in my example you have to change the contract address with yours. Now after changing the address do you still experience some errors and if yes what are they saying? – Miroslav Nedelchev Feb 2 at 16:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.