1

My contract has a function that allows only the contract owner to add another address to a mapping.

How do I obtain the address of the contract owner that deployed the smart contract, and another address in order to test this function? I am able to write the javascript test for this, but can't figure out how to do so in solidity.

  • how do you test yr code? truffle? – Badr Bellaj Jul 22 '18 at 8:25
  • yes i am using truffle – tserg Jul 22 '18 at 8:48
1

by default in truffle/ganache the deployer is account[0] where accounts is the first parameter in the contract test function :

contract('MyContract', function(accounts) {
    address owner;
    address user;

    beforeEach(function() {
        owner = accounts[0];
        user = accounts[1];
    });
});

in solidity if you're testing using a contract you can only test with the address of this later which is also the deployer.

NB: Depending on your code you don't have to read the "deployer" address in your constructor only to perform your test.

0

You save it when the contract is created, for example:

pragma solidity ^0.4.24;

contract Ownable {
    address public owner;
    constructor() public {
        owner = msg.sender;
    }
    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }
}

pragma solidity ^0.4.24;
import "./Ownable.sol";

contract MyContract is Ownable {
    mapping (address => bool) public wallets;
    function addWallet(address wallet) external onlyOwner {
        wallets[wallet] = true;
    }
}

Here is a Truffle test example:

contract("MyContractUnitTest", function(accounts) {
    let myContract;

    let owner    = accounts[0];
    let nonOwner = accounts[1];
    let wallet   = accounts[2];

    describe("test:", function() {
        before(async function() {
            myContract = await artifacts.require("MyContract.sol").new();
        });
        it("function addWallet should complete successfully if called by an owner", async function() {
            await myContract.addWallet(wallet, {from: owner});
        });
        it("function addWallet should abort with an error if called by a non-owner", async function() {
            await tryCatch(myContract.addWallet(wallet, {from: nonOwner}), errTypes.revert);
        });
    });

    async function tryCatch(promise, errType) {
        try {
            await promise;
            throw null;
        }
        catch (error) {
            assert(error, "Expected an error but did not get one");
            assert(error.message.startsWith(PREFIX + errType), "Expected an error starting with '" + PREFIX + errType + "' but got '" + error.message + "' instead");
        }
    }

    let errTypes = {
        revert            : "revert",
        outOfGas          : "out of gas",
        invalidJump       : "invalid JUMP",
        invalidOpcode     : "invalid opcode",
        stackOverflow     : "stack overflow",
        stackUnderflow    : "stack underflow",
        staticStateChange : "static state change"
    };

    let PREFIX = "VM Exception while processing transaction: ";
});
  • And don't forget to start your test provider (Ganache, I would guess) with at least 3 accounts. – goodvibration Jul 22 '18 at 8:37
  • what is the equivalent of this in solidity? let owner = accounts[0]; let nonOwner = accounts[1]; let wallet = accounts[2]; – tserg Jul 22 '18 at 8:51
  • @tserg: there is no equivalence (nor there should be any). – goodvibration Jul 22 '18 at 10:16
  • thanks for the clarification! i was inclined to think so as i have been unable to find anything on it. – tserg Jul 22 '18 at 11:02

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.