Well, when a coinbase transaction and a fusion transaction love each other very much…
Just kidding. Grab a drink, this is a long, and confusing read.
Lets start by looking at where the money for a transaction comes from in the first place. All money originates in the network from mining – which creates new coins, via a coinbase transaction.
A coinbase transaction is a special kind of transaction that is rewarded to the person who mines a block. The money ‘magically’ appears, and is not sent to the miner by anyone.
This might make you think that miners can print as much money as they want. However, the coinbase transaction cannot be more than the current ‘reward’ – if it is, the other pools and daemons will reject the block containing it. The current reward is calculated by looking at the emission curve, and the total amount of coins in the network.
Lets say Bob decides to do some solo mining, and gets lucky one day. Maybe he mined block 900,000.
Bob got 29,013.99 TRTL from mining this block. As you can see, this transaction has no inputs, because it is a coinbase transaction. The bit we’re interested in here are the outputs. Interestingly, Bob does not just receive a big chunk of 29,013.99 TRTL. Instead, he receives 6 outputs, of varying amounts, which add up to the full 29,013.99 TRTL.
Whenever a transaction is sent, it must be split into denominations. This is quite simple to do – it’s just splitting into units, such as thousands, hundreds, tens, etc.
The reason for this is due to how the mixin / privacy features work. When we form a transaction, we need to match the amounts we use with other ones other people have sent. If we didn’t split our outputs into these standardized amounts, we would need other people to have made transactions of exactly 29,013.99 TRTL before, which is pretty unlikely. Think of these standard amounts as building blocks to make any transaction amount.
So, Bob has got an amount of TRTL now, comprised of a few separate outputs. How does he spend them?
Finding which transaction outputs belong to us
First, Bob needs to work out if this transaction belongs to him. Since CryptoNote coins are private, we can’t tell what address a transaction was sent to without owning the private keys belonging to that address.
Now we’re going to have to get a bit nerdy and talk through some code. I’ll try and keep it simple. If you want to follow the code, check it out here.
Each transaction has a transaction public key which comes with it. We start by taking this public key, and our private view key, and performing some magic crypto operations, we can generate a key derivation.
Next, we loop through each output in the transaction, so in this case we’d start with the 0.09 TRTL output.
For each output in the transaction, we take our key derivation, the output index (This is simply the ordering of the outputs in the transaction), and the output key (That’s the long hex string which looks like a hash in the image)
We do some more magic crypto operations, and we get out a public spend key. This is the public spend key that the transaction was sent to.
If you weren’t aware, a TurtleCoin address (and any CryptoNote address, actually) is just a ‘nicer’ representation of the public spend key and the public view key.
For example, the address:
corresponds to the public spend key:
and the public view key:
So, we’ve got out the public spend key this transaction was sent to. What’s next? We just need to checkout if that public spend key is the same as the public spend key our wallet uses.
If it is the same as the public spend key our wallet uses, this transaction output belongs to us!
By the way – if the transaction doesn’t belong to us, we won’t get out the actual spend key the transaction was sent to – we’ll just get some meaningless garbage. So, your privacy is intact 😉
We then repeat this process for every output in the transaction. We can’t automatically assume because one output belongs to us, they all do. Remember, you can send a transaction to more than one person at once.
Once we’ve added up the outputs that belong to us, we’ve worked out how much we’ve been sent in this transaction. In Bob’s case, that’s 29,013.99 TRTL. Good work, Bob!
Storing the magic stuff which lets us send transactions
Bob’s got his wallet all synced. He wants to buy a TurtleCoin t-shirt from Alice. How does he send his money?
If we find that a transaction output belongs to us, we can then create a transaction input from that, using our private spend key. We can then spend those inputs, creating new outputs, for someone else to repeat the cycle with. A little bit confusing.
There are a few bits of information we need to store that comprise our new input. We need:
- The transaction public key – This is included in the transaction.
- The output index – This is the output index previously mentioned.
- The amount – We can take this from the output data.
- The key – This is the output key we used before.
We also need the global output index. This is part of the output data. This is used to keep track of all the output keys. Each different amount has a different global output index store. So, the first ‘1’ amount that was ever used in a transaction gets a global output index of 0. The second ‘1’ amount gets an index of 1, and so on. If someone then sends a ‘2’ amount, this gets an index of 0, since the indexes for different amounts are not related.
That’s a bit confusing, but if you don’t understand it, don’t worry – It doesn’t really matter.
Finally, we need to generate this inputs key image. To do this, we need to take the key derivation from before (remember that?), and our private spend key. We then perform yet again some magic crypto operations, and we are left with the key image.
Because we need to generate a key image to spend our funds, and we need a private spend key to do so, this allows us to create ‘view only’ wallets, which can only find incoming transactions, and cannot spend them, since it has no private spend key.
If you’re feeling utterly baffled by the previous explanation, the following diagram might help. Or, it might confuse you more. Sorry!
Spending our transaction inputs
Bob has got his transaction inputs all ready in his wallet. Surely he’s able to make a transaction by now?? Good news Bob. Let me explain the steps he needs to take.
Selecting the inputs
Link to the code here.
To start with, we need to find enough inputs to cover the amount Bob wants to send. Alice is sending her t-shirts for 25,000 TRTL, so we need at least that much. He also needs at least 0.1 TRTL for the network fee.
Inputs are selected randomly, to make it harder to detect any patterns in spending. We just keep taking inputs whilst we don’t have enough funds to cover the transaction.
Lets say that the inputs that get randomly selected are 3 TRTL, 0.09 TRTL, 20,000 TRTL, and 9000 TRTL. That sums up to 29003.09 TRTL, so we’ve got enough to cover the transaction.
Since Bob only wants to send Alice 25,000 TRTL, but he doesn’t have the exact amount to send, he instead sends the ‘change’ back to himself. In this case he wants to send 25000 TRTL + 0.1 TRTL (for the network fee) and he’s got 29003.09 TRTL in the inputs, so he needs to send 4002.99 TRTL back to himself.
Preparing the destinations
Link to the code here.
Now we need to split this 29,003.09 into separate atomic amounts, and indicate who we’re actually sending each bit to.
Alice has given Bob her address, which we extract the public spend and view key from. We then split the 25,000 TRTL we’re sending her up into units, which is simply 20,000 TRTL + 5000 TRTL. These will eventually become two outputs for Alice to scan, just like we did at the beginning of this article.
Next, we need to setup the destinations that Bob is sending to himself. We take our address, split it into a public spend and view key, and again split up the amount into units. This will give us 4,000 TRTL + 2 TRTL + 0.9 TRTL + 0.09 TRTL.
So, the transaction will have 6 outputs – 2 belonging to Alice, and 4 belonging to Bob.
Outputs = 20000 TRTL + 5000 TRTL + 4000 TRTL + 2 TRTL + 0.9 TRTL + 0.09 TRTL
Preparing the Transaction Inputs
Link to the code here.
Next we need to hide our real inputs among other inputs, to obscure which inputs are really used to create the transaction. We ask the daemon for as many fake outputs as our mixin value, and we need this many for each amount we are sending. If we are using a mixin of 3, we need 3 fake outputs for 20,000 TRTL, 3 for 9,000 TRTL, and so on.
Next, we loop through each real input, and the fake outputs. We generate a key image using the real input transaction public key, our private view key, and our private spend key. This also gives us a temporary key pair for each transaction input, which we’ll need later for our ring signatures.
Now we can finally make a transaction input, which consists of the amount, the key image we just generated, and the global output indexes of both the fake outputs and our real input. Gah, confusing.
We end up with 6 transaction inputs, with each one having 3 fake global output indexes, and one real global output index. No-one but us can tell which is the real index.
Preparing the Outputs
Link to the code here.
Now we can make the outputs of the transaction. We start by generating a random key pair. This is used so multiple transactions to the same address cannot be linked together.
Next, we loop through the destinations we prepared earlier. We generate the output key by taking the receivers public view key, the private key from the random key pair we just generated, and the receivers public spend key.
Then, we create our output, which is just comprised of the output key we just generated, and the amount the output is worth.
We store the public key from the random key pair we generated – this becomes the transaction public key later.
Assembling the transaction
Link to the code here.
We’ve done most of the work now, we can start putting this transaction together. We start by creating the tx_extra – This has a few bits of data in, but most importantly is the transaction public key. If we’re using a payment ID, we also add that in here.
Then, we copy over the inputs and outputs we prepared earlier, and add a few extra bits like the transaction version, and the unlock time if you want your transaction to not be spendable instantly.
Finally, we hash this data to give us the transaction prefix hash.
Generating the Ring Signatures
Link to the code here.
Finally, we generate the transaction ring signatures. These are used to verify that we own all the funds being spent. We generate signatures for each transaction input, using the private key of the temporary key pair we created for each input earlier, the transaction prefix hash, the public key that each fake transaction output has (including our real input), and each transaction input key image. This again, uses some cryptography magic.
Ring signatures indicate that one person of a group signed a message with their private key, but it cannot be determined which person signed the message. This proves we are able to spend the amounts in the transaction, but our identity is kept hidden.
Sending the transaction
Finally, we’re done! We send our transaction off to a daemon, and if it verifies the transaction is legitimate, Alice will get her funds shortly. There’s one thing we missed when I explained this – detecting when you have spent funds, rather than just when you have received funds.
Finding which transaction inputs belong to us
Fortunately, this bit is pretty simple. Remember when we generated a key image, when we found a transaction that belonged to us? Because that key image is used in a transaction when we send it, we simply look at each transaction input, and if it uses a key image which we created, then we sent it.
Thus, when Bob scans the transaction he sent to Alice, he will see the 4 inputs we used to create the transaction, and find that they use key images he previously created. He will mark these key images as spent, so he doesn’t accidentaly use them in another transaction. This would cause an attempted double spend, which would fail, as a key image can only ever be used once.
When Bob sums the transaction inputs, he would get 3 TRTL, 0.09 TRTL, 20,000 TRTL, and 9000 TRTL – The exact amount he sent. He should then scan the transaction outputs, and find 4 outputs that belong to him – 4000 TRTL + 2 TRTL + 0.9 TRTL + 0.09 TRTL – The change that he sent back to himself.
With this, Bob can work out the total amount he spent on the transaction – inputs – outputs = 25000.1 TRTL.
You may remember that Bob decided to pay a network fee of 0.1 TRTL, but we never gave an address to send this to. The network fee is simply the difference between the sum of the inputs, and the sum of the outputs – the miner who includes this transaction in a block is allowed to add this amount to the coinbase transaction as a reward.
In summary, a transaction is comprised of inputs, outputs, and ring signatures.
- Transaction inputs are money we have previously received, combined with some data to generate the keys. They are also hidden among other people’s inputs.
- Transaction outputs are money that the receiver(s) get. This may include some change which returns to the sender.
- Ring signatures prove the transaction is valid and we own the corresponding private keys. This is an example of a zero knowledge proof: A third party can prove the signatures are legitimate, but it gives them no information about who the sender is, or who the receiver is, just that the transaction is legitimate.
- If a transaction input has the same key image as one we generated, that is an outgoing transaction by us.
- If a transaction output has the same public spend key as ours when decrypted, that is an incoming transaction for us.
I’m sorry if you didn’t understand this. It’s quite confusing, and quite hard to explain. I have to say, the whole inputs, outputs, fake outputs + real input thing confuses me as well.
Thanks for reading – hopefully you learnt something!
A common question we get from users is wondering what the maximum amount of TRTL they can send is, often because they went to send a (relatively) small amount, and got an error ‘Transaction is too big’.
The question seems pretty simple, but the answer is not quite so simple!
To begin with, lets talk about what a transaction is made of.
Transaction Inputs / Outputs
When you send a transaction, lets say, 1000 TRTL, you might think it’s as simple as taking 1000 TRTL from your balance, encrypting it with your recipient’s public keys, and sending it out to the miners, to be included in a block.
However, your 1000 TRTL is actually made up of lots of smaller ‘Inputs’. These inputs come from previous transactions that you have recieved.
To demonstrate what I mean by this, lets start by looking at a coinbase transaction. A coinbase transaction is a special kind of transaction, where there is no sender. These are the rewards a miner gets for finding a block.
Here’s the transaction that the miner of block 800,000 found. As you can see, they received 29,100.54 TRTL, but, if we look at the outputs section, they did not receive it all in one lump.
The transaction has been split up into several standard sized ‘Outputs’. The reason for doing this links into the privacy elements of TurtleCoin, and other CryptoNote coins. When we send a transaction, we hide one of our inputs alongside many other inputs. The network can verify that we own one of the inputs, but not which one. This allows the sender of a transaction to be hidden.
For this to work, we need there to be other inputs to select from. If we simply sent the exact amount in every transaction, then if you wanted to send an amount that had never been sent before, say, 1337 TRTL, you would not be able to obscure that you were the sender.
To ensure we always have enough inputs to match with, we use some set values, and build our transactions out of these smaller sized building blocks.
If you’re interested, you can view the possible sizes for transaction inputs here.
Hold on, what does it matter if my transaction has lots of inputs?
Well, when we send a transaction, we have to include each of our transactions inputs, along with the decoy inputs from other users, for the privacy features to function. These need to be available so we can verify that a user isn’t spending funds they don’t own, or trying to spend an input that has already been used.
To use a real world example, if you try and pay for a car in pennies, you’d need a pretty large jar to hold them all in. Similarly, when sending a transaction, each input takes up a bit of space in the blockchain. The largest a transaction can be is approximately 140 KB, and if your transaction will be larger than this, your wallet will reject it. This prevents your transaction being too large for a block, and never getting mined.
If your transaction is too large, stop thinking in amount, and start thinking in bytes.
Hopefully now you understand that a transaction is comprised of multiple inputs to make up the full amount of your transaction. One question on your mind may be – What if I have an input of 2000 TRTL, but I only want to send 1500 TRTL?
Well, we can do the exact same thing as when you were a kid and wanted to buy a candy bar, but you only had 5 dollars – you give the cashier your 5 dollars, and she gives you back 4 dollars in change.
Here’s an example of a real transaction, to show what I mean.
In this image, I sent 1500 TRTL to someone. You can see I used one input, of 20000 TRTL to do so. 500 TRTL + 1000 TRTL went to the receiver, and the other 18500 TRTL got sent back to my wallet.
You may have noticed when you send a transaction, some of your balance gets ‘Locked’. This is because you have had to send a bit more of your funds than needed, as you cannot make the exact amount, and you are waiting for the change to confirm on the blockchain, and return to you.
Optimization / Fusion Transactions
Now lets talk a bit about fusion transactions. If you haven’t heard of these before, that’s OK, they’re quite simple.
Recall how when we send a transaction, as long as the total value of the inputs/outputs on both sides match up, the amount of inputs/outputs we have doesn’t matter?
A fusion transaction is a special kind of transaction, where you are sending a transaction to yourself. We take all our small inputs on one side, and combine them into a few large outputs.
It’s a bit like those machines where you pour in your loose change, and get out a few dollar bills.
How can I send more TRTL?
So, on to the final section of this article – putting these steps into practice, so you can send more TRTL at one time.
Sending fusion transactions
Our first step we can take is to perform fusion transactions. The manner to do this depends upon what wallet you are using.
If you are using zedwallet, you can type optimize to perform multiple fusion transactions. This will also be done automatically for you, if a transaction fails due to being too large.
Similarly in Nest, if a transaction fails, it will offer you the chance to send a fusion transaction. These are done one at a time, so may take quite a while if you have a very unoptimized wallet!
Splitting up our transactions
If you’ve performed fusion transactions, and still aren’t able to send very large amounts, then unfortunately, the best option you can do is to split your transaction up into multiple smaller transactions.
Again, zedwallet will do this automatically for you (If you agree) upon failing to send a transaction due to it being too large. In Nest however, you will have to do this manually, with trial and error.
Avoiding the issue
Now, you might be wondering why you have so many small inputs. The simple answer is you have recieved a lot of transactions, or more importantly, a lot of small transactions. If you receive 1000 TRTL at a time, then the largest a single input could be, is 1000 TRTL. If you then want to send 100,000 TRTL, you will need to include 100 inputs, which ends up as a pretty large transaction.
If your mining pool has the option, you can increase your payment threshold. This will result in fewer inputs in your wallet, each with a larger amount. 1 payout of 5000 TRTL instead of 5 payouts of 1000 TRTL may make your transactions around 5 times smaller!
You may also like to consider using a smaller pool, which due to taking a longer time to find blocks, pays you out in larger chunks. Special mention to http://cryptonote.social/ which is a very cool solo mining pool – You get a full block payout everytime.
This is one of the reasons you encounter this issue in TurtleCoin, but don’t in other currencies, such as Monero, or Bitcoin – The payout thresholds for these currencies on mining pools are often very high, so you have very few transactions received. It’s worth noting that most cryptocurrencies use this method of including past payments in your payments, and returning extra change as a transaction to yourself.
If you’d like to read up more on the topic, in Bitcoin, these are called ‘Unspent Transaction Outputs’, or UTXOs.
- Thanks to turtle.land for the transaction screenshots – it’s a very nice looking block explorer, with great uptime!
- Thanks to Der Wixer for his optimize maymay