1

Im Trying to create a DAPP with two contracts generating assets. One is acting as the "factory" for the other contracts. From the latter I try to call a function in the factory without knowing its address yet, therefore I want to pass it in as an argument. This throws an error in Remix because that contract obviously doesn't exist yet.

To simplify the situation think about this scenario in Remix (both contracts are written in the same file):

    contract AssetFactory{

    address[] deployedAssets;

      function createAsset(string name) public {
        address newAsset = new Asset(name);
        deployedAssets.push(newAsset);
        return newAsset;
      }

    }

    contract Asset{

     string name;

     function Asset(string name) public{
       name = name;
     }

     function ModifyAssetAndCreateNew(string name, address factory){
       factory.createAsset(name);
       name = name;
     }

   }

Any Ideas or other approaches? I realize that the idea behind the above contract doesn't make much sense in this example but i tried to keep it as short as possible.

Thank you!

0

There were a number of compilation errors in your example code, but once I fixed those up, and changed address factory to AssetFactory factory, everything looks to be fine.

(I just took a guess at which name you meant in the line factory.createAsset(name). When producing a simple example, make sure it's one you've actually tested.)

pragma solidity ^0.4.23;

contract AssetFactory {
    Asset[] deployedAssets;

    function createAsset(string name) public returns (Asset) {
        Asset newAsset = new Asset(name);
        deployedAssets.push(newAsset);
        return newAsset;
    }

}

contract Asset {
    string name;

    constructor(string _name) public {
        name = _name;
    }

    function modifyAssetAndCreateNew(string _name, AssetFactory factory) public {
        factory.createAsset(_name);
        name = _name;
    }
}
  • This solved the issue I was having. Sorry for the silly example. You're right, I didn't test it but just quickly put something together to make my point. Thank you! – Marlon Gelpke Apr 25 '18 at 14:10
0

As an aside, I noticed some strange goings on thought some alternatives are worth mentioning.

  1. The assets can derive the Factory address automatically.
  2. You can prevent someone from deploying an Asset without using the Factory, and that can be useful to ensure integrity and safeguard assumptions about what's going on.
  3. I found it strange to put a "create asset" function in the asset itself. This strikes me a little bit like asking the car to take orders for more cars. Not unthinkable, but why? In most cases, it would be more consistent to let the factory be a factory and let the asset be an output of the factory.
  4. I changed Asset's constructor back to old style, ignoring the warning, because many things do not compile in the same way, this included, using the new syntax.

pragma solidity 0.4.23;

  contract AssetFactory {
    Asset[] public deployedAssets;

  function createAsset(string name) public returns (Asset) {
    Asset newAsset = new Asset(name);
    deployedAssets.push(newAsset);
    return newAsset;
  }

  function isFactory() public pure returns(bool isIndeed) {
    return true;
  }
}

contract Asset {
  string public name;
  AssetFactory factory;

  event LogAsset(address sender, bool isFactory);

  function Asset(string _name) public {
    name = _name;
    factory = AssetFactory(msg.sender);
  }

  // this seems like a strange thing to want. Consider removing it.

  function modifyAssetAndCreateNew(string _name) public {
    factory.createAsset(_name);
    name = _name;
  }   
}
  • Thank you for your comment! I was trying to develop a Value-Chain kind of scenario, where Assets (things like a cow or a piece of wood) can be registered and later processed. I haven't spent a lot of time on it yet but the only way I saw this to work before I got smarx answer was by modifying the "parent asset" and right away creating a new "child asset" within the same function. – Marlon Gelpke Apr 27 '18 at 6:45
  • With the solution that @smarx and you gave me I could probably also pass the Asset into a new ProcessAsset() function of the AssetFactory contract. That way AssetFactory would still have control – Marlon Gelpke Apr 27 '18 at 6:52
  • You would probably have contracts for each class of asset and some bi-directional binding. The cow would record the owner. It could also be useful for owners to maintain a book of all assets owned (other direction). – Rob Hitchens - B9lab Apr 27 '18 at 11:56
  • Could you specify what you mean with bi-directional binding? As far as I know, mappings would be the only possible solution for this but you can't iterate over mappings which makes your idea of keeping a book of all assets owned very difficult. – Marlon Gelpke Apr 29 '18 at 12:50
  • Start here: medium.com/@robhitchens/solidity-crud-part-1-824ffa69509a That solves the basic iteration and mgt issues, Summarized here. Summarized over here. ethereum.stackexchange.com/questions/13167/…. For the two-way binding, medium.com/@robhitchens/… – Rob Hitchens - B9lab Apr 29 '18 at 17:18

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.