Image for post
Image for post

Inside an Ethereum transaction

Feb 15, 2017 · 4 min read

Ethereum can be thought of as a transaction based state machine, where transactions can change the state and the state keeps track of interactions. Here we examine at a high level, the constituents of a transaction and explain how most of the gibberish hex values are determined.

We will be using nodejs in this tutorial so we start off by installing the dependencies.

$ npm install web3@0.19 ethereumjs-util@4.4 ethereumjs-tx@1.3

Then creating a file tx.js and requiring the dependencies.

var Web3 = require('web3');
var web3 = new Web3(new Web3.providers.HttpProvider(''));
var util = require('ethereumjs-util');
var tx = require('ethereumjs-tx');

First we start with a private key. Ethereum uses public key cryptography for authentication. More specifically, Elliptic Curve Digital Signature Algorithm (ECDSA) with secp256k1’s curve is used. The private key is just a random 256 bit data except for some restrictions. For example

var privateKey = '0xc0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0de';

To derive the corresponding public key

var publicKey = util.bufferToHex(util.privateToPublic(privateKey));

and you should get the following if you print out publicKey


The Ethereum address associated with this private key is the last 160 bit of the SHA3–256 (Keccak) hash of the public key.

var address = '0x' + util.bufferToHex(util.sha3(publicKey)).slice(26);
Image for post
Image for post

As you can observe, it is actually possible for multiple private keys to have the same address. An Ethereum account is associated with each address and each have the following attributes

nonce the count of the number of outgoing transactions, starting with 0
balance the amount of ether in the account
storageRoot the hash associated with the storage of the account
codeHash the hash of the code governing the account, if this is empty then the account is a normal account that can be accessed with its private key else it is a smart contract whose interactions are governed by its code

Next we take a look at a transaction, there are 6 input fields

nonce the count of the number of outgoing transactions, starting with 0
gasPrice the price to determine the amount of ether the transaction will cost
gasLimit the maximum gas that is allowed to be spent to process the transaction
to the account the transaction is sent to, if empty, the transaction will create a contract
value the amount of ether to send
data could be an arbitrary message or function call to a contract or code to create a contract

A transaction to send 1000 wei (1 ether = 10¹⁸ wei) of ether and leaving a 0xc0de message can be constructed as follows

var rawTx = {
nonce: web3.toHex(0),
gasPrice: web3.toHex(20000000000),
gasLimit: web3.toHex(100000),
to: '0x687422eEA2cB73B5d3e242bA5456b782919AFc85',
value: web3.toHex(1000),
data: '0xc0de'

Notice that the from address is not specified, it will be derived from the signature after signing with the private key. To sign the transaction

var p = new Buffer('c0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0de', 'hex');
var transaction = new tx(rawTx);

The transaction can then be sent to the network and will be tracked by a 256 bit transaction id. This transaction can be viewed at Etherscan. The transaction id is the hash of the transaction

Image for post
Image for post

Next we look at what makes up the data for a function call. Take for example the data of this transaction to a contract


In order to know which function it is calling, the functions of the contract must be known beforehand to create a hash table. The first 32 bit a9059cbb is the first 32 bit of the hash of the function. In this case the function is transfer(address _to, uint256 _value) and its hash is


This is followed by 256 bit for each argument, so in this case the address is


and the unsigned integer is

Image for post
Image for post

Next, as discussed above, by omitting the to field, a contract will be created. But how is the contract’s address determined? Take for example this transaction


The contract address is the last 160 bit hash of the sender address and its nonce can be determined beforehand. For this transaction, the sender and nonce can be found by

var contractTx = web3.eth.getTransaction('0x77a4f46ff7bf8c084c34293fd654c60e107df42c5bcd2666f75c0b47a9352be5');

Thus the contract address is

console.log('0x' + util.bufferToHex(util.rlphash(['0x84f9d8b0e74a7060e20b025c1ea63c2b171bae6f', 0])).slice(26));
Image for post
Image for post

Now we have gotten to know a little bit more about these hexadecimals!

Ethereum and smart contracts have huge potential to disrupt many industries. There are many resources online and you can find a few below to continue your journey on exploring Ethereum!

Ethereum main site
Mist, one of Ethereum’s client
Web3 api
Community discussions

If you have any issues regarding this article, you can raise it at our Github under the nightlyHacks repo.

Follow us on Twitter and Medium for more updates!

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store