This post will in-depth in-detailed to explain how IOTA making a transaction, from transaction to bundle, from hash to address, from private key to signature message. This is all you need about to know how IOTA proposed a transaction from one address to another.

blog post: https://blog.louie.lu/2018/01/08/in-depth-explanation-of-how-iota-making-a-transaction/

0. Before We Start

Please make sure you have already read this two material:

It gives you the basic view of IOTA transaction.

1. The Steps to make a transaction

Making bundle include all inputs and outputs

Prepare output transactions Prepare input transactions until input value fulfill output value Finalized bundle to get bundle hash and filling into all transaction Singing transactions to filling signature message fragment

Get two tips for trunk and branch hash

via IRI getTransactionsToApprove

Proof of Work

Fill up trunk and branch hash to transaction Fill up tag with obsolete tag if tag is not set Fill up timestamp to transaction Calculate nonce via pearlDiver and get transaction hash

At the end of this, we will get transaction trytes which include all elements that we need (bundle hash, branch / trunk hash, nonce, and transaction has).

2. Making bundle

In IOTA bundle, you can find three type of transaction include in it. Input transaction, Output transaction, and Meta transaction.

Input transaction: transaction value is negative.

Output transaction: transaction value is positive.

Meta transaction: transaction value is 0, it can be the carieer of signature, or save other message in transaction’s siganture message fragment.

Let’s take an example, A has 3 address from same seed, with some value:

index 0: AAAAAAAA, balance: 50

index 1: BBBBBBBB, balance: 70

index 2: CCCCCCCC, balance: 20

When A what to send 100i to B’s address DDDDDDDD , IOTA will do something like this:

Gather all transaction we need in bundle

Prepare output transaction to B’s address and add into bundle

Prepare input transaction from A’s address with balance

Add each input transaction into bundle with meta transaction slot

meta transaction slot amount will depend on address security level, default security level of address is 2, that means we will need one additional transaction to carrying transaction signature.

If the balance of bundle is still positive, add in an unspent output transaction to move unspent value

Bundle finalized

Check bundle balance is 0 (that input value = output value, recall that Kirchhoff’s circuit laws)

Generate bundle hash

Using Kerl absorb with transaction validate item (address, value, obsolete tag, timestamp, current index, and last index)

absorb with transaction validate item (address, value, obsolete tag, timestamp, current index, and last index) squeeze out bundle trits and convert to bundle hash

Check if generate a secure bundle hash, if not, increase obsolete tag and regenerate again

Fill bundle hash and init signature fragment to all transaction

notice that transaction hash, transaction tips, signature fragment and nonce are not filling in this step, only bundle hash is determined.

Bundle signing

Get key generator via seed

Iterate through transactions, if transaction is an output transaction, it will try to signing this transaction (with meta transaction if needed)

Get address private key via key generate with address index and security level

and Using address private key and bundle hash to generate signature fragment and filling into transaction’s signature fragment part.

If the security level is 2, then we will need to sign up two transaction (1 for output transaction and the following meta transaction)

At the end of this step, we will get a list of transaction trytes that including bundle hash and transaction signature with the reverse direction (from the last index to 0 index).

3. Get two tips for trunk and branch

In this article I will not cover the MCMC algorithm, think this as a black box that we can get two tips from IRI via getTransactionsToApprove.

4. Proof of Work

In the last step, we will need to fill-up trunk, branch, and find nonce (Proof of Work here!) into each transaction in the bundle.

As bundles documentation mention, a bundle is an atomic transfer item in the tangle, which means in one bundle, they will have the same tips.

It will then walk through all transactions in the bundle from the last index to 0 index, to fill-up trunk, branch hash, timestamp, and then do PoW (pearlDiver) to find nonce and generate transaction hash, then validated the PoW result.

Last index’s transaction trunk and branch hash will be previous tips we get. Other transaction’s trunk will be previous transaction’s hash, and branch hash is trunk transaction from tips.

The diagram of transaction trunk and branch

If everything is fine, we then can get the full transactions trytes with all field be filled in!

5. PoC code for Python with PyOTA

6. Conclusion

Here we describe how IOTA construct a bundle with transactions, and when it fill-up some critical parts of the transaction, such as bundle hash, transaction hash, trunk hash, branch hash, and nonce.

We can clearly know that in all the step to making a transaction, the essential part of an IoT device will only need to take care of the part of signing its transaction, other parts such as other output transaction, tip selection and PoW will no need to be done on it.