a16z领投3000万美元的去中心化社交协议Farcaster教程
July 13th, 2022

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.
More from Greta

Skeleton

Skeleton

Skeleton