4

I want to use UpgradeabilityProxy provided by zeppelin, they have one method createProxyAndCall which they say initialize the new implementation with data parameter we provided which looks like:

   * @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) I am confused with how it is initializing the data, can someone please help me understand what this line is doing?

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

reference link: openzep

2) Also can you please tell me how to pass data to the given function, if my logic contract needs 3 parameters of String, uint and address type how shall I pass that in function createProxyAndCall()?

4

The simplest way to initialize your contract is to use the interactive commands when creating the contract using openzeppelin create.

You will be asked ? Do you want to call a function on the instance after creating it?, choose Yes, then the initialize function and you will be asked to provide the value for each parameter in turn.

A simple example contract and deploying is shown below:

Counter.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 create

Deploy contract, select yes to call the initialize function after creating the contract and then provide the parameters.

$ 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

The recommended way to use the OpenZeppelin SDK is via the command line interface, if a programmatic interface is preferred then please see the documentation: https://docs.openzeppelin.com/sdk/2.5/zos-lib

As an example, using the same Counter.sol contract, if using with Truffle, first compile.

$ 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

Create a script to deploy the Counter contract and initialize

The parameters are passed to the initialize function using: { 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))
};

Deploy Counter contract and initialize

Execute the script

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

Counter's value: 42

Note: Your question gave a link to a much older version of the documentation, the latest is: https://docs.openzeppelin.com/sdk/2.5/

I assume you may be using an older version of OpenZeppelin SDK (pre version 2). I recommend using the latest version of OpenZeppelin SDK.

The above used OpenZeppelin SDK 2.5.2

$ npx openzeppelin --version
2.5.2

If you have questions on using OpenZeppelin you can ask in the Community Forum: https://forum.openzeppelin.com/

Disclosure: I am the Community Manager at OpenZeppelin

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.