From Part 4…
I’m going to extend this feature in my example to cover an SAP S/4 Hana Financial enterprise integration in the next blog post. I’ll keep the details a secret for now, but as a teaser I’ll leave you with this hint.
“What is MicroStrategy leading the corporate world in doing?”
OK, originally I’d just simply put MicroStrategy and that led to some speculation in the blogosphere. I’d been watching the financial news pretty closely, looking for evidence that corporations were indeed adding cryptocurrencies as investment assets to their balance sheet. I thought that most of the readers of this series would have been following that trend as well and get my implicit inference. What I failed to realize is that not all blockchain/crypto watchers have the same agenda nor do they consume the news to the same extent and in the same way. Many are keen to find support for their favorite blockchain/crypto project and existing and/or potential partnerships that project may have tends to strengthen that project’s outlook. While I do work in a team at SAP that interfaces with strategic partners, my role is to take what I’m hearing from partners who are developing with our technology stack and feed it back to our development organization for future feature development. As of this writing, no official partnership in the blockchain/crypto space exists between SAP and MicroStrategy but their offering does interface with SAP S/4 Hana as a data source and this is the sort of integration I like to promote with our partners. The theme of corporations adding crypto assets to their portfolio is becoming more and more prevalent as evidenced by articles and position papers from the likes of Forbes and Accenture to name a few.
How to Account…for BTC.
One of the natural questions that comes to mind once you’ve decided to bite the bullet and add cryptos to your corporate balance sheet is how will this be accounted for and tracked? If you’re an SAP customer using S/4 Hana Treasury & Risk Management then you’ll likely be adding it as something that in accounting speak is called an indefinite-lived intangible asset. Since all assets rise and fall in value over time, the next question you are going to have is “what’s its value today?” Luckily SAP provides a service in its Business Technology Platform(BTP) called Market Rate Refinitiv(Formerly Reuters) option that acts as a bridge between S/4 and its market data feed. The problem is that while it includes many standard currency conversion rates, it doesn’t include cryptocurrencies. It turns out that even the standards organization that controls all the worlds official currency definitions hasn’t figured out how to categorize cryptocurrencies yet. In order to get currency cryptocurrency rate data, you could use the SAP Market Rates Bring Your Own Rates service and enter the price of Bitcoin manually every day, but that would quickly become a chore and what about getting enough data for forecasting? No that won’t do either. You really need a service that will act as a data feed to SAP S/4 and pull in data from a cryptocurrency exchange. There are many in existence, but I’ll use Binance since it’s broadly available and has a handy API for getting historic rates.
But getting the rates is one thing and paying for getting the rates is yet another. This example is really a simplified proof of concept(PoC) implementing such a monetization strategy using the Theta blockchain off-chain micropayments feature from part 4 of this blog series. You can get the sample project as of this blog post with the following.
git clone https://github.com/SAP-samples/btp-blockchain-theta.git git checkout v5.0
In order to make this sample self-contained, I had to combine what would naturally be two separate parties, the sender of something of value (i.e. the latest crypto exchange rates) and the party paying for the service(S/4 customer). Normally these parties would establish a way to advertise the offering and agree to the price before anything is exchanged. How this is done is left up to the customer and provider. A convention may emerge to handle this but for the time being it’s just assumed that the parties have already agreed. Another thing that needs to happen before anything else is that a reserve fund needs to be established for the paying account on the blockchain. Since this is an on-chain operation it can take some time (15-20 secs or so) to get established so in the context of this sample project it’s a manual operation, but in a real S/4 system some mechanism like a cron job would likely need to be needed to set up the reserve fund ahead of data feed requests. In the case where you’re using the privatenet testing blockchain node like I am for this sample I give the receiving party a little TFuel so that they have an initial balance on the blockchain. I’ve deployed this sample app to the BTP Europe region and will try to leave it up for a few weeks if you want to kick it around.
The trustee module is the NodeJS part of the app that handles most of the functions so click on that link to get started.
Who are Alice, Bob and Carol?
The privatenet blockchain node comes prepped with a few private keys. I’m using them for this example to track with the situation described in the Theta article discussing the off-chain micropayment topic. An account can’t be queried on the blockchain until after some value has been transferred to it. This is why you can create wallet addresses at will and without any Internet connection and still have them be valid. It’s a crypto GUID thing.
Give the Bob and Carol test accounts some TFuel and then click micro-payments to view the status of Alice’s account and Bob and Carol’s account balances.
Notice that Alice’s(the party that’s paying) account has an empty reserved_fund and that Bob and Carol have a TFuel balance. Theta blockchain uses a very small unit of account called a wei that is 1/1000000000000000000th of a TFuel and the balances are expressed in this when we look at things in raw form. Most often it’s converted for you as a decimal with some number of digits of precision. More on this later.
Click reserve-fund to preview the transaction and doit to actually establish a reserve fund on Alice’s account.
The important thing to note here is that the resource_ids are needed to indicate which resource the reserve fund is allowed to be charged against. This allow you to set up different resource funds for different purposes.
Note: The Off-Chain/On-Chain links are not working here. Initially I wanted to get all of the off-chain micropayment features working from NodeJS but ran into issues with the existing NodeJS libraries being incomplete. I had to result to implementing them in the Go language in a separate module. This is actually not a bad thing because it demonstrates that with a micro-services approach to development, you are free to use the most appropriate development language for the most appropriate purpose. In this case the library wasn’t available when I wanted(needed) it. In other circumstances it might be that you’d want to isolate a compute heavy task so that you could dynamically scale it out as needed.
Click on the micro-payments link again to see an updated summary now that the reserve fund has been created.
This time things look a bit different.
Notice that now the reserved_funds section is filled in with a collateral section, initial_fund, used_fund, and the resource_ids just mentioned. The end_block_height determines when the fund expires and is destroyed(in block height time). It’s important to remember that all on-chain transaction attempts must be made before this occurs or any outstanding payments will be invalidated.
This as well as the timing and size of the reserve fund needs to be managed, this time by the recipient of the payments. Perhaps a cron job would fit this need as well but this again is left to the implementation.
Now we’re ready to start issuing payments against the reserve fund.
The S/4 Side of Things.
While it’s outside the scope of this blog posting, the setup on the S/4 side of things is configured via transaction SPRO under the Treasury and Risk Management section. Shown here. I’m just going to give you enough detail so that you get a sense of what’s required. As a side-note, Venenzuela had to do something similar when they currency went hyper-inflationary in 2018 and similar steps were required to get BTC to be recognized within S/4.
This involves among other things, defining a datafeed name, an RFC connection, mappings, currency conversions, and translations. Then there is the setup of a new currency by pretending that it’s an official currency and giving it an iso number that won’t conflict with the existing entries. If you would like all the gory details, let me know and I’ll consider doing an addendum to this post.
We can now attempt to request a current cryptocurrency rate from our service. We do this with transaction TBD4.
However when I try this, I get an error.
When I originally set up the currency settings for BTC I told it to use 1:1 ratio with USD. I’ll go set it to 1:100 so that we can get past this issue.
Now when we try to get the latest exchange rate for BTC we get this.
The warning here is just because changing the ratio throws the limit check off for this value and will correct itself on subsequent days.
Turns out one of the big stumbling blocks for any accounting system is that crypto values need to have its values stored with as much as 18 decimal places of precision(Theta Wei) and that not all parts of the system can deal with that. So you get into “rolling up” issues when trying to report and reconcile things. I’ll probably be an accountant by the time this is over. 😉. I do know it can be done since one of our current partners https://www.conbatex.ch/english/customer-stories/iti-sl-1-en/ has a live solution working so knowing something can be done is more than half the battle.
We can. prove that the data got ingested into S/4 by checking the TCURR table with the SE16 transaction.
No S/4 No Problem.
If you don’t have an S/4 Hana Financial system lying around at your disposal, I’ve created a feature in this example to simulate one. Go back to the home page and click on the Request Market Rates button.
The request will ask for the current price of BTC(by passing it zeros) and that of a day randomly chosen between January 1st and 8th of 2021. This way you can click it a few times and get several dates as well as request a few duplicate dates.
The example code simulates storing the crypto rate data in its own database and charging a different amount for rates fetched from cache and those where it actually makes a call out to Binance for the authoritative rate. I did this to demonstrate that since the off-chain micropayment feature is quick and flexible, you can design different monetization strategies to find out what works well in your situation. You might for instance charge more for more timely date, more granular data(hourly vs. daily) forecasted data, time delayed data, etc. The party redeeming the payment only pays for one on-chain settlement no matter the situation.
It’s when you as the solution provider can manage a mis-match of cost(monthly fee to Binance) and revenue(charge many customers per rate) models to your benefit that you are in the best position to maximize your profits.
Now that we have stored up a few off-chain payments, let’s actually get paid. Click on the Settle off-chain link.
You should see a list of pending payments. These have all be signed with the payers signature so that they will be valid when you submit them for on-chain payment.
Scroll to then end and notice that the tfuelwei amount of the last payment is the largest one. This is because the amount accumulates in sequence. Once you take a payment on-chain the blockchain logic prevents you from submitting any earlier payments. This way you are always incentivized to wait as long as possible and only submit one per reserve fund(lest you miss out on a payment you’d otherwise be owed).
For the purposes of testing, the reserve fund has quite a short life so that we don’t have to wait before it expires. Normally you’d have a much longer time to submit your larges payment on-chain.
Now click micro-payment again to see the state of Alice’s(the payers) account.
There is now a tranfer_record within the reserved_funds. This finally represents a real on-chain payment between Alice and Bob(note his address). If we look at Bob’s balance, we see that it’s increased minus the fee to take the payment on-chain.
The numbers here probably don’t match up since I let the fund expire a few times as I was writing this.
Again I encourage you to play with the sample app if it’s still available. If you want to deploy it in your own space, just see the COMMANDS.md file in the cf folder of the project for details on building and deploying it.
I will be recasting this sample as a true multi-tenant application in the future. Maybe this become part 6 at some point but for now I’m going to close out this blog series here. These innovative blockchain projects and features are opening up a world of opportunity for those who willing to venture outside the box.
I’d love to hear your suggestions on if you found this series useful of where you’d like to see it go from here. You can contact me directly if you’d like to dive deeper.
Let me know if you have and questions or issues by leaving me a question below or better yet, asking it on the SAP community.