无摩擦的上链入口与 zkLogin
如何消除钱包摩擦,保持用户流动,并预测收益
如果你的 Web3 应用拥有与现代 Web2 服务相同的无缝注册流程会怎样?这正是 Sui 区块链上 zkLogin 的核心承诺。它的工作方式类似于 Sui 的 OAuth,允许用户使用 Google、Apple、X 等熟悉的账户登录。随后,零知识证明安全地将该 Web2 身份关联到链上的 Sui 地址——无需钱包弹窗、无需助记词、也不会导致用户流失。
这种影响是真实且立竿见影的。已有数十万 zkLogin 账户上线,案例研究显示,在去除传统钱包壁垒后,用户转化率从低迷的 17% 飙升至健康的 42%。下面我们来拆解其工作原理以及它能为你的项目带来什么。
为什么钱包阻碍首次转化
你已经构建了突破性的 dApp,但用户获取漏斗出现泄漏。罪魁祸首几乎总是相同的:“连接钱包”按钮。标准的 Web3 入门流程是一系列扩展安装、助记词警告以及加密术语问答的迷宫。
这对新手来说是巨大的障碍。用户体验研究者观察到,一旦出现钱包提示,流失率高达 87%。在一次有说服力的实验中,仅将该提示重新安排到结算流程的后期,完成率就提升至 94%。即使是对加密感兴趣的用户,主要担忧也是“如果点错按钮,我可能会失去资金” 。去除这一步骤是释放指数增长的关键。
zkLogin 工作原理(通俗易懂)
zkLogin 通过使用每个互联网用户已经信任的技术,巧妙地规避了钱包问题。以下几个快速步骤在幕后完成了魔法:
- 临时密钥对:当用户想要登录时,浏览器本地会生成一个临时的、仅限单次会话的密钥对。可以把它看作一次性通行钥,只在本次会话有效。
- OAuth 流程:用户使用 Google、Apple 或其他社交账户登录。你的应用巧妙地在登录请求中嵌入唯一值(nonce)。
- ZKP 服务:登录成功后,ZKP(零知识证明)服务生成加密证明。该证明确认 “此 OAuth 令牌授权临时通行钥的持有者”,且从未在链上泄露用户的个人身份。
- 派生地址:将 OAuth 提供商返回的用户 JWT(JSON Web Token)与唯一的 盐 结合,确定性地生成其永久的 Sui 地址。盐保持私密,可在客户端或安全的后端保存。
- 提交交易:你的应用使用临时密钥签名交易并附加 ZK 证明。Sui 验证节点在链上验证该证明,确认交易合法性,用户无需传统钱包。
步骤集成指南
准备好实现了吗?以下是使用 TypeScript SDK 的快速指南。Rust 或 Python 的原理完全相同。
1. Install SDK
@mysten/sui
包含了所有你需要的 zklogin
辅助工具。
pnpm add @mysten/sui
2. Generate Keys & Nonce
首先,创建一个临时密钥对,并生成与当前 Sui 网络 epoch 关联的 nonce。
const keypair = new Ed25519Keypair();
const { epoch } = await suiClient.getLatestSuiSystemState();
const nonce = generateNonce(keypair.getPublicKey(), Number(epoch) + 2, generateRandomness());
3. Redirect to OAuth
为你使用的提供商(例如 Google、Facebook、Apple)构建相应的 OAuth 登录 URL,并将用户重定向至该 URL。
4. Decode JWT & Fetch User Salt
用户登录并返回后,从 URL 中获取 id_token
。使用它向后端获取用户专属的盐,然后派生出他们的 Sui 地址。
const jwt = new URLSearchParams(window.location.search).get('id_token')!;
const salt = await fetch('/api/salt?jwt=' + jwt).then(r => r.text());
const address = jwtToAddress(jwt, salt);
5. Request ZK Proof
将 JWT 发送至证明服务以获取 ZK 证明。开发阶段可以使用 Mysten 的公共证明服务。生产环境下请自行部署或使用如 Enoki 的服务。
const proof = await fetch('/api/prove', {
method:'POST',
body: JSON.stringify({ jwt, ... })
}).then(r => r.json());
6. Sign & Send
现在,构建交易,将发送者设为用户的 zkLogin 地址并执行。SDK 会自动附加 zkLoginInputs
(即证明)。✨
const tx = new TransactionBlock();
tx.moveCall({ target:'0x2::example::touch_grass' }); // Any Move call
tx.setSender(address);
tx.setGasBudget(5_000_000);
await suiClient.signAndExecuteTransactionBlock({
transactionBlock: tx,
zkLoginInputs: proof // The magic happens here
});
7. Persist Session
为获得更流畅的用户体验,请将密钥对和盐加密后存储在 IndexedDB 或本地存储中。记得每隔几个 epoch 轮换一次,以提升安全性。
KPI 投影模板
zkLogin 带来的差异不仅是定性的,更是可量化的。对比典型的入职漏斗与使用 zkLogin 的漏斗:
漏斗阶段 | 常规(钱包弹窗) | 使用 zkLogin | 差异 |
---|---|---|---|
Landing → Sign-in | 100 % | 100 % | – |
Sign-in → Wallet Ready | 15 %(安装扩展,助记词) | 55 %(社交登录) | +40 个百分点 |
Wallet Ready → First Tx | \ 23 % | \ 90 % | +67 个百分点 |
Overall Tx Conversion | 15 % (install, seed phrase) | 55 % (social login) | +40 pp |
Overall Tx Conversion | 23 % | 90 % | +67 pp |
Overall Tx Conversion | – | – | – |
👉 这意味着: 对于一次吸引 10,000 名独立访客的活动,这相当于 300 次首日链上行为与超过 2,500 次之间的差距。
Best Practices & Gotchas
为了打造更无缝的体验,请牢记以下专业提示:
- 使用赞助交易:为用户支付前几笔交易费用。这消除所有摩擦,带来令人惊叹的 “啊哈” 时刻。
- 谨慎处理盐:更改用户的盐会生成新地址。仅在你拥有可靠的恢复方案时才这样做。
- 展示 Sui 地址:注册后向用户展示其链上地址。这样高级用户可以在以后自行导入到传统钱包中。
- 防止刷新循环:缓存 JWT 和临时密钥对直至过期,避免反复要求用户登录。
- 监控证明服务延迟:关注证明生成的往返时间。如果超过 2 秒,考虑部署区域性证明服务以保持快速响应。
Where BlockEden.xyz Adds Value
虽然 zkLogin 完善了面向用户的流程,但在扩展时会带来新的后端挑战。这正是 BlockEden.xyz 发挥作用的地 方。
- API 层:我们的高吞吐、地域路由的 RPC 节点确保你的 zkLogin 交易以最低延迟处理,无论用户位于何处。
- 可观测性:提供开箱即用的仪表盘,跟踪关键指标,如证明延迟、成功/失败比例以及转化漏斗健康度。
- 合规性:对于桥接至法币的应用,我们的可选 KYC 模块可直接基于用户已验证身份提供合规的上链入口。
Ready to Ship?
笨拙、令人望而却步的钱包流程时代已经结束。启动 zkLogin 沙盒,接入 BlockEden 的全节点端点,观察你的注册曲线向上攀升——而用户甚至不需要听到 “钱包” 这个词。 😉
// 这里可以放置示例代码或其他内容