前言随着Web3社交协议(如Lens、Farcaster)的爆发,底层区块链的性能和交互成本成为制约用户增长的瓶颈。FormNetwork作为首个专为SocialFi设计的以太坊Layer2,由BinaryX(BNX)战略升级而来。它不仅解决了扩展性问题,还通过FORM
随着 Web3 社交协议(如 Lens、Farcaster)的爆发,底层区块链的性能和交互成本成为制约用户增长的瓶颈。Form Network 作为首个专为 SocialFi 设计的以太坊 Layer 2,由 BinaryX (BNX) 战略升级而来。它不仅解决了扩展性问题,还通过FORM 的 1:1 迁移,开启了社交资产化的新篇章。
一、 什么是 Form Network?
Form Network 是基于 OP Stack 构建的模块化 L2,利用 Celestia 作为数据可用性(DA)层。
在 Form Network 生态启动阶段,最关键的任务是引导 $BNX 持有者无缝迁移到 $FORM。为了极致的 UX(用户体验),我们集成了 EIP-2612 Permit 和 Multicall 功能。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {ERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";
import {SafeERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {Multicall} from "@openzeppelin/contracts/utils/Multicall.sol";
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
// 模拟旧币 BNX (需支持 Permit 以测试一键迁移)
contract BNXToken is ERC20, ERC20Permit {
constructor() ERC20("BinaryX", "BNX") ERC20Permit("BinaryX") {
_mint(msg.sender, 1000000 * 10**18);
}
}
// Form Network 核心合约
contract FormNetworkCore is Multicall, AccessControl {
using SafeERC20 for IERC20;
bytes32 public constant MIGRATOR_ROLE = keccak256("MIGRATOR_ROLE");
IERC20 public immutable bnx;
ERC20 public immutable form;
event Migrated(address indexed user, uint256 amount);
constructor(address _bnx, address _form) {
bnx = IERC20(_bnx);
form = ERC20(_form);
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
}
// 1:1 迁移逻辑
function migrate(uint256 amount) public {
require(amount > 0, "Amount zero");
bnx.safeTransferFrom(msg.sender, address(this), amount);
// 实际场景中 FORM 由此合约 Mint 或预存
form.transfer(msg.sender, amount);
emit Migrated(msg.sender, amount);
}
// 辅助 Permit 调用,用于 Multicall 组合
function applyPermit(
address token, uint256 value, uint256 deadline,
uint8 v, bytes32 r, bytes32 s
) external {
ERC20Permit(token).permit(msg.sender, address(this), value, deadline, v, r, s);
}
}
import assert from "node:assert/strict";
import { describe, it, beforeEach } from "node:test";
import { network } from "hardhat";
import { parseEther, keccak256, stringToBytes, encodeFunctionData } from "viem";describe("Form Network 核心迁移闭环测试", function () { let bnx: any, form: any, core: any; let admin: any, user: any; let publicClient: any;
beforeEach(async function () {
const { viem: v } = await (network as any).connect();
[admin, user] = await v.getWalletClients();
publicClient = await v.getPublicClient();
// 1. 部署 BNX (旧币) 和 FORM (新币)
bnx = await v.deployContract("BNXToken");
form = await v.deployContract("BNXToken"); // 复用合约代码作为 FORM
// 2. 部署核心迁移合约
core = await v.deployContract("FormNetworkCore", [bnx.address, form.address]);
// 3. 初始化:给用户发 BNX,给 Core 存入 FORM 储备
await bnx.write.transfer([user.account.address, parseEther("1000")]);
await form.write.transfer([core.address, parseEther("5000")]);
});
it("创新点测试:Multicall + Permit 实现 [无授权感] 迁移", async function () {
const amount = parseEther("100");
const deadline = BigInt(Math.floor(Date.now() / 1000) + 3600);
// A. 准备 Permit 签名 (EIP-712)
const domain = {
name: "BinaryX",
version: "1",
chainId: await publicClient.getChainId(),
verifyingContract: bnx.address
};
const types = {
Permit: [
{ name: "owner", type: "address" },
{ name: "spender", type: "address" },
{ name: "value", type: "uint256" },
{ name: "nonce", type: "uint256" },
{ name: "deadline", type: "uint256" },
]
};
const nonce = await bnx.read.nonces([user.account.address]);
const signature = await user.signTypedData({
domain, types, primaryType: "Permit",
message: { owner: user.account.address, spender: core.address, value: amount, nonce, deadline }
});
// B. 解析签名 r, s, v
const r = signature.slice(0, 66);
const s = `0x${signature.slice(66, 130)}`;
const v = parseInt(signature.slice(130, 132), 16);
// C. 组合 Multicall 调用 (1. applyPermit -> 2. migrate)
const permitData = encodeFunctionData({
abi: core.abi,
functionName: "applyPermit",
args: [bnx.address, amount, deadline, v, r, s]
});
const migrateData = encodeFunctionData({
abi: core.abi,
functionName: "migrate",
args: [amount]
});
// D. 用户发起原子交易
await core.write.multicall([[permitData, migrateData]], { account: user.account });
// E. 验证结果:用户 BNX 减少,FORM 增加
const bnxBal = await bnx.read.balanceOf([user.account.address]);
const formBal = await form.read.balanceOf([user.account.address]);
assert.strictEqual(bnxBal, parseEther("900"), "BNX 未正确扣除");
assert.strictEqual(formBal, amount, "FORM 未正确发放");
});
it("安全边界测试:非授权代币迁移应失败", async function () {
const fakeToken = admin.account.address; // 随便一个地址
try {
await core.write.migrate([parseEther("10")], { account: user.account });
assert.fail("未授权转账应该回滚");
} catch (e: any) {
// Viem 会抛出合约执行错误
assert.ok(e.message.includes("ERC20InsufficientAllowance") || e.message.includes("revert"), "错误原因不符合预期");
}
});
});
# 四、部署脚本
// scripts/deploy.js import { network, artifacts } from "hardhat"; async function main() { // 连接网络 const { viem } = await network.connect({ network: network.name });//指定网络进行链接
// 获取客户端 const [deployer] = await viem.getWalletClients(); const publicClient = await viem.getPublicClient();
const deployerAddress = deployer.account.address; console.log("部署者的地址:", deployerAddress); // 加载合约 const bnxartifact = await artifacts.readArtifact("BNXToken"); const formartifact = await artifacts.readArtifact("BNXToken"); const coreartifact = await artifacts.readArtifact("FormNetworkCore"); // 部署(构造函数参数:recipient, initialOwner) const bnxhash = await deployer.deployContract({ abi: bnxartifact.abi,//获取abi bytecode: bnxartifact.bytecode,//硬编码 args: [],//process.env.RECIPIENT, process.env.OWNER });
// 等待确认并打印地址 const bnxreceipt = await publicClient.waitForTransactionReceipt({ hash: bnxhash }); console.log("BNX合约地址:", bnxreceipt.contractAddress); const formhash = await deployer.deployContract({ abi: formartifact.abi,//获取abi bytecode: formartifact.bytecode,//硬编码 args: [],//process.env.RECIPIENT, process.env.OWNER }); const formreceipt = await publicClient.waitForTransactionReceipt({ hash: formhash }); console.log("Form合约地址:", formreceipt.contractAddress); const corehash = await deployer.deployContract({ abi: coreartifact.abi,//获取abi bytecode: coreartifact.bytecode,//硬编码 args: [bnxreceipt.contractAddress, formreceipt.contractAddress],//process.env.RECIPIENT, process.env.OWNER }); const coreceipt = await publicClient.waitForTransactionReceipt({ hash: corehash }); console.log("Core合约地址:", coreceipt.contractAddress); }
main().catch(console.error);
# 五、 结语:SocialFi 的未来
Form Network 的价值不在于它又是一个 L2,而在于它通过**技术手段降低了社交门槛**。通过 `Multicall` 减少弹窗交互,通过 `Permit` 省去授权步骤,Web3 社交应用正在向 Web2 的丝滑体验靠拢。 如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!