稳定性-松露:错误:处理事务时VM异常:无效的操作码不是由于还原

时间:2019-02-23 19:40:50

标签: ethereum solidity smartcontracts opcode truffle

我正在开发智能合约,并且正在通过将其部署在松露上进行测试。虽然编译良好,但是当我调用train()函数时,出现以下错误:

  

错误:处理事务时VM异常:无效的操作码

在阅读了一些内容之后,我了解到它通常是在发生还原后引起的,因此我尝试注释掉我只想看看它是否会表现出不同的2个require函数,但事实并非如此。

签出this问题对我没有帮助,或者我不知道如何解决。

这是train()函数,以及我在其中使用的映射和结构类型。我应该注意,在创建开发人员时,他们的钱包设置为300,因此我看不到所有者如何第一次恢复火车功能。

<div class="row">
    <figure>
        <figcaption>Fig.1 - Trulli, Puglia, Italy.</figcaption>
        <img src="https://www.w3schools.com/tags/img_pulpit.jpg" alt="The Pulpit Rock" width="304" height="228">
    </figure>
    <figure>
        <figcaption>Fig.1 - Trulli, Puglia, Italy.</figcaption>
        <img src="https://www.w3schools.com/tags/img_pulpit.jpg" alt="The Pulpit Rock" width="304" height="228">
    </figure>
    <figure>
        <figcaption>Fig.1 - Trulli, Puglia, Italy.</figcaption>
        <img src="https://www.w3schools.com/tags/img_pulpit.jpg" alt="The Pulpit Rock" width="304" height="228">
    </figure>
</div>

谢谢您的帮助。

1 个答案:

答案 0 :(得分:0)

这很可能是因为您试图访问空数组的第一个条目。您正在使用do while循环,并且正在尝试检查developers_all[h].skills[i]之前访问developers_all[h].skills.length == 0,因此do while的第一个if语句数组可能为空。

您可以将代码重写为类似以下内容,以确保您永远不会访问未分配的阵列插槽。

bool foundSkill = false;

for (uint i = 0; i < developers_all[h].skills.length; i++) {
    if (developers_all[h].skills[i] == _skill) {
        developers_all[h].skill_levels[i]++;
        foundSkill = true;
        break;
    }
}

if (!foundSkill) {
    developers_all[h].skills.push(_skill);
    developers_all[h].skill_levels.push(1);
}

请注意,遍历整个数组并进行比较非常昂贵,如果数组太大,则变得不可能。您可能需要考虑将结构更改为以下内容:

struct Developer {
    address owner;
    string name;
    bytes32 namehash;
    mapping(bytes32 => uint) skill_levels;
    uint wallet;
}

这样,您可以将整个内容替换为

developers_all[h].skill_levels[skill]++;

但是您将无法遍历这些技能。