Hi @xxs,
You don’t need to use utf8ToHex
to convert your strings.
I would create the proxies in a separate script rather than in the one migration.
I have created a simple example below, where I create the proxies in truffle console:
SimpleToken.sol
pragma solidity ^0.5.0;
import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20Detailed.sol";
/**
* @title SimpleToken
* @dev Very simple ERC20 Token example, where all tokens are pre-assigned to the sender.
* Note they can later distribute these tokens as they wish using `transfer` and other
* `ERC20` functions.
*/
contract SimpleToken is Initializable, ERC20, ERC20Detailed {
/**
* @dev initialize that gives holder all of existing tokens.
*/
function initialize(string memory name, string memory symbol, address holder) public initializer {
ERC20Detailed.initialize(name, symbol, 18);
_mint(holder, 1000000 * (10 ** uint256(decimals())));
}
}
SimpleTokenFactory.sol
pragma solidity ^0.5.3;
import "@openzeppelin/upgrades/contracts/upgradeability/ProxyFactory.sol";
contract SimpleTokenFactory is ProxyFactory {
address[] public tokens;
event TokenCreated(address indexed tokenAddress);
function createToken(address logic, string calldata name, string calldata symbol, address holder) external {
bytes memory payload = abi.encodeWithSignature("initialize(string,string,address)", name, symbol, holder);
// Deploy minimal proxy
address token = deployMinimal(logic, payload);
emit TokenCreated(token);
tokens.push(token);
}
}
2_deploy.js
I only deploy the logic contract and the factory.
Minimal proxies can be created via a script or the console
const SimpleToken = artifacts.require("SimpleToken");
const SimpleTokenFactory = artifacts.require("SimpleTokenFactory");
module.exports = async function (deployer) {
await deployer.deploy(SimpleToken);
await deployer.deploy(SimpleTokenFactory);
};
Deploy
$ npx truffle migrate
Compiling your contracts...
===========================
> Compiling ./contracts/Migrations.sol
> Compiling ./contracts/SimpleToken.sol
> Compiling ./contracts/SimpleTokenFactory.sol
> Compiling @openzeppelin/contracts-ethereum-package/contracts/GSN/Context.sol
> Compiling @openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol
> Compiling @openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20.sol
> Compiling @openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20Detailed.sol
> Compiling @openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol
> Compiling @openzeppelin/upgrades/contracts/Initializable.sol
> Compiling @openzeppelin/upgrades/contracts/cryptography/ECDSA.sol
> Compiling @openzeppelin/upgrades/contracts/upgradeability/BaseAdminUpgradeabilityProxy.sol
> Compiling @openzeppelin/upgrades/contracts/upgradeability/BaseUpgradeabilityProxy.sol
> Compiling @openzeppelin/upgrades/contracts/upgradeability/InitializableAdminUpgradeabilityProxy.sol
> Compiling @openzeppelin/upgrades/contracts/upgradeability/InitializableUpgradeabilityProxy.sol
> Compiling @openzeppelin/upgrades/contracts/upgradeability/Proxy.sol
> Compiling @openzeppelin/upgrades/contracts/upgradeability/ProxyFactory.sol
> Compiling @openzeppelin/upgrades/contracts/upgradeability/UpgradeabilityProxy.sol
> Compiling @openzeppelin/upgrades/contracts/utils/Address.sol
> Artifacts written to /home/abcoathup/projects/forum/xxs/build/contracts
> Compiled successfully using:
- solc: 0.5.16+commit.9c3226ce.Emscripten.clang
Starting migrations...
======================
> Network name: 'development'
> Network id: 1596177951625
> Block gas limit: 6721975 (0x6691b7)
1_initial_migration.js
======================
Deploying 'Migrations'
----------------------
> transaction hash: 0xbdfc268046175ecac57a5c478995178dda88769035299d4d2b92a351c3f0a340
> Blocks: 0 Seconds: 0
> contract address: 0xe78A0F7E598Cc8b0Bb87894B0F60dD2a88d6a8Ab
> block number: 1
> block timestamp: 1596177963
> account: 0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1
> balance: 99.9967165
> gas used: 164175 (0x2814f)
> gas price: 20 gwei
> value sent: 0 ETH
> total cost: 0.0032835 ETH
> Saving migration to chain.
> Saving artifacts
-------------------------------------
> Total cost: 0.0032835 ETH
2_deploy.js
===========
Deploying 'SimpleToken'
-----------------------
> transaction hash: 0x2f449545e91f8f82878c54ed59b81de9a2d720a09d21d4547da2da2d2eb7ae11
> Blocks: 0 Seconds: 0
> contract address: 0xCfEB869F69431e42cdB54A4F4f105C19C080A601
> block number: 3
> block timestamp: 1596177963
> account: 0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1
> balance: 99.96726942
> gas used: 1430013 (0x15d1fd)
> gas price: 20 gwei
> value sent: 0 ETH
> total cost: 0.02860026 ETH
Deploying 'SimpleTokenFactory'
------------------------------
> transaction hash: 0xd61d6304698eb95d8ef5ea817119f8e2fb9d4124ea184b42653dda06195a2c9b
> Blocks: 0 Seconds: 0
> contract address: 0x254dffcd3277C0b1660F6d42EFbB754edaBAbC2B
> block number: 4
> block timestamp: 1596177963
> account: 0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1
> balance: 99.92872796
> gas used: 1927073 (0x1d67a1)
> gas price: 20 gwei
> value sent: 0 ETH
> total cost: 0.03854146 ETH
> Saving migration to chain.
> Saving artifacts
-------------------------------------
> Total cost: 0.06714172 ETH
Summary
=======
> Total deployments: 3
> Final cost: 0.07042522 ETH
Create and interact with minimal proxies
$ npx truffle console
truffle(development)> logic = await SimpleToken.deployed()
truffle(development)> factory = await SimpleTokenFactory.deployed()
truffle(development)> await factory.createToken(logic.address, "Token A", "TKA", accounts[0])
truffle(development)> await factory.createToken(logic.address, "Token B", "TKB", accounts[0])
truffle(development)> tokenA = await SimpleToken.at(await factory.tokens(0))
truffle(development)> tokenB = await SimpleToken.at(await factory.tokens(1))
truffle(development)> await tokenA.name()
'Token A'
truffle(development)> await tokenB.name()
'Token B'
You also had a separate question about what does npx oz deploy
kind `minimal do.
This creates minimal proxies using the OpenZeppelin CLI.
Please find below a deployment of the SimpleToken as a minimal proxy using the CLI.
$ npx oz deploy
✓ Compiling contracts with Truffle, using settings from truffle.js file
Truffle output:
Compiling your contracts...
===========================
> Compiling ./contracts/Migrations.sol
> Compiling ./contracts/SimpleToken.sol
> Compiling ./contracts/SimpleTokenFactory.sol
> Compiling @openzeppelin/contracts-ethereum-package/contracts/GSN/Context.sol
> Compiling @openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol
> Compiling @openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20.sol
> Compiling @openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20Detailed.sol
> Compiling @openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol
> Compiling @openzeppelin/upgrades/contracts/Initializable.sol
> Compiling @openzeppelin/upgrades/contracts/cryptography/ECDSA.sol
> Compiling @openzeppelin/upgrades/contracts/upgradeability/BaseAdminUpgradeabilityProxy.sol
> Compiling @openzeppelin/upgrades/contracts/upgradeability/BaseUpgradeabilityProxy.sol
> Compiling @openzeppelin/upgrades/contracts/upgradeability/InitializableAdminUpgradeabilityProxy.sol
> Compiling @openzeppelin/upgrades/contracts/upgradeability/InitializableUpgradeabilityProxy.sol
> Compiling @openzeppelin/upgrades/contracts/upgradeability/Proxy.sol
> Compiling @openzeppelin/upgrades/contracts/upgradeability/ProxyFactory.sol
> Compiling @openzeppelin/upgrades/contracts/upgradeability/UpgradeabilityProxy.sol
> Compiling @openzeppelin/upgrades/contracts/utils/Address.sol
> Artifacts written to /home/abcoathup/projects/forum/xxs/build/contracts
> Compiled successfully using:
- solc: 0.5.16+commit.9c3226ce.Emscripten.clang
? Choose the kind of deployment minimal
? Pick a network development
? Pick a contract to deploy SimpleToken
Minimal proxy support is still experimental.
✓ Added contract SimpleToken
✓ Contract SimpleToken deployed
All implementations have been deployed
? Call a function to initialize the instance after creating it? Yes
? Select which function * initialize(name: string, symbol: string, holder: address)
? name: string: My Token
? symbol: string: TKN
? holder: address: 0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1
✓ Instance created at 0x3408fb50BEeEF75145EC4a51Ba819cb7c71d2732
✓ Deployed ProxyFactory at 0x59d3631c86BbE35EF041872d502F218A39FBa150
To upgrade this instance run 'oz upgrade'
0x3408fb50BEeEF75145EC4a51Ba819cb7c71d2732
We can now interact with the token using call
and send-tx
$ npx oz call
? Pick a network development
? Pick an instance SimpleToken at 0x3408fb50BEeEF75145EC4a51Ba819cb7c71d2732
? Select which function name()
✓ Method 'name()' returned: My Token
My Token