0

I have 2 smart contract, below is the implementatin of them :

1)

import "./MaintainableUpgradeabilityProxy.sol";

function _createProxy(address implementation, address serviceRegistry) internal returns (MaintainableUpgradeabilityProxy) {
    MaintainableUpgradeabilityProxy proxy = new MaintainableUpgradeabilityProxy(implementation, serviceRegistry);
    emit ProxyCreated(proxy, msg.sender);
    return proxy;
  }

MaintainableUpgradeabilityProxy.sol -->

2)
pragma solidity ^0.4.22;

import "zos-lib/contracts/upgradeability/UpgradeabilityProxy.sol";
import "../registry/interface/IServiceRegistry.sol";


/**
 * @title AdminUpgradeabilityProxy
 * @dev This contract combines an upgradeability proxy with an authorization
 * mechanism for administrative tasks.
 * All external functions in this contract must be guarded by the
 * `ifAdmin` modifier. See ethereum/solidity#3864 for a Solidity
 * feature proposal that would enable this to be done automatically.
 */
contract MaintainableUpgradeabilityProxy is UpgradeabilityProxy {

  /**
   * @dev Emitted when the administration has been transferred.
   * @param previousRegistry Address of the previous registry.
   * @param newRegistry Address of the new registry.
   */
  event ServiceRegistryChanged(address previousRegistry, address newRegistry);

  /**
   * @dev Storage slot with the admin of the contract.
   * This is the keccak-256 hash of "org.zeppelinos.proxy.admin", and is
   * validated in the constructor.
   */
  bytes32 private constant ADMIN_SLOT = 0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b;

  /**
   * @dev Modifier to check whether the `msg.sender` is the admin.
   * If it is, it will run the function. Otherwise, it will delegate the call
   * to the implementation.
   */
  modifier ifMaintainer() {
    if (IServiceRegistry(_serviceRegistry()).getMaintainerRegistryV1().isMaintainer(msg.sender)) {
      _;
    } else {
      _fallback();
    }
  }

  /**
   * Contract constructor.
   * It sets the `msg.sender` as the proxy administrator.
   * @param _implementation address of the initial implementation.
   */
  constructor(address _implementation, address _serviceReg) UpgradeabilityProxy(_implementation) public {
    assert(ADMIN_SLOT == keccak256("org.zeppelinos.proxy.admin"));
    _setServiceRegistry(_serviceReg);
  }

  /**
   * @return The address of the implementation.
   */
  function implementation() external view ifMaintainer returns (address) {
    return _implementation();
  }

  /**
   * @dev Changes the service registry of the proxy.
   * Only the current admin can call this function.
   * @param _newRegistry Address to transfer proxy administration to.
   */
  function changeServiceRegistry(address _newRegistry) external ifMaintainer {
    require(_newRegistry != address(0), "New registry cannot be address(0)");
    emit ServiceRegistryChanged(_serviceRegistry(), _newRegistry);
    _setServiceRegistry(_newRegistry);
  }

  /**
   * @dev Upgrade the backing implementation of the proxy.
   * Only the maintainers can call this function.
   * @param newImplementation Address of the new implementation.
   */
  function upgradeTo(address newImplementation) external ifMaintainer {
    _upgradeTo(newImplementation);
  }

  /**
   * @dev Upgrade the backing implementation of the proxy and call a function
   * on the new implementation.
   * This is useful to initialize the proxied contract.
   * @param _implementation Address of the new implementation.
   * @param data Data to send as msg.data in the low level call.
   * It should include the signature and the parameters of the function to be
   * called, as described in
   * https://solidity.readthedocs.io/en/develop/abi-spec.html#function-selector-and-argument-encoding.
   */
  function upgradeToAndCall(address _implementation, bytes data) external payable ifMaintainer {
    _upgradeTo(_implementation);
    // solium-disable-next-line security/no-call-value
    require(address(this).call.value(msg.value)(data), "Call failed");
  }

  /**
   * @return The service registry slot.
   */
  function _serviceRegistry() internal view returns (address _serviceReg) {
    bytes32 slot = ADMIN_SLOT;
    // solium-disable-next-line security/no-inline-assembly
    assembly {
      _serviceReg := sload(slot)
    }
  }

  /**
   * @dev Sets the address of the proxy admin.
   * @param _serviceReg Address to use
   */
  function _setServiceRegistry(address _serviceReg) internal {
    bytes32 slot = ADMIN_SLOT;

    // solium-disable-next-line security/no-inline-assembly
    assembly {
      sstore(slot, _serviceReg)
    }
  }

  /**
   * @dev Only fall back when the sender is not a maintainer.
   */
  function _willFallback() internal {
    require(
      !IServiceRegistry(_serviceRegistry()).getMaintainerRegistryV1().isMaintainer(msg.sender),
      "Maintainer cannot call fallback functions");
    super._willFallback();
  }
}

Things start with me calling _createProxy(address1, address2) from contract 1

What I am confused with :

1) The return type of function _createProxy from contract 1

function _createProxy(address implementation, address serviceRegistry) public returns (MaintainableUpgradeabilityProxy) {...}

Here MaintainableUpgradeabilityProxy is name of contract so what is it returning a contract address?

2) inside function _createProxy new instance of MaintainableUpgradeabilityProxy is during

MaintainableUpgradeabilityProxy `proxy` = new MaintainableUpgradeabilityProxy(implementation, serviceRegistry);

It should call its constructor which is calling _setServiceRegistry which is returning nothing then what value will variable proxy receives?

3) What is happening in _setServiceRegistry()

  • 3
    This should answer all of your questions: new MyContract creates an instance of MyContract, deploys it to the network and returns the address of that instance on the network. – goodvibration Oct 2 at 14:43
0

Here MaintainableUpgradeabilityProxy is name of contract so what is it returning a contract address?

Yes. The difference between doing this and returning an address is that if another contract calls this method, then it will receive that contract instance. It's equivalent to returning the address of the contract and then doing MaintainableUpgradeabilityProxy(returnedAddress) in the caller.

For example, if you have:

contract Foo {
  function returnContract() returns (SomeContract) {
    SomeContract sc = new SomeContract();
    return sc;
  }

  function returnAddress() returns (address) {
    SomeContract sc = new SomeContract();
    return address(sc);
  }
}

then foo.returnContract() is pretty much equivalent to SomeContract(foo.returnAddress())

I think the rest of the questions are answered by goodvibration's comment.

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.