Cómo hacer una llamada de función a través de un contrato de relevo/nivel de entrada

Estoy tratando de crear un contrato de nivel de entrada (uno que sea el punto de entrada):

relé.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;
    }
}

y mi contrato

Acceso2.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;
    }   
}

Ambos contratos están desplegados.

Si accedo al método de Access2 a través de web3 usando el objeto de Access2, funciona bien, pero ahora el problema es cómo puedo acceder al método de Access2 a través de Relay.

¿Puedo usar el Objeto de Relay?

Esto se verá como un duplicado del contrato actualizable aquí, pero mi pregunta no se trata de escribir un contrato actualizable sino llamar las funciones de nuestro contrato desde el contrato de nivel de entrada: es decir, ¿cómo funciona el concepto de contrato de nivel de entrada?

Gracias por adelantado

@niksmac, en realidad no es un duplicado, sino el siguiente paso o una explicación más detallada de la respuesta a los contratos inteligentes actualizables
Creo que la funcionalidad deseada de esta pregunta es similar a la utilizada para Multisig Exploit; llame a una función del contrato de Access2 utilizando la función de consecuencias del contrato de retransmisión. Más detalles en hackingdistributed.com/2017/07/22/deep-dive-parity-bug

Respuestas (2)

Sí, desde Relaypuede llamar a Access2funciones, como createEntity.

El código importante Relayque lo hace posible es su :

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

Es útil leer las preguntas y respuestas sobre para aprender más sobre ellas.

Básicamente, cuando invoca (llama) createEntityen Relay, porque Relayno tiene una createEntityfunción, Relayse llamará a la función alternativa de. El valor de currentVersiones su instancia de Access2, por lo que funcionará delegatecall(msg.data)en esa Access2instancia. msg.datacontiene la información que luego invocará la createEntityfunción en esa Access2instancia.

Otra forma de decirlo: solicita Relayejecutar algunos datos (función de llamada createEntitycon ciertos datos y argumentos), pero como Relayno sabe cómo manejar esos datos, pasará los datos a 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.¿Cuál será el comando web3 para invocar createEntity en retransmisión?
@AK Esa es una buena pregunta y se hizo en ethereum.stackexchange.com/questions/23369/…
esa pregunta tampoco tiene respuesta
@AK Tiene una respuesta ahora y es para usar web3.eth.sendTransaction. El datacorrespondiente a la llamada createEntitydeberá especificarse de acuerdo con el abi .

Sí, puede usar una instancia de su Relaycontrato para llamar funciones de la instancia vinculada del Access2contrato.

Creé el siguiente ejemplo mínimo que podrías probar en 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();
    }
}

Para probar esto, puede crear una instancia de relay(que crea una instancia de targeten su constructor). Cuando lo llame relayCall, llamará a la doSomethingfunción de esa targetinstancia. Verá correspondientemente el evento somethingque se está llamando.

No es que importe, pero para completar: hay un pequeño problema en su Access2contrato:

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

Aquí thisestá la dirección de la instancia actual de Access2(que no es de tipo Relay). Como no llamas a nada en ese robjeto, todo está bien. Pero lo más probable es que tenga errores de tiempo de ejecución al intentar acceder a funciones que no existen (ya que asigna una Access2instancia a un objeto de tipo Relay).

Creo que me entendiste mal, no se trata de llamar a funciones de otro contrato,
Pero eso es lo que escribió: "cómo puedo acceder al método de Access2 a través de Relay"; si eso no es lo que quiso decir, reformule su pregunta.
Hola, @SwapnilKumbhar. Haz la pregunta que pretendías como una pregunta nueva. Esta pregunta sigue siendo útil para la comunidad, por lo que podemos mantener esta pero aclararla. Gracias
@ValidityLabs-Sebastian, De acuerdo!! para evitar esta confusión, publiqué el código de ambos contratos, que ilustran claramente mi pregunta