*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)
)
)
)));
}
}