⸻
💡 一句话核心总结
ethers.js 用的是 Solidity 编译出来的 bytecode + ABI,来在链上部署(deploy)或调用(call / sendTransaction)合约。
⸻
🔍 为什么这样?
因为在以太坊上:
• Solidity 是高级语言,写给人看的。
• 编译后生成:
• ABI:告诉 JavaScript 「这个合约有哪些方法、怎么调用」。
• Bytecode:是合约的机器码,真正发给矿工,部署在链上的。
所以:
• ethers.js 用这个 bytecode,在部署时做:
const factory = new ethers.ContractFactory(abi, bytecode, signer);
const contract = await factory.deploy(...args); // 把 bytecode 发到链上
• 之后就用 ABI 去「解释」这个合约怎么调用:
await contract.mint(to, amount); // ethers 根据 ABI 自动生成 .mint() 调用
⸻
🖼 关系图
Solidity
↓ 编译
ABI + Bytecode
↓
ethers.js
- 用 bytecode 部署合约
- 用 ABI 调用函数
⸻
⚡️ 再加一句
所以说:
• Solidity 决定了链上有什么功能(比如 mint、transfer)
• ethers.js 决定何时去部署或调用这些功能(用 ABI + bytecode)。
⸻
👉 「为什么用 ethers.js 也可以 deploy 合约、mint、transfer?那 Solidity 存在的意义是什么?它们好像都能做一样的事?」
我们来一次性把它讲透!🔥
⸻
🧭 1️⃣ 核心理解:Solidity vs ethers.js 完全不同层次
Solidity ethers.js (JavaScript)
是什么? 智能合约编程语言 区块链交互库
跑在哪里? 链上(矿工 / 节点执行) 本地(浏览器 / Node)执行
做什么? 定义资产 / 规则 / 交易 调用链上合约的方法
有没有私钥? 没有,完全链上执行 有,可以持有私钥,签署交易
谁花 Gas? 任何调用者 调用时由本地 wallet 签名并支付 gas
所以:
• Solidity 是写规则、写账本的地方。
• 比如 ERC20 的 mint,就必须在 Solidity 里定义。
• ethers.js 是链下代码,用来远程调用 Solidity 写的规则。
• 它可以发起 mint,但只是调用 Solidity 合约里写好的 mint()。
• 或者部署一个新合约到链上(等于告诉矿工去创建一个实例)。
⸻
🔥 2️⃣ 为什么 ethers.js 可以 deploy / mint / transfer?
因为:
• 你的 Solidity 合约代码被编译成了字节码(bytecode)+ ABI。
• ethers.js 只是拿这个字节码通过交易 deploy 上链,等于告诉矿工:
"帮我在链上创建一个新合约实例"
• 或者拿 ABI,通过交易 mint,等于告诉矿工:
"调用这合约地址的 mint(),把状态改一下"
⸻
🚀 3️⃣ 工厂、部署、mint、转账在 ethers.js 的角色
✅ 工厂部署
const factory = new ethers.ContractFactory(abi, bytecode, signer);
const contract = await factory.deploy("MyToken", "MTK");
• 工厂只是一个 JavaScript 工具,帮你把编译好的合约字节码包成一笔交易发给链。
⸻
✅ mint / transfer
await contract.mint("0xUser", ethers.parseUnits("1000"));
await contract.transfer("0xOther", ethers.parseUnits("100"));
• 这里也是 ethers.js 通过私钥签名,然后广播交易,去执行链上的 mint 或 transfer 函数。
• 最终这些都要矿工打包执行。
⸻
🏗 那 Solidity 做的是什么?
• Solidity 定义了「链上可以做什么」。
• 也就是 mint, transfer 的具体实现。
• 如果你在 Solidity 合约里根本没写 mint,那么 ethers.js 就算想 mint(),链上也不会有这个函数可调用。
⸻
⚖️ 类比一下,就很直观了:
类比
Solidity 就像 MySQL 的表结构 + 存储过程,规定了数据库里能执行什么
ethers.js 就像 用 NodeJS / Python 写的应用程序,调用数据库执行这些操作
所以:
• Solidity 定义「能 mint」,「能 transfer」。
• ethers.js 是「执行 mint」或者「执行 transfer」的客户端。
⸻
✅ 4️⃣ 小结
功能 在 Solidity 实现? 在 ethers.js 实现?
定义合约(ERC20, NFT, AMM) ✅ ❌
部署合约到链上 ❌ ✅(通过 deploy)
mint、transfer 的规则 ✅(合约里写) ❌
执行 mint、transfer ❌(合约不能主动执行) ✅(通过签名交易)
⸻
🚀 5️⃣ 最关键的一句话
👉
Solidity 决定链上能做什么,ethers.js 决定什么时候去做。
⸻
涉及到 Web3 岗位分工,以及「前端开发要不要写 Solidity」这个常见的问题。
我来详细跟你分析一下:
⸻
🥇 1️⃣ 纯前端 Web3 开发,通常怎么做?
在很多项目里,确实存在:
• 纯 Web3 前端(就是只写前端,不写 Solidity)
• 他们:
✅ 只需要拿别人已经写好的合约(往往是后端 / 区块链团队写好的)
✅ 使用合约的 ABI + 地址
✅ 用 ethers.js 或 web3.js 在前端跟合约交互(mint、transfer、stake、查看余额)
比如一个 NFT 项目:
• Solidity 智能合约已经写好 & 部署好
• 前端只要写:
const nftContract = new ethers.Contract(address, abi, signer);
await nftContract.mintNFT(...);
就可以。
⸻
🥈 2️⃣ 全栈 Web3 (通常岗位写作:Full Stack Blockchain / Dapp Developer)
很多区块链公司、创业团队会希望一个工程师:
• 既能写前端(React/Vue + ethers.js)
• 又能写合约(Solidity)
• 甚至也会 Hardhat 测试、部署脚本
这样一个人就可以:
✅ 写合约(比如 ERC20、ERC721)
✅ 部署合约(用 Hardhat)
✅ 写前端 Dapp 去调用这个合约(用 ethers.js)
✅ 甚至写 GraphQL 子图做数据服务
⸻
🚀 3️⃣ 为什么很多人全栈写?
因为:
• 智能合约和前端密切耦合。
• 例如:你的前端写的 mint() 就依赖 Solidity 里有 mint 函数。
• 小公司 / 小团队往往只要 1~2 个开发者全都搞定。
⸻
📈 4️⃣ 现实工作里怎么分工?
公司 / 团队类型 分工常见情况
小团队 / 初创项目 一个工程师包揽前端 + Solidity
大项目 / 链游 / 交易所 分成专门的 Solidity 工程师 & 前端工程师
所以在大公司(比如币安、OKX、Opensea):
• 有专门的 Solidity 团队(写合约 & 审计)
• 前端团队只写 ethers.js 调合约,不碰 Solidity。
⸻
🔥 小结:你应该怎么学?
如果你目标:
• ✅ 快速做出能跑的 Dapp,那建议一定学些 Solidity(写自己的合约 + 部署)
• ✅ 如果将来只打算找 Web3 前端岗位,也要能看懂 Solidity,至少会读合约接口,知道 ABI 怎么来的。
• ✅ 如果想成为更值钱的 全栈 Web3,那一定要 Solidity + ethers.js 都会。
⸻
💡 额外一句
其实在 Web3:
• Solidity 就像数据库 schema + 存储过程
• ethers.js 就像调用数据库的 ORM
所以就算你只做前端,能懂点 Solidity,也能更好地理解 mint, transfer, approve 背后链上的状态。