调用合约方法创建子合约后获取子合约地址

在通过调用合约的方法创建合约后,不能直接得到子合约地址。不便于单元测试。如下方法可解决:

合约:

// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.13;

contract A {                    // 子合约
    string public name;
}

contract B {                    // 父合约
    event NEWA(address addr);   //定义事件
    address private aa;         // 用来验证

    function createA() public returns (A){  // 创建A合约
        A a = new A();
        aa = address(a);
        emit NEWA(address(a));  // 发送事件
        return a;
    }

    function getaa() public view returns (address){
        return aa;
    }
}

单元测试:

const { expect } = require('chai');
const { ethers } = require('hardhat');

describe('Test', () => {
	let owner, user1, users, contract;

	it('Should return address of sub-contract.', async () => {
		[ owner, user1, ...users ] = await ethers.getSigners();

		const Contract = await ethers.getContractFactory('B');
		contract = await Contract.deploy();     // 部署父合约B          

		const exec = await contract.createA();        // 通过B合约创建子合约A
		const event = await exec.wait();
		const Baddr = ethers.utils.getAddress(          // 标准化为地址格式
            ethers.utils.hexStripZeros(                 // 去0
                event.events[0].data                    // 读取事件的值
                )
            );
		expect(await contract.getaa()).to.equal(Baddr);
	});
});