因此,我创建了一个“执行契约”和一个“克隆工厂”,它创建了执行契约的克隆。我已经测试了CloneFactory的功能,它可以在Remix中工作。
然而,我现在正在用硬帽子为合同编写测试,它似乎没有正确地工作(摩卡和柴)。我面临的问题是克隆合同没有被正确初始化。
这是我的克隆工厂:
contract CloneFactory {
address public implementationContract;
address[] public allClones;
event NewClone(address indexed _instance);
mapping(address => address) public list;
constructor(address _implementation) {
implementationContract = _implementation;
}
function createClone(address _creator) payable external returns(address instance) {
instance = Clones.clone(implementationContract);
(bool success, ) = instance.call{value: msg.value}(abi.encodeWithSignature("initialize(address)", _creator));
allClones.push(instance);
list[_creator] = instance;
emit NewClone(instance);
return instance;
}下面是我的实现契约中的initialiser函数:
function initialize(address _creator) public initializer {
VRFConsumerBaseV2.initialise(vrfCoordinatorV2);
i_vrfCoordinator = VRFCoordinatorV2Interface(vrfCoordinatorV2);
creator = _creator;下面是我正在运行的测试(这是我认为存在问题的地方):
it("Initialises contract correctly", async function () {
Main = await ethers.getContractFactory("Main");
main = await Main.deploy();
await main.deployed();
const dir = path.resolve(
__dirname,
"/Users/xxx/hardhat-smartcontract-main/artifacts/contracts/Main.sol/Main.json"
)
const file = fs.readFileSync(dir, "utf8")
const json = JSON.parse(file)
const abi = json.abi
CloneFactory = await ethers.getContractFactory("CloneFactory");
cf = await CloneFactory.deploy(main.address);
await cf.deployed();
let currentProvider = new web3.providers.HttpProvider('http://localhost:8545');
let web3Provider = new ethers.providers.Web3Provider(currentProvider);
const [addr1, addr2] = await ethers.getSigners();
const tx = await cf.createClone(addr1.address, {
value: ethers.utils.parseUnits("0", "ether")
});
const txReceipt = await tx.wait(1)
const cloneAddress = await txReceipt.events[0].args._instance
const clonedContract = new ethers.Contract(cloneAddress, abi, web3Provider)
const accountConnectedClone = clonedContract.connect(addr1)
const creator = await accountConnectedClone.getCreator()
expect(addr1.address).to.equal(creator)
})当我运行这个测试时,我得到以下输出:
AssertionError: expected '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb…' to equal '0x00000000000000000000000000000000000…'
+ expected - actual
-0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
+0x0000000000000000000000000000000000000000基本上,创建者不会被保存为'createClone‘函数调用者的地址(这意味着它没有被初始化。我不认为克隆工厂有什么问题,因为这在Remix中是正确的。
我怀疑这与ABI或ether/web3提供商有关,不过我可能错了。
网上似乎没有太多关于测试克隆或代理智能合同的信息,所以我希望这里有人能帮助我。
提前感谢!
EthereumBoy
发布于 2022-09-09 16:58:18
我将在createClone中的(bool success, ) = ...行之后添加这一行:
require(success, "initialize failed");您正在调用initialize forwarding msg.value,但是initialize是不需要支付的,所以我可以通过在这里添加payable来修复
function initialize(address _creator) public payable initializer {或者删除调用中的{value: msg.value}。
我不认为这是调用失败的原因,因为您使用的是0值,但是修复它很好。
_creator,编译器不是给您一个警告或错误吗?应该是_whoopyCreator。(bool success, ) = instance.call{value: msg.value}(abi.encodeWithSignature("initialize(address)", _creator));尝试执行上述三项建议,希望它们能有所帮助。
https://ethereum.stackexchange.com/questions/135310
复制相似问题