猛戳订阅学习专栏🍁🍁 👉 solidity系列合约源码+解析 👈 🍁🍁

何为工厂合约呢?相信有过编程经验的小伙伴都听说过工厂模式,此处的工厂合约其实和他的概念相似,该合约将承担创建其他合约的任务。在基于类的编程中,此模式的主要动机来自单一职责原则(一个类不需要知道如何创建其他类的实例),并且该模式为构造函数提供了一种抽象。
为什么要用到工厂合约呢?
// SPDX-License-Identifier:MIT;
pragma solidity ^0.8;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
contract TestNFT is ERC721,ERC721Enumerable, ERC721URIStorage {
using Counters for Counters.Counter;
Counters.Counter private _tokenId;
constructor(string memory _contract_name,string memory _contract_symbol) ERC721(_contract_name,_contract_symbol){}
function mint(address _recipient, string memory _tokenUrl) public returns(uint _mintTokenId){
require(bytes(_tokenUrl).length > 0,"The _tokenUrl must be have");
_tokenId.increment();
uint newTokenId = _tokenId.current();
_mint(_recipient, newTokenId);
_setTokenURI(newTokenId, _tokenUrl);
return newTokenId;
}
function _beforeTokenTransfer(address from, address to, uint256 tokenId)
internal
override(ERC721, ERC721Enumerable)
{
super._beforeTokenTransfer(from, to, tokenId);
}
function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
super._burn(tokenId);
}
function tokenURI(uint256 tokenId)
public
view
override(ERC721, ERC721URIStorage)
returns (string memory)
{
return super.tokenURI(tokenId);
}
function supportsInterface(bytes4 interfaceId)
public
view
override(ERC721, ERC721Enumerable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}
contract Factory{
// TestNFT[] public addr;
uint nowNum = 0;
mapping(address => string) public ERC_project;
mapping(string => address) public name_addr;
mapping(uint => address) public addr;
function createContract(string memory _name,string memory _symbol) public returns(address){
address t_address;
TestNFT t= new TestNFT(_name,_symbol);
t_address = address(t);
addr[nowNum] = t_address;
ERC_project[t_address] = _name;
name_addr[_name] = t_address;
nowNum++;
return t_address;
}
function getAddress(string memory _name) public view returns(address){
return name_addr[_name];
}
}
首先我们先部署要测试的工厂合约:

利用我们工厂合约定义的createContract方法来创建一个新的ERC721合约:

可以在返回值中查看到我们新创建的合约地址:0xb7b6b4aA81A6b0Dd20500cd19a485a95Fa206687,
其次我们也可以通过新创建的合约的名称来查询到我们新创建的合约的地址,可以看到两次查询到的地址是一致的。

接下来我们把通过工厂合约创建的ERC721合约通过地址导入到remix中进行进一步的验证:

可以查看其名称和我们定义的是一致的:

到此我们几句实现了一个简单的Factory工厂合约,也实现了通过Factory工厂合约成功创建了一个ERC721合约。
当然你也可以去尝试调用新生成合约中的其他方法来进行验证,文章中就不再一一测试了。