# 去中心化社交协议Farcaster教程(a16z领投) **Published by:** [kool](https://paragraph.com/@kool/) **Published on:** 2022-07-14 **URL:** https://paragraph.com/@kool/farcaster-a16z ## Content Step 1: 设置环境在编写代码之前,您需要设置一个 Node.js 环境,推荐使用 https://replit.com/ 它是一个基于 IDE 进行编程的浏览器。 1.在 repli 上注册一个免费帐户并登录; 2.点击左上角的create创建;3.出现提示时选择 Node.js,然后点击Create Repl。还需要一个以太坊节点来与 Facaster Registry 合约对话。 建议使用 Alchemy 。 如果您是第一次注册,以下步骤可能会略有不同: 1.注册 Alchemy.com ,并登录。2.选择以太坊作为区块链,点击get started。3.team name和app name随便取,网络选择Rinkeby,点击Create APP。4.选择第一个免费的,点击continue。5.点击跳过。6.继续点击跳过。7.点击continue。8.随便输入什么,点击let‘s go。9.点击view details。10.点击view key。11.找到HTTP的URL,复制v2/后面那部分代码,将其保存在某个地方。12.切换回 Replit 并转到右侧窗格中的 Shell 选项卡并运行以下代码: npm install ethers got@11.8.2 这将安装 ethers ,一个用于与 Ethereum 一起工作的库, got ,一个用于发出 HTTP 请求的库。 您可能会看到一些关于缺少 package.json 的警告,您可以忽略这些警告。Step 2: 连接到以太坊节点1.切换到 Replit 中心窗格中的 index.js 选项卡,然后复制下面的代码片段。 确保将那一堆×换成step1 的第11步保存的代码,点击run。 const { providers, Contract, utils } = require("ethers"); const got = require("got"); const doStuff = async () => { const ALCHEMY_SECRET = 'jeb8oUMpgcUfTe0-1A7_0niISnRpmNhM'; // Replace with your secret const provider = new providers.AlchemyProvider('rinkeby', ALCHEMY_SECRET); const block = await provider.getBlockNumber(); console.log("The latest Ethereum block is:", block); const REGISTRY_CONTRACT_ADDRESS = '0xe3Be01D99bAa8dB9905b33a3cA391238234B79D1' const REGISTRY_ABI = [ { name: 'getDirectoryUrl', inputs: [{ internalType: 'bytes32', name: 'username', type: 'bytes32' }], outputs: [{ internalType: 'string', name: '', type: 'string'}], stateMutability: 'view', type: 'function', }, { inputs: [{ internalType: 'address', name: '', type: 'address' }], name: 'addressToUsername', outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], stateMutability: 'view', type: 'function', }, ]; const registryContract = new Contract(REGISTRY_CONTRACT_ADDRESS, REGISTRY_ABI, provider); const username = 'v'; const byte32Name = utils.formatBytes32String(username); const directoryUrl = await registryContract.getDirectoryUrl(byte32Name); console.log(${username}'s Host is located at: ${directoryUrl} \n); const directoryResponse = await got(directoryUrl); const directory = JSON.parse(directoryResponse.body); console.log(${username}'s Directory is: ); console.log(directory, '\n'); const addressActivityUrl = directory.body.addressActivityUrl; const addressActivityResponse = await got(addressActivityUrl); const addressActivity = JSON.parse(addressActivityResponse.body); const cast = addressActivity[0]; console.log(${username}'s most recent Cast was: ) console.log(cast, '\n'); const stringifiedCastBody = JSON.stringify(cast.body); const calculatedHash = utils.keccak256(utils.toUtf8Bytes(stringifiedCastBody)); const expectedHash = cast.merkleRoot; if (calculatedHash !== expectedHash) { console.log(FAILED: the calculated hash ${calculatedHash} does not match the one in the cast: ${expectedHash}); } else { console.log(PASSED: the calculated hash ${calculatedHash} matches the one in the cast); } const recoveredAddress = utils.verifyMessage(cast.merkleRoot, cast.signature); const expectedAddress = cast.body.address; if (recoveredAddress !== expectedAddress) { console.log( Failed: the recovered address ${recoveredAddress} does not match the address provided in the cast ${expectedAddress} ); } else { console.log(PASSED: the recovered address ${recoveredAddress} matches the one in the cast); } const encodedUsername = await registryContract.addressToUsername(expectedAddress); const expectedUsername = utils.parseBytes32String(encodedUsername); const castUsername = cast.body.username; if (expectedUsername !== castUsername) { console.log(FAILED: ${expectedAddress} does not own ${castUsername}, it owns ${expectedUsername}); } else { console.log(PASSED: ${expectedAddress} owns ${castUsername}); } } doStuff(); 2.Step 3: 验证有用户名V的地址如果这成功完成,您会看到如下消息: 通过:0x012D3606bAe7aebF03a04F8802c561330eAce70A 拥有 v 恭喜 - 你已经在 Farcaster 上构建了你的第一个可以读取用户消息的应用程序! 您还学习了如何验证签名,以便您可以安全地接收来自网络上任何用户的消息! ## Publication Information - [kool](https://paragraph.com/@kool/): Publication homepage - [All Posts](https://paragraph.com/@kool/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@kool): Subscribe to updates