millix foundation
10 min readJun 23, 2022

--

By: Dr. Emmanuel Braden

Millix | How To: Transaction

What is Millix?

Millix is a novel cryptocurrency. It is novel because it does not utilize blockchains or tokens or other similar technologies. It utilizes a Directed Acyclic Graph, or DAG. Each transaction, from the genesis on, is a node on the graph. The graph can branch, but it can not loop or go backwards. It is a one-way graph through time. Other cryptocurrencies have utilized a DAG, but none of them, to the best of our knowledge, are truly decentralized. They have various methods of validating transactions that usually require specialized or trusted software to gatekeep transactions. This can cause choke points, which limit the number of transactions that can be validated over time. As such, they are not fully decentralized.

Millix is truly decentralized. The same software (millix node) not only stores the DAG, communicates with other nodes, and creates transactions, but also participates in validating transactions as well. The speed limit of transaction processing is proportional to the size of the network. The larger the network, the faster transactions can and will be processed.

Because the millix DAG is one way through time, you can take a transverse slice (between 2 points in time) of the DAG and know all the transactions that occurred between those times. In the image below you can see that 3 transactions exist in the time period between the two lines.

More information, including the whitepaper, can be found at https://millix.org .

What is a Millix transaction?

Andreas Antonopoulos defined a bitcoin transaction as follows:
Transactions are data structures that encode the transfer of value between participants in the Bitcoin system. Each transaction is a public entry in bitcoin’s blockchain, the global double-entry bookkeeping ledger.

A millix transaction can be similarly described:

Transactions are data structures that encode the transfer of value between participants in the millix system. Each transaction is a public entry in millix’s DAG, the global double-entry bookkeeping ledger.

Participants’ are identified by their addresses. Millix addresses are different from bitcoin addresses.

A valid millix address is made up of three parts:

The address_base is the derived address from the address_identifier. The address_identifier is the same for any address generated by a specific wallet.. Lastly, the address_version denotes the type of address. As the millix network grows, the types of addresses will increase to handle other types of transactions. Similar to the way that the first digit(s) denotes the type of address in Bitcoin.

The structure of transaction data is:

Millix transactions are funded from the outputs of previous transactions. These are then considered the inputs for the current transaction, and the outputs of the current transaction are the amounts and addresses where millix is to be sent. The list of inputs and outputs are contained in the transaction_payload. The transaction_payload also indicates the amount of the transaction fee.

The structure of a transaction_payload is:

The transaction payload then needs to be signed and then sent. The signed transaction is sent to the network via a randomly selected proxy.

An overview of the process is shown below:

After a 10 minute period the transaction enters a state of hibernation. This establishes a state of the network, prevents further work from occurring on this transaction and reduces network chatter.

Using the API:

To get the most out of this article it is helpful to understand both curl (GET/POST) and json. Most data submissions are GETs, POSTs are exceptions and are called out.

You need to run our reference millix node software (https://github.com/millix/millix-node) or the https://tangled.com browser — which includes the reference software and in many cases is a more flexible solution.

The millix node software is written in javascript using nodejs. It can be run on most computers.

Let’s start with calling the millix api.

On a computer running the millix node you can access the api’s by performing a CURL in the following format:

By default, the port that the millix node api runs on is 5500 (changeable via config). The ssl certificate is self-signed, so you will need to ignore ssl authentication on the curl.

The {node_id} and {node_signature} can be found in node.json which resides in the millix data directory.

In our case they are:

The base of the url is always the same, and the api you want to call is identified at the end:

To start off, let’s call:

This calls api OBexeX0f0MsnL1S3, or in human speak. api get_session. If everything worked out, you should see the following:

Congratulations, you have successfully called your first millix api! You will also need some of these values later, so well done!

Next, let’s go ahead and check the balance of the wallet. Otherwise known as “do I even have millix to send?”

This api is zLsiAkocn90e3K6R (get_address_balance). The p0 parameter is the millix address you want the balance for, in this case (16ucvq33XeLSXeVZUbDHWGAt5bqGbrKFqY0a016ucvq33XeLSXeVZUbDHWGAt5bqGbrKFqY).

It should return something like this:

The stable amount is the balance that’s available to spend.

The unstable amount is the sum of transactions that are pending verification.

Now it is time to gather the unspent transaction outputs, which we will use to fund our transaction. We can get the list from api FDLyQ5uo5t7jltiQ (list_transaction_output) with the following parameters. The full list of parameters and values are located in the Millix API Guide.

I only listed a couple of the unspents, as there are a bunch of them. You can use other parameters to further filter the unspents returned (please check the Millix API Guide.) You can also change the number of outputs that are returned from the api. The default limit is 1000, but you can populate p14 with any number.

Just a reminder, transactions are funded with outputs from previous transactions. These are inputs for the current transaction. We will be using the first unspent in the list, which has an amount of 10,000,000 millix. We could define up to 128 inputs for our transaction. But, let’s keep this as simple as possible.

Below are the values we will populate into the transaction_input_list portion of the transaction_payload.

Next, where do we want to send this millix?

For this example we are going to send millix to 1PJFrrLEafmdnHxuf7NVPjkxgcVbRfCMVg0a01EH53ZToXMoSbJqBL7bCERev5vDZKm1Drh .

This is an address on https://millix.com — an online wallet/exchange for millix.

Let’s check that this address is valid. Api Xim7SaikcsHICvfQ (verify_address) comes to our rescue. The parameter p0 is used for the address you want to verify.

Which returns:

This not only lets us know that the address is valid, but also provides the three components of the address.

So, we have an output to use as an input for this transaction and we have a valid destination address. This means we can start building the transaction payload!

Well almost, we still need a couple of things. How much are we going to send? What fee are we going to pay for proxying our transaction and finally what are we going to do with the rest of the millix? As with Bitcoin you can not send a partial amount of an output’s value. Just like you can not tear a dollar in half to give someone 50 cents. So, we will also need an address where we can send the change. For this we will use the address of the unspent.

Let’s send 1,000,000 millix with a fee of 1,000 millix. Let’s calculate how much change we send back to ourselves: 10,000,000–1,000,000–1,000 = 8,999,000.

That’s all great. But how will the network know that I own the millix in the output I am using to fund the transaction? It knows this because I will sign the payload with a private key. Anyone can use the public key to prove that I properly signed the inputs and own the funds.

Ok, so let’s get the private key and public key. We already have the public key from above (api OBexeX0f0MsnL1S3 get_session). The public key is 2Bh43AgRq35hqw91XuB8p2YUX8gzAhVAWwT2KkD76Nj7h.

The private key can be obtained from api PKUv2JfV87KpEZwE (get_address_private_key).

Which returns:

Now, we have everything necessary to sign the transaction_payload.

We’re going to use api RVBqKlGdk9aEhi5J (sign_transaction) with the parameters:

p0: the transaction_payload_unsigned

p1: the private_key_hex ( {<address_base>: <address_base_private_key_hex>} )

p2: the public_key ( {<address_base>: <address_public_key_base58>} )

This api is called with a POST not a GET.

The curl we use on linux is:

The output from the api is in the box below. If you look closely, you will see that there are two transactions. The first with a version of ‘0b20’ and the second with a version of ‘0a20.’

This is because the inputs were in a hibernated state. In order for them to be used to fund a transaction they need to be refreshed. Refreshing the inputs causes the network to re-validate that they have not been used. The refresh transaction is recognizable as version 0b20.

If the outputs from the previous transaction were stable, but not hibernated, there would only be a single transaction (0a20).

Also, please note this is where we get the transaction id

( 2ZaHWUE7BQarNShAmgMHh9RvKQTeh9PFtPx37TMSHnf8eWVC8s )

Next, we take the output of that api and call api VnJIBrrM0KY3uQ9X (send_transaction).
This will submit the transaction to the proxy, which propagates the transaction to the network.

p0 is assigned the output from the previous api. The curl is also a POST and is shown in the box below.

And, if everything worked correctly, (which it did!) we will get the following status returned:

Success! YAAAAAY!!!!

You have now sent a transaction programmatically and successfully!!!!

You can check your transaction with millix.com’s explorer:

https://millix.com/tx/2ZaHWUE7BQarNShAmgMHh9RvKQTeh9PFtPx37TMSHnf8eWVC8s

or the hardcore way!

With api IBHgAmydZbmTUAe8 (get_transaction_extended)

p0 contains the transaction_id ( 2ZaHWUE7BQarNShAmgMHh9RvKQTeh9PFtPx37TMSHnf8eWVC8s )

p1 contains the shard in question ( qGuUgMMVmaCvqrvoWG6zARjkrujGMpzJmpNhBgz1y3RjBG7ZR )

There is a lot of information to unpack here. You can look at millix.org for the technical papers and the Millix API Guide for further specifications and options. Also if you need help you can contact us directly via millix.org. This article is meant to be a bare bones description of how to send a transaction via the api ‘how-to.’ The millix protocol also includes the ability for private DAGs, data, chat, and other features which are way beyond the scope of this simple article.

Congratulations on getting your feet wet!!!

TL;DR

You do realize… there must be a much easier way of sending transactions from your wallet.

There is! Just use api XPzc85T3reYmGro1 (send_transaction_from_wallet).

This api takes “transaction output payload” as a parameter.

transaction output payload has the following components:

We don’t need to select the inputs, and we also don’t need to provide the change address.

Let’s send 1,000,000 millix to 1PJFrrLEafmdnHxuf7NVPjkxgcVbRfCMVg0a01EH53ZToXMoSbJqBL7bCERev5vDZKm1Drh like we did in the previous example:

p0: transaction output payload

The call to the api:

Please note that it may be necessary to url encode the above. In this case the url would look like:

which returned the following:

Success! You can see this transaction on the DAG, it has a transaction id of 2nEGw2Gtj5bvFvbGxD57SeWFctQu9azMbgFnuv6Jp3kpriMp6Y .

--

--

millix foundation

millix is an open source cryptocurrency project. millix is fully decentralized, designed for simplicity, transacts at very high speed and very large scale.