Hi everyone, here is my code. It’s completely different than Filip’s but it works. I did not use double mapping even though double mapping seems useful.
The only thing that i can’t figure out is it seems i cannot call some of the view functions from other functions. For example, every time the transaction is approved, I want the “pending transactions” list to refresh automatically without having to click on the button “getPendingTx” each time.
Does anyone know how to do that? It seemed simple, but for some reason it doesn’t work the way i wanted it.
pragma solidity 0.7.5;
pragma abicoder v2;
// SPDX-License-Identifier: UNLICENSED
contract myWallet {
address[] owners;
address transactionSender;
mapping(address=>uint) ownersContribution;
uint txCount;
struct Transaction{
address from;
address payable to;
uint amount;
uint txId;
uint txApproved;
address approver1;
address approver2;
}
Transaction[] pendingTx;
Transaction[] completedTx;
mapping(uint=>Transaction) TxId;
modifier onlyOwner{
require(msg.sender==owners[0] || msg.sender==owners[1] || msg.sender==owners[2]);
_;
}
constructor(){
owners.push(0x5B38Da6a701c568545dCfcB03FcB875f56beddC4);
owners.push(0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2);
owners.push(0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db);
txCount=0;
}
function getOwners() public view returns(address[] memory){
return(owners);
}
function Deposit() public payable {
ownersContribution[msg.sender]+=msg.value;
}
function getWalletBalance() public view returns(uint){
return(address(this).balance);
}
function getOwnersContribution() public view returns(uint, uint, uint){
return(ownersContribution[0x5B38Da6a701c568545dCfcB03FcB875f56beddC4], ownersContribution[0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2], ownersContribution[0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db]);
}
function ApproveTransfer(uint _txId)public onlyOwner returns(Transaction[] memory){
require(TxId[_txId].txApproved<2, "transaction already approved");
require(msg.sender!=TxId[_txId].from, "you cannot approve your own transaction");
require((msg.sender!=TxId[_txId].approver1) && (msg.sender!=TxId[_txId].approver2), "you already approved this transaction");
if(TxId[_txId].txApproved==0){
TxId[_txId].approver1=msg.sender;
}
else{
TxId[_txId].approver2=msg.sender;
}
TxId[_txId].txApproved+=1;
if(TxId[_txId].txApproved==2){
sendFunds(TxId[_txId].to, TxId[_txId].amount);
completedTx.push(TxId[_txId]);
remove(getIndex(TxId[_txId].txId));
getCompletedTx();
getPendingTransaction();
}
return(pendingTx);
}
function Transfer(address payable recepient, uint amount) public onlyOwner {
pendingTx.push(Transaction(msg.sender, recepient, amount, txCount, 0,address(0), address(0) ));
TxId[txCount]=Transaction(msg.sender, recepient, amount, txCount, 0,address(0), address(0));
txCount++;
getCompletedTx();
getPendingTransaction();
}
function getPendingTransaction() public view returns(Transaction[] memory){
return(pendingTx);
}
function sendFunds(address payable _to, uint _amount) private {
_to.transfer(_amount);
}
function getCompletedTx() public view returns(Transaction[] memory){
return(completedTx);
}
function getIndex(uint _txId)public view returns(uint){
uint index;
for (uint i=0; i<pendingTx.length; i++){
if(pendingTx[i].txId==_txId){
index=i;
}
}
return(index);
}
function remove(uint _index) private {
for (uint i = _index; i<pendingTx.length-1; i++){
pendingTx[i] = pendingTx[i+1];
}
delete pendingTx[pendingTx.length-1];
pendingTx.pop();
}
}