在Solidity中是否可以有多个映射映射到同一结构?

时间:2019-03-08 08:13:37

标签: struct mapping solidity

我想要实现的是让两个结构值类型的映射指向相同的结构引用,因此我可以通过两种方式查找和编辑特定的结构实例。但是,在一个映射中更新结构似乎并不会在另一映射中更新结构。这是我简化的合同来说明这个想法:

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结构体是引用类型。因此,我期望对一个池的修改将同时反映在映射poolsByDaypoolsById中,但事实并非如此。是我未能正确初始化两个映射吗?

1 个答案:

答案 0 :(得分:1)

否,这两个映射将指向不同的结构,因此您需要自己处理间接操作,例如通过使用从天到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; 
    }
}

(在这个人为的示例中,它们似乎都使用相同的键,但是我认为在您的真实代码中,有两个映射的原因。)