First Ethereum Project 101

Hello @thecil and @dan-i!

I hope I mad the tags correctly!

Mikolaj instructed me to come here and post my first ethereum project here. He has sent me a list and I have chosen the first to be the following: Make a contract that sends funds and checks the ledger for the transaction.

I have done as many things I think it should be in the contract so far but I think it is not ready ( I am not entirely sure that I understand everything regarding how the ledger things work as a smart contract).

So my question is, where can I improve this and do I understand everything correctly regarding the Ledger check?

I have made an addBalance function and also add a transfer inside the CreateTransaction function. Numbers are moving okay as far as I have checked and also my way of thinking was regarding to checking the ledger is to add a struct with the two addresses and I have chosen an amount which has been sent and one which was remaining after the transaction.

The getTransaction function is getting those 4 array elements out by the transaction Id which I chose to be the array length.

What I do not know is that how the ledger checks works anonimously . So does this mean I have to convert the addresses to some kind of number (I cannot really imagine a string working but I am open to everything).

Also any upgradement can be made I will do as I want to get out the most of this project before I move on. I have came to the Academy in January with 0 knowledge so I believe I am in still need of much assistance but I think if I can get 1 or 2 tips I can expan this project.

Here is the github link for the coding: https://github.com/Riki0923/LedgerFunds/blob/main/First%20Project%20-%20Ethereum%20Programming%20.md

Also pasting it here just in case:

//SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.4; pragma abicoder v2;

contract LedgerFunds {

address[] private participants;

constructor(address[] memory _participants){
    participants = _participants;
}

     modifier onlyOwner (){
      bool participant = false;
      for(uint i =0; i<participants.length; i++){
          if (participants[i] == msg.sender){
              participant = true;
          }
      }
      require(participant = true);
      _;
     }

struct Transactions {
    uint256 id;
    address payable _receiver;
    address _sender;
    uint256 _amountSent;
    uint256 _balanceRemained;
    
}

Transactions[] transactionNumber;


mapping(address => uint256) balances;

event balanceAdded(uint256 addedAmount);


function addBalance(uint256 _toAdd) onlyOwner public payable {
    balances[msg.sender] += _toAdd;
    emit balanceAdded(_toAdd);
}


function createTransaction(address payable _receiver, uint _amount) public payable  onlyOwner  {
    
    require(balances[msg.sender] >= _amount, "insufficient balance");
    uint256 _balanceRemained = balances[msg.sender] -=_amount;
    balances[_receiver] += _amount;
    
    
    Transactions memory newTransaction = Transactions(transactionNumber.length, _receiver, msg.sender, _amount, _balanceRemained);
    transactionNumber.push(newTransaction);
}

function getTransaction(uint256 _id) external view returns(address, address, uint256, uint256 ){
   return (transactionNumber[_id]._receiver, transactionNumber[_id]._sender, transactionNumber[_id]._amountSent, transactionNumber[_id]._balanceRemained);
}
function getBalance() public view returns(uint256){
    return balances[msg.sender];
}

Thanks Everyone.

1 Like

Hey @Riki, hope you are well.

I have tested your contract, is quite nice but have some few improvements to be made.

function addBalance(uint256 _toAdd) onlyOwner public payable {
    balances[msg.sender] += _toAdd;
    emit balanceAdded(_toAdd);
}

That one is quite nice, but since it have an argument (uint256 _toAdd), I can add whatever number i like.
I get the idea to receive ETH, thats why its payable, But keep in mind that payable is only used to receive funds, these funds are manage through msg.value which is a variable like msg.sender (function caller) but msg.value will set the amount of ETH to sent.

After you have fixed the addBalance function, if you want to track properly the balance in ETH of the contract, you can use something like this:

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

This one should not need to be payable since it should check the funds of the contract instead

function createTransaction(address payable _receiver, uint _amount) public payable  onlyOwner

By ledger you mean the blockchain right? I mean, how the data is saved on the blockchain? or how to request data on it?

Carlos Z

Hi.

I have changed the addBalance function to the following, also updated the whole smart contract on the github link:

function addBalance() onlyOwner public payable {
    require(msg.value <= 10 ether, "The amount you want to add is too big");
    balances[msg.sender] += msg.value;
}

I hope I understood correctly what you meant by your previous reply.

So regarding the ledger. Mikolaj gave me a list of ethereum projects and I have chosen this one: "Make a contract that sends funds and checks the ledger for the transaction."

So I believe that the part where I can send funds are okay ( correct me please if not) but I am not sure I understand everything correctly regarding the “checks the ledger for the transaction” part and how to implement it into a smart contract.

So right now all I understand regarding how ledger works that it tracks the addreses and the amount what have been sent and how much has been remained in each address. For those I implemented the createTransaction and getTransaction function. I am not sure that it is good for a ledger check or not. I think the createTransaction is okay but the getTransaction is showing each transaction’s sender and getter Address and also the amount which has been sent and remained from the sender address by the transaction id, which is the length of the array.

So my question is, does my contract covers everything regarding the project I have chosen to create? (Hope it makes sense).

Thanks again for the assistance!

Riki

1 Like

Now, to check the funds in the ledger is quite basic.

You need a mapping balance which will manage each address (owners) and its funds.

There are 2 types of balance, one is the contract balance, the other the user balance.
You can get both of them with this:

function getContractBalance() public view returns(uint256){ 
    return address(this).balance; 
}

function getBalance() public view returns(uint256){ 
    return balances[msg.sender];
}

To check the ledger for transactions, you already made a good start with:

function getTransaction(uint256 _id) external view returns(address, address, uint256, uint256 ){ 
    return (
        transactionNumber[_id]._receiver, 
        transactionNumber[_id]._sender, 
        transactionNumber[_id]._amountSent, 
        transactionNumber[_id]._balanceRemained); 
    
} 

So by adding the suggestions I made for you, your contract will be ok for what mikolaj asked :slight_smile: , off course we can improve it more (there will be always room for improvements), but dont worry that much on now, just build something that does what is ask for.

If you have not yet complete the Smart Contract Programming 101 course, you should give it a close eye into the lessons, all the tricks and good practices to achieve a good contract are here, just pay attention on what filip explain, each video contains a lot of info that some times is worth to rewatch again. :nerd_face:

Carlos Z

1 Like

Well that is really good for me to hear :slight_smile:

So the mapping was already there I think, so I only needed to add the getBalance function for balances[msg.sender]

My mapping is the following:

mapping(address => uint256) balances;

Thank you very much for the assistance, really feeling good that I got the most of it in the first place when I created the contract. I have update the github page so it should be okay to go now. I will also contact Mikolaj and ask for the next steps.

All the best Carlos !

Riki

1 Like