May 29, 2019
This is the third post in our series describing the details of Securitize’s Digital Securities Protocol (DS Protocol). After our initial introductory post, we introduced the basic interfaces for the Protocol in the second post.
This post will concentrate on two specific DS Protocol Services:
In particular, we will look at the role they play when working with Exchanges so that they can support DS Tokens.
The Trust Service allows for the coordination of activities between different actors in the DS Protocol. This is managed via the roles that the Trust Service can assign to different Ethereum addresses. DS Services take into consideration the roles of those invoking any of their methods, in order to allow or deny certain actions. For instance, the issuer control functions that we described when talking about the DS Token are only offered to actors that have the ISSUER role assigned.
The roles contemplated in the first code release for the DS Protocol are described in the DSTrustServiceInterface:
// Role constantsuint8 public constant NONE = 0; uint8 public constant MASTER = 1; uint8 public constant ISSUER = 2; uint8 public constant EXCHANGE = 4;
One typical use of the Trust Service is for an Issuer to authorize an Exchange so that they can add new investors into the Registry Service. To do this, the Exchange will provide the Issuer with the wallet address (or addresses) that they will use for the DS Protocol operations. The Issuer will then register the wallet as an
EXCHANGE role via the Trust Service method defined in the DSTrustServiceInterface:
function setRole(address address, uint8 role) public /*onlyMasterOrIssuer*/ returns (bool);
This will give the Exchange permission to add new investor information into the Registry Service.
The Registry Service keeps an on-chain register of the investors that may hold the DS Token. To protect investor privacy, the stored data does not include personal identification information, only the relevant attributes to determine the investor category (relevant for regulatory purposes).
The canonical way to get the correct Investor Registry address is to query it from the DS Token via the DSServiceConsumerInterface, using the method:
function getDSService(uint8 _serviceId) public view returns (address);
with the appropriate service ID
The Registry Service is much more than a simple whitelist of authorized wallets. The Registry Service is what allows the DS Protocol to provide investor-centric capabilities to its DS Tokens.
By supporting an entity (i.e. the Investor) that has its own unique identifier and can have one or more wallets assigned to it, DS Tokens move beyond the limitations of traditional ERC20 tokens.
On top of that, the Registry Service holds investor attributes that can identify an investor as a member of a generic category: an accredited U.S. investor, a retail Germany investor, etc. This characterization is fundamental to fulfilling the goal of applying regulatory constraints to trades. We will look more at this when we discuss the Compliance Service, but it is important to realize that said Compliance Service would not be able to provide its functions if not for the information provided by the Registry Service.
The DSRegistryServiceInterface includes all methods required to interact with the Registry Service. Both Issuers and Exchanges (authorized via the Trust Service) will have to interact with it to add new investors, so that they can be part of issuances and secondary trades.
The usual process to add investor information to the Registry Service is:
function registerInvestor(string id, string collision_hash) public /*onlyExchangeOrAbove*/ returns (bool);
If an investor with the same ID is already present in the Registry, the operation will throw. In that case, a different Investor ID must be used.
2. Assign a Country to the Investor, using the method:
function setCountry(string id, string country) public /*onlyExchangeOrAbove*/ returns (bool);
The country value will be the country code in ISO 3166–1 alpha-2 code.
3. Add relevant attributes to the Investor, using the method:
function setAttribute(string id, uint8 attributeId, uint256 value, uint256 expiry, string _proofHash) public /*onlyExchangeOrAbove*/ returns (bool);
The parameters for
uint8 public constant NONE = 0; uint8 public constant KYC_APPROVED = 1; uint8 public constant ACCREDITED = 2; uint8 public constant QUALIFIED = 4; uint8 public constant PROFESSIONAL = 8;
uint8 public constant PENDING = 0; uint8 public constant APPROVED = 1; uint8 public constant REJECTED = 2;
4. Add wallet addresses belonging to this Investor, using the method:
function addWallet(address address, string id) public /*onlyExchangeOrAbove*/ returns (bool);
This operation will fail if the wallet is already assigned to another Investor.
Once an Investor is added to the Registry Service, they will be ready to start receiving tokens, either at the initial issuance or in a secondary trade. Of course, being registered is a required step, but that is not enough. Besides registration, it is also necessary that the Investor attributes match the specific criteria required by the issuance or secondary trade.
We will discuss that in our next post when we look at the Compliance Service, which holds the specific rules that govern the issuance, holding and trading of DS Tokens.