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

本文介绍在Solidity中通过父合约创建子合约后如何获取子合约地址的问题,强调了直接获取的不便及事件监听的解决方案。在合约B中定义了创建子合约A的函数,并通过事件发送子合约地址。在单元测试中,展示了如何监听事件来获取并验证子合约的地址。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

合约:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值