Debugging Solidity

Here you can ask questions related to this specific course section.

5 Likes

This is a great walk through to conquer those bugs. Sometimes they are so silly yet hard to find. Happy coding!!

2 Likes

Hi @filip I followed your instructions and also tried myself to solve this problem, but it seems like I need your help.

I updated in truffle-config.js also the solc but still facing the error message.

Do you maybe know what I do wrong?

Hey @crypto.thoms

From your screenshot it seems like you did not save truffle-config

image

Save the file and reboot truffle.

Cheers,
Dani

4 Likes

Ummm, I still can’t work out the error. May is because I didn’t have the Government contract or Ownable contract?

pragma solidity 0.7.5;
pragma abicoder v2;
import "./Ownable.sol";

interface GovermentInterface{
    function addTransaction(address _from, address _to, uint _amount) external payable;
}

contract Bank is Ownable{
    
    GovermentInterface govermentInstance = GovermentInterface(0x3328358128832A260C76A4141e19E2A943CD4B6D);
    
    mapping(address => uint) balance;
    
    event depositDone(uint amount, address indexed depositedTo);
    
    
    function deposit() public payable returns (uint)  {
        balance[msg.sender] = msg.value;
        emit depositDone(msg.value, msg.sender);
        return balance[msg.sender];
    }
    
    function withdraw(uint amount) public onlyOwner returns (uint){
        require(balance[msg.sender] >= amount);
        msg.sender.transfer(amount);
        return balance[msg.sender];
    }
    
    function getBalance() public view returns (uint){
        return balance[msg.sender];
    }
    
    function transfer(address recipient, uint amount) public {
        require(balance[msg.sender] >= amount, "Balance not sufficient");
        require(msg.sender != recipient, "Don't transfer money to yourself");
        
        uint previousSenderBalance = balance[msg.sender];
        
        _transfer(msg.sender, recipient, amount);
        
        //govermentInstance.addTransaction(msg.sender, recipient, amount);
        
        assert(balance[msg.sender] == previousSenderBalance - amount);
    }
    
    function _transfer(address from, address to, uint amount) private {
        balance[from] - amount;
        balance[to] + amount;
    }
      function getTransfers() external view returns(uint[] memory) {

    }
    
}
1 Like

Hi @Hector_Martinez

What is the issue you are facing?

I was trying to debug the contract, and need assistance. I’ll try to deploy the contract in Remix, but it comes up with errors. I’m trying to do debugging exercise.

Hey @Hector_Martinez

What’s the error message you get? What’s the code you are compiling?

Cheers,
Dani

I’m glad you had the error with the wrong hard-coded Government address. That is the same error I was fighting with in the 101 class! I also see how the address should have been set in the Government constructor, which makes a lot of sense! Good walk through on debugging. I had several bugs in my Bank contract that took a lot of noodling to figure out what/where/how the errors were occuring. I tried using the debugger but could not make heads or tails. Now I’m anxious for the next lesson to learn how to use the debugger!

Thanks!

1 Like

Hello, I just have a really quick question. Below is some of the code from the section of the course on data storage. I can’t seem to figure out why the revert line of code does what it does and was hoping someone could explain it to me. I just haven’t ever come across that syntax before.
Thanks!

pragma solidity 0.8.0;

contract mappedWithUnorderedIndexAndDelete {

  struct EntityStruct {
    uint entityData;
    //more data
    uint listPointer; //0
  }

  mapping(address => EntityStruct) public entityStructs;
  address[] public entityList;

  function isEntity(address entityAddress) public view returns(bool isIndeed) {
    if(entityList.length == 0) return false;
    return (entityList[entityStructs[entityAddress].listPointer] == entityAddress);
  }

  function getEntityCount() public view returns(uint entityCount) {
    return entityList.length;
  }

  function newEntity(address entityAddress, uint entityData) public returns(bool success) {
    if(isEntity(entityAddress)) revert();
    entityStructs[entityAddress].entityData = entityData;
    entityList.push(entityAddress);
    entityStructs[entityAddress].listPointer = entityList.length - 1;
    return true;
  }

  function updateEntity(address entityAddress, uint entityData) public returns(bool success) {
    if(!isEntity(entityAddress)) revert();
    entityStructs[entityAddress].entityData = entityData;
    return true;
  }
  
  //[ADRESS1, ADDRESS4, ADDRESS3]

  function deleteEntity(address entityAddress) public returns(bool success) {
    if(!isEntity(entityAddress)) revert();
    uint rowToDelete = entityStructs[entityAddress].listPointer; // = 1
    address keyToMove   = entityList[entityList.length-1]; //save address4
    entityList[rowToDelete] = keyToMove;
    entityStructs[keyToMove].listPointer = rowToDelete; //= 2
    entityList.pop();
    delete entityStructs[entityAddress];
    return true;
  }

}
1 Like

Hey @Ben17, hope you are well.

You are missing a error message inside your revert().

Take a look into this lecture which explain the difference of each, you could use the revert the way you are doing it, or could use a require which could do the same trick.

https://medium.com/blockchannel/the-use-of-revert-assert-and-require-in-solidity-and-the-new-revert-opcode-in-the-evm-1a3a7990e06e

Carlos Z

What about logic error? - I learnt about it when I was learning C++.
Is it the same as usage error?

Has anyone faced the difficulty of trying to run “……> truffle develop” within the terminal and have had errors pop up due to unsupported digital envelope routines? Ive tried looking it up and I’ve found that the error is frustrating lots developers, has anyone found a workaround or solution worth trying?

Hey @jacobo, hope you are well.

Could you please share a screenshot of the error that is showed to you?? :nerd_face:

Carlos Z

Hey Carlos! I’m doing well and hope you are as well, here the picture of the error… am I correct in thinking this has to do with new version of nodejs?image

1 Like

It could be the node version, please try this guide to downgrade it to the version proposed on it:

Sorry for the late replay sir :nerd_face:

Carlos Z

hey @filip and the champs here … I am actually building while learning right now but i have run to some problems in my code and i will be making the post here for the champs to help review the code and point out errors and how i can solve them…really i dont know if i am making sense at all in what i am coding but i will be awaint the champs reviews.

pragma solidity 0.8.10;

import "@OpenZeppelin/contracts/token/ERC20/IERC20.sol";
import "@OpenZeppelin/contracts/access/Ownable.sol";
import "@OpenZeppelin/contracts/utils/math/SafeMath.sol";

contract  lenderfile{
    
    using SafeMath for uint256;
       
       /* purpose of this smart contract :
       * lender creaate a loan offer and pushed to market
       *borrower take loan
       *borrower pays back loan
       *liquidate borrower and take collateral if borrower default
        */
   
   
       enum Status { initial, lent, paid, destroyed }
           Status status;
           Status constant defaultStatus = Status.initial;

         //uint256 a2zfee;

        struct offer{
         Status status;
         uint256 amount;
         uint256 collValue;
         uint256 duration; 
         
         address offerToken;
         address acceptedColl;

         address lender;
         address borrower;

         uint256 interestRate;
         uint256 expirationOffer;
        }

        Loan[] private loans;
        mapping(uint256 => Offer) public offers;

   
   /* +createOffer function makes the lender set his loan term and at that instant the money he is lendin out will be withdran from his wallet and locked in this contract  */
   function createOffer(address _offerToken, uint256 _amount, uint256 _collValue, address _acceptedColl, uint256 _duration, uint256 _expirationOffer, uint256 _interestRate) public returns (uint256) {
      offer.lender == msg.sender;

      require(_amount != 0);
      require(_interestRate != 0); 
      require(_duration != 0);
      require(_expirationOffer > block.timestamp);

      Loan memory Id = Loan (
         Status.initial,
         _amount,
         _collValue,
         _duration,
        _offerToken,
        _acceptedColl,
         address(0),
        _interestRate,
        _expirationOffer
 );

        offer.push(Id);
         uint256 id = loans.length - 1;

         IERC20.transferFrom(msg.sender, address(this), _amount);

        return id;

   }

/* this function is called by a borrwer who find interest in the loan terms and ready to take it. the borroer must provide the right collateral and at the instant of calling this function the collateraal is withdrawn from his wallet and locked uptill payment time */ 


  function takeOffer(uint256 id, address _owner) public {
     require(offer.status == Status.initial);

     Deed memory offer = offers[id];
     offer.borrower = _owner;
     offer.duration = uint40(block.timestamp) + offer.duration;
     offer.collValue = _collValue;
     offer.acceptedColl = _acceptedColl;

     offer.status = Status.lent;

     /* withdrawing the collateral as the borrower is taking a loan offer */
      IERC20.transferFrom(_owner, address(this), _collValue);


     /* sending the loan amount to the borrower */
      uint256 resortAmount = lastResortAmount(_offerAmount, _interest);

      IERC20.transfer(_owner, resortAmount);   


      emit offerTaken(id, _owner);
      
  }

 
  function payLoan(uint256 id) public  returns (bool) {
     require(offer.status = Status.lent);   

     offer.status = Status.paid;
     offer.amount = offer.amount(id);

    // IERC20.transferFrom(address(this), msg.sender, collValue(id));
     /* withdrawing collateral from the contract and send to the borrower at loan payment instance */
     IERC20.transfer(offer.collValue(id), offer.borrower(id));

     /*Taking the payment from borrower's wallet at instance of loan payment */
     IERC20.transferFrom(offer.borrower(id), offer.lender(id), offer.amount(id));

    emit LoanPaid(id, msg.sender);

     return true;  
     
  }
  
  /*  function a2zfee(uint256 _amount) internal returns (uint256){
        offer.amount = _amount;
         uint256 memory feeNum = 2;
         uint256 memory feeDen = 100;
         
         uint256 memory feepercent = div(feeNum, feeDen);

         uint256 a2zfee = mul(_amount, feepercent);

         return a2zfee;
   
    }

    */


   function lastResortAmount(uint256 _offerAmount, uint256 _interest) internal returns (uint256) {
     offer.amount = _offerAmount;
     offer.interestRate = _interest;
    // uint256 a2zfee = _a2zfee;

     uint256 endAmount = sub(_offerAmount, _interest);

     return endAmount;  

   }

/*todo 

liquidation machine function
pls i need help to make this and i will appreciate help from the expert here..thanks
*/
}

Here aare the errors I am having

   Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing "SPDX-License-Identifier: <SPDX-License>" to each source file. Use "SPDX-License-Identifier: UNLICENSED" for non-open-source code. Please see https://spdx.org for more information.
--> project:/contracts/lender.sol

,Warning: This declaration shadows an existing declaration.
  --> project:/contracts/lender.sol:72:6:
   |
72 |      Deed memory offer = offers[id];
   |      ^^^^^^^^^^^^^^^^^
Note: The shadowed declaration is here:
  --> project:/contracts/lender.sol:18:9:
   |
18 |         struct offer{
   |         ^ (Relevant source part starts here and spans across multiple lines).


DeclarationError: Identifier not found or not unique.
  --> project:/contracts/lender.sol:34:9:
   |
34 |         Loan[] private loans;
   |         ^^^^
  --> project:/contracts/lender.sol:72:6:
   |
72 |      Deed memory offer = offers[id];
   |      ^^^^^^^^^^^^^^^^^
Note: The shadowed declaration is here:
  --> project:/contracts/lender.sol:18:9:
   |
18 |         struct offer{
   |         ^ (Relevant source part starts here and spans across multiple lines).


DeclarationError: Identifier not found or not unique.
  --> project:/contracts/lender.sol:34:9:
   |
34 |         Loan[] private loans;
   |         ^^^^

i willl really appreciate the community help to solve this errors and also help me in making the code more better…thanks all awaiting quick response…thanks

Hello @everyone I need help plsss

@mcgrane5 pls help me out too

Others pls I need help

1 Like

Hey whats up phasman?

I can’t know what’s the wrong with my code, I need help :crazy_face:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.20; 
pragma abicoder v2;

import "./Ownable.sol";

interface GovermentInterface{
    function addTransaction(address _from, address _to, uint _amount) external payable;
}

contract Bank is Ownable {
    
    GovermentInterface govermentInstance = GovermentInterface(0x3328358128832A260C76A4141e19E2A943CD4B6D);
    
    mapping(address => uint) balance;
    
    event depositDone(uint amount, address indexed depositedTo);
    
    
    function deposit() public payable returns (uint)  {
        balance[msg.sender] = msg.value;
        emit depositDone(msg.value, msg.sender);
        return balance[msg.sender];
    }
    
    function withdraw(uint amount) public   onlyOwner returns (uint){
        require(balance[msg.sender] >= amount);
        msg.sender.transfer(amount);
        return balance[msg.sender];
    }
    
    function getBalance() public view returns (uint){
        return balance[msg.sender];
    }
    
    function transfer(address recipient, uint amount) public {
        require(balance[msg.sender] >= amount, "Balance not sufficient");
        require(msg.sender != recipient, "Don't transfer money to yourself");
        
        uint previousSenderBalance = balance[msg.sender];
        
        _transfer(msg.sender, recipient, amount);
        
      govermentInstance.addTransaction(msg.sender, recipient, amount);
        
        assert(balance[msg.sender] == previousSenderBalance - amount);
    }
    
    function _transfer(address  from, address to, uint amount) private {
        balance[from] -= amount;
        balance[to] += amount;
    }
      function getTransfers() external view returns(uint[] memory) {

    }
    
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

contract Government {

   struct Transaction{
       address from;
       address to;
       uint amount;
       uint txId;
   }

  Transaction[] transactionLog;

  function addTransaction(address _from, address _to, uint _amount) external payable {
      transactionLog.push( Transaction(_from, _to, _amount, transactionLog.length));
  }
  function getTransaction(uint _index) public view returns (address, address, uint){
      return (transactionLog[_index].from, transactionLog[_index].to,
      transactionLog[_index].amount);
  }

      function getBalance() public view returns (uint){
          return address (this).balance;
      }

}

it shows error