Original article: "Social protocols are rolling up! What is Farcaster?"

Author:ELEN

Farcaster Protocol is another leading product in the SocialFi track after Lens Protocol. Farcaster is a project of former Coinbase executives Dan Romero and Varun Srinivasan. It has currently received US$30 million led by A16Z.

Farcaster's goal is to provide a trusted neutral protocol for the WEB3 ecosystem, allowing users to have a direct connection with their audience while allowing developers to freely build new clients.

Viafarcaster V God settled in

Farcaster's long-term goal is to become an important underlying infrastructure in the WEB3 social track, which is consistent with the direction of Lens Protocol. However, Farcaster's architectural design is much more sophisticated than Lens Protocol, and it adopts a strategy of trying to find an optimal balance between WEB2 and WEB3.

ViaBlockTurbo

Today we will take a deeper look at Farcaster's protocol layer design and ecological application ideas. If you want to study it in depth, you can check out the official github:

https://github.com/farcasterxyz/protocol

Farcaster Introduction

Social networking is the fastest growing industry in the past 10 years. Many social platforms provide APIs for developers, allowing them to "recreate" and develop new ecosystems, such as various fun plug-ins on Twitter. However, in recent years, things seem to be wrong. Developers can do less and less. API restrictions and various censorships have made developers no longer free, and sometimes they are even deprived of access rights without any notice.

Farcaster is a completely decentralized protocol that makes it easy for developers to build decentralized social networking applications. Farcaster's definition of decentralization is simple: when two users want to communicate with each other, there is no way to prevent this from happening. In other words, users have full control over their identities, their data, and their social relationships. Developers can break any third-party or even network restrictions to build a completely decentralized social application.

This vision is also what Lens Protocol wants to achieve. We can think that the greatest value of SocialFi's underlying protocol is to provide a technical underlying implementation method for a completely decentralized social network, so that it will not be controlled by any third party at all, similar to the value of IPFS in the decentralized storage market.

Viafarcaster.network Farcaster Architecture

Farcaster uses a hybrid architecture of on-chain + off-chain to complete the construction of decentralized protocols. Farcaster's identity is stored on the Ethereum chain, and Ethereum is used to ensure its security, composability and consistency. The identity is controlled by the Ethereum address, and the off-chain information is signed by the Ethereum account.

The user's data is encrypted and signed by identity and stored on a server controlled by the user (Farcaster Hubs). The reason why the data is not stored on the chain is that the settlement cost on most L1 and L2 networks is too high and the speed is too slow.

This architecture is somewhat different from the design of LENS Protocol. Farcaster takes more into account the actual needs of developers and is more similar to the expression of WEB2 social media, reducing the cost of user learning. However, Farcaster is still decentralized, and the user's identity, data and social relationships are based on blockchain.

Account

Farcaster accounts are similar to accounts on pseudonymous social networks such as Twitter or Reddit, where an individual can operate several accounts at the same time. Each account has a unique number associated with it, called a Farcaster ID, or Fid. A Farcaster ID can be obtained from an Ethereum address by calling the Farcaster ID Registry (FIR). This address is called an escrow address and can sign off-chain and on-chain messages on behalf of the account. Users can choose to obtain a Farcaster name, or fname, from the Farcaster Name Registry (FNR), which issues them a unique name such as @alice.

It can be understood that Fid is the on-chain identity, and FNR is the social readable identity. If Fid is the wallet address, then FNR is ENS.

Signature Information

Signed information is a tamper-proof and self-authenticated object signed by a fid. Signed information represents a user's behavior, such as posting, social feedback (commenting/forwarding), or modifying account information, such as username.

A signed message has message properties that contain some payload. The payload is serialized, hashed, and signed by a valid key pair (e.g. a costody address). The envelope contains the hash, the signature, and the public key of the signing key pair, which any recipient can use to verify the fid's signature.

Messages must be serialized using RFC-8785, hashed using BLAKE2b, and signed using the Ed25519 signature scheme. Each message must also contain a fid to query the escrow address on the chain, and a timestamp for sorting.

application

Applications are programs that people use to interact with the Farcaster network. A simple application might consist of a standalone desktop or mobile client that talks directly to the Farcaster Hub. It can post new messages and view messages posted by other fids. Such applications are self-hosted and must be instantiated with a hosting address or a valid signing key.

More complex applications might add a proxy backend server that indexes the Hub's data. Indexing allows the server to implement features such as search, algorithmic feeds, and spam detection that are difficult or expensive to perform on the Hub. Such applications can be self-hosted by storing keys on the client; delegated by requiring users to provide delegated signing keys; or hosted by managing all keys.

Hubs

The Hub is an always-online server that verifies, stores, and replicates signed messages. Users select a Hub and publish its URL on-chain using FIR. Their Followers can use this URL to find and download their messages. Users can also run the Hub themselves or use a third-party hosting service.

Farcaster's identity

Farcaster's identity system enables users to have the following characteristics:

Secure and fully decentralized Easily identifiable in social networks Easy to set up (fast and cheap) Recoverable (without violating the decentralized nature)

These properties are challenging to implement in an identity system because they are often in conflict. For example, it is difficult to have a decentralized, trustworthy name system (e.g., whether the name system is unique or not).

Farcaster leverages these features through two separate systems. The Farcaster ID Registry (FIR) issues new ID numbers, called fids, and the Farcaster Name Registry (FNR) issues new usernames, called fnames. Fids are secure, decentralized identifiers that exist in every piece of information and are similar in concept to uuids.

Fnames are primarily for FIR decoration, replacing fid at render time, and can be changed at any time. Separating an identity into these two components allows us to achieve our goals, but at the cost of adding some complexity to the system. Both systems also implement a recovery mechanism to protect against the loss of the key pair that controls the name without affecting decentralization.

Farcaster ID Registry (FIR)

Farcaster IDs are numeric identifiers, similar to UUIDs. When displayed to the user, they are preceded by an exclamation mark (for example: !8098).

A FID represents a unique entity, such as a person or an organization. Every piece of information that references that entity must use its fid, not its fname. The registration fee for a fid is low, and it is a lifetime ownership. The FID contract cannot be upgraded or modified in any way.

FID starts at 0 and increments by 1 every time a new registration occurs. A fid is stored on-chain as a uint256, guaranteeing a nearly infinite supply as it can be incremented up to ~10^77.

Users can use FIR to configure the URL where their off-chain information is located.

Farcaster Name Registry (FNR)

Farcaster names are unique, similar to usernames on other networks. When displayed to users, they are shown with an @ symbol in front (for example: @alice).

Fnames, along with profiles, names, and verification stamps, help visually identify an entity while browsing the web. Unlike fids, fnames are primarily readable and have no relationship to the underlying data created by the user. Ownership of an fname is not permanent and users must pay some fees every year. Fname renewal can be done 90 days before the expiration of the fname. Expired names will be auctioned in a Dutch auction, and bidders must pay an annual fee and a premium, which starts at 1000 ETH. The premium decreases by 10% every 8 hours until it reaches 0 ETH.

Fnames are NFTs issued by the Farcaster name registry on a first-come, first-served basis. Each name must conform to the regular expression /^[a-z0-9][a-z0-9-]{0,15}$/. They have specific properties that make them more useful in social networks relative to other namespaces such as ENS. They are cheaper to mint and own, are less vulnerable to homophone attacks due to the limited character set, and are also recoverable. Farcaster does not enforce the use of fnames, and users are free to use other namespaces with their fids.

Abandoning the use of fnames does not have a big impact, because Farcaster is designed around fid, and every information and behavior refers to fid rather than frame. fnames can be changed at any time without losing any previous dependency information.

Username Policy

During the beta period, usernames can be registered for free and are subject to a simple policy. The purpose of the policy is to prevent names from being taken by inactive users or used maliciously to impersonate someone else. The solution to this problem is not easily automated and requires human judgment to enforce. The username policy has two core principles:

Impersonation Registration - If you register a username that belongs to a well-known public figure or entity, your name may be deregistered. For example, @elonmusk, @vitalikbuterin, @google, or @whitehouse. Inactivity - If you have not actively used a username for more than 60 days, your name may be deregistered at the request of other users or at our discretion.

We expect manual intervention will often be needed because there may be legitimate conflicts. For example, you registered @vitalik and Vitalik Buterin registered after you and wants that name. In this case, we ask three questions to guide the decision:

Is the user active and engaged on Farcaster? (For example, if they have made high-quality posts over the past few months.) Does the user have a legitimate claim to the name? (For example, if their first name is also Vitalik) Does the user have similar, active accounts on other networks? (For example, if they have vitalik and vitalik.ens on Twitter).

If the answers to these questions are mostly yes, they will retain their claim to their name. In the testnet, the core team will arbitrate such conflicts, and we hope to formally establish a governance system around this issue as we get closer to mainnet. If a name is reclaimed as a result of arbitration, the user will not be refunded.

Account Recovery

Farcaster IDs and names are recoverable if the user loses the keys to the address holding the ID and name. Both contracts implement a delayed recovery system that allows the recovery address to request a transfer to a new address. The recovery address can complete the transfer if the custodial address does not cancel the transfer within three days.

Users can set the recovery address to another address in their own wallet, a multisig shared with friends, or a third-party recovery service. Users can also change the recovery address at any time. Ownership remains decentralized because the recovery address cannot be transferred without the consent of the custodial address.

Transferring assets to a new escrow address will unset the recovery address. Otherwise, a user could buy a name on OpenSea, but have the previous owner secretly claim it back using their recovery address.

Information Processing

Message processing is the process by which a Hub receives new messages and determines the status of a user. Users send messages to a Hub for each of their actions. If a user likes a URL, dislikes it, and likes it again, three messages will be generated. A Hub that receives all messages will determine the current status of the URL that the user likes.

The Hub can discard the first two messages to save space. The Hub can use a merge operation to compress such messages, which avoids client inconsistencies and saves space. Messages may have different rules for their merge operations. For example, two likes from a user to the same user can be compressed into one, but two replies cannot.

The Hub may miss some information about a user and end up in an incorrect state. For example, it may only receive the first like and dislike, which sets the current state to dislike. The merge operation should allow the state to move forward and reach consistency when the missing messages are rebroadcast. In other words, the merge should ensure eventual strong consistency.

Hubs do this by implementing a set of CRDTs for each message type, encoding specific validation and merging rules. This feature makes Hubs highly available, as they can go offline at any time and always be able to get back in sync. Formally, our CRDT sets are anonymous delta-state CRDT2s, where each message is a connected and irreducible update on the set.

Information sorting

Message collections can sort signed messages by timestamp, resolving merge conflicts in a last-written order. However, they cannot guarantee perfect ordering, as timestamps are susceptible to clock skew, clock drift, spoofing by malicious users, and can collide for a number of reasons. Applications can use hybrid clocks to produce perfectly ordered timestamps that do not collide, but we cannot enforce their use.

Instead, we define an ordering system for messages that ensures total ordering by using timestamps to determine the initial ordering and hash values ​​to break conflicts. Total ordering is guaranteed because two messages cannot have the same hash value unless they are the same message. Two messages a and b can be compared using this algorithm:

If a.timestamp > b.timestamp, then a is greater. If a.timestamp < b.timestamp, then b is greater. If a.timestamp == b.timestamp

- If a.hash>b.hash, then a is larger.

- If a.hash < b.hash, then b is greater.

- If a.hash = b.hash, a == b

Timestamps are compared as numbers, while hashes are compared as strings. Since string comparisons vary between implementations, we must be precise in our comparison algorithm. We assume that two hash values ​​x and y can be compared by comparing every pair of characters:

If all character pairs are equal and both x and y terminate, then x == y If all character pairs are equal and x terminates first, then y>x If a different character pair xC, yC is encountered, then if ASCII(yC)>ASCII(xC), then y>x

Information Verification

In addition to message type specific validation, all messages must pass the following validations:

message.timestamp is no more than 1 hour ahead of the system time. message.fid must be a known fid number from the FIR. signerPubKey should be a valid escrow signer or delegate signature for message.fid hashFn(serializeFn(message)) must match envelope.hash, where hashFn is a Blake2B function and serializeFn performs JSON canonicalization. EdDSA_signature_verify(envelope.hash, envelope.signerPubKey, envelope.signature) should pass.

Casts

Casts are public messages created by users that contain text and can also embed media, on-chain events, or other Casts. Casts are stored in a two-phase collection CRDT3 to resolve conflicts between messages.

A Cast can be added via a CastAdd message, which is placed in the CRDT's add-set. Each Cast is indexed by its hash value, which is guaranteed to be unique unless the Casts are identical. By extension, two add messages will never conflict unless they are identical, in which case one can be safely discarded.

Casts can be removed via a CastRemove message, which contains a reference to the hash value of the target CastAdd. When this message is received, the target is removed from the add-set if it exists, and the removed is added to the rem-set. Conflicts between adds and removes are handled with the Remove-Wins rule, while conflicts between removes are handled with the Last-Write-Wins rule, falling back to lexicographical ordering in case of a tie.

add information

A Cast Add can contain up to 320 characters of unicode text and two URIs of up to 256 characters. The client is responsible for decoding and rendering the URIs and text together.

A Cast without a parent is a top-level Cast that the client should display on the user's profile or timeline. A Cast with a parent is a reply to another Cast, web URL, or on-chain object and should be displayed in a thread.

Votes form a series of trees, with each root being a vote or URI and each child being a reply to a vote. Each tree can be rendered as a threaded conversation. The tree is guaranteed to be acyclic because a parent node must be hashed and signed before a child node can point to it. Any change to a parent node's data will break all relationships with its children.

Cast information must pass the following verification steps.

The text must contain <=320 valid unicode characters embed must contain 0 to 2 items. An item must be a URI of at most 256 characters. If a parent is present, it must be a valid URI that is not equal to the URI of this message (e.g., fid:/cast:).

delete message

Cast Remove contains only a reference to the hash value of Cast Add. It allows to permanently remove the Cast, while deleting the data of the original Cast.

The message must pass the following validation steps:

message.data.body.hash must not be equal to message.envelope.hash. message.timestamp must be <= system clock + 10 minutes message.data.fid must be a known fid in the FIR

Merge rules

When an add message a is received, if there is r in rem-set and r.data.body.hash is equal to a.hash, then discard a. Otherwise, add a to the add set. When a remove message r is received, if there is an a.hash equal to r.data.body.hash in the add set, remove it. If there is an r' in rem-set where r.data.body.hash is equal to r'.data.body.hash, if r'>r, discard r'; if r'

Actions

An action is a public operation performed by a user on a target, which can be another user or an on-chain activity. Currently two types of actions are supported: like and follow. The protocol can be easily extended to support new actions. Users can undo and redo actions by toggling the activity property on a message. Conceptually, each action is an edge in the social graph.

Actions are managed with LWW-Element-Set CRDTs, which guarantee eventual consistency. Conceptually, there is a single set that stores all messages, and conflicts are resolved by timestamp and lexicographical hash order. Additions are made by constructing an action message a with active set to true, while deletions are made by setting active to false. In both cases, the logic for merging messages into the set is:

If there is an Action x in the collection, its type, target Uri, and fid values ​​are the same as the passed action y. If x>y, discard y; if x

verify

Verification is a two-way proof of ownership between a Farcaster account and an external entity. Verification can be used to prove ownership of an Ethereum address, a specific NFT, other social media accounts, or even a domain name.

There are three core concepts in verification:

A claim, including references to a Farcaster account and an external entity. Claims can be hashed to create a unique identifier for each claim. A directional proof from an external entity that is authorized to make the claim, showing its intent to connect to a Farcaster account. A directional proof from a Farcaster account, accepting a request to associate a claim with a Farcaster account.

Signer Authorization

A signer authorization is a message authorizing a new key pair to generate signatures for a Farcaster account.

Once a FID is minted, only the custodial address can sign messages on its behalf. Users may not want to load this key pair into every device as it increases the risk of an account being compromised. Custodial addresses, also known as custodial signers, can authorize other key pairs known as delegate signers. Unlike custodial signers, delegate signers are only allowed to publish off-chain information and cannot perform any on-chain operations.

Custodial signers generate ECDSA signatures on the secp256k1 curve and can only publish signer authorization information. All other types of messages must be signed by a delegate signer, which creates EdDSA signatures on curve255194. Delegated signers can be used to authorize new devices or even third-party services to sign messages for an account. If a delegate signer is compromised, it can be revoked by itself, its ancestors in the trust chain, or any custodial signer. When a signer is revoked, Hubs discards all of its signed information because there is no way to distinguish between a user's information and an attacker's information.

A user may also transfer an ID to a new custody address due to key recovery or wallet change. It is usually desirable to preserve history, so both custody addresses become valid custody signers. The set of valid signers for an ID forms a series of different trees. The root of each tree is a historical custody address, and the leaves are delegated signers.

The signer set is a modified two-phase set with delete-wins and last-write-wins semantics. New messages are added to the set if they are signed by a valid principal or guardian. Delete messages are accepted if they are signed by self or an ancestor. Once a signer is removed, it cannot be added again, and all its descendants and messages are discarded.

If two valid signers each authorize the same delegate signer, a set collision will occur, which destroys the tree data structure. If this happens, the set will retain the message with the highest timestamp and lexicographical hash, in order.

Fragmentation

Hubs can replicate data only for specific accounts, a useful property for scaling the network. If Farcaster grows large enough that a single server cannot support replicating the entire network of Hubs, the workload can be spread across multiple Hubs. Hub operators can also avoid syncing data for users who have malicious intent or are unrelated to the operator.

Selective replication only provides a partial view of the network. If a Hub is syncing Alice's data, it will know that she replied to and liked one of Bob's posts. However, it will not know the content of Bob's post, or the fact that Bob liked her reply and then followed up with a reply. An application that aims to provide accurate like counts and provide information about all replies should replicate as many users as possible.