Ethereum Smart Contract Programming

Hey @henmeh, hope you are good.

Are you sure that is the correct address for that file? maybe you should check the openzepellin documentation to import correctly the file.

If you have any more questions, please let us know so we can help you! :slight_smile:

Carlos Z.

    1.Mapping Problem and Solution

I believe what is wrong is that the instance of a dog, could be overwritten by simply typing a new name to the contract. It will override any previous dog name according to the address being used.

that is the correct site…
click on the Ballot.sol file.
it will immediately open a tab on the interface showing the context of that file(contract).

      function updateBalance(uint id, uint balance)  public{
              User storage user = users[id];
             user.balance = balance;
          }

this was my solution to the problem. From the previous video, Filip mentioned that memory is not used with uint, only with string, struct, ,ect. so removing memory and using storage for uint worked.
but i see the solution was much simpler. Is there a rise on cost *(gas) for using storage keyword in the contract? or by default is the same cost?

1 Like

The gas cost will vary on the memory type you are trying to use, storage will save the results into the blockchain, so it is more expensive, memory will create a memory space for operation result that does not need to be saved into the blockchain, more like the ram in the pc.

Carlos Z

thanks for the clearing that up Carlos. :metal:t5: metal:t5:

1 Like

@thecil
Hi Carlos,

I could solve my last problem. But meanwhile I have a new one.
I wrote a smart contract thats uses the Chainlink to get some data from an external API. I followed the instruction on the ChainLink website and everything works fine.
The problem now is that for one request to the API the answer is an uint256 value and for a second request the answer is a bool value. With the simple example on the ChainLink website this does not work. Do you have any idea to solve this? Of course I could write 2 Contracts but that would not be very elegant.

Best regards
Henning

1 Like

Hey @henmeh, hope your geat.

I might need to see the code, which variable or function returns a uint and which a boolean, if that is from the API??

Carlos Z

Hi Carlos,
yes I’m fine. Hope you too.
Thank you for your quick response. Here you can see the code


As you can see I solved the problem now with two different fulfill-Functions. It works although it would be interesting if there is a better way to do this.

Thank you for your support.

Best regards
Henning

1 Like

Nice, but what about the returned values on the API? I mean, req.add("get", "https://api... request a data from that web address and then some data is returned to you, can you check the returned data structure? is a JSON object for example?

My question is, who return the uint and boolean values, the API request right? so in that sense, you request to the same web address the same data, just that in one variable you bind the value as uint and in another variable the same data but boolean, maybe would better to check the returned data of that api and check what parameters you need from it.

Carlos Z

Yes the response from the API looks as follows

It is a list of dictionaries. For the prediction market I need the numbers ā€œAwayScoreā€ and ā€œHomeScoreā€ and the status ā€œisOverā€ beacuse only then the scores should be checked to decide which team has won.

Best regards
Henning

1 Like

Ok, so that API data is saved in the req variable right? So you could try to create a function that returns the content of req after the API request, to verify if the data is saved and then you should be able to access each variable value through something like req.GameKey for example.

Carlos Z

Thank you Carlos. That was really a good idea. It works and is a much better way than my one to simply double the fulfill-function.

Best regards
Henning

1 Like

Can someone explain exactly how smart contracts on Ethereum are updated? It’s amazing that the vulnerabilities e.g. recent yDAI exploit can be fixed literally in hours. What I don’t understand is how the deployed smart contracts are updated.

  • Can you add and modify certain lines in the smart contract or do you deploy the complete updated code?
  • What are the safety regulations for updating this? I guess there is a admin key but I’m not sure if there are other mechanisms that prevent e.g. bad intentions like modifying a contract so that certain vaults are emptied or similar.
  • Are the governance votes for e.g. implementing a new feature only there to have an on-chain vote mechanism or is it somehow linked to the adjustment and deployment of the smart contract updates?
  • What are the implications on trust and safety?

Thanks to anyone that can help to solve my questions :slight_smile:

Hey @Tobias, hope you are well.

Here is a very internesting lecture that should have the answer to your questions. Is very common to use security measures like pausable contracts, access control and upgradable contracts.

https://medium.com/cardstack/upgradable-contracts-in-solidity-d5af87f0f913

Also i suggest to get use to OpenZepellin contracts which is one of the best frameworks to use security proof contracts that save you time when developing contracts properly.

https://docs.openzeppelin.com/learn/upgrading-smart-contracts

If you have any more questions, please let us know so we can help you! :slight_smile:

Carlos Z.

Hello Community,
I am working on my first little project after taking the Ethereum Programming 101 course.
So the contract is about ā€œearning interestā€.

  1. user deposits some ether
  2. user can query for interested earned since deposit

I got everything running so far as you can deposit some, query for your deposit, see the annual interest and also query for the interested earned since time of deposit. You can also get total annual interest for your total balance ( of all deposits).
Now I try to make it work so you can query ā€œAll Interest earned so far from all depositsā€.
I hope this makes sense. Here is my code:

pragma solidity 0.7.5;
pragma abicoder v2;

contract EarnInterest{
    
    address saver;
    deposit[] depositsList;
 
    struct deposit{
        uint id;
        uint amount;
        address depositor;
        uint time;
        uint annualInterest;
    }
    
    mapping (address => uint) depositLog;
    mapping (address => uint) balance;
 
    function newDeposit() public payable{
        balance[msg.sender] += msg.value;
        depositsList.push(deposit(depositsList.length, msg.value, msg.sender, block.timestamp, msg.value / 10));
    }
    
    function interest(uint _id) public {
      //  uint timePassed = block.timestamp - depositsList[_id].time;[
        if(block.timestamp >= depositsList[_id].time){
             balance[msg.sender] = balance[msg.sender] + (balance[msg.sender] / 10);
        }
       
    }
    
    function MyBalance() public view returns(uint){
        // uint annualInterest = balance[msg.sender] / 10;
        //annual interest sind 10% bei 1 Jahr (31 536 000 sekunden)
        //interest earned now = 31 536 000 / timepassed. 
        //earnedNow = timepassed / 1 Jahr * annualInterest
        
        return balance[msg.sender];
    }
    
    function ShowTimePassed(uint _id) public view returns(uint){  // shows timePasseds since deposit for queried deposit
        uint calcTimePassed = block.timestamp - depositsList[_id].time;
        return (calcTimePassed);
    }
    function showAnnualInterest(uint _id) public view returns(uint){ //shows annual Interest for queried deposit
        return depositsList[_id].annualInterest;
        
    }
    
    function showCurrentInterest(uint _id) public view returns(uint){ //shows current Interest earned from a queried deposit
        uint timePassedNow = block.timestamp - depositsList[_id].time;
        uint annualInterest = depositsList[_id].amount / 10;
        uint secondInterest = annualInterest / 31536000;
        uint InterestEarned = secondInterest * timePassedNow; //passes Interest earned till timePassedNow
        return (InterestEarned);
    }
    

     function showTotalInterest() public view returns(uint){ //shows total annual Interest of balance of msg.sender
        uint totalInterest = balance[msg.sender] / 10;
        return totalInterest;
    }
    
//HERE starts my question... 

 /*   function showTotalCurrentInterest()public view returns(uint){ //supposed to show Total Current Interest of all deposits of msg.sender
        
    }
*/    
/*
    function showUserDeposits()public view returns(uint, uint, address, uint, uint){ //supposed to show all Deposits of msg.sender
        for(uint i = 0;i>=depositsList.length;i++){
            bool isUserDeposit = false;
            if(depositsList[i].depositor == msg.sender){
                isUserDeposit = true;
                return (depositsList[i].id, depositsList[i].amount, depositsList[i].depositor, depositsList[i].time, depositsList[i].annualInterest);
            }
        }
    }
  */  
}
1 Like

What you need is a variable that summarize all deposits amount based on a simple calculation (totalEarned = [depositsList[i].amount/depositsList[i].annualInterest] * depositsList[i].time) for example.

Here is a basic contract that i have to give you an example:

pragma solidity 0.6.2;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v2.5.0/contracts/math/SafeMath.sol";

contract Stake {

  using SafeMath for uint256;

  uint256 constant YearlyStakeInterest = 10;

  struct StakeIt {
    uint256 startTime;
    uint256 endTime;
    uint256 amountStaked;
  }

  mapping (address => StakeIt) public staking;

  function _startStaking (uint256 _amount, uint256 _nOfDays) internal {
    staking[msg.sender].startTime = now;
    staking[msg.sender].endTime = now + (_nOfDays.mul(1 days));
    staking[msg.sender].amountStaked = _amount;
  }

  function _endStaking () internal returns (uint256) {
    require (staking[msg.sender].endTime >= now);
    uint256 timeStakedDays = (staking[msg.sender].endTime.sub(staking[msg.sender].startTime)).div(1 days);
    uint256 toMint = ((staking[msg.sender].amountStaked*YearlyStakeInterest/100)/365)*timeStakedDays;
    return toMint;
  }
}

Carlos Z

1 Like

Thank you for your reply @thecil.
As I already mentioned in my post above, I need a function that returns ā€œAll Interest earned so far from all depositsā€.
I already have a function that returns ā€œinterest earned since the time of depositā€ for each deposit, but what I want to implement now is a function that returns the sum of all deposits of msg.sender up to ā€œnowā€

I hope my question is clear :slight_smile:

1 Like

Yeah, it can be done through a mapping for example that only store the amount deposited each time from an account (msg.sender) then you can use the value to calculate the total earned.

something like:

mapping (address=>uint256) totalDeposited;

then in the newDeposit() you can add the mapping to track the amount.

If you have any more questions, please let us know so we can help you! :slight_smile:

Carlos Z.

1 Like

Thank you @thecil. Haha! Yesterday, right around the time you replied, I also realized that I could use a mapping. Of course! It was so obvious. :sweat_smile:

1 Like