it('should be able to atomically initialize the contract with upgradeTo()', async function() { let initialized = await uintInitializebyProxy.initialized(uintInitializeV1a_NotInitialized.address); assert(initialized, "target uintInitializeV1a_NotInitialized should be initialized") let initializeTx = await uintInitializebyProxy.initialize.request(); let initializeData = initializeTx.params[0].data; let initializeSignature = web3.sha3("initialize()").substring(0, 10);; assert.equal(initializeData, initializeSignature, "initialization data does not equal signature") initialized = await uintInitializebyProxy.initialized(uintInitializeV1b_Initialized.address); assert(!initialized, "target uintInitializeV1b_Initialized should not be initialized yet") const upgradeToOverloadedAbi = { "constant": false, "inputs": [ { "name": "_target", "type": "address" }, { "name": "_data", "type": "bytes" } ], "name": "upgradeTo", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" } let upgradeToTransactionData = web3Abi.encodeFunctionCall(upgradeToOverloadedAbi, [uintInitializeV1b_Initialized.address, initializeData]); // let upgradeToTransactionData = web3.eth.encodeFunctionCall(upgradeToOverloadedAbi, [uintInitializeV1b_Initialized.address, initializeData]); // needs web3 v1.0 await web3.eth.sendTransaction({from: accounts[0], to: uintInitializebyProxy.address, data: upgradeToTransactionData, value: 0}); // await uintInitializebyProxy.upgradeTo(uintInitializeV1b_Initialized.address, initializeData) // upgrade to 1b // overloaded function not usupported initialized = await uintInitializebyProxy.initialized(uintInitializeV1b_Initialized.address); assert(initialized, "target uintInitializeV1b_Initialized should be initialized") let value = await uintInitializebyProxy.getValue.call() assert.equal(value.toNumber(), 111, "value should be what was initialized by UintInitializeV2") upgradeToTransactionData = web3Abi.encodeFunctionCall(upgradeToOverloadedAbi, [uintInitializeV1a_NotInitialized.address, initializeData]); // upgradeToTransactionData = web3.eth.encodeFunctionCall(upgradeToOverloadedAbi, [uintInitializeV1a_NotInitialized.address, initializeData]); // needs web3 v1.0 try { await web3.eth.sendTransaction({from: accounts[0], to: uintInitializebyProxy.address, data: upgradeToTransactionData, value: 0}); // await uintInitializebyProxy.upgradeTo(uintInitializeV1a_NotInitialized.address, initializeData) // revert back to v1a // overloaded function not usupported throw new Error("This error should not happen") } catch (error) { assert.equal(error.message, "VM Exception while processing transaction: invalid opcode", "should not be able to initialize again when upgradeing") } await uintInitializebyProxy.upgradeTo(uintInitializeV1a_NotInitialized.address) // revert back to v1a })
it('should be able to atomically initialize the contract with upgradeTo() for an initialize function with arguments', async function() { let initialized = await uintInitializebyProxy.initialized(uintInitializeV1a_NotInitialized.address); assert(initialized, "target uintInitializeV1a_NotInitialized should be initialized") initialized = await uintInitializebyProxy.initialized(uintInitializeV3.address); assert(!initialized, "target uintInitializeV3 should not be initialized yet") const initializeOverloadedAbi = { "constant": false, "inputs": [ { "name": "_valu", "type": "uint256" } ], "name": "initialize", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" } let initializeTransactionData = web3Abi.encodeFunctionCall(initializeOverloadedAbi, [777]); const upgradeToOverloadedAbi = { "constant": false, "inputs": [ { "name": "_target", "type": "address" }, { "name": "_data", "type": "bytes" } ], "name": "upgradeTo", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" } let upgradeToTransactionData = web3Abi.encodeFunctionCall(upgradeToOverloadedAbi, [uintInitializeV3.address, initializeTransactionData]); await web3.eth.sendTransaction({from: accounts[0], to: uintInitializebyProxy.address, data: upgradeToTransactionData, value: 0}); // await uintInitializebyProxy.upgradeTo(uintInitializeV1b_Initialized.address, initializeData) // upgrade to 1b initialized = await uintInitializebyProxy.initialized(uintInitializeV3.address); assert(initialized, "target uintInitializeV3 should be initialized") let value = await uintInitializebyProxy.getValue.call() assert.equal(value.toNumber(), 777, "value should be what was initialized by UintInitializeV2") })