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

如何通过Governor提案实现原生代币(如ETH)转账?

如何在Governor提案中实现原生代币(ETH)转账

核心问题分析

你之前的尝试存在两个关键错误:

  1. 直接将收款人地址作为target时,传入的3是普通数值而非wei单位的ETH——以太坊合约仅识别以wei为单位的金额
  2. 使用web3.eth.sendTransaction().encodeABI()是错误操作,sendTransaction是Web3发送交易的API,并非合约方法,无法编码为提案所需的calldata

正确实现方案

前提准备

确保Timelock合约地址持有足够的ETH,因为最终由Timelock执行转账操作,需先向其转入对应金额的ETH。

方案1:直接通过提案向收款人转ETH(无需修改合约)

利用Governor提案的values参数指定要发送的ETH金额(wei单位),calldatas传空值(仅需转ETH,无需调用目标地址的函数):

// 转换3 ETH为wei单位
const ethAmount = web3.utils.toWei('3', 'ether');
// 创建提案
const nativeProposal = await governor.propose(
    [accounts[6]], // 收款人地址
    [ethAmount],   // 要发送的ETH金额(wei)
    ["0x"],        // 空calldata,仅执行转账
    "Grant 3 ETH for marketing to Bob",
    {from: accounts[4]}
);

方案2:通过Timelock合约的自定义方法转账(更安全可控)

如果需要对转账操作做权限控制或日志记录,可给Timelock合约添加一个转账ETH的方法:

// Timelock合约中添加
function transferEth(address payable _recipient, uint256 _amount) external onlyGovernor {
    require(address(this).balance >= _amount, "Insufficient ETH balance");
    _recipient.transfer(_amount);
    emit EthTransferred(_recipient, _amount);
}

然后在JS中编码该方法的calldata并创建提案:

const timelock = await artifacts.require("Timelock").deployed();
const ethAmount = web3.utils.toWei('3', 'ether');
// 编码转账方法的calldata
const calldata = timelock.contract.methods.transferEth(accounts[6], ethAmount).encodeABI();

const propose_res = await governor.propose(
    [timelock.address], // 目标为Timelock合约
    [0],                // 此处value为0,ETH从Timelock余额中扣除
    [calldata],         // 调用自定义转账方法的calldata
    "Grant 3 ETH for marketing to Bob",
    {from: accounts[4]}
);

提案执行流程

无论采用哪种方案,都需要走完标准Governor提案流程:

  • 等待提案进入投票期
  • 发起投票并获得足够支持
  • 提案通过后进入Timelock延迟期
  • 延迟期结束后执行提案,完成ETH转账

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 04:15:42