You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Solidity动态添加地址至数组时Truffle测试失败求助

你的Solidity测试失败原因分析&修复方案

嘿,我找到你测试失败的核心问题了!问题出在你对Solidity中storage类型变量的使用方式上,咱们一步步说清楚:

为啥原来的代码会崩?

在Solidity里,storage类型的变量是指向合约持久化存储位置的引用,你不能直接在函数里声明一个无绑定的storage数组(就像你写的address[] storage adopters;)。这种未初始化的storage引用会默认指向合约存储的第0个位置,你以为是在给这个数组加元素,但实际上是在乱改合约存储的起始数据,完全不符合你的预期,最后断言自然失败。

两种修复方案,按需选:

方案1:用临时内存数组(纯逻辑测试用)

如果你只是想验证数组push的逻辑,不需要把数据存在合约里,就用memory类型的临时数组——这是函数内的临时内存,用完就丢,适合这种测试场景:

function testAddPet() public {
 address expected = this;
 // 初始化一个空的动态memory数组
 address[] memory adopters = new address[](0);
 // 如果你用的是Solidity 0.8.0及以上版本,直接push就行
 adopters.push(expected);
 // 要是版本更低,就用abi.encodePacked扩展数组
 // adopters = abi.encodePacked(adopters, expected);
 Assert.equal(adopters[0], expected, "Cannot add new pet" );
}

方案2:绑定合约状态变量(模拟合约状态修改用)

如果你的测试是想模拟合约里的状态数组操作,那就在测试合约里先声明一个状态变量,再用storage引用它:

// 先在测试合约里加一个状态变量,用来模拟合约里的adopters数组
address[] public testAdopters;

function testAddPet() public {
 address expected = this;
 // 把storage引用绑定到上面的状态变量
 address[] storage adopters = testAdopters;
 adopters.push(expected);
 Assert.equal(adopters[0], expected, "Cannot add new pet" );
}

补个小确认

你之前对address expected = this;的理解是对的,this确实会返回当前测试合约的地址,和Ganache/MetaMask用的账户没关系,这部分逻辑没问题~

内容的提问来源于stack exchange,提问作者Crittje

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:36:39