Grasp the Outline of Bundles through Knowledge of the API for Transfers

This blog post is very useful for understanding what I didn’t explain before because of high expertise. If you are interested in my previous blog post, you can read it, “What is Happening in the Back-end of IOTA Wallet” (currently in preparation).

Anyway, the reason I post this blog post is to help you to grasp the basic knowledge of Bundles. Since the knowledge is required when you try to understand IOTA’s emerging technologies like MAM and multiple signatures.

I used the source codes of Java. Because I’m familiar with Java, and you can easily comprehend the types of variables. Of course, you can develop IOTA with various environments. And you can check the IOTA official Github.

Useful Links (for mainly Japanese)

This blog is an IOTA pioneer in Japan and introduces many useful web-sites. You can use this as a base to get information about IOTA.

In the opening it explains the outline of the Tangle. Then it explains security, possible attacks, and resistance to the attacks with using highly skilled mathematics. So I don’t recommend the latter half of the paper for beginners.

I started my IOTA life from this thread.

If the whitepaper is considered as a faculty of Science, this is considered as a faculty of Engineering.

IOTA community has grown in Slack. There is also a Japanese-based channel. We, Japanese, welcome people all over the world to the Japanese channel.



Structure of a Transaction

Maybe you can easily understand the structure of a transaction after reading my previous blog post(currently in preparation). I quoted blow codes from I added comments with the important codes.

public class Transaction {

    private static final transient Logger log = LoggerFactory.getLogger(Transaction.class);

    private transient ICurl customCurl;

    private String hash;                //  transaction hash (Identity)
    private String signatureFragments;  //  Fields for signatures and so on They have 2187 trytes length.
    private String address;             //  Define an address
    private long value;                 //  Define an amount of spending
    private String obsoleteTag;
    private long timestamp;             //  Required
    private long currentIndex;          //  Indicate the index in a bundle (It starts from 0.)
    private long lastIndex;             //  Indicate the index of the last Tx.
    private String bundle;              //  Define which this Tx belongs to
    private String trunkTransaction;    //  Tx part 1 approved by this Tx
    private String branchTransaction;   //  Tx part 2 approved by this Tx
    private String nonce;               //  Find this nonce in PoW
    private Boolean persistence;        //  If this Tx is approved by other Tx, it indicates True. If not, False.
    private long attachmentTimestamp;
    private String tag;                 //  arbitrary 27 trytes tag
    private long attachmentTimestampLowerBound;
    private long attachmentTimestampUpperBound;

You need two addresses, a recipient’s address and a spender’s address at least. But as you see, the transaction object has only one address. Then IOTA adopted a concept called Bundles. A bundle includes some transaction objects. The transaction objects are separately in charge of a recipient’s addresses, a spender’s address, signatures or various important requirements. Which means that a bundle collects multiple transaction objects together and manages them.

API for Transfers

You can easily see the API for tranfers.

Trasnfer Class

It holds information for a transfer.

public class Transfer {

    private String timestamp;      // timestamp
    private String address;        // recipient's address
    private String hash;
    private Boolean persistence;   // true : approved, false : unapproved
    private long value;            // amount for transfer
    private String message;        // arbitrary trytes
    private String tag;            // tag(27 trytes)

    // Generate Transfer Object
    // recipient's address, amount for transfer, arbitrary trytes, tage
    public Transfer(String address, long value, String message, String tag) {
        this.address = address;
        this.value = value;
        this.message = message;
        this.tag = tag;

sendTransfer Function

The sendTransfer function is used for transfers. The function takes a list of transfer objects as an argument, and then makes multiple transfers at once.

 * Wrapper function that basically does prepareTransfers, as well as attachToTangle and finally, it broadcasts and stores the transactions locally.
 * @param seed               Tryte-encoded seed
 * @param security           The security level of private key / seed.
 * @param depth              The depth.
 * @param minWeightMagnitude The minimum weight magnitude.
 * @param transfers          Array of transfer objects.
 * @param inputs             Optional: List of inputs used for funding the transfer.
 * @param remainderAddress   Optional: If defined, this remainderAddress will be used for sending the remainder value (of the inputs) to.
 * @param validateInputs     Whether or not to validate the balances of the provided inputs.
 * @param validateAddresses  Whether or not to validate if the destination address is already used and if a key reuse is detect.
 * @return Array of valid Transaction objects.
 * @throws ArgumentException is thrown when the specified input is not valid.
public SendTransferResponse sendTransfer(
        String seed,
        int security, int depth, int minWeightMagnitude,
        final List<Transfer> transfers,
        List<Input> inputs,
        String remainderAddress,
        boolean validateInputs, boolean validateAddresses) throws ArgumentException {


Take a casual glance at an example “Alice transfers 100 iotas to Bob”.

// trytes in arbitrary size
String message = "MESSAGE..."

// tag(27 trytes)
String tag = "SAMPLE9TAG99999999999"

// address size : 81 trytes (Bob's address)
String address = "B9ADDRESS..."

// Generate Transfer Object(Alice transfers 100 iotas to the Bob's address with a message.)
Transfer transfer = new Transfer(address,100,message,tag);
List<Transfer> list = new List<>();

// transfer
sendTransfer("Alice's seed",security,depth,minWeightMagnitude,list,null,null,true,true);

I simplified the part of a transfer in the official wallet. Actually I haven’t tried this case. So I don’t know it works well. But you can understand the flow of a transfer.

In this blog post, I focus on how the contents of the sendTransfer function works. If you want to know the accurate way to transfer, I recommend you to refer the official source codes.

  • Python

  • Android


Structure of a Bundle

For a transfer, we need to make a bundle first in IOTA. The bundle holds multiple transactions together. (In IOTA, a transaction is a minimum unit.) As such, a bundle manages information required for a transfer like an amount, a signature and so on.

A bundle has mainly three sections.

  1. Output Section(You can define where and how much you spend for.)
  2. Input Section(You can define where the amount comes from. )
  3. Remainder Section(You can define where a remainder is sent to.)

Output Section

We refer to transferring to a defined address as an output. The output section has below three rolls in the first section of a bundle.

  1. Defining an amount
  2. Defining a recipient
  3. Storing an arbitrary message

Now follow the above case of “Alice transfers 100 iotas to Bob”.

  • SinF means the signatureFragments in the above Transaction.
  • For comprehensibility, I assigned Bob to the address. But technically, his name means his address.
  • The 0 and 1 of the Tx.0 and Tx.1 indicates a currentIndex in the transaction.

Output Section

As you see the figure, the amount is defined as the value of the Tx.0 and the recipient is defined as the address of the Tx.0. The message is divided into chunks (the size of 2187 trytes). Then, from the top, the chunks are stored in each sigF of Tx.0, Tx.1, … . If the message is shorter than 2187 trytes, it requires only one output, Tx.0. In other words, that’s enough only one transaction. And as the message becomes longer, the number of transactions becomes bigger. As such, the output becomes longer. Messages are rarely a multiple of 2187. So we usually pad ‘9’ with the blank in sigF.

Although messages are represented in each sigF by trytes, they can be converted to characters. So everyone can read messages in the Tangle. Then a method called MAM (Masked Authenticated Message) that provides private space on the Tangle by encrypting sigF has also been proposed and undergoing research and development.

Relationship to MAM

MAM is one of the most promising functions. It can stores data with privacy in the Tangle. As such, MAM encrypts the contents of sigF that everyone can read before. In IOTA, you can transfer with no fee. So you can positively use the sigF in transactions as a private data area. It is my last dream of the year to release a blog post about MAM.

Input Section

We refer to making an amount for spending from addresses that have a balance as inputs. In order to execute an output, we have to hold a sufficient amount somewhere. And we have to prevent double-spending through signatures. The input has below three rolls in the second section of a bundle.

  1. Defining an amount for an input
  2. Defining an address for the input
  3. Signature on the address for the input

Again follow the case of “Alice transfers 100 iotas to Bob”. Alice defines where she brings over 100 iotas or more from. Here, “or more” means that she can get a remainder. I mention it in the next part, Remainder Section.

Input Section

This case has two inputs(input1 and input2). The reason two inputs are required is that she can manage to cover 100 iotas by totaling the amounts of each address (Alice① + Alice② = -144). The rest (44 iotas), is defined in the next part, Remainder Section. If Alice uses an address that has a balance of 100 iotas or more, the input becomes shorter consequently. Because it’s enough to use the input only.

Although the more important thing is sigF. There are two signatures for each input address. This depends on the security argument of the sendTransfer function. If the security argument is 1, you have to sigh on one input address. As such, in this figure Alice has to sign two times per input address(Alice① and Alice②). If the security argument is 3, you have to sign three times on every input address. Therefore, altogether 6 transactions(2*3=6) are generated. You can see the formula below.

\({\rm Number\ of\ Transaction}={\rm Security} \times {\rm Number\ of\ Input}\)

If you are interested in how to sign, you can read my previous blog post(currently in preparation).

Remainder Section

Output amounts rarely match balances in input addresses completely. So we usually gather balances above the output amount from multiple input addresses. Then we get changes. In IOTA, if you reuse an address that is signed once, it leads to a leak of your private key. In other words, don’t receive iotas with an address that was signed once. Returning a change to the same input address is violation of the principal. So a change is transferred to other new address.

The remainder section has below two rolls in the lst section of a bundle.

  1. Defining difference
  2. Defining an output address

In the case of “Alice transfers 100 iotas to Bob“, Alice gets a remainder(44 iotas). Look at the figure below.

Remainder Section

It’s very simple. If there is difference, only one Tx is generated.
The remainder is just outputted to the Alice’s new address (Alice ③). If you don’t know the ‘new address’, you can check my previous blog post(currently in preparation).

By the way, if a remainder is zero (if an output amount matches a balance in an input address completely), the remainder output part is not generated.

Transfer to Multiple Addresses

When you transfer to multiple different addresses, the number of output transactions is increased according to the number of addresses.

Output Section

We can easily handle the input section and the remainder section. In the input section, e.g. this case, just find input addresses that have 1734 iotas(100+1000+634=1734)and more and return the difference to a new address as a exchange. Nothing special.

Outline of a Bundle

An IOTA’s transaction is not only created but also has a task of approving two transactions called trunkTransaction and branchTransaction.

Selection of Unapproved Tips

You can get the unapproved transactions called Tips by using getTransactionToApprove function. It is easy to use. But the function uses highly skilled mathematics. So it is not easy to understand how it works. I would like to ask good mathematicians for instructions about it.

Approval Relations in a Bundle

I drew a figure of a bundle in the previous blog post, but dared to redraw this figure.


You can apply trunkTransactions and branchTransactions returned from the getTransactionsToApprove function to Milestone and other Tx in the figure respectively.

And you can check some transactions and the bundle with the Tangle Explorer like this( It must be as introduced in this blog post. (Please report to me if it is wrong.)

Cheat Sheet

The size is good to print it. I hope to update it as needed and finish it as a beautiful one.

Cheat Sheet


IOTA Java Library JOTA

About Writer


I would like to understand IOTA.
In 10 years, I hope to see a surprising future of IOTA.
I am waiting for your feedback on this blog post.

Twitter : @abmushi
Slack(iotatangle) : @abmushi

About Translator


I am interested in DLTs.
Co-Editor of this Blog
Big Animal Lover(especially Golden Retriever)
Actually Abmushi has better English ability than me.
So you can feel free to contact him and give him your feedback!
And also I welcome your comments about this blog 🙂

Twitter : @iotafan_jp
Slack(iotatangle) : @take

2 件のコメント

  • I am dying to buy IOTA but don’t have access to Coinbase or any of the other traditional ways of buying using Bitcoin, because I live in Japan and cannot gain access. What do you recommend I do?

    • Thank you for your comment, and sorry for this late reply. You can access to Bitfinex or Binance even if you are in Japan. But as you know, Bitfinex does’t accept Americans. So if you are American, use Binance.

  • Leave a Reply

    Your email address will not be published. Required fields are marked *