在编写代码之前,您需要设置一个 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 的警告,您可以忽略这些警告。


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 节点连接到区块链。
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

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

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

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

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 上构建了你的第一个可以读取用户消息的应用程序! 您还学习了如何验证签名,以便您可以安全地接收来自网络上任何用户的消息!
上班族如何一年小撸百万——走近三割
蛙总火了之后,再也不分享项目了,在推特,他只干三件事: 1.坚持当一个十足的LSP,对,这件事他坚持下来了!2.开始传播焦虑和pua。3.蒙着脸,聚众干见不得人的事。冰蛙现在唯一的作用,就是让人畅想屌丝逆袭后的美好生活,让撸毛党在漫漫长路上坚定不移地走下去。但是,冰蛙的推少看,特别是评论和点赞,看多了容易虚。一、为什么写这一篇?蛙总的路线只能借鉴,不可复制,毕竟不是每个人都可以支撑一家撸毛工作室。 在币圈,更多的是像我们这样的,边工作,边撸毛,可能还边做一个推特。 那Greta你为什么不写自己?自己吹自己,终究是有点不好意思。 为什么写sanyi?他皮厚耐C。银河初代大表、继老何之后的二代喷子、翻车的三割又名web3李佳琦、三姨、价值0.02b的男人、狗都不用、京总的一生之敌! 集这么多称号于一身的男人,难道不比我有趣得多?二、普通人sanyi的撸毛战况来看看sanyi近一年的撸毛收获。 1.galxe:4048个gal,银河大脑的2500gal和自己撸的1500gal,差不多是11u出完,收益30多万。那一年,三割还不会喊单,也不喷人,银河大脑是最早的银河撸毛人集体要求给他上的...
如何像冰蛙一样在下一个Aptos撸到1000万?——走近冰蛙
冰蛙——一个能把我送到医院的男人。 Greta008 @Greta0086 我回来啦!昨天真是吓死我了! 起因:前天半夜刷冰蛙的推@Ice_Frog666666,刷失眠了。。。 过程:昨天一早完成单位工作后,从早上11点一直刷多号到晚上10点,基本没动。 结果:10点开始天旋地转,血压蹦到160/110 ,直接送医院去了 撸毛撸到去医院的,我是史上第一人吧,珍爱生命,远离冰蛙。 133 10:40 PM • Oct 20, 2022 一、为什么写这一篇?一直以来都是和大家一起研究项目,太枯燥了,今天和大家一起来研究人,比项目有趣多了。 从高中开始我就喜欢研究人: 高一的时候英语只能考90分左右,高考考了138,因为我一直研究英语第一在干嘛。 高二的时候化学总是60多分(总分108),我把状元学姐的笔记要过来了,最后长期保持95以上。 大四的时候别人从3月份开始准备考研,我一直玩到8月底,家里气的问我还考不考研了?我就开始在猿题库和考研吧研究了差不多30多篇高分经验贴,备考4个月,最后也超了专业线150多分,英语直接免修(新东方那本绿皮书我背了54遍,一直没扔,解封回去拍给大家看看...
估值102亿融资5.45亿的Alchemy 项目Road to Web3第一周NFT获取教程
Alchemy是什么项目?2019年12月,Alchemy完成1500万美元A轮融资,资方为Pantera Capital,斯坦福大学,Coinbase,三星等。 2021年4月,Alchemy以5.05亿美元估值完成8000万美元B轮融资,Coatue和Addition领投,DFJ Growth、K5 Global、Chainsmokers(烟鬼组合)、演员Jared Leto和Glazer家族参投。 2021年10月,Alchemy以35亿美元估值完成2.5亿美元C轮融资,由a16z领投的。 2022年2月,Alchemy以102亿美元估值完成2亿美元融资,Lightspeed与Silver Lake领投。 Alchemy是一个背景强大、经费充足、踏实做事、没有发币的团队,这样的项目不刷,难道去刷土狗吗? 并且,Alchemy计划将新资金用于推广Web3采用,这方面的一些举措包括推出Web3 University,就是现在的 Road to Web3 活动,活动为期10周,每周一个NFT。看了下nft数量极少,估计由于任务难度大,很多小伙伴直接放弃,这样的项目若是空投,绝对是...
galaxy girl,gal to moon! 银河小女孩,币圈流浪少年收容所
在编写代码之前,您需要设置一个 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 的警告,您可以忽略这些警告。


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 节点连接到区块链。
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

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

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

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

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 上构建了你的第一个可以读取用户消息的应用程序! 您还学习了如何验证签名,以便您可以安全地接收来自网络上任何用户的消息!
上班族如何一年小撸百万——走近三割
蛙总火了之后,再也不分享项目了,在推特,他只干三件事: 1.坚持当一个十足的LSP,对,这件事他坚持下来了!2.开始传播焦虑和pua。3.蒙着脸,聚众干见不得人的事。冰蛙现在唯一的作用,就是让人畅想屌丝逆袭后的美好生活,让撸毛党在漫漫长路上坚定不移地走下去。但是,冰蛙的推少看,特别是评论和点赞,看多了容易虚。一、为什么写这一篇?蛙总的路线只能借鉴,不可复制,毕竟不是每个人都可以支撑一家撸毛工作室。 在币圈,更多的是像我们这样的,边工作,边撸毛,可能还边做一个推特。 那Greta你为什么不写自己?自己吹自己,终究是有点不好意思。 为什么写sanyi?他皮厚耐C。银河初代大表、继老何之后的二代喷子、翻车的三割又名web3李佳琦、三姨、价值0.02b的男人、狗都不用、京总的一生之敌! 集这么多称号于一身的男人,难道不比我有趣得多?二、普通人sanyi的撸毛战况来看看sanyi近一年的撸毛收获。 1.galxe:4048个gal,银河大脑的2500gal和自己撸的1500gal,差不多是11u出完,收益30多万。那一年,三割还不会喊单,也不喷人,银河大脑是最早的银河撸毛人集体要求给他上的...
如何像冰蛙一样在下一个Aptos撸到1000万?——走近冰蛙
冰蛙——一个能把我送到医院的男人。 Greta008 @Greta0086 我回来啦!昨天真是吓死我了! 起因:前天半夜刷冰蛙的推@Ice_Frog666666,刷失眠了。。。 过程:昨天一早完成单位工作后,从早上11点一直刷多号到晚上10点,基本没动。 结果:10点开始天旋地转,血压蹦到160/110 ,直接送医院去了 撸毛撸到去医院的,我是史上第一人吧,珍爱生命,远离冰蛙。 133 10:40 PM • Oct 20, 2022 一、为什么写这一篇?一直以来都是和大家一起研究项目,太枯燥了,今天和大家一起来研究人,比项目有趣多了。 从高中开始我就喜欢研究人: 高一的时候英语只能考90分左右,高考考了138,因为我一直研究英语第一在干嘛。 高二的时候化学总是60多分(总分108),我把状元学姐的笔记要过来了,最后长期保持95以上。 大四的时候别人从3月份开始准备考研,我一直玩到8月底,家里气的问我还考不考研了?我就开始在猿题库和考研吧研究了差不多30多篇高分经验贴,备考4个月,最后也超了专业线150多分,英语直接免修(新东方那本绿皮书我背了54遍,一直没扔,解封回去拍给大家看看...
估值102亿融资5.45亿的Alchemy 项目Road to Web3第一周NFT获取教程
Alchemy是什么项目?2019年12月,Alchemy完成1500万美元A轮融资,资方为Pantera Capital,斯坦福大学,Coinbase,三星等。 2021年4月,Alchemy以5.05亿美元估值完成8000万美元B轮融资,Coatue和Addition领投,DFJ Growth、K5 Global、Chainsmokers(烟鬼组合)、演员Jared Leto和Glazer家族参投。 2021年10月,Alchemy以35亿美元估值完成2.5亿美元C轮融资,由a16z领投的。 2022年2月,Alchemy以102亿美元估值完成2亿美元融资,Lightspeed与Silver Lake领投。 Alchemy是一个背景强大、经费充足、踏实做事、没有发币的团队,这样的项目不刷,难道去刷土狗吗? 并且,Alchemy计划将新资金用于推广Web3采用,这方面的一些举措包括推出Web3 University,就是现在的 Road to Web3 活动,活动为期10周,每周一个NFT。看了下nft数量极少,估计由于任务难度大,很多小伙伴直接放弃,这样的项目若是空投,绝对是...
galaxy girl,gal to moon! 银河小女孩,币圈流浪少年收容所

Subscribe to Greta

Subscribe to Greta
Share Dialog
Share Dialog
>1.2K subscribers
>1.2K subscribers
No activity yet