Strictly speaking, it is not possible to hide the sender of an Ethereum transaction. This is due to the fact that it is possible to extract the public key of the sender, and thereby the address, directly. A valid Ethereum transaction contains v
, r
, s
(among other fields) which makes up the ECDSA signature.
Here is an example of public key extraction from ethereumjs-utils:
/**
* ECDSA public key recovery from signature
* @param {Buffer} msgHash
* @param {Number} v
* @param {Buffer} r
* @param {Buffer} s
* @return {Buffer} publicKey
*/
exports.ecrecover = function (msgHash, v, r, s) {
const signature = Buffer.concat([exports.setLength(r, 32), exports.setLength(s, 32)], 64)
const recovery = v - 27
if (recovery !== 0 && recovery !== 1) {
throw new Error('Invalid signature v value')
}
const senderPubKey = secp256k1.recover(msgHash, signature, recovery)
return secp256k1.publicKeyConvert(senderPubKey, false).slice(1)
}
A valid transaction also contains a to
field which can be receiver address (when sending ethers) or the address of a smart contract. It is null when deploying a new contract (from Solidity docs):
If the target account is not set (the transaction does not have a recipient or the recipient is set to null), the transaction creates a new contract.
That means that you can theoretically hide the address of the receiver if you create your own token contract using zero-knowledge proofs. You could probably implement a protocol similar to Zcash, but people will be able to retrieve the address of the sender. This might or might not be a problem according to your requirements. As a side node, there is a nice proof-of-concept ethereum mixer that uses zk-SNARKs.
I am not familiar with Elements Confidential Addresses, but according to Elements website they use their own blockchain that can optionally be pegged to another blockchain (it is deployed as a side-chain; a blockchain like Ethereum is used as a trust anchor). It is therefore not directly related to Ethereum.