0

I'm using the .transfer() method in my smart contract to pay a particular address. I've checked the Ganache logs and the transaction does not revert and is auto-mined successfully. But I don't see a VALUE transaction in the Ganache transaction logs reflecting the transfer and I don't see the amount paid in Metamask for the Eth address that was supposed to receive the payment.

Why don't I see a VALUE transaction in the Ganache transaction list or see the payment in Metamask?

function claimPayment(uint256 _gameId, bytes32 _videoId, address _payeeAddr)
        public 
        onlyOwner
        onlyIfValidGameIdAndGameOverState(_gameId)
        whenNotPaused
        {
    require(_payeeAddr != address(0), "(claimPayment) The payee address is not set.");
    require(_videoId != "", "(claimPayment) The video ID is not set.");

    // Create a payment details structure from the input parameters so we can generate
    //  a mapping key.
    structPendingPaymentDetails memory pendingPaymentDetails =
        structPendingPaymentDetails(
            0,
            _gameId,
            _videoId,
            _payeeAddr,
            0,
            EnumPaymentType.NOTSET);

    // Build the mapping key from the pending payment details.
    bytes32 mapKey = hashPendingPaymentDetails(pendingPaymentDetails);

    // Make sure they have funds waiting for them.
    pendingPaymentDetails.paymentAmountGwei = s_mapPendingPaymentsByGame[mapKey].paymentAmountGwei;
    require(pendingPaymentDetails.paymentAmountGwei > 0, "(claimPayment) In the context of the given game and resource ID, the payee does not have any funds waiting for them.");

    // Make sure this contract has enough funds to cover the payment.
    require(address(this).balance >= pendingPaymentDetails.paymentAmountGwei, "(claimPayment) The contract does not have enough funds to cover the payment at this time.");

    // Remove the payment from our claim amount storage.
    delete s_mapPendingPaymentsByGame[mapKey];

    // Remove the payment from the pending payments list.
    removePaidAddressFromPendingPaymentsList(mapKey);

    // Make the payment.
    _payeeAddr.transfer(pendingPaymentDetails.paymentAmountGwei);
}
  • 1
    This will help you understand ethereum.stackexchange.com/questions/8315/…. Transfer done by a smart contract are called "internal transactions". They do not exist as a separate transaction in the blockchain so wallets will not show them, but balances should be updated correctly. – Ismael Nov 25 '18 at 6:57
  • @Ismael - So if my smart contract, which is a game/dApp, pays out to several people at the end of the game, none of them will see the payment in their Metamask clients, they will just see their balances update? If so, that's something that really needs an EIP to change this, if we want to speed adoption of the Ethereum platform by users. That would be like getting your bank statement with only updated totals. Let me know if I'm right about this before I post something on Reddit in the hopes of starting a discussion. – Robert Oschler Nov 25 '18 at 14:29
  • 1
    It is possible for a wallet detect such changes and notify to the user but most wallets do not have such feature. One of the reasons perhaps is that there's no standard api to query "internal transactions" and developers tend to be conservatives and only use standard apis. So there's a solution but not widely used yet. Also for payments a withdraw pattern is prefered. – Ismael Nov 26 '18 at 5:28
  • @ismael I'm already using the withdraw pattern. At the end of the game the payments are calculated by the smart contract during a "finalizeGame()", but the funds are not distributed, just set up for payment. Another call called "claimPayment()" actually makes a single payment to one payee using <payee>.transer(). Would this still be considered an "internal" payment, or not? I'm not seeing any payments in Metamask after executing a "claimPayment()" call against the smart contract, as you can see at the end of the code I posted above. – Robert Oschler Nov 26 '18 at 12:45
  • 1
    I'd say that everything done by a smart contract is an internal transaction, because it doesn't have a transaction hash that can be referenced by Metamask or other wallets. – Ismael Nov 26 '18 at 16:33

Your Answer

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

Browse other questions tagged or ask your own question.