0

I was trying to learn how smart contract interaction by implementing a bank contract and a client contract. The end user create a Client contract. Then, he use the Client contract to deposit or withdraw money from Bank contract.

An error occurred

However, I was not able to transfer the money from Client contract to the Bank contract, and the prompt throw error when the user called addDeposit() method in Client. The prompt says Error: Returned error: VM Exception while processing transaction: revert

Below is the TestContract.js

const Bank = artifacts.require("Bank");
var Client = artifacts.require("Client");
// ether = 10**18;

contract("TestContracts", function(accounts) {
    const alice = accounts[1];
    it("add deposit using client contract", async () => {
        const bank = await Bank.deployed();
        const client = await Client.deployed(bank.address, alice); //the owner of the contract is alice

        client.addFund({ from: alice, value: web3.utils.toWei("30","ether") });

        balance = web3.utils.fromWei(await client.checkBalance());
        assert(balance, 30, "balance of the contract wrong");

        await client.addDeposit(5);
        let deposit = web3.utils.fromWei(await client.checkDeposit()); //ERROR HERE!!!!
        assert(deposit, 5, "balance of the contract wrong");
    })

Here is the Client contract

contract Client {
    address owner; // the client contract connect with the account who creates it
    Bank bank; // the bank that this client contract connected with

    constructor (address _referBank, address _owner) public payable {
        owner = _owner;
        bank = Bank(_referBank);
        bank.enroll(address(this));
    }

    function isClientActive() public view returns(bool) {
        return bank.isClientActive(address(this));
    }

    function addFund() public payable {
        require(msg.sender == owner, "only owner are allow to send money to client contract");
    }

    function addDeposit(uint amount) public {
        bank.transfer(amount);
    }

    function withdraw(uint amount) public payable {
        bank.withdraw(amount);
    }

    function checkDeposit() public view returns(uint) {
        return bank.checkDeposit(address(this));
    }

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

    // transfer the balance from the client's contract to the owner account
    function () public payable {
        require(msg.sender == owner, "only owner are allow to send money to client contract");
    }
}

Below is the Bank contract

contract Bank {
    struct Client {
        uint deposit;
        bool active;
    }

    address owner;
    mapping(address => Client) public clientList;
    uint clientCounter;

    constructor() public payable {
        require(msg.value == 30 ether, "Initial funding of 30 ether required for rewards");
        /* Set the owner to the creator of this contract */
        owner = msg.sender;
        clientCounter = 0;
    }

    function enroll(address _addr) public {
        clientList[_addr].deposit = 0;
        clientList[_addr].active = true;
        clientCounter++;
    }

    function isClientActive(address _addr) public view returns(bool) {
        return clientList[_addr].active;
    }

    function getClientCounter() public view returns(uint) {
        return clientCounter;
    }

    // add the deposit to the sender account
    function addDeposit() public payable {
        if (clientList[msg.sender].active != true) {
            revert("the client's address does not exist");
        } else {
            clientList[msg.sender].deposit += msg.value;
        }
    }

    // transfer the amount of ether to the provided address
    function withdraw(uint amount) public payable {
        if (clientList[msg.sender].deposit < amount) {
            revert("not enough deposit to make the withdraw");
        } else {
            clientList[msg.sender].deposit -= amount;
            msg.sender.transfer(amount);
        }
    }

    // return the deposit of the provide address
    function checkDeposit(address _addr) public view returns (uint) {
        return clientList[_addr].deposit;
    }

    // received money from the client contract
    function () public payable {
        if (!isClientActive(msg.sender)) {
            revert("client does not exist");
        } else {
            clientList[msg.sender].deposit += msg.value;
        }
    }
}
1

The issue is in the function (in the Client contract):

function addDeposit(uint amount) public {
    bank.transfer(amount);
  }

Because bank is not an address. You can save the bank address in the ocnstructor and use it to do the transfer or better, use the addDeposit function of bank in the Client, like this:

function addDeposit(uint amount) public {
    bank.addDeposit.value(amount)();
  }

I test it in remix and it works well.

Hope this helps you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.