0

I have the following contract:

contract C {

  address owner;
  address bigboss;

  modifier onlyOwner() {
    require(msg.sender==bigboss);
    _;
  }

  function C() {
    owner = msg.sender;
    bigboss = msg.sender;
  }

  function changeOwner(address _newAccount) onlyOwner {
    owner = _newAccount;
  }

}

So, I'm using truffle and Javascript to test creation of the contract, and testing of change of ownership.

const C = artifacts.require('C.sol');

var account_finance = 0x123456; // finance
var account_main = 0x7890abc; // main

contract('C', (accounts) => {
  payroll = new C({from: account_main});
  payroll.changeOwner({from: account_main}).call(account_finance);
});

I get this error:

TypeError: Cannot read property 'call' of undefined

What's wrong? Why couldn't I call changeOwner? Is my code correct?

Thank you.

  • I think it should be: payroll.changeOwner(account_finance, {from: account_main}); – Abhishek Oct 5 '17 at 3:24
1

First, in order to interact with a contract in your test, you need to have access to the deployed contract on the network. Simply instantiating it with new won't make the contract deployed to the network to start transactions. The way to do this is like so:

contract('C', (accounts) => {
  C.deployed().then(payroll => {
    // now you can use payrole as you wish inside here
  })
});

Another issue is that you are actually calling the changeOwner function wrong.

Instead of

payroll.changeOwner({from: account_main}).call(account_finance);

You probably wanted to use this:

payroll.changeOwner.call(account_finance, {from: account_main});

Also, you don't need to invoke the call method on changeOwner, you can directly invoke changeOwner() like this:

payroll.changeOwner(account_finance, {from: account_main});

The difference between the two forms is actually in the value that is resolved by the Promise they return. The first one would return the resolve to the value returned by the changeOwner function defined in the Contract, while the second one would return the current block that was mined to execute that function.

  • any idea how to retrieve the value that should be returned? instead as you mentioned, the current mined block is returned in the response – BlocksByLukas Mar 13 '18 at 18:49
  • Or I guess it's a different way of doing things? for now I will use the .call() pattern to get directly the value instead of getting the block. – BlocksByLukas Mar 13 '18 at 19:07
  • A little late, but you should know that call executes and reads from the blockchain state, but it does not make any persistent changes to the blockchain. To make changes or update state in your contract you need to send a transaction. Typically to get results from contract you would either update a state value or emit an event. It depends on your use case. So in your code interacting outside the contract, you read for the updated state value or you listen for the emitted event and read its value. – perfectmak Oct 4 '19 at 16:36

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.