（1）地址生成：保持钱包无状态，用户可以轻松地在钱包之间导出和导入密钥; 这意味着使用一些确定性方案privkey_for_dapp=hash(master_key + dapp_id)。但问题是dapp_id？对于多合同dapps该怎么用？
我们可以使用URL或IPFS哈希作为dapp标识符吗？（可以考虑中间件） - 或者正如你所说的dapp合同地址。
Right now, Ethereum privacy is quite lacking. There are two reasons why. First, all of your activity is by default done through a single account, so it is all linkable on-chain. Second, and more insidiously, even if you have multiple accounts that you split your activity between (ideally, the default would be to use a different account for each application), the fact that you need to transfer ETH between accounts to pay for gas on all of them is itself a privacy leak.
This is a situation that could use improvement. Two areas come to mind.
We can encourage the development of easy-to-use, and importantly decentralized (ie. not just “trustless”, completely serverless) mixers targeting privacy-preserving transfer of small amounts of ETH, so if you want to send gas payment to another account you can do so without linking the two.
Note that here, one major challenge with (eg. ringsig or zk snark based) smart contract mixers is that if you want to send funds from A to B, B still needs to have ETH to pay gas to submit the proof to receive their funds, and sending that gas would be a privacy leak; this can be solved with a layer-2 protocol where a user can broadcast their proof (including a commitment to what address they want to receive to and what fee they are willing to pay) over something like Whisper, and a specialized set of nodes could accept these proofs, include them into a transaction and pay for the gas, and collect the fee from the recipient. But this protocol needs to be specced out, standardized and implemented…
If we make a default that for every dapp, a user uses a separate account, we have to overcome a few challenges:
Address generation: It would be nice to keep wallet software stateless, so users can easily export and import their keys between wallets; this implies using some deterministic scheme like privkey_for_dapp=hash(master_key + dapp_id). But then what is the dapp_id? How would that work for multi-contract dapps?
Dapp interaction: The most common category here is using ERC20 tokens inside another dapp. What is the workflow by which they would do that? To use KNC on Uniswap, would you first transfer KNC from their “Kyber account” to your “Uniswap account” and then do whatever you wanted to do with Uniswap? Something else? Ideally from a UX point of view, it would still feel like the user makes one operation; the UX of dapps that requires users to sign three transactions in a row to do something honestly really sucks.
Have people here thought about these issues more deeply?
“mixers targeting privacy-preserving transfer of small amounts of ETH, so if you want to send gas payment to another account you can do so without linking the two.”
This seems like a doable first task. The second part about Whisper etc. etc. seems like there are a lot of rabbit holes to go down. If we get these simple mixers, one can start by having users actually generate multiple accounts and not immediately link them. Still relies on OPSEC of the user, but a good start for simple dApp usage.
On the UX front, this is mainly a middleware and best practices issue. Can we help out wallets / web3 providers succeed at making this easier to set / generate accounts per dapp?
Do we use URL or IPFS hash as dapp identifiers? (think middleware) – or, of course, as you say, the contract address of the dapp.
I think starting with multiple accounts and multiple keys may not be ideal, but all of our single account solutions for securing / generating keys still work.
Privacy by default for everything a la ZEXE would be really nice, but it’s still far away, and not something that could be easily done technologically. What I’m proposing here is some low hanging fruit that can reduce the extent to which users’ activities are all immediately linked to each other. It’s nowhere close to total privacy, but it’s a very significant improvement.
True, but making a mixer that doesn’t have the “deanonymize yourself by paying for gas” issue requires a layer 2 messaging protocol for things other than transactions (unless the way we want to solve this is by adding some limited form of base-layer abstraction…)
At Least Significant：
To be clear, the issue with using one account - or transacting between multiple accounts you own, effectively making it a single “profile” - makes it easier to identify people in meaningful ways.
For example, I can look at things like where addresses are getting their ETH/tokens from, which leads to eventually to an exchange. Exchanges help identify potential attack vectors for spear phishing, but it also reveals some geographic information. The times that these transactions occur also helps to narrow locale.
I can see what Dapps an entity is using, which helps point me towards where these users may be reachable on social media.
You can even profile what kind of wallet scheme their using. Whether they have a cold storage address, are just using MetaMask or some other hot wallet, etc. This helps to know how difficult it would be to attack the user.
There’s a ton of meta information on top of the obvious X sent Y to Z.
This problem becomes exponentially worse when you add it to things like airdrops or giveaways where many people are associating their social media identity with their address. Anything that can be used to tie an address down to any other identifiable information makes this blockchain meta-information very powerful to attackers.
There’s also the concern for big data mining operations / government conspiracies that may not be so far fetched that are applying deep learning algorithms to all of this to pain a bigger picture.
The problem with mixers/privacy layers/Dapp support is that they aren’t usually trustless and easy. If possible, I’d rather see privacy built into the base protocol and not be an option for users. They should have to explicitly prove a transaction, not explicitly hide them
I agree that privacy by default is the only real solution. If it’s a choice, there’s always going to be incentives to trade information for access. Trading data for services is the default for major applications on the web today, and it’s what users are accustomed to, so they won’t even question it. Also, if it takes extra effort for developers or users to create privacy, and there are no economic incentives for doing so, then it’s an just an inconvenience at best and a sub optimal game theoretic business decision at worst. Better to have options for privacy than not, but like we see with 2FA and password managers today, they’re the exception and not the norm.
An idea that could help with geographic analysis via IPs and such might be dandelion routing. From what I understand it routes a tx between peers a certain number of times before having that tx broadcast to the network. This way you can’t tell where a tx originated from, but you would still be able to see which address is sending what to whom.
edit: realized danelion routing would help with network analysis, but not tx analysis.
This is an idea for CREATE2 which can be applied in some situations. We use the fact that we can precalculate the CREATE2 address - which means we can transfer tokens here and we can even supply a salt! It is applied to ERC20 tokens where we try to semi-interact with contracts in a single TX.
The idea is that an user transfers tokens to the address which is precalculated by seeding the address of the user together with the calldata. Knowing these values proves that the user wants to “deposit” the value which is currently the balance of the precalculated address together with the calldata. Hence the seeded data in CREATE2 is the address of the user and the calldata.
Now let’s say we have an useless dummy contract to show the usage. An user A wants to transfer tokens to B but not directly. This useless SplitContract is deployed and we can now calculate the CREATE2 address where A should deposit: the salt is simply the address of A and B and the init_code simply transfers all tokens at the CREATE2 address to SplitContract. When we created the contract at the address where A deposited to in the SplitContract we hence knew the seed so at this point we also know address B. We can calculate how many tokens were transferred and now transfer all tokens to B. Note that the CREATE2 contract can be selfdestructed immediately after we transferred tokens (hence yielding extra used gas of about 11k (~32k contract deployment, 22k refund, ~1k execution cost).
This is of course rather stupid but it can be expanded. Think of a DDEX: here you can match someones trade by transferring tokens to a certain address. The only thing the user now needs to do is to broadcast that these tokens are deposited and either the maker of this order can now take them or the user includes a fee for someone else to ““mine”” this token on-chain which gives them incentive to pay for this gas. (This fee is hence in the calldata / salt). If the order is not matched the user can go on-chain to withdraw their tokens by simply providing the supplied calldata and showing that the user wants to cancel the order (to prevent the contract to try to match the order again). (Or the order is fulfilled already).
Notice that in the DDEX cases the contract is also only created and selfdestructed so no code is deposited, yielding a low amount of extra gas. The only downside in the implementation-side is that you can’t selfdestruct, create2 it again, and selfdestruct it again in the same tx which means you have to deposit code if you want to call back into this contract for some reason. When thinking about this I can also see why it would be really nice to have some kind of memory between call frames, something EIP 1283 tries to accomplish.
I’m interested also in how this applies to “account contracts”, which are essentially multisigs for a single person but with private keys on different devices + a recovery mechanism.
Account contracts make Ethereum more usable and help safeguard against loss of access to someone’s most important dapps, but they make privacy more challenging due to encouraging users to have a single point of entry to many dapps.