Logo
新用户订阅 RPC,首月享 6.5 折优惠查看优惠
OnFinality Learn
网络与协议指南阅读约 11 分钟

Lens 社交协议:在链上社交图谱上构建

一份关于 Lens 社交协议的实用指南,涵盖账户、社交图谱、发布、读取信息流,以及保持 Lens 集成健康运行的 RPC 可靠性实践。

TL;DR

Lens 是一个去中心化社交协议:身份、关注和内容都在链上表示,而应用通过合约和索引器读写这些状态。因此,Lens 社交集成有两个可靠性层面:用于交易的链上 RPC,以及用于信息流的索引层。本文解释心智模型,展示带占位符的可运行读写模式,并提供一套你可以自行复现的延迟和错误率测量流程。它将有文档记录的协议行为与运营建议区分开来,也与你必须在自己基础设施上测量的数字区分开来。

范围与 Lens 社交集成的两个层面

Lens 社交协议是一组链上合约加上一个应用层,让用户拥有账户、关注其他账户、发布内容,并允许他人收藏或与该内容互动。从工程角度看,Lens 社交应用涉及两个不同的层面。第一个是链:账户所有权、关注和发布记录都是状态转换,必须通过 RPC 端点签名并提交。第二个是读取层面:信息流、个人资料和互动计数通常由已经解析链上事件的索引器或 API 提供。

本指南侧重于工程工作流,而非提供商名单。如果你只需要针对目标网络的具体端点推荐,请使用 RPC Assistant,而不要将本页视为端点目录。关于 RPC 端点行为差异的更广泛背景,请参阅 RPC 端点指南。

  • 写入路径:钱包签名、交易提交、收据确认和事件解析。
  • 读取路径:针对索引器或 API 进行个人资料和信息流查询,并使用链上读取进行验证。
  • 身份路径:将钱包地址映射到 Lens 账户及其所有权状态。

假设与前提条件

以下流程假设你在 Lens 合约部署的网络上有资金充足的钱包、Node.js 或 Python 环境,以及你控制或已获分配的 RPC_URL。它们还假设你对应用使用的任何 Lens 索引 API 具有读取权限;确切的查询形状取决于你集成的 API 版本,因此请将这里的请求体视为结构示例,而非固定不变的契约。

在发送任何交易之前,你应该知道 RPC_URL 服务于哪个链 ID。你认为所在的链与端点实际服务的链不匹配,是导致令人困惑的 Lens 集成失败的最常见原因。

curl -s -X POST "$RPC_URL" \
  -H 'content-type: application/json' \
  --data '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'

心智模型:账户、社交图谱和发布内容

Lens 将用户建模为由钱包或智能账户拥有的账户。账户是其他一切事物的锚点:它控制的个人资料、它关注的账户以及它创建的发布内容。社交图谱是账户之间的关注关系集合,它存在于链上,这正是它能够跨应用移植的原因。发布内容是一条内容记录,可以携带元数据,并可根据创作者设定的规则被收藏或互动。

对开发者而言,重要的结果是图谱并非由你的应用拥有。如果你的应用消失,账户和关注关系仍然可以被任何其他 Lens 客户端读取。这是去中心化社交图谱的核心承诺,也意味着你的应用必须将其本地数据库与链上状态进行协调,而不是假设自己是真相来源。

要深入了解节点基础设施如何支撑这类状态,请参阅 区块链节点托管指南。

  • 账户:拥有个人资料和关系的链上身份。
  • 关注:社交图谱中的有向边,写入链上。
  • 发布内容:带有元数据和可选收藏规则的内容记录。
  • 索引器:将事件转换为可查询信息流的链下服务。

通过 RPC 端点读取社交图谱

在构建信息流之前,请验证你的端点健康,并且你可以读取所依赖的合约状态。以下 JavaScript 示例使用通用 JSON-RPC 调用读取最新区块,然后调用合约视图函数。将 CONTRACT_ADDRESS 和 ABI 片段替换为你正在集成的实际 Lens 合约;重点在于模式,而非具体的选择器。

在信任读取结果之前,始终将端点返回的区块号与第二个来源进行比较。滞后的端点可能返回看似有效但已过时的状态。

const RPC_URL = process.env.RPC_URL;

async function rpc(method, params) {
  const res = await fetch(RPC_URL, {
    method: 'POST',
    headers: { 'content-type': 'application/json' },
    body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params })
  });
  const json = await res.json();
  if (json.error) throw new Error(json.error.message);
  return json.result;
}

(async () => {
  const blockHex = await rpc('eth_blockNumber', []);
  console.log('latest block', parseInt(blockHex, 16));

  // Example view call; replace with the Lens contract and selector you need.
  const data = '0x' + 'YOUR_FUNCTION_SELECTOR' + 'YOUR_PADDED_ARGUMENTS';
  const result = await rpc('eth_call', [
    { to: 'CONTRACT_ADDRESS', data },
    'latest'
  ]);
  console.log('view result', result);
})();

发布内容:带验证的写入路径

写入社交图谱是一笔交易,因此工作流是签名、提交、等待收据,然后解析日志。以下示例使用 Python 和 web3.py,并为私钥和合约使用占位符。切勿提交私钥;从环境变量或密钥管理器加载它。

提交后,不要将交易哈希视为成功。等待收据并确认状态字段,然后解码日志以提取应用将存储的发布标识符。

import os
from web3 import Web3

w3 = Web3(Web3.HTTPProvider(os.environ['RPC_URL']))
acct = w3.eth.account.from_key(os.environ['PRIVATE_KEY'])

contract = w3.eth.contract(
    address=Web3.to_checksum_address('CONTRACT_ADDRESS'),
    abi=[]  # load the Lens ABI you are integrating against
)

tx = contract.functions.YOUR_PUBLISH_FUNCTION(
    'YOUR_ARGS'
).build_transaction({
    'from': acct.address,
    'nonce': w3.eth.get_transaction_count(acct.address),
    'chainId': w3.eth.chain_id,
    'gas': 500000,
    'maxFeePerGas': w3.eth.gas_price * 2,
    'maxPriorityFeePerGas': w3.to_wei(1, 'gwei')
})

signed = acct.sign_transaction(tx)
hash_ = w3.eth.send_raw_transaction(signed.raw_transaction)
receipt = w3.eth.wait_for_transaction_receipt(hash_, timeout=120)
print('status', receipt.status, 'block', receipt.blockNumber)

测量 Lens 工作负载的 RPC 延迟和错误率

由于 Lens 读写对延迟敏感,你应该测量端点,而不是假设它足够快。从与应用相同的区域运行固定工作负载的读取调用和少量写入调用,并在固定窗口内记录 p50、p95 和错误率。不要发布你未测量的数字;下表是模板,不是结果。

可复现的流程:以稳定速率发送 200 次 eth_blockNumber 调用和 200 次 eth_call 调用,记录每次往返时间,丢弃前 10 次作为预热,并计算百分位数。对每个候选端点和你服务的每个区域重复此过程。保持负载相同,以确保比较公平。

  • | 指标 | 端点 A | 端点 B | 备注 |
  • | p50 读取延迟 | 测量 | 测量 | 相同负载,相同区域 |
  • | p95 读取延迟 | 测量 | 测量 | 报告样本量 |
  • | 错误率 | 测量 | 测量 | 统计超时和 JSON-RPC 错误 |
  • | 写入确认时间 | 测量 | 测量 | 从提交到收据 |

预期验证结果

健康的读取路径返回与配置匹配的链 ID、随时间推进的区块号,以及解码无错误的合约视图结果。健康的写入路径返回状态为 1 的收据,并且至少有一个与预期事件签名匹配的日志。如果你的索引器同步,个人资料或信息流查询应在索引器文档记录的延迟窗口内反映新的发布内容。

如果任何这些检查失败,请停止并在其上构建更多功能之前进行诊断。读取路径中的静默失败是最昂贵的,因为它们会产生看似合理但错误的信息流。

排查常见的 Lens 集成失败

大多数失败属于少数几类:链不匹配、读取过时、nonce 冲突和索引器滞后。链不匹配表现为链 ID 与配置不同。读取过时表现为区块号落后于第二个来源。nonce 冲突表现为从一个密钥并发发送时出现替换交易或提交被丢弃。索引器滞后表现为发布内容存在于链上但尚未出现在信息流查询中。

有关端点可靠性的系统方法,请参阅 多链 RPC 端点指南 和 Web3 项目最佳 RPC 提供商 概述。

  • 在每个写入批次之前确认链 ID。
  • 每个 nonce 序列使用单一签名者,或显式管理 nonce。
  • 在信任读取之前,比较两个端点的区块号。
  • 将索引器健康与链健康分开检查。

限制与权衡

链上社交图谱以成本和延迟换取可移植性和所有权。每次关注或发布都是一笔交易,这意味着 gas、确认时间以及失败的可能性。索引器使读取快速,但引入延迟和第二个真相来源,你必须进行协调。需要即时反馈的应用应显示乐观 UI 状态,并在之后与链和索引器状态进行协调。

还存在版本控制的权衡。Lens 随时间演进了其合约和 API,因此请固定应用依赖的 ABI 和 API 版本,并在推出之前在暂存环境中测试升级。对于运行自己基础设施的团队,专用节点 可以减少共享端点的差异,但仍需要监控。

后续步骤:从原型到生产

一旦你的读写路径得到验证,下一步就是加固它们。为瞬态 RPC 错误添加带退避的重试,对错误率和区块滞后设置警报,并配置备用端点。如果你正在为生产选择端点,请查看 RPC 定价 和 API 服务 选项,并检查 网络 列表以了解目标链。

对于希望获得托管起点的团队,RPC Assistant 可以为你指出适合网络的具體端点选择,而本指南仍然是验证它的方法论。在承诺使用提供商之前,测量你自己的延迟和错误率,并随着流量增长重新审视这些测量结果。

永远不用担心基础设施

OnFinality 消除了 DevOps 的繁重工作,让您能够更聪明、更快地构建。

开始