0

I'm trying to create a smart contract that would send funds from one wallet to another by taking values ​​from an array that I fill. But it does not send values ​​unless I specify them in msg.value. How can I send money by property id without user participation? P.s: in private network

pragma solidity ^0.4.18;

contract property {

uint256 cad_number;
address customer;

struct propertyInfo{
    address Owneradress;
    uint256 cad_number;
    string location;
    uint32 cost;
    bool housing_status;
}

mapping(uint256 => propertyInfo) propertys;
mapping (address => uint) public balances;

    function Create_Property(address Owneradress,
                             string memory location, 
                             uint32 cost, 
                             bool housing_status
                            ) public{
        propertyInfo storage NewProperty = propertys[cad_number];
        NewProperty.Owneradress = address(Owneradress);
        NewProperty.location = location;
        NewProperty.cost = cost;
        NewProperty.cad_number = cad_number;
        NewProperty.housing_status = housing_status;
        cad_number++;
    }

    function Listing_property(uint256 prop_id) public view returns (
                                                                     address, 
                                                                     string memory,
                                                                     uint256, 
                                                                     uint32,
                                                                     bool
                                                                   ){
        propertyInfo storage s = propertys[prop_id];
        return(s.Owneradress, s.location, s.cad_number, s.cost, s.housing_status);
    }

    function transaction_to_contract(uint256 _id) public payable {
        propertyInfo storage s = propertys[_id];
        s.Owneradress.transfer(s.cost);
        balances[s.Owneradress] += s.cost;
    }
} 
  • 1
    So you want to get the funds of a user without getting the user's consent (which you refer to as participation)? Why do you think that could possibly work, and if it did, what would you think of the monetary system which allowed something like that? Would you trust it enough to put your own funds in it? – goodvibration Nov 23 '19 at 12:15
  • Sorry for misleading. This is a private network. I just want to send transaction ether through smart contract. – GumanXD Nov 23 '19 at 12:18
  • "through smart contract" - means that you first need to send it to the smart contract, and then send it from the smart contract. Are you seriously expecting a system where the smart contract can withdraw at will from a given wallet? – goodvibration Nov 23 '19 at 12:28
  • Can I somehow change the owner of the property when transferring funds? I do not know how to transfer the owner through a smart contract using a transaction – GumanXD Nov 23 '19 at 12:44
0

You can't do it.

It is not possible to write a contract that directly accesses the wallet of another user or the storage of another contract. So, you need a different approach.

Consider users that give the contract authorization to manage a certain amount of money. That can include redistributing to other users according to the rules. Think about an Escrow contract or ATM that holds funds and can even transfer funds as an internal accounting procedure.

pragma solidity 0.5.13;

contract ATM {

    mapping(address => uint) public balances;

    event Deposit(address sender, uint amount);
    event Withdrawal(address receiver, uint amount);
    event Transfer(address sender, address receiver, uint amount);

    function deposit() public payable {
        emit Deposit(msg.sender, msg.value);
        balances[msg.sender] += msg.value;
    }

    function withdraw(uint amount) public {
        require(balances[msg.sender] >= amount, "Insufficient funds");
        emit Withdrawal(msg.sender, amount);
        balances[msg.sender] -= amount;
    }

    function transfer(address receiver, uint amount) public {
        require(balances[msg.sender] >= amount, "Insufficient funds");
        emit Transfer(msg.sender, receiver, amount);
        balances[msg.sender] -= amount;
        balances[receiver] += amount;
    }

    // In a Batch

    function transfer(address[] memory receivers, uint amount) public {
        require(balances[msg.sender] >= receivers.length * amount, "Insufficient funds");
        for (uint i=0; i<receivers.length; i++) {
            emit Transfer(msg.sender, receivers[i], amount);
            balances[msg.sender] -= amount;
            balances[receivers[i]] += amount;
        }
    }
}

This is, of course, a simplified example to give you some ideas. It is not optimized for performance or security.

You can see that the contract holds funds and users are free to withdraw available funds without warning or qualification. It's better for the users because they control the extent of permission the contract has - by explicitly transferring funds to the contract's control. Think of the contract as a vending machine/ATM/card dealer they mutually decide to trust. They put their money on the table, in the machine, etc., or else the contract can't touch it.

The transfer functions are a proxy for whatever the app is supposed to do. In the example, the users send money back and forth. A real app could use any set of appropriate rules including batch processes.

One can use the same internal accounting approach to commit funds to games/deals, payout when ready, process refunds, etc. Move funds from balances (which are available for withdrawal) to other ledgers.

It's important to maintain the conservation of funds, so the accounting always exactly matches the funds on deposit.

The contract effectively sends ETH from user to user.

Hope it helps.

  • Thank you very much, for this, it gave me more ideas, but Mist complains about the function deposit (), it deploys it but does not execute it. Writes: "Couldn't estimate gas, resorting to default parameters.". – GumanXD Nov 25 '19 at 9:12
  • I noticed your example used a really old compiler. It's possible you are also using a pre-Constantinople blockchain. I would concentrate on the possible incompatibility between the backend geth or ganache (or something else). it would be better to upgrade that rather than observing a rule like compiler should be "no higher than x". Better to use the latest blockchain protocol and use a compiler "no older than x". – Rob Hitchens - B9lab Nov 25 '19 at 9:26
  • How can a user withdraw money from a contract? – GumanXD Nov 25 '19 at 11:32
  • They send a transaction to withdraw() and the function sends money back with msg.sender.transfer(amount); – Rob Hitchens - B9lab Nov 25 '19 at 16:24

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.