You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何部署Polygon智能合约并由他人签署部署交易?

Polygon主网离线签署部署合约方案

核心思路是离线生成部署交易数据,由目标所有者钱包签署后,再广播到主网,完全不需要多签或复杂配置,匹配你要的两步流程。

步骤1:生成未签名的部署交易

用Hardhat+ethers.js编写脚本,生成包含合约部署数据的未签名交易,保存为文件发送给签署人。

示例脚本(generate-unsigned-tx.js)

const { ethers, network } = require("hardhat");
const fs = require("fs");

async function main() {
  // Polygon主网链ID
  const CHAIN_ID = 137;
  // 签署人的钱包地址(用来获取交易nonce)
  const DEPLOYER_ADDRESS = "0x替换为上司的钱包地址";

  // 加载你的合约工厂
  const TargetContract = await ethers.getContractFactory("你的合约名称");
  // 合约构造函数参数(无参数则留空数组)
  const constructorArgs = [];

  // 生成部署合约的交易数据
  const deployTxData = TargetContract.getDeployTransaction(...constructorArgs).data;

  // 连接Polygon主网RPC节点(需提前在hardhat.config.js配置)
  const provider = new ethers.providers.JsonRpcProvider(network.config.url);
  // 获取签署人地址的当前nonce(pending状态避免重复)
  const nonce = await provider.getTransactionCount(DEPLOYER_ADDRESS, "pending");
  // 估算gas上限
  const gasLimit = await provider.estimateGas({ from: DEPLOYER_ADDRESS, data: deployTxData });
  // 获取当前主网gas价格
  const gasPrice = await provider.getGasPrice();

  // 构建未签名交易对象
  const unsignedTx = {
    chainId: CHAIN_ID,
    nonce: nonce,
    gasLimit: gasLimit.toHexString(),
    gasPrice: gasPrice.toHexString(),
    data: deployTxData,
    to: null, // 部署合约时to字段为空
    value: ethers.utils.parseEther("0"), // 无需转账ETH则设为0
  };

  // 保存未签名交易到本地文件
  fs.writeFileSync("unsigned-deploy-tx.json", JSON.stringify(unsignedTx, null, 2));
  console.log("未签名交易已生成:unsigned-deploy-tx.json");
}

main().catch(err => {
  console.error(err);
  process.exit(1);
});

运行脚本前,确保hardhat.config.js中配置了Polygon主网的RPC节点(比如Alchemy/Infura的节点地址)。

步骤2:由目标所有者签署交易

将生成的unsigned-deploy-tx.json发送给签署人,对方可以通过两种方式签署:

方式1:MetaMask可视化签署(推荐,无需暴露私钥)

签署人可以用一个简单的前端页面完成签名:

  1. 创建HTML文件,引入ethers.js
  2. 读取unsigned-deploy-tx.json内容
  3. 调用MetaMask的签名接口:
// 示例前端代码片段
const unsignedTx = JSON.parse(读取的文件内容);
const provider = new ethers.providers.Web3Provider(window.ethereum);
await provider.send("eth_requestAccounts", []);
const signer = provider.getSigner();
const signedTx = await signer.signTransaction(unsignedTx);
// 复制signedTx字符串发给你

方式2:离线私钥签署(签署人自行操作)

如果签署人愿意使用私钥,可以用以下脚本完成签名:

const { ethers } = require("ethers");
const fs = require("fs");

async function signTx() {
  const unsignedTx = JSON.parse(fs.readFileSync("unsigned-deploy-tx.json"));
  // 签署人的私钥(仅本人使用,绝对不能泄露)
  const privateKey = "0x签署人的私钥";
  const wallet = new ethers.Wallet(privateKey);
  const signedTx = await wallet.signTransaction(unsignedTx);
  fs.writeFileSync("signed-deploy-tx.json", JSON.stringify({ signedTx }, null, 2));
  console.log("已签名交易生成:signed-deploy-tx.json");
}

signTx().catch(err => {
  console.error(err);
  process.exit(1);
});

步骤3:广播已签名交易到Polygon主网

拿到签署后的交易字符串,用脚本广播到主网:

广播脚本(broadcast-signed-tx.js)

const { ethers, network } = require("hardhat");
const fs = require("fs");

async function main() {
  const { signedTx } = JSON.parse(fs.readFileSync("signed-deploy-tx.json"));
  const provider = new ethers.providers.JsonRpcProvider(network.config.url);
  // 广播交易
  const txResponse = await provider.sendTransaction(signedTx);
  console.log(`交易已广播,哈希:${txResponse.hash}`);
  // 等待交易确认
  await txResponse.wait();
  console.log(`交易确认完成,合约地址:${txResponse.contractAddress}`);
}

main().catch(err => {
  console.error(err);
  process.exit(1);
});

关键注意事项

  • 签署人的钱包必须有足够的MATIC支付gas费
  • 确保合约的Ownable逻辑默认将部署者(签署人地址)设为初始所有者(比如OpenZeppelin的Ownable合约默认如此)
  • 生成未签名交易时,nonce必须准确,若期间签署人有其他交易,需要重新生成nonce

内容的提问来源于stack exchange,提问作者user2701487

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 05:04:53