1

I have a list of products, each product has a price.

I would like to create a function that can be called by a user and automatically checks whether the user's balance has enough money to buy the product, it transfers a fee from the buyer to the contract's balance and the price from the buyer to the seller.

Is that possible?

This code obviously cannot work, because the smart contract has to be fed, somehow.

    struct Product {
        uint id_prod;
        address owner_addr;
        uint curr_price;
        bool onSale;
    }

    struct Owner {
        uint id_owner;
        address payable addr;
    }

    // function to receive ethers into the contract
    receive() external payable {
    }

    // function to send ether
    function pay(address payable _to, uint amount) private {
        (bool sent, bytes memory data) = _to.call{value: amount}("");
        require(sent, "Failed to send Ether");
    }

    function buyProduct(uint _id_product) external payable productOnSale(_id_product) buyerHasEnoughMoney(_id_product) alreadyOwner(_id_product){

        Owner storage _owner = getOwnerStruct(_id_product);
        Product storage _product = ProductList[_id_product];
        
        // pay 1 finney to the contract
        pay(payable(address(this)), 10**15);
        pay(_owner.addr, _product.curr_price);


        _product.owner_addr = msg.sender;
    }

I think the workaround is to create a payable function where the buyer can specify the amount of money, so that the smart contract receives the money, and subsequently it transfers the price amount to the seller.

My question is if there exists a way to avoid the buyer to specify the amount and just calls a function that directly takes money from their balance, holds a fee to its own balance, and transfers the price amount to the seller.

2 Answers 2

0

I think the workaround is to create a payable function where the buyer can specify the amount of money, so that the smart contract receives the money, and subsequently it transfers the price amount to the seller.

This is the way to do it. Since there isn't a way to pull ETH from an address (it must be sent with a call), what you describe can't be done. You would just implement in the modifier something like require(msg.value >= minimumPrice). When it fails (user isn't sending enough), the call reverts and the transfer of ETH wont even happen.

0

You can do that, but you will have to use ERC20 tokens and your buyer would have to approve your contract for some amount prior to the sale transaction.

In case of ETH, you will need to use WETH, because ETH alone is not compliant.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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