3

I am trying to create an entry level contract (one that is the entry point):

Relay.sol

pragma solidity ^0.4.8;
contract Relay {
    address public currentVersion;
    address public owner;

    modifier onlyOwner() {
        if (msg.sender != owner) {
            throw;
        }
        _;
    }

    function Relay(address initAddr) {
        currentVersion = initAddr;
        owner = msg.sender; 
    }

    function changeContract(address newVersion) public
    onlyOwner()
    {
        currentVersion = newVersion;
    }

    function() {
        if(!currentVersion.delegatecall(msg.data)) throw;
    }
}

And my contract

Access2.sol

pragma solidity ^0.4.8;
import './Storage.sol';
import './Relay.sol';

contract Access2{
Storage s;
address Storageaddress=0xcd53170a761f024a0441eb15e2f995ae94634c06;

function Access2(){
Relay r=new Relay(this);
}

 function createEntity(string entityAddress,uint entityData)public returns(uint rowNumber){
        s = Storage(Storageaddress);
        uint row=s.newEntity(entityAddress,entityData);
        return row;
    }

    function getEntityCount()public constant returns(uint entityCount){
        s = Storage(Storageaddress);
        uint count=s.getEntityCount();
        return count;
    }   
}

Both the contracts are deployed.

If I access the method of Access2 via web3 using the object of Access2 it works fine, but now the problem is how can I access the the method of Access2 via Relay.

Can I use the Object of Relay?

This will look like duplicate of up-gradable contract here but my question is not about writing upgradable contract but calling the functions of our contract from the entry level contract: i.e. how does the concept of entry level contract work?

Thanks in advance

3

Yes, from Relay you can call Access2 functions, like createEntity.

The important code in Relay that makes it happen is its :

function() {
    if(!currentVersion.delegatecall(msg.data)) throw;
}

It is helpful to read the questions and answers on to learn more about them.

Basically, when you invoke (call) createEntity in Relay, because Relay doesn't have a createEntity function, the fallback function of Relay will be called. The value of currentVersion is your instance of Access2, so it will do delegatecall(msg.data) on that Access2 instance. msg.data contains the information which will then invoke the createEntity function on that Access2 instance.

Another way of putting it: you ask Relay to run some data (call function createEntity with certain data and arguments), but since Relay doesn't know how to handle that data, it will pass the data along to Access2.

  • Basically, when you invoke (call) createEntity in Relay, because Relay doesn't have a createEntity function, the fallback function of Relay will be called. what will be the web3 command to for invoking createEntity in relay ? – Aniket Aug 3 '17 at 14:13
  • @A.K. That's a good question and asked in ethereum.stackexchange.com/questions/23369/… – eth Aug 10 '17 at 6:54
  • that question is also not answered – Aniket Aug 11 '17 at 11:06
  • @A.K. It has an answer now and it's to use web3.eth.sendTransaction. The data corresponding to calling createEntity will need to be specified according to the abi. – eth Sep 15 '17 at 4:48
1

Yes, you can use an instance of your Relay contract to call functions of the linked instance of the Access2 contract.

I created the following minimal example that you could test in Remix:

contract target {
    event something();
    function doSomething() {
        something();
    }
}

contract relay {
    target myTarget;

    function relay() {
        // this will deploy a new target contract, you could also just set its address
        myTarget = new target();
    }

    function relayCall() {
        myTarget.doSomething();
    }
}

To test this, you can create an instance of relay (which creates an instance of target in its constructor). When you then call relayCall it will call the doSomething function of that target instance. You will correspondingly see the event something being called.

Not that it matters but for completeness: there is a small issue in your Access2 contract:

function Access2(){
Relay r=new Relay(this);
}

Here this is the address of the current instance of Access2 (which is not of type Relay). Since you dont call anything on that r object all is fine. But you would most likely into runtime errors when trying to access functions that do not exist (since you assign an Access2 instance to an object of type Relay).

  • I think you got me wrong, Its not about calling functions of other contract, – SwapnilKumbhar Jul 11 '17 at 13:42
  • 1
    But that is what you wrote: "how can I access the the method of Access2 via Relay" - if that is not what you meant please rephrase your question. – Validity Labs - Sebastian Jul 11 '17 at 13:59
  • 1
    Hi @SwapnilKumbhar Please ask the question that you intended as a new question. This question is still helpful for the community so we can keep this one but make it clearer. Thanks – eth Jul 12 '17 at 4:06
  • @ValidityLabs-Sebastian, Agree!! to avoid this confusion, I posted the code for both the contracts, which are clearly illustrating my question – SwapnilKumbhar Jul 12 '17 at 5:50

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.