Solidity

無法理解 UpgradeabilityProxyFactory 的實現

  • August 29, 2019

我想使用zeppelin 提供的UpgradeabilityProxy,他們有一個方法createProxyAndCall,他們說使用我們提供的數據參數初始化新實現,如下所示:

  * @dev Creates an upgradeability proxy with initial implementation and calls it.
  * This is useful to initialize the proxied contract.
  * @param implementation Address of the initial implementation.
  * @param serviceRegistry service registry
  * @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.
  * @return Address of the new proxy.
  */


 function createProxyAndCall(
   address implementation,
   address serviceRegistry,
   bytes data
 ) public payable returns (MaintainableUpgradeabilityProxy) {
   MaintainableUpgradeabilityProxy proxy = _createProxy(implementation, serviceRegistry);
   // proxy.changeAdmin(owner);
   /* solium-disable-next-line */
   require(address(proxy).call.value(msg.value)(data), "failed to call proxy with data");

   if (autoActivate) {
     Activatable(address(proxy)).activate();
   }

   return proxy;
 }

1)我對它如何初始化數據感到困惑,有人可以幫我理解這條線在做什麼嗎?

require(address(proxy).call.value(msg.value)(data), "failed to call proxy with data");

參考連結:openzep

2) 另外你能告訴我如何將數據傳遞給給定的函式,如果我的邏輯合約需要 String、uint 和地址類型的 3 個參數,我應該如何在函式 createProxyAndCall() 中傳遞它?

初始化合約的最簡單方法是在使用openzeppelin create.

系統將詢問您? Do you want to call a function on the instance after creating it?,選擇Yes,然後是初始化功能,並要求您依次提供每個參數的值。

一個簡單的範例合約和部署如下所示:

計數器.sol

pragma solidity ^0.5.0;

import "@openzeppelin/upgrades/contracts/Initializable.sol";

contract Counter is Initializable {
   uint256 public value;

   function initialize(uint256 initialValue) initializer public {
       value = initialValue;
   }

   function increase() public {
       value++;
   }
}

openzeppelin 創建

部署合約,創建合約後選擇yes呼叫initialize函式,然後提供參數。

$ npx openzeppelin create
✓ Compiled contracts with solc 0.5.11 (commit.c082d0b4)
? Pick a contract to instantiate Counter
? Pick a network development
✓ Added contract Counter
✓ Contract Counter deployed
All contracts have been deployed
? Do you want to call a function on the instance after creating it? Yes
? Select which function * initialize(initialValue: uint256)
? initialValue (uint256): 42
✓ Setting everything up to create contract instances
✓ Instance created at 0x25D02115bd67258a406A0F676147E6C3598a91a9
0x25D02115bd67258a406A0F676147E6C3598a91a9

使用 OpenZeppelin SDK 的推薦方式是通過命令行界面,如果首選程式界面,請參閱文件: https ://docs.openzeppelin.com/sdk/2.5/zos-lib

例如,使用相同的 Counter.sol 合約,如果與 Truffle 一起使用,則首先編譯。

$ npx truffle compile

Compiling your contracts...
===========================
> Compiling ./contracts/Counter.sol
> Compiling ./contracts/Migrations.sol
> Compiling @openzeppelin/upgrades/contracts/Initializable.sol
> Artifacts written to /mnt/c/Users/andre/Documents/projects/forum/upgrade/build/contracts
> Compiled successfully using:
  - solc: 0.5.8+commit.23d335f2.Emscripten.clang

index.js

創建腳本來部署 Counter 合約並初始化

使用以下參數將參數傳遞給初始化函式:{ initArgs: [42] }

// Required by @openzeppelin/upgrades when running from truffle
global.artifacts = artifacts;
global.web3 = web3;

// Import dependencies from OpenZeppelin SDK programmatic library
const { Contracts, SimpleProject, ZWeb3 } = require('@openzeppelin/upgrades')

async function main() {

 /* Initialize OpenZeppelin's Web3 provider. */
 ZWeb3.initialize(web3.currentProvider)

 /* Retrieve compiled contract artifacts. */
 const Counter = Contracts.getFromLocal('Counter');

 /* Retrieve a couple of addresses to interact with the contracts. */
 const [creatorAddress, initializerAddress] = await ZWeb3.accounts();

 /* Create a SimpleProject to interact with OpenZeppelin programmatically. */
 const myProject = new SimpleProject('MyProject', null, { from: creatorAddress });

 /* Deploy the contract with a proxy that allows upgrades. Initialize it by setting the value to 42. */
 const instance = await myProject.createProxy(Counter, { initArgs: [42] })
 console.log('Counter\'s value:', (await instance.methods.value().call({ from: initializerAddress })).toString());

}

// For truffle exec
module.exports = function(callback) {
 main().then(() => callback()).catch(err => callback(err))
};

部署 Counter 合約並初始化

執行腳本

$ npx truffle exec index.js
Using network 'development'.

Counter's value: 42

注意:您的問題提供了一個更舊版本的文件的連結,最新版本是:https ://docs.openzeppelin.com/sdk/2.5/

我假設您可能使用的是舊版本的 OpenZeppelin SDK(pre version 2)。我推薦使用最新版本的 OpenZeppelin SDK。

以上使用了 OpenZeppelin SDK 2.5.2

$ npx openzeppelin --version
2.5.2

如果您對使用 OpenZeppelin 有任何疑問,可以在社區論壇中提問:https ://forum.openzeppelin.com/

披露:我是 OpenZeppelin 的社區經理

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