Ethers.js 开发入门:从本地链转账到合约交互与事件监听

1. 先搞清楚 Ethers.js 到底在帮你省什么事

很多新手刚接触 Web3 开发时,第一反应是跑去读共识算法、看 Solidity 语法,折腾一星期连一条真实交易都没发过,然后就被劝退了。我的建议正好相反:想入门,先直接把 Ethers.js 用起来,在一台本地开发链上做一笔转账、调一个合约方法,把“链上交互”这个闭环跑通,再去补底层原理,你会发现一切都顺了。

你可能会问,Ethers.js 是什么?简单说,它可以让你用 JavaScript 的语法去读写以太坊上的数据。以前要是想读一个地址的余额,你得自己拼 JSON-RPC 请求,自己处理十六进制结果,自己解析错误;现在你只需要拿到一个 provider,然后调用provider.getBalance(address)。底层那些复杂的编码、签名、网络通信,都被封装掉了。

1.1 从中心化应用的“用户体系”说起

传统互联网应用里,用户登录靠的是账号密码,数据存在自己的数据库里。Web3 世界里没有“数据库里的一行记录”能用密码改,所有状态都保存在区块链上,状态变更必须通过交易来触发。这意味着两件事:第一,你的代码要会构造交易;第二,你的代码要能签名,证明你有权操作某个账户。

Ethers.js 把这两件事拆成了两个概念:provider 负责连接网络、查询状态;signer 负责持有私钥、签名交易。这种分离初看有点啰嗦,但它和你真实面对的编程模型完全一致。读数据不需要花钱,也不需要身份;写数据一定要有账户签名,并且要支付 gas。

所以,学习 Ethers.js 不只是学一个 API,而是在学以太坊自己的“权限模型”。

1.2 为什么新项目我更愿意用它

市面上的 Web3 交互库不少,老一些的教程里更多是另一套库的写法,我自己早期也用过,但后来的项目基本都换到了 Ethers.js。

原因有三个:

  • API 设计更符合直觉:你不需要记大量与链上协议强绑定的规则,写出来的代码更接近“面向对象”的用法,比如contract.balanceOf(addr)就是一个普通方法调用。
  • 类型信息更完整:如果你用 TypeScript,它能给你非常清楚的类型提示。合约的方法名、参数类型,都能在你写代码时被编辑器检查出来,这对项目维护太重要了。
  • 内部数据表示更现代:新版已经迁移到原生BigInt,不再依赖自带的大数类,跟 Node.js 和浏览器的兼容性都好很多。

当然,不是说别的库一无是处,只是从新项目选型角度看,Ethers.js 的生态和更新节奏更让我放心。

1.3 Provider、Signer、Contract:三个核心抽象

整个 Ethers.js 的日常使用,可以浓缩成三个对象:

  • Provider:链的只读窗口。传入一个 RPC 地址,你就能查区块高度、账户余额、合约状态。
  • Signer:有私钥的账户。它扩展了 provider 的能力,可以签名并广播交易。
  • Contract:合约地址与 ABI 的组合。有了它,你调用合约方法就像调用普通函数。

我见过不少人把这三个概念混在一起用,最后写出的代码非常拧巴。比如只传 provider 给合约,却在里面调用转账方法,结果报错“missing signer”。你先在脑子里理清楚这三个抽象,后面所有例子都会好懂很多。

2. 动手前的准备:把本地项目连上一条链

不要一开始就连接主网去操作真实资产,谁的钱都不是大风刮来的。安全、便宜、还能反复折腾的方式,是先搭一个本地开发链。你在本机跑一个开发链后,可以为所欲为地制造区块,还不用担心把测试币耗尽。

2.1 搭建最小项目骨架

打开终端,建一个目录,初始化 npm 项目:

mkdir ethers-playground cd ethers-playground npm init -y npm install ethers

装完之后确认一下版本。如果你看到package.json里的版本是 6.x,就按本文的语法来;如果看到 5.x,很多 API 是不一样的。

接着创建一个index.js,先用最少的代码连接网络:

const { JsonRpcProvider } = require("ethers"); const provider = new JsonRpcProvider("http://127.0.0.1:8545"); (async () => { const network = await provider.getNetwork(); const blockNumber = await provider.getBlockNumber(); console.log("chainId:", network.chainId); console.log("当前区块高度:", blockNumber); })();

如果你本地已经跑起了开发链,运行node index.js应该能看到 chainId 和区块高度。

2.2 RPC 节点与网络配置里最容易踩的坑

很多新人第一次连接网络就卡住,不是因为代码写错,而是 RPC 地址给错了。请记住一个原则:RPC URL 决定了你连接的是哪条链。

如果你连接的是公共测试网,官方会提供一个公开 RPC 地址;如果你连接的是本地开发链,通常是http://127.0.0.1:8545。后者是明文 HTTP,只能在本地调试时用,千万不能拿它去传主网私钥。生产环境一定要用加密通道,并且建议把 RPC 地址和 API Key 放进环境变量里,别硬编码进代码提交到仓库。

一个更稳妥的做法是在代码里校验当前网络是不是预期的链:

const expectedChainId = 1337n; const network = await provider.getNetwork(); if (network.chainId !== expectedChainId) { throw new Error(`网络不匹配,期望 chainId ${expectedChainId},实际 ${network.chainId}`); }

这个检查能帮你挡住“测试网地址填错、连上主网”这种致命问题。

2.3 测试币从哪里来

本地开发链有一个内置账户,通常全自动生成,里面有一堆 ETH,你可以直接拿它的私钥做实验。如果想模拟更接近真实的环境,也可以用公共测试网,去水龙头网站上领一些测试币。

说句实话,测试币虽然不值钱,但领起来也烦。我觉得最好的上手方式还是本地开发链,因为它的账户余额充足,也没有网络延迟,所有交易秒级确认。等你把逻辑都调通了,再去公共测试网做一次完整的部署和交互,体验会好很多。

下面是一个简单的对比:

网络类型用途获取测试币难度适合阶段
本地开发链日常调试无需领取初学、测试逻辑
公共测试网模拟真实环境需要去水龙头上线前验证
主网真实资产无测试币概念生产环境

3. 第一笔转账:代码量不大,细节却不少

网络通了,下一步就是发一笔真正上链的交易。第一次看到自己能转账,是很上头的。但激动归激动,还是要稳。

3.1 钱包是怎么来的

在 Ethers.js 里,你想发交易,首先得有一个 signer。它的来源主要有三种:

const { Wallet } = require("ethers"); // 方式一:从私钥导入 const wallet1 = new Wallet(process.env.PRIVATE_KEY, provider); // 方式二:随机生成一个新钱包 const wallet2 = Wallet.createRandom(); // 方式三:从助记词恢复 const wallet3 = Wallet.fromPhrase(process.env.MNEMONIC, provider);

方式一最常用。开发时你把私钥放在.env文件里,通过环境变量读取。方式二适合创建新测试账户,它会生成一组助记词,记录好了下次还能恢复。方式三是给用户做导入用的,比如你写了一个钱包工具,需要支持用户输入助记词登录。

注意:私钥就是账户的唯一凭证,谁拿到谁就有权动用里面的所有资产。测试网上还好,主网上一旦泄露,神仙都救不回来。

3.2 完整转账代码与参数逐行拆解

假设你已经从私钥创建好了wallet,现在想给另一个地址转 0.01 ETH:

const tx = await wallet.sendTransaction({ to: "0xRecipientAddress", value: parseEther("0.01"), gasLimit: 21000n, maxFeePerGas: parseUnits("20", "gwei"), maxPriorityFeePerGas: parseUnits("1", "gwei"), });

让我逐行解释:

  • to:接收方地址。如果写错了,交易会发送到一个别人可能永远无法找回私钥的地址,资产直接消失。
  • value:转账金额。这里用parseEther("0.01")把 ETH 转成最小单位 Wei。千万不要直接写0.01,链上都是整数单位,前端展示才用浮点数。
  • gasLimit:这笔交易最多消耗多少 gas。普通 ETH 转账固定是 21000,不需要多给。
  • maxFeePerGas:你愿意支付的单份 gas 价格上限。
  • maxPriorityFeePerGas:给矿工/验证者的小费,用来让交易更快被打包。

相比旧版教程里只有一个gasPrice,现在以太坊主要使用 EIP-1559 模式,理解这两个参数能帮你排查交易一直“待确认”的问题。

3.3 交易发出去了,不代表已经成功

很多人以为await wallet.sendTransaction(...)执行完,交易就成功了。实际情况是,sendTransaction只是把交易广播了出去,返回一个 Promise,里面是交易响应对象tx。

交易能不能被确认,取决于网络是否接受了它,以及 gas 是否足够。你必须再等一个确认:

const receipt = await tx.wait(); if (receipt.status === 1) { console.log("交易成功,tx hash:", tx.hash); } else { console.log("交易失败,回执状态:", receipt.status); }

receipt.status为 1 表示成功,为 0 表示执行失败。失败同样会消耗 gas,因此调试合约调用时,如果失败总是反复发生,你得先看回执里的日志,不能盲目重试。

4. 打合约:从 ABI 到事件监听,一次说清

转账只是单方动作,真正让 Web3 世界丰富多彩的是智能合约。Ethers.js 让你调用合约方法就像调用本地函数一样,但它并不是魔法,它背后依赖一个关键的东西:ABI。

4.1 ABI 决定你能调什么

ABI 是一个 JSON 数组,描述了合约有哪些函数、参数类型、返回值类型,还会告诉你某个函数是可读还是可写。没有 ABI,你就不知道该怎么编码调用数据,只能拿着原始十六进制数据发呆。

获取 ABI 通常有两个渠道:一是你自己编译智能合约时生成的构建产物,二是从区块浏览器上复制别人合约的 ABI。总之,只要合约地址和 ABI 都是真的,你就能和这个合约交互。

创建合约实例时,要特别注意第三个参数:

const { Contract } = require("ethers"); const contract = new Contract(contractAddress, abi, signer);

第三个参数如果传的是 provider,那么这个合约只能做只读操作;如果传的是 signer,那它既能读也能写。反过来,你必须清楚当前调用到底需不需要签名。

4.2 只读方法:零 gas 也能拿到链上数据

合约里的view或pure方法属于只读调用,不会改变链上状态,所以不需要签名,也不需要消耗用户的 gas。用 Ethers.js 调用它们非常简单:

const name = await contract.name(); const totalSupply = await contract.totalSupply(); const balance = await contract.balanceOf("0xSomeAddress");

这里有一个很常见的误解:不是所有网络读取都是完全“免费”的。节点执行这些调用仍然会消耗计算资源,只不过费用不由发起者承担,而是由节点自己消化。对用户来说,体验确实像免费查询。

4.3 写方法:签名、广播、等待确认,缺一不可

如果方法是transfer、mint、swap这类会修改状态的,那就得用 signer 调用,并等待交易确认:

const tx = await contract.transfer("0xRecipientAddress", parseEther("1.5")); const receipt = await tx.wait(); if (receipt.status === 1) { console.log("合约调用成功,hash:", tx.hash); }

有些合约的写方法还要求你附带 ETH,比如购买 NFT 或铸造代币。Ethers.js 允许你传入一个额外的覆盖参数:

const tx = await contract.mint({ value: parseEther("0.1"), });

这里的{ value: ... }就是给合约转账 0.1 ETH。你还可以同时覆盖 gas 参数,比如gasLimit、maxFeePerGas。

4.4 事件监听:从“查状态”到“等通知”

链上数据的另一种常见用法是监听事件。比如你关心某个代币的转账,可以通过合约事件接口订阅:

contract.on("Transfer", (from, to, value, event) => { console.log(`${from} 转账给 ${to}: ${value}`); });

但要记住一个关键前提:HTTP 连接无法主动接收节点推送。如果你用的是JsonRpcProvider("http://..."),直接调用on是无效的,因为 HTTP 是单向请求。要么换成支持订阅的WebSocketProvider,要么定期用queryFilter去扫历史事件。

const events = await contract.queryFilter("Transfer", startBlock, endBlock);

对入门项目来说,轮询虽然笨,但胜在稳定,也不需要额外维护长连接。

5. 真正让我印象深刻的是这些坑

Ethers.js 整体不难,但实际写起来,有些坑几乎每个人都踩过。我把它们放在一起,希望能帮你节省几天时间。

5.1 BigInt 精度:不是玄学,是你没看清类型

链上金额通常用最小单位表示,比如 0.01 ETH 在链上是10000000000000000(Wei)。这个数远超 JavaScript 普通number的安全整数范围,所以在 Ethers.js 新版里,数值类型统一用的是原生BigInt。

我见过很多报错都长这样:

const amount = parseEther("0.01"); console.log(amount + 1); // 报错,BigInt 和 number 不能直接相加

解决办法很简单:所有数值运算都用BigInt,用人眼看着恶心,但精度绝对靠谱。展示给用户前,再调用formatEther(amount)转回字符串。

5.2 Nonce 卡住:一笔 pending 交易堵住整个账户

每笔交易都会带一个nonce,代表这个账户发出的第几笔交易。节点要求交易必须按照 nonce 顺序执行,如果一个账户有一笔 nonce 为 5 的交易始终没被确认,那你后面所有 nonce 更大的交易都会排队,哪怕你重新提交也未必有效。

排查时,可以先打印一下这个账户的 nonce:

const nonce = await wallet.getNonce(); console.log("下一笔可用 nonce:", nonce);

如果发现有交易卡了很久,有两种处理思路:一是用更高 gas 重新广播同一笔交易,覆盖旧的;二是以nonce作为参数发送一笔 0 ETH 转账给自己,手动把它“顶掉”。这里面的操作细节很多,但至少你得先知道问题出在 nonce 上面,而不是无脑重试。

5.3 Gas 估算与限额:宁可多留余地,也别卡死在半路

Ethers.js 里有个estimateGas,能在发送前估算交易需要的 gas。但估算结果不一定完全准确,因为它基于当前链上状态做模拟,合约执行路径一变,实际消耗可能比估算值高。

更稳妥的做法是给gasLimit留一个缓冲,比如估算出来是 50000,你就设 60000,甚至写死。对普通 ETH 转账 21000 是固定的,不需要缓冲;对合约调用,建议多留 10% 到 20%。

Gas 价格同理。如果你把maxFeePerGas设得太低,交易就会一直滞留。测试环境无所谓,主网上要留意当前网络的平均费率,别凭感觉填。

5.4 网络环境切换:同一个私钥在不同链上的教训

本地开发链、公共测试网、主网,它们的 chainId 完全不同。同一个私钥在主网和测试网都能推导出相同的地址,但你如果拿着测试网的 RPC 去发主网交易,极大概率会直接失败。

以前我在一个脚本里同时配了多个网络,结果忘了改环境变量,差点把主网交易发到测试网。从那以后,我习惯在代码启动时强制检查 chainId,把错误暴露在第一时间,而不是等交易失败了再回头看日志。

6. 进阶方向:从脚本到 DApp

当你已经把转账和合约调用跑通,接下来无非是把这套能力变成产品。这里有几个方向,我建议按顺序去扩展。

6.1 私钥安全:所有 Web3 开发的底线

在脚本里直接碰私钥,关起门自己玩可以,但一旦要给别人用,就不能再用服务器私钥签名了。安全底线是:

  • 私钥不写入代码仓库,用环境变量或密钥管理服务。
  • 助记词不截图、不粘贴到聊天工具、不存云笔记。
  • 主网真实资产尽量走硬件钱包,或者通过浏览器钱包让用户自行授权签名。
  • 对任何看似“免费领取”的签名请求保持警惕,授权签名可能让你损失资产。

Ethers.js 本身只是一个库,它不会替你做安全决策,但你应该从一开始就养成习惯。

6.2 接浏览器钱包:EIP-1193 是标准

现在大多数 DApp 并不是在服务器端用私钥签名,而是在浏览器里连接用户自己的钱包。Ethers.js 对这种场景有专门的支持:

const { BrowserProvider } = require("ethers"); // 浏览器环境里,钱包会往 window.ethereum 注入一个 provider const provider = new BrowserProvider(window.ethereum); const signer = await provider.getSigner();

这里不需要你管理私钥,用户自己点击确认授权,你的代码拿到的是一个受限的 signer。这种方式虽然牺牲了自动化能力,但安全性和用户体验都远好于“服务器保存用户私钥”。

6.3 下一步还能玩什么

基础链路已经通了,你完全可以往这些方向继续探索:

  • 批量转账工具:读取 CSV,循环调用代币合约的transfer。
  • 链上监控机器人:监听某个合约的特定事件,触发告警。
  • 简单的资产管理面板:用 provider 查询多个地址的币种余额。
  • 合约部署脚本:用ContractFactory把 Solidity 编译产物部署到测试网。

给你一个最实在的下一步建议:找一个你感兴趣的 ERC-20 代币合约 ABI,把它接到你的本地开发链测试合约上,写一个自动转账加监听事件的脚本。两三个小时跑下来,你对 Web3 开发的核心链路就不会再恐惧了。

最后说一点个人体会。我每次带新人入门,都不会让他们先背一堆概念,而是让代码先跑起来。Ethers.js 恰恰是那种“五分钟能见到效果”的库,它的价值不是帮你写业务逻辑,而是帮你把链上交互的复杂度收敛在一个很舒服的抽象层里。先动手,等你在交易和合约上栽过几个小跟头,再回去看共识算法、看状态树,你会发现一切都变得特别好懂。别怕踩坑,坑本身就是这条路上最好的老师。

相关新闻

VSS2026安装配置全流程详解:从环境准备到权限与备份实战

VSS2026安装配置全流程详解:从环境准备到权限与备份实战

大家做开发或者做文档管理,手头一定绕不开版本控制这件事。VSS2026,也就是微软这套 Visual SourceSafe 的最新版本,仍然是很多老团队、传统企业级项目在用的源代码和文档管理方案。相比 Git 那套分布式思路,VSS2026 更像是一个集中…

2026/10/19 16:37:52 阅读更多 →
NSGA-II多目标优化Matlab实战:从Pareto前沿绘制到答辩话术

NSGA-II多目标优化Matlab实战:从Pareto前沿绘制到答辩话术

简介:本资源是一套完整的NSGA-II多目标优化算法Matlab实现代码包,面向高校学生、科研人员及工程优化从业者,用于学习和求解典型多目标优化问题(如参数权衡、Pareto前沿探索等)。压缩包共10个文件,含8个核心…

2026/10/19 16:37:51 阅读更多 →
ShardingSphere-JDBC事务与分片路由深度解析

ShardingSphere-JDBC事务与分片路由深度解析

简介:本资源是一个基于SpringBoot、ShardingJDBC与MyBatis的轻量级分库分表实战项目,面向Java后端中级开发者及分布式数据库学习者,聚焦高并发场景下单库性能瓶颈的工程化解决方案。压缩包共15个文件(61KB)&#xff0c…

2026/10/19 16:37:51 阅读更多 →

最新新闻

E3神U+P106矿卡变身AI推理建站服务器实战

E3神U+P106矿卡变身AI推理建站服务器实战

坐拥 E3 神U 和 P106 矿卡这两块二手市场的大热门,把这套配置改造成一台集 AI 推理与建站于一体的全能服务器,是很多折腾党都想干的事。E3 的多核生产力在百元价位几乎没有对手,P106 这块被矿潮埋没的显卡又恰好拥有大显存和高吞吐量的底子&a…

2026/10/19 17:27:01 阅读更多 →
ROS多版本OpenCV共存实战:从符号冲突到RPATH隔离的完整方案

ROS多版本OpenCV共存实战:从符号冲突到RPATH隔离的完整方案

简介:这份资源面向在Ubuntu 20.04上使用ROS Noetic的开发者,尤其是需要运行依赖旧版OpenCV的开源算法、又不愿破坏系统默认OpenCV 4.2.0环境的用户。教程围绕多版本OpenCV与cv_bridge共存展开,涵盖依赖安装、OpenCV 3及contrib库源码编译、依…

2026/10/19 17:27:01 阅读更多 →
政务办公智能体系统建设调研:从场景识别到RAG落地全记录

政务办公智能体系统建设调研:从场景识别到RAG落地全记录

刚接到“政府办公助手智能体系统建设调研报告”这个活儿的时候,团队里好几个同事的第一反应都是:这不就是拿大模型套个壳,做个问答机器人吗?等真的扎进去做调研,才发现完全不是这么回事。政务办公场景有一种天然的“重…

2026/10/19 17:27:01 阅读更多 →
nxdk入门:在原始Xbox上运行裸金属C代码

nxdk入门:在原始Xbox上运行裸金属C代码

简介:nxdk是一款专为初代Xbox(2001年发布)开发的跨平台开源SDK,面向嵌入式逆向开发者、复古游戏自制程序(homebrew)爱好者及系统级C/C工程师,解决原生Xbox程序开发长期依赖闭源XDK工具链的难题。…

2026/10/19 17:27:01 阅读更多 →
开源CLI代码审查工具:LLM驱动的本地化Code Review实践

开源CLI代码审查工具:LLM驱动的本地化Code Review实践

1. 项目概述:一个真正能嵌入日常开发流的开源代码审查 CLI 工具“open-code-review”这个名字乍一听有点抽象,但拆开来看就非常实在:open 是开放、透明、可审计;code review 是软件工程里最基础也最容易被形式化的关键环节&#x…

2026/10/19 17:27:01 阅读更多 →
Java SE蓝牙开发实战:SPP通信全链路实现与跨平台适配

Java SE蓝牙开发实战:SPP通信全链路实现与跨平台适配

简介:本资源是一个面向Java开发者与物联网初学者的蓝牙通信实践项目,聚焦JSR-82规范在桌面端的落地实现,解决Java SE环境下缺乏原生蓝牙支持的开发痛点,适用于智能家居设备控制、低功耗传感器通信等IoT场景。压缩包为RAR格式&…

2026/10/19 17:25:59 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →