1

I'm working on the problem of smart contract upgradability and in that, I'm calling kill function of the contract with newly deployed contract's address as an argument. So that kill function can link the dataStore of my old contract to the new contract and then do the transfer of ownerships.

However, in order to link old data store to the new contract, I need to reference the definition of my contract itself and call a function called setDataStore. I'm doing it in following way -

    pragma solidity ^0.4.8;

    import "./DataStore.sol";
    import "./SecurityLibrary.sol";
    import "./DataVerifiable.sol";


    contract Parent is DataVerifiable {

        address public orgStore;

        using SecurityLibrary for address;

        function Parent() payable {
            setDataStore(0x0);
        }

        function setDataStore(address _orgStore) {
            if (_orgStore == 0x0) {
                orgStore = new DataStore();
            } else {
                orgStore = _orgStore;
            }
            if (!orgStore.isSuperAdmin(msg.sender)) {
                orgStore.makeSuperAdmin(msg.sender);    
            }
            DataVerifiable.orgStore = orgStore;
        }

         function kill(address upgradedParent) superAdminOrOwner {
            if (upgradedParent == 0x0) {
            throw;
            }
          // At this line I'm trying to reference the definition of 
          // my contract itself and calling a function of new Parent 
          // which is already deployed.

           Parent(upgradedParent).setDataStore(orgStore);
           DataStore(orgStore).transferOwnership(upgradedParent);
           selfdestruct(upgradedParent);
         }
}

Is this a correct way to reference the contract definition within the contract, if not then can someone advise what could be an alternative approach here?

Updating the question with more details -

Test case -

it('should let SuperAdminOrOwner kill parent', async function() {
    let newParent = await Parent.new();
    // I have instantiated the old parent in before each block
    orgStore = await parent.orgStore();
    await parent.kill(newParent.address);
    assert.equal(orgStore, await newParent.orgStore());
}); 

I'm running this testcase using testRPC and it gives following error -

Error: VM Exception while processing transaction: invalid opcode

When if I explicitly call the setDataStore function on newParent from my test case and remove that call from kill function then it works fine.

it('should let SuperAdminOrOwner kill parent', async function() {
    let newParent = await Parent.new();
    orgStore = await parent.orgStore();
    await newParent.setDataStore(orgStore);
    await parent.kill(newParent.address);
    assert.equal(orgStore, await newParent.orgStore());
});
  • 1
    This seems fine. Is there any reason why you think it is not correct? – Tjaden Hess Jul 6 '17 at 8:31
  • It's not working for me and the test case fails. However, if I explicitly call the setDataStore function on newParent from my test case and remove that call from kill function then it works fine. – Sanchit Jul 6 '17 at 8:37
  • What exactly isn't working? Is it throwing an exception? Is the result not what you expected? How are you calling the function? You can edit your question to clarify these things – Tjaden Hess Jul 6 '17 at 8:45
  • Sure, I'll add more details. – Sanchit Jul 6 '17 at 8:46
  • I've added more details now. – Sanchit Jul 6 '17 at 8:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.