Solidity

幫我理解這個智能合約的流程

  • October 3, 2019

我有 2 個智能合約,下面是它們的實現:

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

可維護升級能力代理.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();
 }
}

事情從我_createProxy(address1, address2)從契約 1開始

我感到困惑的是:

  1. 合約 1 的函式 _createProxy 的返回類型
function _createProxy(address implementation, address serviceRegistry) public returns (MaintainableUpgradeabilityProxy) {...}

MaintainableUpgradeabilityProxy是合約的名稱,那麼它返回的合約地址是什麼?

2)MaintainableUpgradeabilityProxy的函式_createProxy內部新實例在

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

它應該呼叫它的建構子,該建構子正在呼叫 _setServiceRegistry,它什麼都不返回,那麼變數代理將接收什麼值?

  1. _setServiceRegistry() 中發生了什麼

這裡 MaintainableUpgradeabilityProxy 是合約的名稱,那麼它返回的合約地址是什麼?

是的。這樣做和返回地址的區別在於,如果另一個合約呼叫了這個方法,那麼它將接收到那個合約實例。相當於返回了合約的地址,然後MaintainableUpgradeabilityProxy(returnedAddress)在呼叫者裡面做。

例如,如果您有:

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

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

那麼foo.returnContract()幾乎等同於SomeContract(foo.returnAddress())

我認為goodvibration的評論回答了其餘的問題。

引用自:https://ethereum.stackexchange.com/questions/76434