Texto original: "¡El Protocolo Social está enrollado!" ¿Qué es el teleyector? 》
Autor: ELÉN
Farcaster Protocol es otro producto líder en el ámbito SocialFi después de Lens Protocol. Farcaster es un proyecto de los ex ejecutivos de Coinbase Dan Romero y Varun Srinivasan. Actualmente ha recibido 30 millones de dólares en inversiones lideradas por A16Z.
El objetivo de Farcaster es proporcionar un protocolo neutral confiable para el ecosistema WEB3, permitiendo a los usuarios tener contacto directo con sus audiencias, al mismo tiempo que permite a los desarrolladores crear nuevos clientes libremente.
El dios Viafarcaster V se instaló
El objetivo a largo plazo de Farcaster es convertirse en una infraestructura subyacente importante en la vía social WEB3. Esto es consistente con la dirección de Lens Protocol. Sin embargo, el diseño arquitectónico de Farcaster es mucho más sofisticado que Lens Protocol y adopta un intento de cerrar la brecha. entre WEB2 y WEB3.Una estrategia para encontrar un punto de equilibrio óptimo.
VíaBlockTurbo
Hoy analizaremos en profundidad el diseño de la capa de protocolo y las ideas de aplicaciones ecológicas de Farcaster. Si desea estudiar en profundidad, puede consultar el github oficial:
https://github.com/farcasterxyz/protocol
Introducción al teleyector
Las redes sociales han sido la industria de más rápido crecimiento en los últimos 10 años. Muchas plataformas sociales proporcionan API a los desarrolladores, lo que les permite realizar una "creación secundaria" y desarrollar nuevos ecosistemas, como varios complementos divertidos en Twitter. Sin embargo, en los últimos años, las cosas no parecen estar bien. Parece que cada vez hay menos cosas que los desarrolladores pueden hacer. Las restricciones de API y varias censuras hacen que los desarrolladores ya no sean libres, a veces incluso sin previo aviso. privado del derecho de acceso.
Farcaster es un protocolo completamente descentralizado que facilita a los desarrolladores crear aplicaciones de redes sociales descentralizadas. La definición de descentralización de Farcaster es simple: cuando dos usuarios quieren comunicarse entre sí, no hay forma de evitar que esto suceda. Es decir, los usuarios tienen control total sobre sus identidades, sus datos y sus conexiones sociales. Los desarrolladores pueden romper las restricciones de cualquier tercero o incluso de la red para crear una aplicación social completamente descentralizada.
Esta visión es también lo que Lens Protocol quiere lograr. Podemos pensar que el mayor valor del protocolo subyacente de SocialFi es proporcionar un método de implementación técnica subyacente de red social completamente descentralizado, de modo que no sea controlado por ningún tercero. Similar al valor de IPFS en el mercado de almacenamiento descentralizado.
Viafarcaster.network Arquitectura Farcaster
Farcaster adopta una arquitectura híbrida dentro y fuera de la cadena para completar la construcción de un protocolo descentralizado. La identidad de Farcaster se almacena en la cadena Ethereum y aprovecha Ethereum para garantizar su seguridad, componibilidad y coherencia. Las identidades se controlan a través de direcciones de Ethereum y los mensajes fuera de la cadena se firman a través de cuentas de Ethereum.
Los datos del usuario se cifran y firman mediante identidad y se almacenan en servidores controlados por el usuario (Farcaster Hubs). La razón por la que los datos no se almacenan en la cadena es porque el costo de liquidación en la mayoría de las redes L1 y L2 es demasiado alto y la velocidad. es demasiado lento.
Esta arquitectura es diferente del diseño del Protocolo LENS. Tiene más en cuenta las necesidades reales de los desarrolladores y es más similar a la forma de expresión de las redes sociales WEB2, lo que reduce el costo de aprendizaje del usuario. Sin embargo, Farcaster todavía está descentralizado y los usuarios. La identidad, los datos y las relaciones sociales se basan en blockchain.
Cuenta
Las cuentas de Farcaster son similares a las cuentas de redes sociales seudónimas como Twitter o Reddit, y los individuos pueden operar varias cuentas al mismo tiempo. Cada cuenta tiene un número único asociado, llamado Farcaster ID o Fid. Se puede obtener una ID de Farcaster desde una dirección de Ethereum llamando al Registro de ID de Farcaster (FIR). Esta dirección se denomina dirección de depósito de garantía y puede firmar información dentro y fuera de la cadena en nombre de la cuenta. Los usuarios pueden optar por obtener un nombre de Farcaster o un fname del Registro de nombres de Farcaster (FNR), que les emite un nombre único como @alice.
Se puede entender que Fid es una identidad en cadena, mientras que FNR es una identidad socialmente legible. Si Fid es la dirección de la billetera, entonces FNR es ENS.
Información de firma
La información de la firma es un objeto autocertificado y a prueba de manipulaciones, firmado por fid. La información de la firma representa acciones del usuario, como publicaciones, comentarios sociales (comentarios/retwitteo) o modificación de información de la cuenta, como el nombre de usuario.
Los mensajes firmados tienen atributos de mensaje que contienen cierta carga útil. La carga útil se serializa, se procesa mediante hash y se firma mediante un par de claves válido (por ejemplo, dirección de costody). El sobre contiene el valor hash, la firma y la clave pública del par de claves de firma, que cualquier destinatario puede usar para verificar la firma del fid.
Los mensajes deben serializarse mediante RFC-8785, aplicar hash mediante BLAKE2b y firmarse mediante el esquema de firma Ed25519. Cada mensaje también debe contener un fid para consultar la dirección de depósito en garantía en cadena y una marca de tiempo para ordenar.
solicitud
Las aplicaciones son los programas que las personas utilizan para interactuar con la red Farcaster. Una aplicación simple podría consistir en un cliente móvil o de escritorio independiente que se comunica directamente con Farcaster Hub. Puede publicar mensajes nuevos y ver mensajes publicados por otros FID. Estas aplicaciones son autohospedadas y se les debe crear una instancia con una dirección de alojamiento o una clave de firma válida.
Las aplicaciones más complejas pueden agregar un servidor proxy backend para indexar los datos del Hub. La indexación permite al servidor implementar funciones como búsqueda, alimentación de algoritmos y detección de spam, que son difíciles o costosas de realizar en el Hub. Una aplicación de este tipo puede autohospedarse almacenando claves en el cliente; delegarse solicitando al usuario que proporcione una clave de firma delegada o custodiarse administrando todas las claves.
Centros
El Hub es un servidor siempre activo que verifica, almacena y replica información de firmas. El usuario selecciona un Hub y publica su URL en la cadena usando FIR. Sus seguidores pueden utilizar esta URL para buscar y descargar sus mensajes. Al mismo tiempo, los usuarios también pueden ejecutar el Hub ellos mismos o utilizar servicios de alojamiento de terceros.
La identidad del teleyector
El sistema de identidad de Farcaster permite que la identidad de un usuario tenga las siguientes propiedades:
Seguro y totalmente descentralizado Fácilmente identificable en redes sociales Fácil de configurar (rápido y barato) Recuperable (no viola la naturaleza de la descentralización)
Estas características son difíciles de implementar en un sistema de identidad porque a menudo están en conflicto. Por ejemplo, es difícil tener un sistema de nombres descentralizado y confiable (por ejemplo, si se debe garantizar la unicidad del sistema de nombres).
Farcaster equilibra estas características a través de dos sistemas independientes. El Registro de identificación de Farcaster (FIR) emite nuevos números de identificación, llamados fids; el Registro de nombres de Farcaster (FNR) emite nuevos nombres de usuario, llamados fnames. Los Fids son identificadores seguros y descentralizados que están presentes en cada mensaje y son conceptualmente similares a los uuids.
Los nombres F son principalmente para modificación FIR, reemplazan a fid al renderizar y se pueden cambiar en cualquier momento. Separar una identidad en estos dos componentes nos permite lograr nuestros objetivos, pero a costa de agregar cierta complejidad al sistema. Ambos sistemas también implementan un mecanismo de recuperación que protege la pérdida de los pares de claves que controlan los nombres sin afectar la descentralización.
Registro de identificación de teleyectores (FIR)
Los ID de Farcaster son identificadores numéricos, similares a los uuids. Cuando se muestren al usuario, estarán precedidos por un signo de exclamación (por ejemplo:! 8098).
Un FID representa una entidad única, como una persona o una organización. Cada referencia a esta entidad debe utilizar su fid, no su fname. La tarifa de registro para FID es muy baja y su propiedad es de por vida. Los contratos FID no se pueden actualizar ni modificar de ninguna manera.
El FID comienza en 0 y se incrementa en 1 cada vez que se produce un nuevo registro. Un fid se almacena en cadena como uint256, lo que garantiza un suministro casi infinito, ya que puede incrementarse a ~10^77.
Los usuarios pueden usar FIR para configurar URL para encontrar la ubicación de su información fuera de la cadena.
Registro de nombres de teleyectores (FNR)
Los nombres de los teleyectores son únicos, similares a los nombres de usuario de otras redes. Cuando se muestran al usuario, estarán precedidos por un símbolo @ (por ejemplo: @alice).
Fname, junto con el perfil, el nombre y los tokens de verificación, ayuda a identificar visualmente una entidad mientras navega por la web. A diferencia de fids, fname es principalmente legible y no tiene nada que ver con los datos subyacentes creados por el usuario. La propiedad de fname no es permanente y los usuarios deben pagar algunas tarifas anuales. La renovación de fname se puede realizar 90 días antes de que expire. Los nombres caducados se subastarán en una subasta holandesa, y los postores deberán pagar una tarifa anual y una prima, a partir de 1000 ETH. La prima disminuye un 10% cada 8 horas hasta llegar a 0 ETH.
Los Fnames son NFT emitidos por Farcaster Name Registry por orden de llegada. Cada nombre debe coincidir con la expresión regular /^[a-z0-9][a-z0-9-]{0,15}$/. Tienen propiedades específicas que los hacen más útiles en las redes sociales en comparación con otros espacios de nombres como ENS. Son más baratos de acuñar y poseer, son menos susceptibles a ataques homófonos debido a limitaciones en el conjunto de caracteres y también son recuperables. Farcaster no requiere el uso de fname, los usuarios son libres de usar otros espacios de nombres y sus fids.
Renunciar al uso de fname no tendrá mucho impacto, porque Farcaster está diseñado en torno a fid, y cada información y comportamiento apunta a fid en lugar de frame. Los nombres fname se pueden cambiar en cualquier momento sin perder ninguna información de dependencia anterior.
Política de nombre de usuario
Durante el período beta, los nombres de usuario se pueden registrar de forma gratuita y están sujetos a una política sencilla. El propósito de esta política es evitar que usuarios inactivos tomen nombres o los utilicen maliciosamente para hacerse pasar por otros. La solución a este problema no se automatiza fácilmente y requiere juicio humano para su ejecución. La política de nombre de usuario tiene dos principios básicos:
Suplantación de identidad: si se registra con un nombre de usuario que pertenece a una figura o entidad pública conocida, es posible que se cancele el registro de su nombre. Por ejemplo, @elonmusk, @vitalikbuterin, @google o @whitehouse. Inactividad: si no ha utilizado activamente un nombre de usuario durante más de 60 días, es posible que se cancele el registro de su nombre a petición de otro usuario o a nuestra discreción.
Anticipamos que a menudo será necesaria la intervención manual, ya que puede haber conflictos legítimos. Por ejemplo, usted registró @vitalik y Vitalik Buterin se registró después de usted y quería ese nombre. En este caso, hacemos tres preguntas para guiar la decisión:
¿Este usuario está activo y comprometido en Farcaster? (Por ejemplo, si han publicado publicaciones de alta calidad en los últimos meses). ¿Tiene este usuario un derecho legítimo sobre el nombre? (Por ejemplo, si su nombre también es Vitalik) ¿Este usuario tiene cuentas activas similares en otras redes? (Por ejemplo, si tienen vitalik y vitalik.ens en twitter).
Si la mayoría de las respuestas a estas preguntas son afirmativas, conservarán el derecho a su nombre. En la red de prueba, el equipo central arbitrará este conflicto y esperamos establecer formalmente un sistema de gestión en torno a este problema a medida que nos acerquemos a la red principal. Si se retira un nombre como resultado de un arbitraje, los usuarios no recibirán ningún reembolso.
Recuperación de Cuenta
Si un usuario pierde la clave de la dirección que contiene el ID y el nombre, el ID y el nombre de Farcaster son recuperables. Ambos contratos implementan un sistema de recuperación retrasada que permite que las solicitudes de dirección de recuperación se transfieran a una nueva dirección. Si la dirección de custodia no cancela la transferencia dentro de los tres días, la dirección de recuperación puede completar la transferencia.
Los usuarios pueden configurar la dirección de recuperación en otra dirección en su propia billetera, una firma múltiple compartida con amigos o un servicio de recuperación de terceros. Los usuarios también pueden cambiar la dirección de recuperación en cualquier momento. La propiedad permanece descentralizada porque la dirección de recuperación no puede realizar transferencias con las que la dirección de custodia no esté de acuerdo.
La transferencia de activos a una nueva dirección de depósito en garantía cancelará la dirección de recuperación. De lo contrario, un usuario podría comprar un nombre en OpenSea, sólo para que el propietario anterior lo reclame en secreto utilizando su dirección de recuperación.
procesamiento de información
El procesamiento de información es el proceso mediante el cual el Hub acepta nuevos mensajes y determina el estado del usuario. Los usuarios envían mensajes a un Hub para cada una de sus acciones. Si a un usuario le gusta una URL, no le gusta y le gusta, se generarán tres mensajes. Un Hub que reciba toda la información determinará el estado actual de las URL favoritas del usuario.
Hub puede descartar los dos primeros datos para ahorrar espacio. El Hub puede comprimir dichos mensajes mediante una operación de fusión, lo que evita inconsistencias del lado del cliente y ahorra espacio. Los mensajes pueden tener reglas diferentes para sus operaciones de combinación. Por ejemplo, dos Me gusta de un usuario al mismo usuario se pueden comprimir en uno, pero dos respuestas no.
El Hub puede perder parte de la información del usuario y terminar en un estado de error. Por ejemplo, es posible que solo reciba el primer mensaje de Me gusta y No me gusta, lo que establece el estado actual en No me gusta. La operación de fusión debería permitir que el estado avance y logre coherencia a medida que se retransmiten los mensajes faltantes. En otras palabras, la fusión debería garantizar al final una fuerte coherencia.
Hub logra esto implementando un conjunto de CRDT para cada tipo de mensaje, codificando reglas de validación y fusión específicas. Esta característica hace que los Hubs tengan una alta disponibilidad, ya que pueden desconectarse en cualquier momento y siempre pueden restaurarse para sincronizarse. Formalmente, nuestro conjunto CRDT es un CRDT2 anónimo de estado delta, y cada mensaje es una actualización conectada e irreductible del conjunto.
clasificación de información
La recopilación de información puede ordenar la información de la firma por marca de tiempo y resolver conflictos de fusión con una última política escrita. Sin embargo, no pueden garantizar un orden perfecto porque las marcas de tiempo son susceptibles a sufrir desfases y desviaciones del reloj, suplantación de identidad por parte de usuarios malintencionados y pueden colisionar por varias razones. Las aplicaciones pueden utilizar relojes mixtos para producir marcas de tiempo perfectamente ordenadas sin colisiones, pero no podemos forzar su uso.
En su lugar, definimos un sistema de ordenación de mensajes que garantiza la ordenación total mediante el uso de marcas de tiempo para determinar la ordenación inicial y hashes para romper colisiones. El orden total está garantizado porque dos mensajes no pueden tener el mismo valor hash a menos que sean el mismo mensaje. Se pueden comparar dos mensajes a y b utilizando este algoritmo:
Si a.timestamp>b.timestamp, entonces a es mayor. Si a.timestamp < b.timestamp, entonces b es mayor. si a.marca de tiempo == b.marca de tiempo
- Si a.hash>b.hash, entonces a es mayor.
- Si a.hash < b.hash, entonces b es mayor.
- resultado a.hash = b.hash, a == b
Las marcas de tiempo se comparan como números, mientras que los hashes se comparan como cadenas. Dado que las comparaciones de cadenas varían entre implementaciones, debemos ser precisos en nuestros algoritmos de comparación. Creemos que se pueden comparar dos valores hash xey comparando cada par de caracteres:
Si todos los pares de caracteres son iguales y x e y terminan, entonces x == y Si todos los pares de caracteres son iguales y x termina primero, entonces y>x Si se encuentra un par de caracteres diferente xC, yC, entonces Si ASCII( yC)>ASCII(xC), entonces y>x
Verificación de información
Además de las validaciones específicas del tipo de mensaje, todos los mensajes deben pasar las siguientes validaciones:
message.timestamp no está más de 1 hora por delante de la hora del sistema. message.fid debe ser un número fid conocido en la FIR. signerPubKey debe ser un firmante administrado válido o una firma delegada para message.fid hashFn(serializeFn(message)) debe coincidir con sobre.hash, donde hashFn es una función Blake2B y serializeFn realiza la normalización JSON. EdDSA_signature_verify(envelope.hash, sobre.signerPubKey, sobre.signature) debe pasar.
moldes
Cast es información pública creada por los usuarios, que contiene texto y también puede integrarse en medios, actividades en cadena u otros Casts. Las transmisiones se almacenan en una colección CRDT3 de dos etapas para resolver conflictos entre mensajes.
Se puede agregar un Cast a través del mensaje CastAdd, que se coloca en el conjunto de complementos del CRDT. Cada Cast está indexado por su valor hash, que se garantiza que será único a menos que los Casts sean idénticos. Por extensión, dos mensajes de adición nunca entrarán en conflicto a menos que sean idénticos, en cuyo caso uno puede descartarse de forma segura.
Las conversiones se pueden eliminar mediante el mensaje CastRemove, que contiene una referencia al hash del CastAdd objetivo. Cuando se recibe este mensaje, el objetivo se elimina del conjunto adicional si existe, y el objetivo eliminado se agrega al conjunto remoto. Los conflictos entre adiciones y eliminaciones se manejan con la regla Remove-Wins, mientras que los conflictos entre eliminaciones se manejan con la regla Last-Write-Wins, recurriendo al orden lexicográfico en caso de empate.
añadir información
Un Cast Add puede contener texto Unicode de hasta 320 caracteres y dos URI de hasta 256 caracteres. El cliente es responsable de decodificar y representar el URI y el texto juntos.
Un elenco sin un padre es un elenco de nivel superior y el cliente debe aparecer en el perfil o línea de tiempo del usuario. Una transmisión parental es una respuesta a otra transmisión, URL web u objeto en cadena y debe mostrarse en un hilo.
Las encuestas forman una serie de árboles, donde cada raíz es una encuesta o URI y cada nodo secundario es una encuesta de respuesta. Cada árbol se puede representar como una conversación encadenada. Se garantiza que el árbol será aperiódico porque el nodo padre debe tener un hash y firmarse antes de que un nodo hijo pueda señalarlo. Cualquier cambio en los datos del nodo principal destruirá todas las relaciones con sus nodos secundarios.
La información transmitida debe pasar los siguientes pasos de verificación.
El texto debe contener <=320 caracteres Unicode válidos. La inserción debe contener de 0 a 2 elementos. Los elementos deben ser un URI de hasta 256 caracteres. Si un padre está presente, debe ser un URI válido, no igual al URI de este mensaje (por ejemplo, fid:/cast:).
borrar mensaje
Cast Remove simplemente contiene una referencia al hash de Cast Add. Permite la eliminación permanente del Cast mientras se eliminan los datos del Cast original.
El mensaje debe pasar los siguientes pasos de verificación:
message.data.body.hash no debe ser igual a message.envelope.hash. message.timestamp debe ser <= reloj del sistema + 10 minutos message.data.fid debe ser un fid conocido en el FIR
fusionar reglas
Cuando se recibe un mensaje de adición a, si r existe en el conjunto remoto y r.data.body.hash es igual a a.hash, entonces a se descarta. De lo contrario, agregue a al conjunto de suma. Cuando se recibe un mensaje de eliminación r, si hay un.hash igual a r.data.body.hash en el conjunto agregado, elimínelo. Si hay una r' en rem-set, donde r.data.body.hash es igual a r'.data.body.hash, si r'>r, descarte r';
Comportamiento
Una acción es una operación pública realizada por un usuario en un objetivo, que puede ser otro usuario o una actividad en cadena. Actualmente se admiten dos tipos de acciones: me gusta y seguir. El protocolo se puede ampliar fácilmente para admitir nuevas acciones. Los usuarios pueden deshacer y rehacer acciones alternando el atributo de actividad en el mensaje. Conceptualmente, cada acción es una ventaja en el gráfico social.
La acción se gestiona mediante LWW-Element-Set CRDT, lo que garantiza una eventual coherencia. Conceptualmente, existe una única colección que almacena todos los mensajes y los conflictos se resuelven mediante marcas de tiempo y orden hash lexicográfico. La adición se realiza mediante la construcción de un mensaje de acción con active establecido en verdadero, mientras que la eliminación se realiza estableciendo active en falso. En ambos casos, la lógica para fusionar mensajes en conjuntos es:
Si hay una Acción x en la colección, su tipo, Uri objetivo y valores fid son los mismos que los de la acción entrante y. Si x>y, descarta y si x;
verificar
La verificación es una prueba bidireccional de propiedad entre una cuenta de Farcaster y una entidad externa. La verificación se puede utilizar para demostrar la propiedad de direcciones de Ethereum, NFT específicas, otras cuentas de redes sociales e incluso nombres de dominio.
Hay tres conceptos centrales en la verificación:
Declaraciones, incluidas referencias a cuentas de Farcaster y entidades externas. Los reclamos se pueden aplicar hash para crear un identificador único para cada reclamo. Prueba de direccionalidad de una entidad externa que esté autorizada para realizar la solicitud y que muestre su intención de conectarse a la cuenta de Farcaster. Prueba de direccionalidad de una cuenta Farcaster para aceptar solicitudes para asociar un reclamo con una cuenta Farcaster.
Autorización del firmante
Una autorización de firmante es un mensaje que autoriza a un nuevo par de claves a generar firmas para una cuenta de Farcaster.
Cuando se emite un fid, sólo la dirección de custodia puede firmar mensajes en su nombre. Es posible que los usuarios no quieran cargar este par de claves en todos los dispositivos, ya que aumenta el riesgo de que la cuenta se vea comprometida. Una dirección de custodia, también conocida como firmante de custodia, puede autorizar los pares de claves de otros conocidos como firmantes delegados. A diferencia de los firmantes regulatorios, a los firmantes delegados solo se les permite publicar información fuera de la cadena y no pueden realizar ninguna operación dentro de la cadena.
Los firmantes del depósito de garantía generan firmas ECDSA en la curva secp256k1 y solo pueden publicar información de autorización del firmante. Todos los demás tipos de mensajes deben estar firmados por un firmante delegado que crea la firma EdDSA en curve255194. Los firmantes delegados se pueden utilizar para autorizar nuevos dispositivos o incluso servicios de terceros para firmar mensajes para una cuenta. Si un firmante delegado se ve comprometido, puede ser revocado por él mismo, sus antecesores en la cadena de confianza o cualquier firmante delegado. Cuando se revoca un firmante, Hubs descarta toda su información de firma porque no hay forma de distinguir la información del usuario de la información del atacante.
Los usuarios también pueden transferir una identificación a una nueva dirección de depósito en garantía debido a la recuperación de claves o al cambio de billetera. A menudo es deseable preservar el historial para que ambas direcciones de depósito en garantía se conviertan en firmantes de depósito en garantía válidos. El conjunto de firmantes válidos para una identificación forma una serie de árboles diferentes. La raíz de cada árbol es una dirección de custodia histórica y las hojas son firmantes delegados.
El conjunto de firmantes es un conjunto modificado de dos fases con semántica de eliminación-ganar y última escritura-ganar. Se agrega nueva información a la colección si está firmada por un director o tutor válido. Se aceptan eliminaciones si las firma usted mismo o un antepasado. Una vez que se elimina un firmante, no se puede agregar y todos sus descendientes y mensajes se descartan.
Si dos firmantes válidos autorizan respectivamente al mismo firmante delegado, se produce un conflicto de conjuntos que destruye la estructura de datos del árbol. Si esto sucede, la colección mantendrá en orden el mensaje con la marca de tiempo y el hash lexicográfico más altos.
Fragmentación
Los concentradores solo pueden copiar datos de cuentas específicas, lo cual es una propiedad útil para escalar redes. Si Farcaster crece lo suficiente como para que un solo servidor no pueda replicar toda la red de concentradores, la carga de trabajo se puede distribuir entre varios concentradores. Los operadores de hub también pueden evitar la sincronización de datos de usuarios que se comporten de manera maliciosa o que no estén afiliados al operador.
La replicación selectiva solo proporciona una vista parcial de la red. Si un Hub sincroniza los datos de Alice, sabrá que ella respondió y le gustó una de las publicaciones de Bob. Sin embargo, no sabrá el contenido de la publicación de Bob, ni el hecho de que a Bob le gustó su respuesta y luego continuó respondiendo. Una aplicación que tiene como objetivo proporcionar un recuento preciso de Me gusta y proporcionar toda la información de respuesta debe replicar tantos usuarios como sea posible.
