a16z领投3000万美元的去中心化社交协议Farcaster教程

Step 1: 设置环境

在编写代码之前,您需要设置一个 Node.js 环境,推荐使用 replit ,它是一个基于 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 = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; // 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);
}

doStuff();

2.当您点击运行时,如果一切正常,您应该会看到如下内容:

The latest Ethereum block is: 10027943

后面那个数字大家会不一样。

我们刚刚编写的代码创建了一个 Ethers Provider ,这是一个我们可以调用以与 Ethereum 交互的接口。 提供者通过 Alchemy 节点连接到区块链。

Step 3: 连接到Farcaster注册表

1.复制以下it代码并将其添加到底部 doStuff函数,就在最后一行的下方 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);

2.如果一切正常,你会看到以下内容:

v's Host is located at: https://guardian.farcaster.xyz/origin/directory/0x012D3606bAe7aebF03a04F8802c561330eAce70A

Step 4: 获取用户目录

1.将以下代码添加到底部 doStuff,像你刚才做的那样,然后再次运行它:

const directoryResponse = await got(directoryUrl);
const directory = JSON.parse(directoryResponse.body);
console.log(${username}'s Directory is: );
console.log(directory, '\n');

2.如果一切正常,你会看到以下内容:

v's Directory is:
{
body: {
addressActivityUrl: 'https://guardian.farcaster.xyz/origin/address_activity/0x012D3606bAe7aebF03a04F8802c561330eAce70A',
avatarUrl: 'https://lh3.googleusercontent.com/sYAr036bd0bRpj7OX6B-F-MqLGznVkK3--DSneL_BT5GX4NZJ3Zu91PgjpD9-xuVJtHq0qirJfPZeMKrahz8Us2Tj_X8qdNPYC-imqs',
displayName: 'Varun Srinivasan',
proofUrl: 'https://guardian.farcaster.xyz/origin/proof/0x012D3606bAe7aebF03a04F8802c561330eAce70A',
timestamp: 1639029396497,
version: 1
},
merkleRoot: '0xcccabedbe3267e21d80e959de72f2933a68c6cd4c29453aed81a78bc8d4d8521',
signature: '0x3412be3e88bc49cd89a18890bcd8e116776ed649e270ac0a3955864bed1e2cd243407e2a478f66fa47cedb1668a8298c98e632d6607c0a6082b6589e8bf2a2501b'
}

Step 5: 从地址活动获取用户最近行为

1.将以下代码添加到底部 doStuff,就像你刚才做的那样,然后再次运行它:

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')

2.如果一切正常,你会看到以下内容:

v's most recent Cast was:
{
body: {
type: 'text-short',
publishedAt: 1642720790424,
sequence: 493,
username: 'v',
address: '0x012D3606bAe7aebF03a04F8802c561330eAce70A',
data: {
text: 'Is Maine meant to be an outlier? \n\nHard to tell without the legend',
replyParentMerkleRoot: '0x647432bd51231b217f7c31f5d678e7acccf3d1b5f30ba72fc2cffa895927a5d1'
},
prevMerkleRoot: '0x21570c8e24879010978a08339eb344898b22b7d21cc56ce3a176abe118cc5f61'
},
merkleRoot: '0xa20c21aa020c2be7aa6f9577468a4bbf32701ae3d835e882d9a9fd25bdcb4e1e',
signature: '0xca11e5d2e8e1b7259c1d7dd1a08f87275c16a0282e559eec7a77cfad2df1aa01234d01002637e096c208ebb491ed2de8229bbde5ccb2a4a71f194189820071161c'
}

Step 6: 验证签名

1.让我们再次复制粘贴代码:

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);
}

2.如果一切正常,你会看到以下内容:

PASSED: the calculated hash 0xa20c21aa020c2be7aa6f9577468a4bbf32701ae3d835e882d9a9fd25bdcb4e1e matches the one in the cast
PASSED: the recovered address 0x012D3606bAe7aebF03a04F8802c561330eAce70A matches the one in the cast

Step 7: 验证有用户名V的地址

1.最后,我们需要回到区块链并检查执行签名的地址是否与拥有 v用户名的地址相同. 复制并运行底部的以下代码 doStuff:

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});
}

2.如果这成功完成,您会看到如下消息:

PASSED: 0x012D3606bAe7aebF03a04F8802c561330eAce70A owns v

恭喜 - 你已经在 Farcaster 上构建了你的第一个可以读取用户消息的应用程序! 您还学习了如何验证签名,以便您可以安全地接收来自网络上任何用户的消息!

Subscribe to Greta
Receive the latest updates directly to your inbox.
Verification
This entry has been permanently stored onchain and signed by its creator.