0

Even though this is related to Ethereum, it's actually a JavaScript question.

My goal is to have a function to deploy an Ethereum contract which returns its address once the contract is deployed (sidenote: I'm not interested in deploying it with Mist or other options).

function deploy(contractName, accountOwner, _gas) {
    // Get the contract code from contracts
    const input = fs.readFileSync('contracts/' + contractName + '.sol').toString();
    const output = solc.compile(input);
    // The trailing ':' is needed otherwise it crashes
    const bytecode = output.contracts[':' + contractName].bytecode;
    const abi = JSON.parse(output.contracts[':' + contractName].interface);
    const contract = web3.eth.contract(abi);
    const contractInstance = contract.new({
        data: '0x' + bytecode,
        from: accountOwner,
        gas: _gas
    }, sendContract(err, res));
    contractInstance.then(console.log(contractInstance), console.log("Failure"));
}

function sendContract(err, res) {
    return new Promise((resolve, reject) => {
        if (err) {
            console.log(err);
            return reject(err);
        } else {
            console.log("Transaction Hash: " + res.transactionHash);
            // If we have an address property, the contract was deployed
            if (res.address) {
                console.log('Contract address: ' + res.address);
            resolve(res);
            }
        }
    })
}

This isn't working because it returns ReferenceError: err is not defined. I know it's related to the promise but I am not sure how to fix it, even though I have tried different things. Could someone please point me to the error?

I know there are many questions like this here but I (1) have read them as well as promises explanations (this one and this one, among others) and (2) am really stuck and would really appreciate some help.

mcansado
  • 2,026
  • 4
  • 25
  • 39
  • 3
    well, you are passing the result of calling `sendContract(err, res)` as the second argument to `contract.new` ... perhaps that was simply meant to be `sendContract` without the `(err, res)`? – Jaromanda X Jul 28 '17 at 08:44
  • Same problem with the `console.log`s. – Ry- Jul 28 '17 at 08:46
  • See also https://stackoverflow.com/questions/22539815/arent-promises-just-callbacks – Ry- Jul 28 '17 at 08:50
  • The OP is trying to promisify `contract.new()`, and the `sendContract(err, res)` issue is only one aspect of the required fix. I have voted to reopen. – Roamer-1888 Jul 28 '17 at 11:24

1 Answers1

0

This isn't working because it returns ReferenceError: err is not defined.

You define err as an argument to this function:

function sendContract(err, res)

As with all arguments, it is a locally scoped variable to that function.

You attempt to use that variable here:

 }, sendContract(err, res));

So you attempt to call sendContract passing a variable named err from outside the function into the local variable of the same name inside that function.

Since you haven't defined err outside the function, you get a reference error.

You have the same problem with res but you don't see it because the err version triggers first.


I know it's related to the promise

It isn't.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • Thanks for the reply. So should I replace `sendContract(err, res)` by `sendContract` only? I've tried that but then I got an error `TypeError: contractInstance.then is not a function`. If not, could you please show me what change would be required for it to work? – mcansado Jul 28 '17 at 09:05
  • It looks like passing a promise into `contract.new` doesn't make it return a promise. – Quentin Jul 28 '17 at 09:07
  • Probably you should [read this](https://stackoverflow.com/questions/22519784/how-do-i-convert-an-existing-callback-api-to-promises). – Quentin Jul 28 '17 at 09:07