我想要实现的是有两个struct值类型的映射指向同一个struct引用,所以我可以用两种方式查找和编辑一个特定的struct实例。但是,在一个映射中更新结构似乎不会更新另一个中的结构。这是我的简化合同来说明这个想法:
contract Example {
mapping(uint => Pool) public poolsByDay;
mapping(uint => Pool) public poolsById;
constructor(uint day) public {
for (uint i = 1; i <= day; i++) {
Pool memory pool = Pool({
id: i,
amount: 0
});
poolsByDay[i] = pool;
poolsById[i] = pool;
}
}
function deposit(uint day, uint amount) external {
Pool storage pool = poolsByDay[day];
pool.amount += amount;
}
}
请注意,poolsByDay
的密钥可能每天都在变化。我希望能够按天或通过ID查找池。
这是我的测试:
const example = await Example.new(7)
const day = 1
const amount = 100e18
await example.deposit(day, amount.toString())
const pool = await example.poolsByDay(term)
const anotherPool = await example.poolsById(pool.id)
assert.equal(pool.amount, amount) // succeeded
assert.equal(anotherPool.amount, amount) // failed
据我所知,Solidity struct是一种引用类型。所以我期待一个池的修改将反映在映射poolsByDay
和poolsById
中,但事实并非如此。是不是我没能正确初始化两个映射?
不,这两个映射将指向不同的结构,因此您需要自己处理间接,例如通过使用从天到ID的映射:
contract Example {
mapping(uint => uint) public poolsByDay;
mapping(uint => Pool) public poolsById;
constructor(uint day) public {
for (uint i = 1; i <= day; i++) {
poolsById[i] = Pool({ id: i, amount: 0 });
poolsByDay[i] = i;
}
}
function deposit(uint day, uint amount) external {
Pool storage pool = poolsById[poolsByDay[day]];
pool.amount += amount;
}
}
(在这个人为的例子中,他们似乎都使用相同的键,但我假设在你的真实代码中有两个映射的原因。)