Unit tests
You can see that previously I hard coded the properties of ColoredCoin. The reason is that I only wanted to show you how to construct a Transaction out of ColoredCoin coins.
In real life, you would either depend on a third party API to fetch the colored coins of a transaction or a balance. Which might not be a good idea, because it add a trust dependency to your program with the API provider.
NBitcoin allows you either to depend on a web service, either to provide your own implementation for fetching the color of a Transaction. This allows you to have a flexible way to unit test your code, use another implementation or your own.
Let’s introduce two issuers: Silver and Gold. And three participants: Bob, Alice and Satoshi. Let’s create a fake transaction that gives some bitcoins to Silver, Gold and Satoshi.
Init does not contain any Colored Coin issuance and Transfer. But imagine that you want to be sure of it, how would you proceed?
In NBitcoin, the summary of color transfers and issuances is described by a class called ColoredTransaction.
You can see that the ColoredTransaction class will tell you:
Which TxIn spends which Asset
Which TxOut emits which Asset
Which TxOut transfers which Asset
But the method that interests us right now is FetchColor, which will permit you to extract colored information out of the transaction you gave in input.
You see that it depends on a IColoredTransactionRepository.
IColoredTransactionRepository is only a store that will give you the ColoredTransaction from the txid. However you can see that it depends on ITransactionRepository, which maps a Transaction id to its transaction.
An implementation of IColoredTransactionRepository is CoinprismColoredTransactionRepository which is a public API for colored coins operations. However, you can easily do your own, here is how FetchColors works.
The simplest case is: The IColoredTransactionRepository knows the color, in such case FetchColors only returns that result.
The second case is that the IColoredTransactionRepository does not know anything about the color of the transaction. So FetchColors will need to compute the color itself according to the open asset specification.
However, for computing the color, FetchColors needs the color of the parent transactions. So it fetches each of them on the ITransactionRepository, and calls FetchColors on each of them. Once FetchColors has resolved the color of the parent’s recursively, it computes the transaction color, and caches the result back in the IColoredTransactionRepository.
By doing that, future requests to fetch the color of a transaction will be resolved quickly. Some IColoredTransactionRepository are read-only (like CoinprismColoredTransactionRepository so the Put operation is ignored).
So, back to our example: The trick when writing unit tests is to use an in memory IColoredTransactionRepository:
Now, we can put our init transaction inside.
Note that Put is an extension method, so you will need to add
at the top of the file to get access to it.
And now, you can extract the color:
As expected, the init transaction has no inputs, issuances, transfers or destructions of Colored Coins.
So now, let’s use the two coins sent to Silver and Gold as Issuance Coins.
Gold is the first coin, Silver the second one.
From that you can send Gold to Satoshi with the TransactionBuilder, as we have done in the previous exercise, and put the resulting transaction in the repository, and print the result.
This means that the first TxOut bears 10 gold.
Now imagine that Satoshi wants to send 4 gold to Alice. First, he will fetch the ColoredCoin out of the transaction.
Then, build a transaction like this:
Except you will get the exception NotEnoughFundsException. The reason is that the transaction is composed of 600 satoshi in input (the goldCoin), and 1200 satoshi in output. (One TxOut for sending assets to Alice, and one for sending back the change to Satoshi.)
This means that you are short 600 satoshi. You can fix the problem by adding the last Coin of 1 BTC in the init transaction that belongs to satoshi.
Let’s see the transaction and its colored part:
We have finally made a unit test that emits and transfers some assets without any external dependencies.
You can make your own IColoredTransactionRepository if you don’t want to depend on a third party service.
You can find more complex scenarios in NBitcoin tests, and also in one of my articles “Build them all” in codeproject. (Like multi sig issuance and colored coin swaps.)
Last updated