I would love to be wrong, but it is not yet possible to send ether from one wallet address to another wallet address using only Solidity.
But still, if you want you can write your contract with some method:
pragma solidity ^0.4.18;
contract Example {
function sendEther(address _addr) public payable {
_addr.transfer(msg.value);
}
}
and then using this method send some ether to desired address:
await instance.sendEther.sendTransaction(accounts[1], { from: accounts[0], value: 10**18 });
But it is not convinient, when you can just use:
await web3.eth.sendTransaction({ from: accounts[0], to: accounts[1], value: 10**18 });
Data storage and representation in the EVM
The address
and address payable
types both store a 160-bit Ethereum address. The concept of payable and non-payable addresses only exists in the Solidity type system at compile-time. The difference between payable and non-payable addresses is gone in the compiled contract code.
Built-in methods
You can use .transfer(..)
and .send(..)
on address payable
, but not on address
.
You can use a low-level .call(..)
on both address
and address payable
, even if you attach value.
Casting from address payable
to address
address payable
can be implicitly or explicitly cast to address
:
address payable addr1 = msg.sender;
address addr2 = addr1; // This is correct
address addr3 = address(addr1); // This is correct
Casting from address
to address payable
address
can only be explicitly cast to address payable
:
address addr1 = msg.sender;
address payable addr2 = addr1; // Incorrect
address payable addr3 = address(uint160(addr1)); // Correct since Solidity >= 0.5.0
address payable addr4 = payable(addr1); // Correct since Solidity >= 0.6.0
Casting address[]
or address payable[]
Although a single address payable
can be cast to address
, arrays of one address type cannot be cast to arrays of another address type:
function testCast(address payable[] memory _addresses) returns (address[] memory)
{
return _addresses; // Type error!
}
Rationale
Types in programming languages exist for two reasons:
To provide special type-specific semantics (e.g. +
on numbers is addition, but +
on strings might be concatenation)
To limit the amount of incorrect programs that are accepted by the compiler
The splitting of addresses into address
and address payable
serves the latter purpose. It forces the smart contract programmer to think about whether an address should ever receive ether from the smart contract. If it should never receive Ether, the address
type can be used. Compilation will fail with a type error if the programmer makes a mistake and tries to transfer Ether to that address.
Built-in address constants
msg.sender
is an address payable
tx.origin
is an address payable
block.coinbase
is an address payable
Best Answer
An
address
is a 20 byte number, so it gets comparison operators for free: Solidity doesn't have to implement anything, and the gas costs for using them are the same as comparing integers.In the future, the comparison operators might be useful depending on how sharding in Ethereum works. For example, one of the simplest and early ideas was to shard according to address space, like shard1 contains the first billion addresses, shard2 contains the next billion, and so on. A contract might then use the comparison operators to determine which shard another contract was in.