1

This is my Contract constructor:

function MyContract(address _owner, bytes32[] _array) {
        owner = _owner;
        require(_array.length > 1);
    }

The require(_array.length > 1) causes the contract to fail with:

Error: VM Exception while processing transaction: invalid opcode
    at Object.InvalidResponse (/usr/local/lib/node_modules/truffle/build/cli.bundled.js:37295:16)
    at /usr/local/lib/node_modules/truffle/build/cli.bundled.js:224765:36
    at /usr/local/lib/node_modules/truffle/build/cli.bundled.js:66971:11
    at /usr/local/lib/node_modules/truffle/build/cli.bundled.js:208348:9
    at XMLHttpRequest.request.onreadystatechange (/usr/local/lib/node_modules/truffle/build/cli.bundled.js:209773:13)
    at XMLHttpRequestEventTarget.dispatchEvent (/usr/local/lib/node_modules/truffle/build/cli.bundled.js:67130:18)
    at XMLHttpRequest._setReadyState (/usr/local/lib/node_modules/truffle/build/cli.bundled.js:67420:12)
    at XMLHttpRequest._onHttpResponseEnd (/usr/local/lib/node_modules/truffle/build/cli.bundled.js:67575:12)
    at IncomingMessage.<anonymous> (/usr/local/lib/node_modules/truffle/build/cli.bundled.js:67535:24)
    at emitNone (events.js:110:20)

Why does this throw an exception? And how do I solve this?

EDIT

contract('MyContract', function(accounts) {
    const testParams = {
        _owner: accounts[0],
        _array: ["first", "second", "third"],
    };

    let testMyContract;

    describe("New MyContract:", async function() {
        before(async function() {
            testMyContract = await MyContract.new(...Object.values(testParams));
        });

        it("sets the first account as the contract creator", async function() {
            let owner = await testMyContract.owner.call();
            assert.equal(owner, accounts[0], "Owner does not match.");
        });

        it("sets the topic result names correctly", async function() {
            let resultName1 = await testMyContract.getResultName(0);
            assert.equal(web3.toUtf8(resultName1), testParams._resultNames[0], "Result name 1 does not match.");

            let resultName2 = await testMyContract.getResultName(1);
            assert.equal(web3.toUtf8(resultName2), testParams._resultNames[1], "Result name 2 does not match.");

            let resultName3 = await testMyContract.getResultName(2);
            assert.equal(web3.toUtf8(resultName3), testParams._resultNames[2], "Result name 3 does not match.");
        });
        });
    });
}

Migration Script

var SafeMath = artifacts.require("./SafeMath.sol");
var MyContract = artifacts.require("./MyContract.sol");
var MyContractCreator = artifacts.require("./MyContractCreator.sol");

module.exports = function(deployer) {
    deployer.deploy(SafeMath);
    deployer.link(SafeMath, MyContract);
    deployer.deploy(MyContract);
    deployer.link(MyContract, MyContractCreator);
    deployer.deploy(MyContractCreator);
};
8
  • The error is _array doesn't have a length greater than 1, then require will throw.
    – Ismael
    Sep 15 '17 at 13:27
  • Sorry I should've have clarified. My tests are failing with this exception even though the array length is greater than 1.
    – The Nomad
    Sep 15 '17 at 14:50
  • Invalid opcode generated by a throw, the only throw in your code generated by the require. If you remove the require does it work? Perhaps your javascript call does not encode the array correctly. How is your javascript call made?
    – Ismael
    Sep 15 '17 at 14:57
  • @Ismael Yes if I remove the require it passes fine. I have edited my OP to include my first test.
    – The Nomad
    Sep 17 '17 at 11:03
  • I've tried your sample and it works here. Do you use a deploy script? Perhaps you are not supplying enough parameters there.
    – Ismael
    Sep 17 '17 at 17:01
2

The problem was in the deploy script. It was is failing because it didn't receive any parameter:

deployer.deploy(MyContract); 

And when the constructor was invoked it will fail because of the require.

Either do not deploy that contract, pass dummy values for testing (and remove them for final deploy)

deployer.deploy(MyContract, "0x12341234", ["0x01", "0x02", 0x03]);

Another option is to remove the require.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.