0

I have to run node.js to execute smart contracts. My quetsion is about the keys.

I have seen this from the docs -

1. Code to sign
2. Code to execute

But I am unsure how the two are combined. Could someone clarify this?

I have a deployed contract which has this function -



 function addBonus( string bonusType, uint bonusTarget,  uint bonusEndYear,
        uint bonusEndMonth, uint bonusEndDay, 
        string bonusToken, uint bonusAmount, string bonusName, uint ineq ) public {
// processing
}

From the docs -

var Tx = require('ethereumjs-tx'); 
var privateKey = new Buffer('e331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', 'hex') 
var rawTx = {  
nonce: '0x00',  
gasPrice: '0x09184e72a000',   
gasLimit: '0x2710',  
to: '0x0000000000000000000000000000000000000000', 
value: '0x00',   
data: '0x7f7465737432000000000000000000000000000000000000000000000000000000600057' } 
var tx = new Tx(rawTx); 
tx.sign(privateKey); 
var serializedTx = tx.serialize();  
web3.eth.sendRawTransaction('0x' + serializedTx.toString('hex'), function(err, hash) {  
if (!err)    
console.log(hash); // "0x7f9fade1c0d57a7af66ab4ead79fade1c0d57a7af66ab4ead7c2c2eb7b11a91385" });

And this -

// contract abi
var abi = [{
    name: 'myConstantMethod',
    type: 'function',
    constant: true,
    inputs: [{ name: 'a', type: 'string' }],
    outputs: [{name: 'd', type: 'string' }]
}, {
    name: 'myStateChangingMethod',
    type: 'function',
    constant: false,
    inputs: [{ name: 'a', type: 'string' }, { name: 'b', type: 'int' }],
    outputs: []
}, {
    name: 'myEvent',
    type: 'event',
    inputs: [{name: 'a', type: 'int', indexed: true},{name: 'b', type: 'bool', indexed: false}]
}];
// creation of contract object
var MyContract = web3.eth.contract(abi);
// initiate contract for an address
var myContractInstance = MyContract.at('0xc4abd0339eb8d57087278718986382264244252f');
// call constant function
var result = myContractInstance.myConstantMethod('myParam');
console.log(result) // '0x25434534534'
// send a transaction to a function
myContractInstance.myStateChangingMethod('someParam1', 23, {value: 200, gas: 2000});
// short hand style
web3.eth.contract(abi).at(address).myAwesomeMethod(...);
// create filter
var filter = myContractInstance.myEvent({a: 5}, function (error, result) {
 if (!error)
   console.log(result);
   /*
   {
       address: '0x8718986382264244252fc4abd0339eb8d5708727',
       topics: "0x12345678901234567890123456789012", "0x0000000000000000000000000000000000000000000000000000000000000005",
       data: "0x0000000000000000000000000000000000000000000000000000000000000001",
       ...
   }
   */
});

I assume we have to combine these two expressed ideas somehow. I cannot see any private keys in the second example and the first one has no example of running a contract.

6
  • Your question is a little confusing, I'm not sure exactly what you're asking. The snippet you posted which involved a private key made a transaction to create a contract, whereas the second snippet made a transaction to call a function on the contract. Your second snippet also used web3, which has built-in account management. When you called .myStateChangingMethod, you would typically need to include a from address in that last object. web3 inferred that you probably wanted to use the first address in the keystore, and automatically fetched its private key for signing the transaction.
    – ohsully
    Commented Oct 17, 2018 at 21:12
  • I am unsure how to use web3 without metamask. You state it has its own approval but that is when using metamask for example. To use web3 we need to somehow sign txns, or provide the private keys. That is what I am asking. Commented Oct 18, 2018 at 8:52
  • Check out the web3 documentation for web.eth.accounts. All that Metamask does is associate a wallet file with your Google account (IIRC). If you already have a wallet with your address & keys, then you can load the wallet and it'll have those keys stored. You can also call wallet.create and it'll create a new wallet in memory which you can then save. Web3 handles getting the keys and signing, you just need to tell it where the keys are -- MetaMask has done that for you in the past.
    – ohsully
    Commented Oct 18, 2018 at 17:14
  • I solved it now. I will post later. It is much more complex than checking out web3 docs. Commented Oct 18, 2018 at 17:35
  • Wish I could've understood your issue better and helped you more, but glad to hear you got it worked out!
    – ohsully
    Commented Oct 18, 2018 at 18:10

3 Answers 3

0
   var infuraApiKey =process.env.INFURA_API_KEY;
  // var privateKey = process.env.PRIVATE_KEY;

   var web3js = new web3(new web3.providers.HttpProvider("https://kovan.infura.io/v3/"+infuraApiKey));

   web3js.eth.defaultAccount = myAddress;
   var privateKey=new Buffer(process.env.PRIVATE_KEY, 'hex');

//   var toAddress = 'ADRESS_TO_SEND_TRANSACTION';

   //contract abi is the array that you can get from the ethereum wallet or etherscan
   var contractABI =bonusABI;
   var contractAddress =bonusAddress;
   //creating contract object
   var contract =  web3js.eth.contract(contractABI).at(contractAddress);
   var count;
   var nounce;
   var errcode="";
   web3js.eth.getTransactionCount(myAddress, function(err, result) {
        nounce=result;
        var nounceHex = web3js.toHex(nounce);

        var rawTransaction = {"from":myAddress,
        "gasPrice":web3js.toHex(2*1e9),
        "gasLimit":web3js.toHex(920000),
        "to":contractAddress,
        "data":contract.addBonus.getData(bonusType, target, year, month, day, token, bonus, bonusName, ineq),
        "nonce":nounceHex}

        var transaction = new Tx(rawTransaction);
        transaction.sign(privateKey);

        var serializedTx = transaction.serialize();
        web3js.eth.sendRawTransaction('0x'+serializedTx.toString('hex'), function(err1, hash) {
           if (!err1) {
               errcode=hash;
          }
           else
               errcode=err1;
        });
  })
0

you can either add it to your .env file if you are only using one account to transfer funds from, or you can store encrypted form of it in a database https://www.npmjs.com/package/bcrypt.

0

There is a better and simple way to sign and execute the smart contract function. Here your function is addBonus.

First of all we'll create the smart contract instance:

 const createInstance = () => {
  const bscProvider = new Web3(
    new Web3.providers.HttpProvider(config.get('bscRpcURL')),
  );
  const web3BSC = new Web3(bscProvider);
  const transactionContractInstance = new web3BSC.eth.Contract(
    transactionSmartContractABI,
    transactionSmartContractAddress,
  );
  return { web3BSC, transactionContractInstance };
};

Now we'll create a new function to sign and execute out addBonus Function

   const updateSmartContract = async (//parameters you need) => {
     try {
    const contractInstance = createInstance();
// need to calculate gas fees for the addBonus
    const gasFees =
      await contractInstance.transactionContractInstance.methods
        .addBonus(
         // all the parameters
        )
        .estimateGas({ from: publicAddress_of_your_desired_wallet });
   const tx = {
      // this is the address responsible for this transaction
      from: chainpalsPlatformAddress,
      // target address, this could be a smart contract address
      to: transactionSmartContractAddress,
      // gas fees for the transaction
      gas: gasFees,
      // this encodes the ABI of the method and the arguments
      data: await contractInstance.transactionContractInstance.methods
        .addBonus(
       // all the parameters
        )
        .encodeABI(),
    };
  // sign the transaction with a private key. It'll return messageHash, v, r, s, rawTransaction, transactionHash
    const signPromise =
       await contractInstance.web3BSC.eth.accounts.signTransaction(
        tx,
        config.get('WALLET_PRIVATE_KEY'),
      );
    // the rawTransaction here is already serialized so you don't need to serialize it again
    // Send the signed txn
    const sendTxn =
      await contractInstance.web3BSC.eth.sendSignedTransaction(
        signPromise.rawTransaction,
      );
    return Promise.resolve(sendTxn);
} catch(error) {
  throw error;
}
    }

Happy coding :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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