How to add SoG cards, Rarepepe and Counterparty assets to your Unity game
One of the things I like most about Counterparty tokens is apart from acting as an asset or coin or a collectable they can also act as game items.
An example is Spells of Genesis which I am sure you have heard of.
Spells of Genesis cards can be used as Game items in the game as well as contactables outside of the game.
Spells of Genesis and Rarepepe have a huge and passionate userbase, and as their items are Counterparty tokens on the Bitcoin blockchain anybody can use them in their own project with out permission.
For example, I make an game and I want to attract SoG and Rarepepe users, I can just add SoG and Rarepepe cards as game items.
In this article I will show how it can simply be done in Unity right now for Android, iOS and soon for PC. Sample application can be found here
From here it is a little technical and an understanding of Unity, iOS or Android dev will be needed. However you can refer to the sample application and the code is very minimal.
Lets take the following example. I have a simple game in which characters battle.
A popular SoG card is SARUTOBICARD and a popular Rarepepe is SARUTOBIPEPE.
I need to do 4 things
1.) Let the user link their coutnerparty wallet which holds the cards
2.) Prove that the user owns that wallet and isn’t using somebody elses address
3.) Read the balance to check the SARUTOBICARD and SARUTOBIPEPE exist on that address
4.) If they exist unlock the Sarutobi and Sarutobi pepe character in the game.
Setup
You can download the following sample project for Unity here
The project is bare bones and simple but lets you link to the users IndieSquare wallet or Book of Orbs wallet, verifies by sign message and loads the balance displaying it on the screen.
If you are not familiar with IndieSquare or Book of Orbs they are Counterparty wallets which lets you store bitcoin and Coutnerparty tokens/assets.
All of the code of interest is located in Scripts/GetAddress.cs
1.) Link the wallet
First we generate a random message and open the IndieSqaure or Book of Orbs app requesting that it returns the users address and signs the message we provided with the private key of the address. With this Signature we can prove that the user does in fact own the address.
These functions simply detect if the platform is iOS or Android. If iOS it calls the url scheme to open the IndieSquare or BoO app, if Android it calls an intent to do the same.
Important point here is you need to set your applications url scheme represented by the variable urlscheme.
After setting your url scheme in the GetAddress.cs script you also need to set it for your project, Unity doesnt let you do this so you have to add it manually/nativley for Android and iOS.
For iOS you do this by adding the following to the plist of the xcode project that Unity creates when building for iOS
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>YOUR_URL_SCEHEME</string>
</array>
</dict>
</array>
For Android you need to use the CustomURLSchemeLauncher libraries that are included in the sample project.
Once added to your project you need to change the AndroidManifest.xml located in Assets/Plugins/Android.
Find and change
<data android:scheme=”indiesquaresdk” />
to
<data android:scheme=”YOUR_URL_SCHEME” />
This functions also generates a random message which is passed to the apps and is used to prove ownership of the address.
These functions will launch the apps if they exist on the users device, once launched the apps should present the user with a request to get the users address, after the user enters their passcode the app will return to your Unity app returning the following data in a url.
1.Users address
2.Random Message that was signed
3. Signature of the message
(Note if the app opens but does not present the user with a confirmation screen you may need to force close the BoO or IS app and try again)
In the next part we will see how the sample apps parses this data and verifies the signature and thus ownership of the address.
2.) Authenticate the ownership of the address
Once you are able to launch IndieSquare or Book of Orbs and the apps redirect back to your Unity project we can parse the returned data and verify the Signature.
However Unity doesnt offer a way to get the passed date so for Android and iOS we need to do a little set up to make sure the data is returned.
iOS
We need to again change the Xcode project built by Unity.
Specifically you need to find the
— (BOOL)application:(UIApplication*)application openURL:(NSURL*)url sourceApplication:(NSString*)sourceApplication annotation:(id)annotation
function in the
UnityAppController.mm
file
To this function we simply need to add the following to the function
[[NSUserDefaults standardUserDefaults] setObject:url.absoluteString forKey:@“url_scheme”];
[[NSUserDefaults standardUserDefaults] synchronize];
When the IS or BoO app returns the data this function is called in iOS, all we are doing is saving the URL to the userdefaults to be read by Unity.
Android
We need to use the CustomURLSchemeLauncher library. You can find this in the example project, basically you need to copy the
Plugins/CustomUrlSchemeLauncherAndroid and Plugins/Android folder into your Plugins folder.
Next in GetAddress.cs we check in OnApplicationPause if the data is there
For iOS we check the userdefaults for url_scheme which we set in UnityAppController.mm, if it exists we call the function verify address and delete it after use.
For Android we can use the CustomUrlSchemeAndroid.GetLaunchedUrlQuery() to detect data.
Next we verify the signature in VerifyAddress()
Here we use the NBitcoin library to handel all the hard crypto stuff, to use this in your project find the NBitcoin.dll and System.Threading.Tasks.Net35.dll in Assets/Plugins and add them to your project.
In the function we simply parse the url to get the base address and signature
We then create a BitcoinPubKeyAddress object from the address and use its VerifyMessage. If true the address is verified and we assume the user owns the address.
We then use IndieSquare API to load the users balance and see what tokens they hold.
3.) Get users balance
We can use IndieSquare API to read the token balance of the address
More info on IndieSquare API can be found here but we simply use the addresses//balance endpoint which returns a JSON object of the users balance.
4.) Unlock characters/game content
Now we know the user balance we can unlock content, unlock characters etc for example you can detect if the user has a certain SoG card or Pepe card or whatever token you want and then give them a power up or item.
i.e. User has SARUTOBIPEPE card they can unlock a green monkey in your game. Be creative!
PC?
This outlines how to do it for mobile but you can do the same for PC using NBitcoins verifyMessage function, however it would need IndieSquare and BoO to implement a manual sign message function which will be added in the future, however other counteparty wallets me allow you to do so already.
For example your PC game shows a form to the user with an address field, random message to sign and a signature field. The user can use their counterparty wallet to sign the message and enter their address and the signature into the fields.
Concluding thoughts
The benefit of this approach is that tokens do not need to be sent to the game to be used it is all off chain but cryptographical proved! rather than spending the tokens you are checking if the user has them. Sign Message Verify lets you know that the user does have those tokens however it may be possible for one user to lend their wallet to another for the purpose of linking, If you think this may be a problem you can ask the user to verify their wallet frequently or keep track of which users have which addresses and check if two users are using the same address etc.
I hope we will see more use cases of apps and game promoting the use of cross platform and title game items using Counterparty.