-
Notifications
You must be signed in to change notification settings - Fork 68
Send Ether Transaction
A script that will sign and broadcast an ethereum transaction to the network, then shows the result in the console.
WARNING! If executed this script will send ether, be sure the info is correct before you run it! Alternatively you should use a test net with test ether first before running this on the main net.
This script is basically amature hour on my part, ethereumjs-tx does have a better way of doing this so if you are a proper developer that's where you want to go. I wrote this up not so much as a teaching opportunity, but more so of an "here's what I did and it seemed to work". It's a learning experience.
For this example we're going to use the script located here.
var Web3 = require('web3');
web3 = new Web3(new Web3.providers.HttpProvider('https://mainnet.infura.io/YOUR-API-TOKEN-HERE'));
WARNING! This is currently set to the main net, to use a test net you'll need to change the URL to a supported test net. Consult your Infura account for that URL and token.
Please read the Basic Required Setup page for this first bit, you'll see it a lot.
var Tx = require('ethereumjs-tx');
Because we are crafting a transaction, we'll need to use an additional node module. Use npm in your project folder and run npm install ethereumjs-tx
.
var privateKey = new Buffer('YOUR-PRIVATE-KEY-HERE', 'hex');
var receivingAddr = ('RECEIVING-ADDRESS-HERE');
WARNING! Hey look a private key! Obviously you really shouldn't make that public, if you do ensure that this script is properly secured otherwise you could be opening yourself up to all sorts of unsavory people.
First we define our private key we will use to sign this transaction. Then we'll define who is going to get this transaction.
var txValue = web3.utils.numberToHex(web3.utils.toWei('0.1', 'ether'));
var txData = web3.utils.asciiToHex('oh hai mark');
Next we're going to define the value of the transaction. In this case we are converting 0.1 Ether to Wei and then turning that number into a hex value, we have to do this to all values we use when we create transactions. the txData
is optional and most normal people just put "0x" which is nothing... but who wants to be normal? For this script I converted the string "oh hai mark" to hex.
Note: Adding extra data may sound like a fun idea but you do pay for it in gas (cost to process your transaction). So while it may seem like fun, if you're not playing with real ether you should just leave this as "0x" unless otherwise needed.
var rawTx = {
nonce: '0x0',
gasPrice: '0x14f46b0400', // 90 GWei
gasLimit: '0x55f0', // 22000 Wei
to: receivingAddr,
value: txValue,
data: txData
}
Now we start to build our transaction. The Nonce is the number of transactions, it should be increased every time you make a transaction. So if you already had one transaction with this address, the nonce on this transaction would be "0x02".
Gas price is the cost of gas you're willing to pay for this transaction. Remember from that note above data costs more? Well that's why we're paying 90 GWei here instead of the average 5 GWei.
Gas limit is the maximum total cost you're willing to pay for this transaction. By default it's usually around 21000 GWei, but because this is just a test and we have some extra data I've kicked it up a notch to 22000 GWei.
Understandably gas price, limit and GWei are pretty confusing. Thankfully there are some resources you can use to better understand this part of Ethereum.
- Gas Price and Network stats: http://ethgasstation.info/
- Ether, Wei, GWei Calculator: https://etherconverter.online/
- Medium blog post explaining all of this: https://hackernoon.com/ether-purchase-power-df40a38c5a2f
Note: On Ethereum you only pay for the gas you used. When I tested this transaction the total cost was 21748 GWei. Fees on ethereum are calculated by gas price times gas used so my transaction here cost 0.00478456 Ether, or about $1.45 USD at current rates. Remember before when I said extra data will cost you? Well there you go, if I sent this transaction on the main network I would have spent $1.45 to say "oh hai mark" in a transaction... Worth it.
We've already defined to
, value
, and data
so I'll skip those. All you need to know is that they are being included in this transaction.
//console.log(rawTx);
I left this in there as it helps to see what the transaction looks like before you send it. It is commented out by default so you need not worry about it. If you want to use it, comment out the code below it.
var tx = new Tx(rawTx);
tx.sign(privateKey);
var serializedTx = tx.serialize();
console.log(serializedTx.toString('hex'));
web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex')).on('receipt', console.log);
The final part of this is rather simple. First we bundle up the rawTx
and then sign it with the private key tx.sign(privateKey)
. Then we serialize it, and log the resulting hex to the console. Then, at last we send the transaction with eth.sendSignedTransaction
and log the receipt which we can use to look it up on Etherscan.io if you so desire.
Now for some reason I had to tack on a "0x" before sending that, I don't know why but it worked. If your fails to send try pasting the hex into Etherscan's transaction broadcasting tool (be sure to select the right network first!), it will tell you more clearly what is wrong with your transaction.
Having a dynamic gas limit, gas price, and nonce would be ideal, and there are web3 functions to support that. Give it a try!