如何将OpenZeppelin ERC721合约内的ETH直接发送到PaymentSplitter合约
实现方案
你只需要对现有MyNFTPrice.sol做少量修改,同时按正确顺序部署两个合约即可实现资金自动划转,具体操作如下:
步骤1:修改MyNFTPrice合约代码
修改逻辑包括:
- 继承
Ownable权限控制,避免PaymentSplitter地址被随意修改 - 新增状态变量存储已部署的PaymentSplitter合约地址
- 新增地址配置函数,仅 owner 可调用
- 在mint逻辑执行完成后,直接将用户支付的ETH转到PaymentSplitter地址
- 新增资金提取函数,可把当前已经存在
MyNFTPrice合约里的存量ETH一次性转到PaymentSplitter
修改后完整代码如下:
pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; // 增加Ownable继承 contract MyNFTPrice is ERC721URIStorage, Ownable { using Counters for Counters.Counter; Counters.Counter private _tokenIds; // 新增PaymentSplitter地址存储变量 address public paymentSplitter; constructor() public ERC721("MyNFTPrice", "NFTPRICE") {} // 新增配置PaymentSplitter地址的函数,仅Owner可调用 function setPaymentSplitter(address _paymentSplitter) external onlyOwner { require(_paymentSplitter != address(0), "Invalid address"); paymentSplitter = _paymentSplitter; } // Mint new NFT function mintNFT(address recipient, string memory tokenURI) public payable { require(msg.value >= 50000000000000000, "You need 0.05 ETH to mint the NFT"); require(paymentSplitter != address(0), "PaymentSplitter not set"); _tokenIds.increment(); uint256 newItemId = _tokenIds.current(); _mint(recipient, newItemId); _setTokenURI(newItemId, tokenURI); // 铸造完成后直接将ETH转到PaymentSplitter payable(paymentSplitter).transfer(msg.value); } // 新增提取存量资金函数,将合约中已有的ETH转到PaymentSplitter function withdrawExistingFunds() external onlyOwner { require(paymentSplitter != address(0), "PaymentSplitter not set"); uint256 balance = address(this).balance; require(balance > 0, "No balance to withdraw"); payable(paymentSplitter).transfer(balance); } }
步骤2:按顺序部署合约
- 首先部署
PaymentSplitter合约,填入你预设的收款人地址和分成比例,部署完成后复制该合约的地址 - 再部署修改后的
MyNFTPrice合约 - 调用
MyNFTPrice合约的setPaymentSplitter方法,将第一步复制的PaymentSplitter地址传入,完成配置
步骤3:存量资金处理
如果你的原MyNFTPrice合约已经有用户铸造存入的ETH,部署新合约后调用withdrawExistingFunds即可将所有存量资金转入PaymentSplitter,后续新铸造的资金会自动实时转入。
注意事项
- 不要直接将PaymentSplitter地址硬编码在NFT合约中,避免部署顺序出错或者需要更换分成合约时要重新部署NFT
- transfer方法会自动发送ETH并携带2300gas,足够PaymentSplitter接收ETH使用,不会出现gas不足问题
内容的提问来源于stack exchange,提问作者johnDoe
相关产品推荐
相关产品推荐

