Full Smart Contract Upgradeability Discussion

Hi @Ahmad_Abd_Allah

Is it possible to share your code through github? I can try running your code to check if I can reproduce the error.

Hi @JohnVersus

Here it’s my code on GitHub
https://github.com/AhnedJoe/New-Proxy-contract.git

Hi @Ahmad_Abd_Allah

Here are the changes that I made to make it work.

uncomment the version line in truffle-config.js and update it to 0.6.2

  // Configure your compilers
  compilers: {
    solc: {
      version: "0.6.2", 

then add the following line after the fallback function. This line is required since fallback is defined as payable function.

receive() external payable {}

This should fix the errors. :slightly_smiling_face:

1 Like

Hi @JohnVersus

I really appreciate your effort.

I added the line, you have provided me.

But if it’s working with you, why it keeps giving me errors, like this one

You know what? I ignored that error and tried to develop it BUT VS code froze and got stuck.

The code which you shared me does not have any code named addFunction.
Do you have this somewhere else in your code?

No and never had such code

Hi @Ahmad_Abd_Allah

There is a solution for the similar error in this below post. It suggests to update truffle to latest using npm update -g truffle command.

https://ethereum.stackexchange.com/questions/84388/solidity-0-6-0-truffle-compile-error-cannot-read-property-of-undefined

1 Like

Hi @JohnVersus

From now on I’ll call you the Great John.

It’s working now

1 Like

Hi,
I did everything like Filip in Improving and Updating video, but I could run the code without the error of reverting the transaction. It throws no error, so that means there is an issue but it is not reverted?
So I don’t have initialize() function yet.

Here is my code:

Proxy.sol

// SPDX-License-Identifier: MIT  
pragma solidity >0.6.0 <0.9.0;

import "./Storage.sol";

contract Proxy is Storage{

    address currentAddress;

    constructor(address _currentAddress) public{
        currentAddress = _currentAddress;
    }

    function upgrade(address _newAddress) public {
        currentAddress = _newAddress; 
    }

    fallback() payable external {
        address implementation = currentAddress;  
        require(currentAddress != address(0)); 
        bytes memory data = msg.data;
      
        assembly {
            let result := delegatecall(gas(), implementation, add(data, 0x20), mload(data), 0, 0)
            let size := returndatasize()
            let ptr := mload(0x40)
            returndatacopy(ptr, 0, size)
            switch result
            case 0 {revert(ptr, size)}
            default {return(ptr, size)}
        }
    }
}

2_deploy_proxy.js

const Dogs = artifacts.require('Dogs')
const Proxy = artifacts.require('Proxy')
const DogsUpdated = artifacts.require('DogsUpdated')

module.exports = async function(deployer, network, account){
    const dogs = await Dogs.new(); /
    const proxy = await Proxy.new(dogs.address); 

    var proxyDog = await Dogs.at(proxy.address); 
    await proxyDog.setNumberOfDogs(10); 

    var nrOfDogs = await proxyDog.getNumberOfDogs(); 
    console.log(nrOfDogs.toNumber()); 

    const dogsUpdated = await DogsUpdated.new(); 
    proxy.upgrade(dogsUpdated.address); 

    nrOfDogs = await proxyDog.getNumberOfDogs(); 
    console.log("After update: " + nrOfDogs.toNumber());

    await proxyDog.setNumberOfDogs(30); 
}

Dogs.sol

// SPDX-License-Identifier: MIT  
pragma solidity >0.6.0 <0.9.0;

import "./Storage.sol";

contract Dogs is Storage{

    modifier onlyOwner(){
        require(msg.sender == owner);
        _;
    }

    constructor() public {
        owner = msg.sender;
    }
    
    function getNumberOfDogs() public view returns(uint256){
        return _uintStorage["Dogs"];
    }

    function setNumberOfDogs(uint256 toSet) public {
        _uintStorage["Dogs"] = toSet;
    }
}

DogsUpdated.sol

// SPDX-License-Identifier: MIT  
pragma solidity >0.6.0 <0.9.0;

import "./Storage.sol";

contract DogsUpdated is Storage{

    modifier onlyOwner(){
        require(msg.sender == owner);
        _;
    }

    constructor() public{
        owner = msg.sender;
    }
    
    function getNumberOfDogs() public view returns(uint256){
        return _uintStorage["Dogs"];
    }

    function setNumberOfDogs(uint256 toSet) public onlyOwner {
        _uintStorage["Dogs"] = toSet;
    }

}

And second question:
when I use accounts[0], why it says me error: ReferenceError: accounts is not defined

Error message is not clear but it says the error is from 2_deploy_proxy.js

So it could be possible that the error occurred on the below line due to the extra \ at the end of the line.


This error occurs if an account is not defined before the line accounts[0]. Can you show the code where you have accounts[0]?

For this code:

    const dogs = await Dogs.new(); /

The “/” sign I forgot delete from here because I had a comment, this is not a problem.
But the point is there is no error but it should be like in video.

and for this:

when I use accounts[0] , why it says me error: ReferenceError: accounts is not defined

Here is the code (after creating initialize() function) where I have accounts[0]:

deploy_proxy.js

const Dogs = artifacts.require('Dogs')
const Proxy = artifacts.require('Proxy')
const DogsUpdated = artifacts.require('DogsUpdated')

module.exports = async function(deployer, network, account){
    const dogs = await Dogs.new();
    const proxy = await Proxy.new(dogs.address);

    var proxyDog = await Dogs.at(proxy.address); 
    await proxyDog.setNumberOfDogs(10); 

    var nrOfDogs = await proxyDog.getNumberOfDogs(); 
    console.log(nrOfDogs.toNumber()); 

    const dogsUpdated = await DogsUpdated.new(); 

    proxy.upgrade(dogsUpdated.address); 
    
    proxyDog = await DogsUpdated.at(proxy.address) 
                                                   
    proxyDog.initialize(accounts[0]); 
    nrOfDogs = await proxyDog.getNumberOfDogs();
    console.log("After update: " + nrOfDogs.toNumber());

    await proxyDog.setNumberOfDogs(30); 

}

DogsUpdates.sol

// SPDX-License-Identifier: MIT  
pragma solidity >0.6.0 <0.9.0;

import "./Storage.sol";

contract DogsUpdated is Storage{

    modifier onlyOwner(){
        require(msg.sender == owner);
        _;
    }

    constructor() public{
        initialize(msg.sender);
    }

    function initialize(address _owner) public{
        require(!_initialized);
        owner = _owner; 
        _initialized = true; 
    }
    
    function getNumberOfDogs() public view returns(uint256){
        return _uintStorage["Dogs"];
    }

    function setNumberOfDogs(uint256 toSet) public onlyOwner {
        _uintStorage["Dogs"] = toSet;
    }

}

For the accounts error replace account with accounts in the above line.

Try running the code again after updating this to check if it solves all the errors from deploy_proxy.js file

1 Like