0

I am trying to run truffle code with Node.JS in the backend to deploy contracts. I want to be able to do this interactively and I am intending to use the Express Library to interact with the Node backend.

However, in the first instance I am just trying to run a .js in node to deploy a contract. I can do so easily in the deploy script but want to be able to do it on the fly. Here is the code I am talking about:

const Web3 = require("web3");
const HDWalletProvider = require("truffle-hdwallet-provider");
const mnemonic = "..."

var httpProvider = new Web3.providers.HttpProvider('https://ropsten.infura.io/v3/<my API>');
var provider = new HDWalletProvider(mnemonic, httpProvider);

var contract        = require("truffle-contract");
var myContractJSON  = require('./build/contracts/Insurer.json');

// Read JSON and attach RPC connection (Provider)
var myContract = contract(myContractJSON);
myContract.setProvider(provider);

myContract.new("0x20202020202020202020204931303031", "0x20202020202020202020436f66616365")
    .then(function(instance) {
    return instance.getInsurerInfo.call()
    }).then(function(result) {
        console.log(result[0], result[1]);
        res.send('Insurer contract made successfully: '+result[0]+' '+result[1]);
        }, function(error) {
    console.log(error);
    });

and here is the relevant contract code:

    contract Insurer {
    bytes16 public insurerUIC;  
    bytes16 public insurerName;

    constructor(bytes16 _insurerUIC, bytes16 _insurerName) public {
        insurerUIC      = _insurerUIC;
        insurerName     = _insurerName;
        } // constructor(bytes16 _insurerUIC, bytes16 _insurerName) public {

    function () payable external {
        // fallback function to receive funds
    } // function () payable external {

    function getInsurerInfo() view public returns (bytes16, bytes16) {
        return (insurerUIC, insurerName);
        } // function getInsurerInfo() view public returns (bytes16, bytes16)

    } // contract Insurer {

The contract takes 2 parameters. When I run the code above it seems to run but nothing actually happens.

Any idea what is wrong? Also how can I debug Node code without being able to use the console?

Sorry for beginner questions but I am struggling!

Thanks,

Phil

1

There are two issues with your code. The first one is preventing the contract to be deployed: you must pass the "from" address whenever you send a transaction to the blockchain (as opposed to a call). So, the instantiation should look like this:

myContract.new("0x20...31", "0x20...65", { from: provider.getAddress() })

The other issue is that you are not listening to the first response you'll get, which is the txHash. That response will come much earlier than the contract's instance. So, even after you add the "from" address, it will still look like nothing is happening because you're waiting for the deploy to be mined.

In order for you to get this first response, you should add the following:

.once('transactionHash', function(hash) {
    console.log("TxHash: " + hash);
})

That should happen pretty fast, and then you can wait another 30 seconds or so to get the result you expect.

The final code is:

const Web3 = require('web3');
const HDWalletProvider = require("@truffle/hdwallet-provider");

require('dotenv').config();
const provider = new HDWalletProvider(process.env.PRIVATE_KEY, process.env.INFURA_URL);

const contract = require('@truffle/contract');
const artifacts = require('./../contracts/Insurer.json');

var myContract = contract(artifacts);
myContract.setProvider(provider);

myContract.new("0x20202020202020202020204931303031", "0x20202020202020202020436f66616365", { from:provider.getAddress() })
        .once('transactionHash', function(hash) {
            console.log("TxHash: " + hash);
        }).then(function(instance) {
            return instance.getInsurerInfo.call()
        }).then(function(result) {
            console.log(result[0], result[1]);
        }, function(error) {
            console.log(error);
        });

Note that I'm using a private key instead of a mnemonic to setup the HDWallet provider, but that should make no difference. Also, I'm using the updated versions of @truffle/hdwallet-provider and @truffle/contract, but I do think that's irrelevant too.

Also how can I debug Node code without being able to use the console?

Try nodemon. That's what I'm using, it prints just fine.

Hope it helps.

| improve this answer | |
  • Thanks Daniel. I implemented what you suggested, and it does work when I install @truffle/contracts and @truffle/hdwallet-provider (it is necessary). Also your code was missing require('dotenv').config(); I do deploy the contract and the getInsurerInfo returns the values correctly, however it seems to hang. I get Start to deploy new contract TxHash: 0x76b31da1ddf04b3b9b5f6409717e91bddc5fcc942d387738fa5e781c9f0a2579 0x20202020202020202020204931303031 0x20202020202020202020436f66616365 but then nothing. The gas was paid, so that I believe it is deployed properly. Any idea why it hangs? – Philip Rutovitz Jan 27 at 15:00
  • You're welcome. You're right about the dotenv, it's required and I was importing it in another file. Ok, actually I don't think it's hanging. The contract has been deployed successfully and this output you posted proves so because what the code is doing there is calling the function getInsurerInfo from the deployed contract. That function should return exactly what you posted. So, yeah, success! :) It's deployed properly. – Daniel Portugal Jan 27 at 16:51
  • As a side note: you can get the receipt for your deploy by adding this to your promise chain: .on('receipt', function(receipt) { console.log("receipt: " + JSON.stringify(receipt)); }) – Daniel Portugal Jan 27 at 17:07
  • Ok, fair enough. However, I still would like to understand why it does not return me to a prompt. When you run it, does it bring you back to the command prompt? – Philip Rutovitz Jan 27 at 17:07
  • 1
    Just after the .once('transactionHash', function(hash) { console.log("TxHash: " + hash); }) Should be something like .once('transactionHash', function(hash) { console.log("TxHash: " + hash); }).on('receipt', function(receipt) { console.log("receipt: " + JSON.stringify(receipt)); }).then(function(instance) { return instance.getInsurerInfo.call() }) and so on – Daniel Portugal Jan 27 at 17:21

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.