llamando un contrato a otro método de contrato

Quiero llamar al método getdata() y recuperar el valor devuelto para usarlo en otro contrato. Pero la llamada solo devuelve bool en caso de éxito o fracaso.

  1. ¿Cómo obtengo el valor de retorno de getdata() de la función caller() en contract extra .

  2. ¿Cómo modifico el estado?: envíe la transacción a setdata (uint, bytes32) desde el contrato adicional y cambie el estado de data1 y data2.

El problema anterior se basa en el siguiente código.

pragma solidity 0.4.21;
contract Base{
    uint public data1;
    bytes32 public data2;

    function setdata(uint a, bytes32 b){
        data1 = a;
        data2 = b;
    }
    function getdata() public view returns(uint){
        return data1 ;
    }

}
contract extra{
   bool public retrive;
   bool public retrive_setter;
   address public baseaddress = 0xca598f876f79a5f8f479bfa1dcc8f4f2dffbd5c2;
   uint a = 5;
   bytes32 b ="Lina";
   function caller(){
        retrive = baseaddress.call.gas(10000)(bytes8(keccak256("getdata()")));
        retrive_setter = baseaddress.call.gas(1000000)(bytes24(keccak256("setdata(uint, bytes32)")),a,b);
   }
}

O puede modificar el código y dar su respuesta. Vi este problema en muchos desarrolladores que son nuevos. Todas las respuestas posibles son aceptables.

simply on testing using Remix . 

recuperar 0:bool: verdadero
recuperar_setter 0:bool: falso

Respuestas (2)

pragma solidity 0.4.21;

contract Base {

    uint public dataA;
    bytes32 public dataB;

    function setAB(uint a, bytes32 b) public {
        dataA = a;
        dataB = b;
    }

    function getA() public view returns(uint) {
        return dataA ;
    }

    function getB() public view returns(bytes32) {
        return dataB ;
    }

}

contract Extra {

   Base base;

   function Extra() public {
       base = new Base();
   }

   function getBaseAddres() public view returns(address) {
       return address(base);
   }

   function baseGetA() public view returns(uint) {
        return base.getA();
   }

   function baseGetB() public view returns(bytes32) {
       return base.getB();
   }

   function baseSetAB(uint a, bytes32 b) public returns(bool success) {
       base.setAB(a,b);
       return true;
   }
}

Espero eso ayude.

ACTUALIZAR

El ejemplo anterior solo crea una nueva Basecon cada implementación de Extrapara mostrarlos hablando de la manera más simple que se me ocurre. Otra forma de hacerlo es implementar un archivo por Baseseparado. Su ubicación se puede retransmitir a Extra.

Podrías pasarlo al constructor:

Base base;

function Extra(address baseAddress) public {
  base = Base(baseAddress);
}

No está comprobando nada, simplemente asumiendo que el implementador sabe lo que está haciendo. También puede hacer que la dirección de la base sea algo que el propietario pueda cambiar.

Agregue an owneral estado y al constructor:

address public owner;

function Extra(address baseAddress) public {
  base = Base(baseAddress);
  owner = msg.sender;
}

Agregue un modificador (después del estado y antes del constructor, por convención) para restringir el acceso a la función sensible.

modifier onlyOwner {
  require(msg.sender == owner);
  _;
}

Agregue una función restringida para cambiar la base.

function changeBase(address newBase) public onlyOwner returns(bool success) {
  base = Base(newBase);
  return true;
}

Es posible que desee saber la dirección de la Base:

return address(base);

Sería una buena práctica agregar emisores de eventos a las funciones de cambio de estado en ambos contratos.

gracias por tu respuesta. cuando crea la nueva instancia de Base, genera una nueva dirección y que es diferente a la dirección real del contrato de base. Ahora, si configura los datos en esa dirección de contrato recién creada, entonces cómo reside en el contrato original. Probé este código pero mientras intentaba obtener el valor del contrato base donde el valor se establece a través de un contrato adicional. esto significa que implementará el contrato en una dirección diferente nuevamente. Para evitar esto, quiero usar sendTransaction y llamar desde un contrato adicional. Creo que entiendes eso.
Por supuesto. Pensé que podrías decir eso. No quería que el ejemplo estuviera sobrecargado con demasiadas preocupaciones que pudieran distraer la atención de la pregunta principal. Agregué una forma de conectarme con una Base desplegada a mi respuesta original, junto con algunas otras preocupaciones que omití intencionalmente.
Hay un poco más de coreografía involucrada. Primero implemente un Base, luego anote la dirección, luego implemente un Extrapase en la dirección del Base. Si se empaña, puede implementar otro Basee informar Extraal respecto. Obviamente quieres proteger esa función. En el ejemplo, solo el mismo usuario que implementó el contrato podría hacerlo.

En primer lugar, dado que conoce las firmas de las funciones que está llamando en el Basecontrato, puede omitir el uso cally llamarlas directamente.

pragma solidity 0.4.21;

contract Base{
    uint public data1;
    bytes32 public data2;

    function setdata(uint a, bytes32 b){
        data1 = a;
        data2 = b;
    }
    function getdata() public view returns(uint){
        return data1 ;
    }

}

contract Extra {
   uint public data;
   Base public baseaddress = Base(0xca598f876f79a5f8f479bfa1dcc8f4f2dffbd5c2);

   function caller(){
        data = baseaddress.getdata();
   }

   function setter(uint _integer, bytes32 _bytes) {
       baseaddress.setdata(_integer, _bytes);
   }
}

Con esto, sus dos preguntas han sido respondidas. Notarás que he cambiado el tipo de baseaddress. Si simplemente usa address, su contrato cree que es simplemente una dirección "normal" y, por lo tanto, no tiene funciones. Entonces, no solo tiene que ser del tipo de contrato que está llamando, sino que, en cuanto a su valor, debe hacer lo mismo y usar el "constructor" pasando la dirección del contrato.

gracias, esta es una forma que ya usé para realizar transacciones con otro contrato, pero para grandes datos hay un problema de límite de gas. Si tiene alguna forma de evitar el problema del límite de gas, continúe.
@Gopalojha en esa situación, una de las mejores cosas que puede hacer es trabajar en la eficiencia del código del contrato en sí.