We already explain how IOTA making a transaction in previous post. But I decide to make a with picture version for you to make sure you get how does this work.

Our transaction scenario

Person A have a seed A_SECRET_SEED that contain 100i in 4 different address relate to this seed:

seed: A_SECRET_SEED

address[0]: AAAAAA……AAA, balance: 10

address[1]: BBBBBB……BBB, balance: 5

address[2]: CCCCCC……CCC, balance: 25

address[3]: DDDDD……DDD, balance: 60

address[4]: EEEEEE……EEE, balance: 0

Person B have a seed B_SECRET_SEED that contain 0i in its address:

seed: B_SECRET_SEED

address[0]: QQQQQQ……QQQ, balance: 0

address[1]: QQQQQQ……VVV, balance: 0

Today, Person A want to send 80i to Person B’s address[0] QQQQQQ……QQQ.

How does IOTA construct this transaction?

1. Making transaction bundle

Bundle is the unit of a transaction, which include three kind of transaction: Input, Output, and meta transactions.

For our scenario, first we need to prepare output transaction, which mean, we want to send to B’s address with 80i IOTA:

Output transaction to B’s Address with 80i IOTA

Next, we will need to prepare input transaction. In our scenario, we will need to use all four address that contain IOTA (10 + 5 + 25 + 60 > 80) to fulfill output value 80i.

Four input transactions that spend out the value to B’s address

But our input transaction need to contain transaction signature, default address security level is 2, that mean we need an additional meta transaction to carry the transaction signature, let’s add it:

Add all input transaction with a 0 value meta transaction to carry security level 2 signature

We are not done yet, now we have an unbalanced bundle. Take a little count, we have 10 + 5 + 25 + 60 = 100 IOTA input, and 80 IOTA output, which mean this bundle still got 100 - 80 = 20 IOTA unspend. We will need to get an additional transaction to receive this unspend IOTA.

In normal contitional, IOTA will get a new address from A’s seed, and make a transaction with unspend value:

The unspend transaction

Great, now we get the balanced bundle. As you see, in previous transactions, we have not fill in bundle hash and other information. Next step, we will finalize bundle to get the bundle hash.

2. Finalize bundle

In this step, we will fill in transaction index, last index and generate bundle hash by Kerl hash function.

Fill in index and last index

Transaction validate items including: Address, value, obsolete tag, timestamp, index, and last index. Kerl hash function using sponge constructor, so it will absorb transaction validate item one by one (order is important), then squeeze out the result.

Using Kerl hash function and transaction validate item to generate bundle hash

I know you will complain about the figure, for more accurate figure of hash function absorb and squeeze, please visit SHA-3 — wikipedia.

Also, in the step to get the bundle hash, it will check if the bundle hash is secure or not. If not, it will increase tail transaction (index 0 transaction)’s obsolete tag and regenerate the hash again.

After we get the bundle hash, we will need to fill-in into all transaction in the bundle, thus we got:

Fill in bundle hash to all transactions

3. Signing signature for input transactions

Next, we will need to signing input transactions with correspond address’ private key. We can get the address private key from key generator with A_SECRET_SEED. From address private key, we can use Signature Fragment Generator with private key and bundle hash to get the transaction signature.

Using Key Generator to get Signature Fragment Generator

Fill in signature with corresponding signature fragment generator to each input transaction

After this, all parts of making bundle is done.

4. Getting two tips — 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.

5. 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.

Fill up trunk, branch, timestamp (yes, again) for all transactions

Pearl Diver will then find the nonce that mach the minimum weight magnitude (the trailing 9)

Finally fill up nonce, and we can get the transaction hash

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!

6. POC code for Python with PyOTA

describe

6. Conclusion

Here we use picture to demostrate 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.