5 使用create2得到目标合约地址,并加盐后,无法执行目标合约里的claim函数(nft mint),是不能写入,只能读吗?

  *krtforum is the contract owner
  *whalehat is the contract builder
*/
pragma solidity ^0.8.8;
  import {StringUtils} from "../libraries/StringUtils.sol";
  import "@openzeppelin/contracts/utils/Base64.sol";
  import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
  import "../interface/investFlowInterface.sol";
  import "../interface/forumFlowNft.sol";
  import "@openzeppelin/contracts/access/Ownable.sol";
contract forumFlowNftCopy is ERC721URIStorage,Ownable{
    uint256 titleNftId; //帖子nft的Id

    constructor() payable ERC721("Encrypted Forum Post Nft", "EFPN") {}

    event claimNft(address,string,uint256);

    function claimTitleNfts(address contractAddress,string calldata _worksName)public{
          _safeMint(msg.sender, titleNftId);
          _setTokenURI(titleNftId, getThisTitleUri(contractAddress,_worksName));
          emit claimNft(msg.sender,_worksName,titleNftId);
          titleNftId++; //+1
    }

    //获取帖子uri
    function getThisTitleUri(address contractAddress,string calldata _worksName)public view returns(string memory){
      return investInterface(contractAddress).getWorksUri(_worksName);
    }

}

contract forumFlowNftFair{
    address[] public allNftsPair;

    address public hat;
    //通过create2得到nft合约地址
    function magicNftContract(address forumContractAddress,string calldata _worksName)external returns(address hatTrick){
        //第一种方法
        // return hat=address(
        //     new forumFlowNft{salt:keccak256(abi.encodePacked(forumContractAddress,_worksName))}()
        // );

        //第二种:内联汇编
        bytes memory nftCreationCode=type(forumFlowNftCopy).creationCode;
        bytes32 saltHash=keccak256(abi.encodePacked(forumContractAddress,_worksName));
        assembly{
            hatTrick :=create2(
                0,  /* ETH gad */
                add(nftCreationCode,32),
                mload(nftCreationCode),
                saltHash
            )
            if iszero(extcodesize(hatTrick)){
                revert(0,0)
            }
            sstore(hat.slot,hatTrick)
        }
        allNftsPair.push(hatTrick);  //将新的合约地址push到数组末尾
    }

    //申领个人投资的nft
    function claim(address nftContractAddress,address forumContractAddress,string calldata _titleName,string calldata _worksName)external {
        require(checkUserInvest(nftContractAddress,forumContractAddress,_titleName),"You not invest This");  //用户是否投资
        require(timeRemain(forumContractAddress,_titleName)==0,"The crowdfunding time is not over");  //众筹时间是否结束
        uint256 getNums=getUserInvestNum(forumContractAddress,_titleName,msg.sender);  //用户投资帖子数量
        for (uint i = 0; i < getNums; i++) {
           forumFlowNftInter(nftContractAddress).claimTitleNfts(forumContractAddress,_worksName);
        }
    }

    //查看帖子主人
    function getThisTitleMaster(address forumContractAddress,string calldata _name)public view returns(address){
        return investInterface(forumContractAddress).getTitleMaster(_name);
    }

    //检查用户是否投资
    function checkUserInvest(address forumContractAddress,address userAddress,string calldata _titleName)public view returns(bool){
        return investInterface(forumContractAddress).personalIfInvest(userAddress,_titleName);
    }

    //帖子众筹剩余时间
    function timeRemain(address forumContractAddress,string calldata _titleName)public view returns(uint256){
        return investInterface(forumContractAddress).withdrawalTimeLeft(_titleName);
    }

    //用户投资某帖子数量
    function getUserInvestNum(address forumContractAddress,string calldata _titleName,address userAddress)public view returns(uint256){
        return investInterface(forumContractAddress).getUserInvestNum(_titleName,userAddress);
    }

    //得到合约地址
    function getContractAddress(address forumContractAddress,string calldata _worksName)public view returns(address){
        return address(uint160(uint(
            keccak256(
                abi.encodePacked(
                    //255
                    uint8(0xff),
                    //当前合约地址
                    address(this),
                    // 加盐
                    keccak256(abi.encodePacked(forumContractAddress,_worksName)),
                    keccak256(type(forumFlowNftCopy).creationCode)
                )
            )
        )));
    }
}
请先 登录 后评论

最佳答案 2023-06-23 13:36

你用 Create2 创建的合约需要实现 IERC721Receiver 接口

请先 登录 后评论

其它 3 个回答

DIO_L2 - web3全栈开发
请先 登录 后评论
合约开发 - 开发工程师
请先 登录 后评论
? or ?
请先 登录 后评论
  • 4 关注
  • 0 收藏,1801 浏览
  • ? or ? 提出于 2023-03-15 11:58