Network

Graphs

The social graph is a set of directed, per-user relationships stored on-chain — one of the few things the contract keeps in state, because the graph must be authoritative and queryable. Unlike posts and reactions (which are events only), a relationship is durable storage you can read directly.

A relationship is a bitmap

mapping(uint256 uid => mapping(uint256 target => bytes32)) relationships;

Each (uid → target) edge holds a bytes32 — a 256-bit bitmap. The contract stores it and never interprets it. Bit meanings are a client/registry convention. A single edge can carry many relationships at once, because they are just different bits set in the same word.

Suggested low bits (a convention, not enforced): bit 0 = follow, bit 1 = block, bit 2 = mute, and so on, with higher ranges reserved for community-registered and private-use meanings. Because it is 256 bits, one edge expresses up to 256 distinct kinds of relationship simultaneously — not just a single "follow."

Writing the graph

setRelationships(uid, uint256[] targets, bytes32[] values)   // requires GRAPH

Setting an edge requires the GRAPH permission on the acting uid. It is batch-only — you pass parallel arrays of targets and values. Each pair emits one event:

RelationshipSet(uint256 indexed uid, uint256 indexed target, bytes32 value)

The contract does not check that target exists (that would cost gas for no safety gain), so you can express a relationship to any uid, and clients validate as needed.

Graph types

Because the edge is an open bitmap, the "graph" is really many overlaid graphs sharing one storage map — a follow graph, a block graph, a mute graph, a labels graph — each just a different bit. Clients read the bits they care about and ignore the rest. New graph types are added by agreeing on a new bit in the convention layer, never by changing the contract.

The community membership graph (a member's standing in a community, and the member's own edge back to it) works the same way — see Communities.