Answering the call: Distributed Twitter made easy!
Jack Dorsey, the CEO of Twitter sent a series of tweets at the end of 2019 saying that Twitter is researching in moving towards a decentralising version of Twitter :
Twitter is funding a small independent team of up to five open source architects, engineers, and designers to develop an open and decentralized standard for social media. The goal is for Twitter to ultimately be a client of this standard. 🧵— jack (@jack) December 11, 2019
As part of these tweets, Jack lays out his reasons for moving towards the decentralisation of Twitter and Social Media. The first reason Jack mentions is the challenges Twitter are facing with their current centralised solution, specifically that applying global policy to a centralised data set is unlikely to scale:
First, we’re facing entirely new challenges centralized solutions are struggling to meet. For instance, centralized enforcement of global policy to address abuse and misleading information is unlikely to scale over the long-term without placing far too much burden on people.— jack (@jack) December 11, 2019
Having a centralised solution for a global product is challenging in today’s ever changing world. How do you ensure that your data meets the standards set by the multiple jurisdictions in which you operate in? How do you ensure that you are not applying the policies of one jurisdiction to the data of another jurisdiction? What do you do when you have conflicting policies to enforce?
From a user’s perspective, once you post a message on Twitter (or other Social Media platforms) you lose all control over that content - you don’t know how your content is monetised, to whom your content is sold to, for what purpose was your data sold, etc.
Finally, new technologies have emerged to make a decentralized approach more viable. Blockchain points to a series of decentralized solutions for open and durable hosting, governance, and even monetization. Much work to be done, but the fundamentals are there.— jack (@jack) December 11, 2019
Benefit of Daml and Smart Contracts
Daml uses the concept of “parties” to represent actors which can be individuals or entities. The disclosure and distribution of data is controlled by the roles these actors play. Actors can have rights (can take actions), be obligable (are accountable for the data they create), and be observers (they can see but not have any obligations or rights).
Since the workflows we define in Daml can run on databases and blockchain alike, developers and business analysts need not think about the underlying platform intricacies. They can instead focus their energies on defining the business logic, which will automatically control the distribution and disclosure of data that the workflow generates. Using a chess analogy, focus on winning the game, not on negotiating the rules and setup of the board.
Before diving into some of the implementation details, here’s a video showing the full functionality of the prototype:
Time for some Smart Contracts!
Central to providing the user with more control over their profile and content is the user profile. Lets create a basic user profile which allows the user to :
- Be the owner to their profile and allows them to maintain it;
- Accept or reject requests from other users to follow them;
- Create posts in the system;
We also need to provide a mechanism for users to find each other in the system :
The ‘signatory’ specifies which parties consents to the creation of a contract. On our contract, we only require the consent of the user. However, other parties must be able to view this contract (otherwise this won’t be a very social network!), which is where `observer` comes in. We’ve specified that other users who have made a request to follow a user may view the contract and also a ‘userDirectory’ party. The ‘userDirectory’ party will allow users to find each other via the front-end public user directory and thus they can make a request to become a follower of a user. This user will be a specific read-only user specifically for this public user directory. Also, we define a key (the username) which allows us to fetch this contract directly a defined key which we will use from the front-end to lookup this contract.
To enforce the observers have a read-only view of this contract, we simply don’t provide any choices for them to perform. That was easy!
Let’s define the choices that only the owner of the contract (ie, the user) can perform against this contract:
The “controller username can” syntax allows us to explicitly specify the set of parties which may modify our contract and the modifications they can make. In our case, we want to limit the choices to the owner of the contract (ie, the end user), meaning no other party will be able to modify our contract.
Interacting with our new models
For the front-end of our “Distributed Twitter” application, we are going to use the React framework (and Typescript). Thankfully, Daml provides us a set of libraries which provides a set of functionality to create smart contracts, execute choices, streaming, etc. for multiple languages.
In order to get started with interacting with the ledger, lets create Typescript representations of our models and choices. Luckily, Daml can do this for us via the command :
For example, this command will generate the following type in Typescript based of our user defined earlier in Daml :
Constants relating to the choices which may be exercised against a given contract in Daml are also generated - This greatly simplifies the exercises of choices :
To create a new contract on the ledger, we simply execute the following :
We have our first smart contract on the ledger in only a few lines of code! We used the ‘useLedger’ React hook to get an instance of the ledger and ‘useParty’ to get the current user connected to the ledger. To create the contract on the ledger, we call the ‘.create’ function on the ledger instance with the target contract type with the details of the contact we wish to create.
Now let’s modify this contract by exercising a choice defined against this contract :
We use the ‘exerciseByKey’ function which allows us to exercise a choice against an existing contract, identified by its key. Our User contract is identifiable by key via the ‘username’ of the contract, so providing this along with the choice we wish to call and the parameters to the choice (in this case, the updated ‘User’) we can modify the contract.
We’ve seen how easy it is to create contracts and modify them (via choices), what about viewing contracts? Of course the Daml library provides functions to retrieve contracts from the ledger! The React library contains React hooks which allow us to stream changes directly from the ledger which means we can update our UI without having to refresh the page!
This will stream all the User contracts which you can observe, which will be your own user contract. In the case of the public user directory, all User contracts are displayed in a read-only view. Any changes to the contract set will update the stream and React will re-render the UI to reflect the change. It’s also possible to provide additional parameters to the Daml React hook ‘useStreamQuery’ to filter on a subset of contracts.
Here’s some more screenshots from the prototype - feel free to explore the implementation of the prototype here at our open source repository:
In conclusion, we’ve learnt how simple it is to use Daml to create Smart Contracts and how to return back control and ownership of data back to the end user. We’ve also learnt how to create, modify or view these contracts from another layer (in our example, the UI layer) and how Daml takes care of all boilerplate code and provides features to make it simple to interact with the underlying ledger.
Please take a look at the open source repository for further implementation details and all pull-requests are welcome:
Also check this application in the OpenWork website: