1

I want to implement my own wallet on the client side instead of using metamask extension. if I understand it correctly, the method of using my own wallet is to use the private key of the generated account to sign any transactions client-side, and then relay them to a public node for execution.

The code below is the to sign the transaction offline.

  sendSigned(txData,wallet_privatekey, cb) {
      var web3 = this.web3;
      const tx = new Tx(txData);
      var _pk = wallet_privatekey.slice(2);
      var privateKey = new Buffer(_pk, 'hex');
      tx.sign(privateKey);
      const serializedTx = tx.serialize();
      web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex'), cb);
  }

  sendData(fromAddress,toAddress,wallet_privatekey) {
    var web3 = this.web3;
    var self = this;
    web3.eth.getTransactionCount(fromAddress).then(txCount => {
        console.log("nonce:" + txCount);
        const txData = {
            nonce: web3.utils.toHex(txCount),
            gasPrice: web3.utils.toHex(web3.utils.toWei('0.00000009', 'ether')),
            gasLimit: web3.utils.toHex(30000),
            to: toAddress,
            value: web3.utils.numberToHex(web3.utils.toWei('0.0001', 'ether')),
            data: web3.utils.asciiToHex('hello'),
            //chainId: 1
        }
        self.sendSigned(txData,wallet_privatekey, function (err, result) {
            if (err) return
            console.log('error', err)
            console.log('sent', result)
        })
    })
  }

however I still don't know how to sign each action on the contract, for example, I have a exampler contract below

contract LocalExample {
address public owner;
    function setOwner(address _newOwner)  external {
        owner = _newOwner;
    }
}

on the client, the code for execution the setOwner method is as below

 contract.methods.setOwner(owner_address)
                            .send({from: account,value:value,gas:210000,gasPrice:5000000000 })
                            .on('transactionHash', function(hash){
                               console.log('hash',hash);
                            })
                            .on('receipt', function(receipt){
                               console.log('receipt',receipt);
                            }) 

using the client code for execution will only trigger the metamask, so my final question is how to combine the client code with creating a raw transaction in order to use the local wallet?

1

You can use web3js to generate the data-value. Then you can sign the transaction manually with your private-key and send it to the blockchain via web3.eth.sendSignedTransaction.

const EthCrypto = require('eth-crypto');
const txDataField = contractInstance.setOwner(YourOwnerAddress).encodeABI();

// create+sign the transaction
const rawTx = {
    from: signerAddress,
    to: contractAddress,
    nonce: 0,
    gasLimit: 5000000,
    gasPrice: 5000000000,
    data: txDataField
};
const serializedRecieveTx = EthCrypto.signTransaction(
    rawTx,
    signerPrivateKey
);

// submit the tx
const receipt = await web3.eth.sendSignedTransaction(serializedRecieveTx);

Actually I made a tutorial on how to send data-txs to the chain

1

The data value in your transaction object is wrong. If you want to execute a contract's function you should use something like this:

var address = '0x...';
var data = web3.sha3("setOwner(address)").substr(0,10); //Function
data += web3.sha3(address).substr(0,32); //Attribute (if value starts with '0x' then use 'substr(2,32)'

Read Interacting with smart contracts for more info.

To sign a transaction (offline) you'd use Accounts signTransaction:

var tx = web3.eth.accounts.signTransaction(txData, privateKey);

To send the tx (online) use sendSignedTransaction:

web3.eth.sendSignedTransaction(tx.rawTransaction);

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.