5

I'm currently trying to test run source code from GitHub based on a 2018 tutorial where solidity was using version 0.5.16. I'm currently using truffle v4.1.14. I understand that there was an update from "address" to "address payable", but I'm still not able to get it to work after referencing to similar threads. Appreciate any help. Thanks!

pragma solidity ^0.5.16;

import "./StringUtils.sol";
import "./Accounts.sol";

/** @title Documents. */
contract Documents {
    
  address payable private owner;
  address public accountsAddress;
  Document payable[] private documents;
  mapping (address => Count) private counts;
  enum DocStatus {Pending, Verified, Rejected}
  mapping (address => uint) balances;
 
  struct Document {
    address requester;
    address verifier;
    string name;
    string description;
    string docAddress;
    DocStatus status;
  }
  
  struct Count {
    uint verified;
    uint rejected;
    uint total;
  }

  event DocumentAdded (address user);
  event DocumentVerified (address user);
  event test (uint test);

function verifyDocument(string memory docAddress, DocStatus status) 
  public 
  payable
  {
    for (uint i=0; i<documents.length; i++) {
      if(StringUtils.equal(documents[i].docAddress, docAddress) && documents[i].verifier == msg.sender && documents[i].status == DocStatus.Pending){
        emit DocumentVerified(msg.sender);
        uint price = Accounts(accountsAddress).getPrice(documents[i].verifier);
        balances[documents[i].verifier] -= price;
        if(status == DocStatus.Rejected){
            counts[documents[i].requester].rejected = counts[documents[i].requester].rejected + 1;
            counts[documents[i].verifier].rejected = counts[documents[i].verifier].rejected + 1;
            // return the ether for rejection
            documents[i].requester.transfer(price);
        }
        if(status == DocStatus.Verified){
            counts[documents[i].requester].verified = counts[documents[i].requester].rejected + 1;
            counts[documents[i].verifier].verified = counts[documents[i].verifier].verified + 1;
            // send ether to verified account
            documents[i].verifier.transfer(price);
        }
        documents[i].status = status;
        break;
      }
    }
  }

** Documents.sol:208:13: TypeError: "send" and "transfer" are only available for objects of type "address payable", not "address". documents[i].requester.transfer(price); ^-----------------------------^ **

Full source code: https://github.com/lionel1702/final-project-RumeelHussain/blob/master/contracts/Documents.sol

Error Log: https://github.com/lionel1702/log/blob/master/emailRegexErrorLog4

3 Answers 3

3

You just need to change a few more of type address to be address payable. Namely here:

struct Document {
    address requester;
    address verifier;
    string name;
    string description;
    string docAddress;
    DocStatus status;
  }

Change into:

struct Document {
    address payable requester;
    address payable verifier;
    string name;
    string description;
    string docAddress;
    DocStatus status;
  }

Possible also changes needed in other parts of the contracts, but this should fix this immediate issue.

2
  • Another error came through Documents.sol:99:19: TypeError: Invalid type for argument in function call. Invalid implicit conversion from address to address payable requested. verifier: _verifier, ^-------^
    – Lionel Lim
    Sep 2, 2020 at 20:18
  • Thank you so much, I did manage to solve this problem too. ethereum.stackexchange.com/questions/71766/… Everything went well.
    – Lionel Lim
    Sep 2, 2020 at 20:32
3

You can declare the transfer_address as payable like,

payable(transfer_address).transfer(address(this).balance);

where transfer_address is the sender's address(msg.sender).

2
  • It quickly fixes something like this payable(msg.sender). Thanks.
    – Tien Do
    Feb 8, 2022 at 4:26
  • Edited to clarify more about 'transfer_address'. Feb 8, 2022 at 6:24
0

From the Solidity docs:

The address type comes in two largely identical flavors:

address: Holds a 20 byte value (size of an Ethereum address).

address payable: Same as address, but with the additional members transfer and send.

The idea behind this distinction is that address payable is an address you can send Ether to, while you are not supposed to send Ether to a plain address, for example because it might be a smart contract that was not built to accept Ether.

So, in order to send Eth to an address, you need to make it payable by:

  1. Declaring it as an address payable
  2. Converting it to an address payable using the payable(addr) method

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.