Ethereum Transaction Structure — Part 2

Santony Choi
Santony’s Blog
Published in
5 min readJul 1, 2018

Series:
Ethereum Transaction Structure— Part 1

We’ve covered RLP, which is a way of encoding data in Ethereum, in the part one. A value encoded in RLP was left at the end of the last part. Let’s look at it again.

0xf87f81c98504a817c80083061a80941234567890123456789012345678901234567890880de0b6b3a764000091d08773616e746f6e7982697384636f6f6c29a0fd3263ef5b7550ec3b9ad789c8ae5930c78f55b2e4ac1984e22bf276cf4ba4e7a0399b9daad024031975346d195043e49e3a3a1ebbec494502978b0aa86a00bae7

Starting with the conclusion, the value above is a signed and RLP encoded plain transaction below with a private key, 0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef .

nonce: ‘0xc9’,
gasPrice: ‘0x4a817c800’,
gasLimit: ‘0x61a80’,
to: ‘0x1234567890123456789012345678901234567890’,
value: ‘0xde0b6b3a7640000’,
data: ‘0xd08773616e746f6e7982697384636f6f6c’,
chainId: 3

We now know about RLP encoding, I will not care about decoding and interpreting the value. I know you can do it by yourself. There are several cool libraries that encode / decode RLP in various languages, but it would be good to do it with your hand at least once.

Let’s get back to today’s topic and see what information does the transaction contain.

nonce

What comes first is nonce. It’s a hexadecimal number that indicates “the order of the transaction being sent among transactions triggered by the account”. Ethereum utilizes this field to prevent malicious actions like Double-spend or to place transaction in a order. Since transaction above is the 201st, the next transaction MUST have nonce of 0xca(202). Otherwise, it will be considered as a wrongful transaction by a client and not going to be included in the chain.

gasPrice & gasLimit

Gas is a way of setting cost and restricting the block size in Ethereum. In a conversation which was hot in May, Vitalik Buterin also mentioned that Gas restricts the size of block. Let’s look into why it does.

Every operations in EVM spends Gas. How much Gas each OPCODE spend is represented in Ethereum Yellowpaper(compared to Whitepaper for the public, it’s more detailed technical specification). While static operations such as ADD, SUB have fixed value, some operations like SSTORE, which stores value in the storage, gets its Gas at runtime. I will cover the Yellowpaper later.

Then, what is Price and what is Limit? Price is simple. In the Yellowpaer, Gas is not written in the unit of Wei. It’s just a constant number. Price is a coefficient of the unit gas consumption. Even if transactions consume the same Gas amount, you will spend 10 times more Wei when you set Price as 10 than when you set it as 1.

Limit is estimated maximum consumption of gas amount for a transaction. The value is set by a user. However, it is recommended to calculate the value using client programs such as Geth, Parity or software libraries of each languages.

What if a transacion exceeds GasLimit or spends less Gas than the limit? The former will fail, spending all the Ether, and the latter will succeeds leaving the Ether unspent.

In conclusion, the maximum Ether(not Gas) that is consumed by a transaction can be represented as, (gasPrice * gasLimit) Wei. The actual consumption is (gasPrice * gas spent actually) Wei.

In our case, gasPrice is 20 Gwei and gasLimit is 400,000. So, the maximum possible consumption will be 8,000,000 Gwei, which equals to 0.008 Ether.

to

It’s a transaction’s destination. It can be an External Account to send a message, or it can be a Contract Account to call a contract function.

value

Transferring Ether value represented in Wei unit. If you want to transfer 1 Ether, put 1x10¹⁸ in decimal representation, i.e., 0xde0b6b3a7640000 in hexadecimal. The transaction above is also transferring 1 Ether.

I have kept using Wei unit in this article. As similar to Satoshi in Bitcoin, it’s the minimum unit representing currency amount in Ehtereum. As Satoshi divides 1 BTC by 100 milions, Wei divides 1 ETH by 10¹⁸. Mwei, which is 10⁶ Wei, and Gwei, 10⁹ wei, are also commonly used. You can try converting the units on the web.

data

Users can put arbitrary data in the transaction. Recently, a student in Peking Univerity sent a transaction with an article encoded in UTF8 to resist government’s censorship. The field the student used to put the article was it, data. The transaction’s to and from fields were same. Other than these special purposed case, data field doesn’t have specific meanings when you send a transaction to an external account.

If you send a transaction to a Contract Account, data field does more significant role. The execution of a contract function. You can put a specially formed — ABI encoded — value in the data field for a recipient contract to decode the data into function name and parameters, and to execute pre-programmed function. ABI encoding will be covered later.

I think that this data field is the thing that separates Ethereum from Bitcoin. There also have been numerous attempts to send messages in Bitcoin. But the core developers in Bitcoin community were negative to this idea, whereas Ethereum developers have actively endorsed creating a protocol supporting it. As a result, Ethereum, blockchain supporting the turing-complete language, protocol has come to the world.

ChainId

The last field is related with a hard fork. You may find out the details about this from EIP-155. It says the field was devised at Spurious Dragon hard fork to prevent replay attacks.

Frankly speaking, we don’t have to be an expert of all, if we just want to use it. Just remember that Ethereum mainnet uses 1 and Ropsten testnet uses 3 for this field. For a backward compatibility, Ethereum supports ChainId 0, the legacy, and it works on any chain.

By the way, we can’t find ChainId in the RawTransaction above. Do you know why?

The rest

You might see that the description is not sufficient if you decoded it by your hand. Among 129 Bytes total, top 62 Bytes are encoded value we described in this article. But ChainId is not included and the rest 67 Bytes contain 3 more items and it’s not easy to catch what the items refer to.

They are v, r and s. Those are for guaranteeing that the raw transaction is from it’s owner account by signing the transaction with the owner’s key. You should understand ECDSA algorithm and secp256k1 curve in order to see what’s actually happening here. I recommend you to google those topics because there are plenty of cool stuffs about those.

ChainId also can be inferred from the value v. In our transaction, the value v is 0x29, i.e. decimal number 41. In the transactions for Ropsten of ChainId 3, the value v is decided either 41 or 42. Therefore, you can catch that we are sending the transaction to ChainId 3.

Interim Summary

You have finally became able to read the tricky cryptography-like(also actually cryptographic) value. Of course you don’t need to create it with typing calculator by yourself. Ethereum is already a popular project and all the common languages have library helping this. Even a language that I use recently, that might be unfamiliar to the most of the readers, Elixir has multiple libraries supporting this process.

In the next article, we will be covering ABI encoding, the final topic of this series.

--

--