Solidity – How to Make Function Call through Relay or Entry Level Contract

contract-designcontract-developmentdelegatecallfallback-functionsolidity

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

Best Answer

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.

Related Topic