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

如何查询并提取ERC721合约中的以太币?

问题解答

1. 支付的以太币存储位置

用户支付的1 ether会直接存储在该ERC721合约的地址中。以太坊合约地址本身具备接收和存储以太币的能力,当调用带payable修饰的mint函数并转入ETH时,ETH会直接存入合约地址对应的账户余额,这也是你在区块链浏览器中看到合约地址有1 ether余额的原因。

2. 提取合约中的以太币

当前你的合约未实现以太币提取功能,需要修改合约添加提取逻辑,以下是两种常见实现方式:

方式一:仅合约所有者可提取(推荐)

先引入OpenZeppelin的Ownable合约实现权限控制,再添加提取函数:

// SPDX-License-Identifier: MIT 
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract Example is ERC721, Ownable {

    uint256 private _tokenId = 0;

    // 补充ERC721构造函数参数
    constructor() ERC721("Example", "EX") {}

    function mint(uint256 tokenURI, uint256 id) public payable returns(uint256){
        require(msg.value == 1 ether);
        require(id > 0);
        
        _tokenId += 1;
        _mint(msg.sender, _tokenId);
        _setTokenURI(_tokenId, tokenURI);
        return _tokenId;
    }

    // 提取合约所有以太币到所有者地址
    function withdraw() public onlyOwner {
        uint256 balance = address(this).balance;
        require(balance > 0, "No ETH to withdraw");
        payable(owner()).transfer(balance);
    }
}

方式二:允许任何人提取(不推荐,仅作示例)

若无需权限控制(存在安全风险,不建议使用),可添加无限制提取函数:

function withdraw() public {
    uint256 balance = address(this).balance;
    require(balance > 0, "No ETH to withdraw");
    payable(msg.sender).transfer(balance);
}

修改后需重新部署合约,或通过合约升级方案(如透明代理)添加该函数。调用提取函数时,若为所有者模式,发起交易的地址需具备所有者权限,交易执行后合约ETH会转入指定地址。

3. 查看合约的以太币余额

ERC721的balanceOf仅查询代币持有数量,查看合约ETH余额可通过两种方式:

  • 直接在区块链浏览器中查看合约地址的Balance字段,该值即为合约存储的以太币数量。
  • 在合约中添加只读函数暴露余额:
    function getContractEthBalance() public view returns(uint256) {
        return address(this).balance;
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 09:50:45