0
votes

I am trying to implement a function which calls a different function on another contract and returns that value. I have suspicion that this could be a problem with promises and functions being called before the value of the previous ones are received. However I have no idea how you could actually implement this in the contract and if it is possible. I am using Truffle, TestRPC and Solidity for writing the contract, and calling the functions from the truffle terminal. The contracts look like these (showing just the bare minimum functions):

Main Contract:

// One (main) contract to control them all
import 'Company.sol';

contract Creator {

    string[] public names;
    address[] public companies;

    // Creates a company
    function createCompany(string _companyName, uint _noOfShares, uint _pricePerShare, address _creator) returns(address) {
        address newCompany = new Company(_companyName, _noOfShares, _pricePerShare, _creator);
        names.push(_companyName);
        companies.push(newCompany);
        return newCompany;
    }

    // Returns the name of a company given an index
    function getName(uint i) constant returns(string companyName) {
        return names[i];
    }
    // Returns the address of a company given an index
    function getAddress(uint i) constant returns(address companyAddress) {
        return companies[i];
    }

    // Returns the address of the last company created
    function getLastAddress() constant returns(address companyAddress) {
        return companies[companies.length - 1];
    }

}

Company Contract

import 'Shareholder.sol';

contract Company {

  mapping(address => address) public shareholders; //Mapping from user 
  account address to shareholder contract address

  function getShareNo(address _user) constant returns (uint _amount){
    // Get the shareholder contract address for the user
    address sellerContractAddr = getShareholder(_user);
    Shareholder sellerContract = Shareholder(sellerContractAddr);

    uint shares = sellerContract.getShareBalance();

    return shares;
  }

    function getShareholder(address _user) constant returns (address shareholder){
        return shareholders[_user];
    }

}

Shareholder Contract:

contract Shareholder {

   uint public shareBalance; 

    // Function to return the share balance
    function getShareBalance() constant returns (uint balance){
      return shareBalance;
    }
}

EDIT: After Rob's response and more testing, I realize this does not have anything to do with promises but with the instantiation of the Company contract by the Creator contract. When deployed directly from truffle, the functions of Company.sol work, but when deployed from Creator only certain ones work, excluding the ones I mentioned. I can't see anything wrong in my constructor createCompany() function, please let me know if you do.

2

2 Answers

0
votes

Possibly you only posted part of the code?

There is nothing to set shareholder[user], so no way the mapping can return anything except 0x0 which is the default value of a mapped address.

As a pseudo solution, you need something along these lines in Company. In this version, Shareholder doesn't exist, so it could created and tracked in/by Company.

function newShareholder() returns (address shareholderContract) {
    Shareholder shareholder  new Shareholder(); // new contract
    shareholder[msg.sender] = shareholder; // store addr with user
    return shareholder;
}

I suspect the creation of a contract for each user is over-complicating matters, but this is a matter of the whole use-case you have in mind.

Promises and callbacks are not in play between Smart Contracts. The inter-contract messages are (roughly) instantaneous.

Hope it helps.

0
votes

After a lot of trial and error I have finally fixed the issue, and it has to do with the ridiculously stupid way truffle works (if I'm correct).

Basically every time I made an update to a contract file and recompiled,the other contracts (eg. the Main one) wouldn't update with the new information so when instantiating the contract those functions would fail on every call. If I added a new empty line or something to the untouched file and re-saved it, then everything worked when compiling.

Truffle developers, make sure to fix these bugs, it took me two weeks of my life to figure it out.