Getting started with the Rouge protocol
Rouge is an Open Source note and voucher protocol as a suite of smart contracts. It aims to implement a global, trustless, permissionless and decentralized voucher and note platform between three types of actors: “Issuers”, “Bearers” and “Distributors”. Vouchers here should be understood as any kind of “right” given by “Issuers” (possibly via “Distributors”) to “Bearers”. Real life examples of this concept are discount coupons or football match tickets. The schema below sums up the relationship between the 3 actors. Please check our white paper for the complete definition of the Rouge protocol.
This medium post— illustrated with screenshots from “The Coupon Demo” ÐApp — is a small technical introduction of the beta implementation version 0.10.0 of the protocol, that don’t yet include the “Distributor” actor. We also have simplified the function definitions of the smart contracts to exclude authorization delegation mechanisms. This aspect will be explain in a follow-up article. As a warning, please consider that you should expect future very frequent changes that may not be backwards-compatible before the version 1 release (the project has adopted the Semantic Versioning standard).
Thus to get an easy start, this post only focus on what’s happening between “Issuers” and “Bearers” with the use case of discount coupons. We are going to compare step by step what’s happening at the smart contracts level on the Ethereum blockchain and the corresponding results on the screen of the “The Coupon Demo” ÐApp.
1. Getting some Rouge tokens (RGE)
In the Rouge protocol you need to deposit — as an issuer — a “Tare” for each new coupon you want to create. The tare price is exactly 0.1 RGE per coupon in the beta implementation of the protocol (the white paper is aiming for 1 RGE in the future). So we first need to get some RGE!
Because it’s a test, we will work with the Ropsten testnet. You can easily get RGE tokens for this network using our faucet. The contract address of the ERC20 Rouge tokens is 0x32C3f2Ca80677Ccb67AB393d4a2429f47c94A3f3.
2. Creating a campaign and issuing “Notes”
MetaMask already installed, and as soon as you get some RGE tokens from our faucet, you should go to the “Create and Issue Coupons” page of our ÐApp. That’s all you need to be able to create a campaign and issue notes (in this case coupons) by submitting a very simple form.
In the Rouge protocol, a campaign is a set of “Notes” with exactly the same characteristics (so they are fungible) issued at the same time by a unique “Issuer”. In our case, it could be for example an Internet shop creating a coupons campaign to give 40% discount on all its “Nyan Cat Tee shirts”. The issuance parameter in the form, is simply the number of coupons to issue.
So let’s decide to create a campaign with 5 coupons! The deposit should then be at least 0.5 RGE (0.1 RGE tare * 5 coupons). But what’s happening under the hood, after we submit the form button with these parameters?
First, your Ethereum account — as the issuer — will call the function newCampaign(uint32 _issuance, uint256 _deposit)
of the RGE contract. This function only job is to transfer the 0.5 RGE tokens deposit and the issuance information to another contract: the Rouge Factory .
The Factory (currently 0x80c4594d8b21134e4ae53b5a9e79e9fb20ffec41 on Ropsten) is changed every time the implementation of the protocol is modified so the Rouge Network can evolve and be upgraded easily. The Rouge Factory is in charge of creating a new contract instance per campaign created. All subsequent actions of the protocol after the campaign creation, are handled by calling directly this new “Campaign” contract instance.
In our example, the factory has created a new campaign contract “Nyan Cat tee shirts” at the address 0x56c9383b1b2374fc50f1d27c2a7b97ef3c81fd53 (see screenshot above). You can also verify on Etherscan that the 0.5 RGE tokens deposit were transferred into this new campaign contract instance.
The second step, when you submit the ÐApp form, is to issue the coupons themselves by calling the function issue(bytes4 _scheme, string _name, uint _campaignExpiration)
of the campaign contract instance. You can check on the explorer this “issuance” transaction. The second parameter _name
is of course the campaign name as requested in The Coupon Demo ÐApp form. The third parameter _campaignExpiration
is a timestamp corresponding to the end our coupons campaign after which coupon acquisition or redemption is not possible anymore. Finally, _scheme
is a protocol code to differentiate between the many uses cases of notes and vouchers (coupons, tickets, etc) that you can safely ignore a this stage.
3. Acquiring Notes
Once a Rouge campaign has issued its “notes” (that represent coupons in our example), they can immediately be acquired by anyone except the issuer itself. That’s why the ÐApp dashboard on the screenshot below, doesn’t list the Nyan Cat coupons in its “available coupons” right column.
So let’s continue our exploration of the protocol, by acquiring the coupon N°4 “Get out Jail Card” from another campaign created by another issuer.
This action is performed at the Ethereum level by a call to the function acquire(bytes32 _hash, uint8 v, bytes32 r, bytes32 s)
of the campaign contract instance. The first argument _hash
is an hexadecimal sha3 of the message string 'acceptAcquisition' + campaign.address + bearer
which communicate unequivocally that the issuer of the campaign accepts this coupon acquisition. The hash is unique for this event since it contains the campaign instance address and the future “Bearer” address of the coupon. The following 3 parameters, uint8 v, bytes32 r, bytes32 s
are simply the issuer signature of this _hash
to guarantee that only the issuer can produce the unequivocal acceptation message. In the real life, all these parameters, representing the acceptation intent from the issuer, could just fit in a QR code that a user could scan to acquire a coupon.
Here are the screenshots corresponding to this coupon acquisition with the intermediate step during which the acquirer confirms the transaction with MetaMask.
The protocol also implements a second function that can only be called by the issuer of a campaign, to directly distribute a note to any address: distributeNote(address _bearer)
. This function is not used in The Coupon Demo ÐApp.
4. Redeeming a “Note”
This fourth step is very symmetric to the acquisition procedure. The bearer of a coupon needs to call the campaign contract instance with the function redeem(bytes32 _hash, uint8 v, bytes32 r, bytes32 s)
. The arguments are equivalent except that the unequivocal acceptation message string used for authorization is'acceptRedemption' + campaign.address + bearer
. Again the data passed to this function could be just a QR code to scan with a phone for example at a point of sale.
Finally, the redemption could alternatively be triggered by the issuer using the function acceptRedemption(bytes32 _hash, uint8 v, bytes32 r, bytes32 s)
with the same authorization message string 'acceptRedemption' + campaign.address + bearer
but this time signed by the bearer.
We would love to hear your questions, comments or suggestions on the Rouge protocol or its current implementation. You can use our telegram or just write directly an email to clb@rouge.network.
You can clone our reference implementation for the Ethereum blockchain in the repository “Rouge-Protocol-ETH” on The Rouge Project github.