Hacker News new | ask | show | jobs
by CVE-2018-17144 2829 days ago
The ethereum network has substantial issues stemming from very poorly defined consensus rules, which manage to grow in complexity every time you look away. The sheer scale of the consensus critical code makes it review resistant. I've been in the room with proficient auditors and struggled to make heads or tails of exactly what some forms of the code are doing.

The scripting languages people use being compiled down into a very strange bytecode complicates matters even worse. The underlying type of the VM being 256 bit has caused the compilers to do heavy amounts of bit packing for efficiency, which makes reasoning about their behavior substantially harder than it should be. It's a struggle to call any of this system well designed with a straight face.

To all of this, I have sat with developers in exchanges who are at a complete loss how to deal with the poor RPC interfaces given. Simple tasks like receiving money as deposits from clients have a never ending stream of edge cases due to contracts and addresses being in the same name space, dealing with combining inputs using multiple transactions with some confirming and some not (leading to partial withdraws, or partial deposits), sequence number behavior driving everybody insane.

I can't speak to the hype around "building on ethereum" as I've never been a part of that, but on a basic level the tools presented are unusable, regardless of what language the client you have chosen to use are written in. The RPC interface in Bitcoin is at least straight forward, with primitives that largely make sense. It's not without fault and some things require kludges or result in head scratching, but it's not as crazy as Ethereum's.

2 comments

Bitcoin is not capable of running any complex code, so it’s not a good comparison. However, the issues you point out are definitely problems in ethereum. What ethereum has is a community of enthusiastic developers constantly discussing and programming on the platform despite its flaws. It’s like the JavaScript of cryptocurrency.
> a never ending stream of edge cases due to contracts and addresses being in the same name space

So, I notice that a lot of people don't understand the motivation for this design decision. Here's a walk through:

• People interact with the blockchain. A person can notice when things happen at particular addresses (by e.g. looking on a website like Etherscan); and can then do arbitrary things in response.

• A person also can have an Ethereum wallet, containing private keys associated with addresses, allowing them to send {contract input, attached ether} messages from a given address.

• Put these two facts together, and you get a person who can observe an event occurring on (or off) the blockchain, and then respond by sending commands to an Ethereum node to submit a transaction coming "from" the address in the person's wallet. This person is functioning as an Ethereum "oracle."

• A bot can be an Ethereum oracle, just like a person can. The bot can listen to an Ethereum node (quite efficiently, through its API); and then, when it notices activity it cares about, can submit transactions back to the node through the same API. The bot oracle, like a human oracle, must have a wallet, because the transactions they submit must be "from" an address.

• Ethereum smart contracts, then, are just bot oracles that happen to be executed by Ethereum itself as a distributed system. The constraints of their execution substrate require these bots' programs to be deterministic when executed in different places at different times, which means they are limited to only looking at state that can't change (i.e. the blockchain); unlike other oracles, "smart contract" oracles can't interact with anything besides the blockchain. But in all other ways, they're interchangeable with a human or bot oracle.

• So, again, just like a human or a bot oracle, a smart-contract "oracle" must have a wallet, in order to have a private key with which to sign output messages to the blockchain. But, unlike a human or bot oracle, since they can only watch the blockchain, they must express their intent of what they want to watch. In the current implementation†, that means that they are limited to watching for messages incoming to their own private key's associated address. Putting those two facts together means that, in effect, a smart-contract oracle is mapped 1:1 to a particular address.

Ethereum doesn't namespace contract addresses from regular addresses, because contract addresses are regular addresses. Sending a message to a contract address (an address watched by a smart-contract oracle) is exactly the same as sending a message to an address watched by a bot oracle, or a human oracle. (In fact, if you distinguished them in any way, you'd probably break bot/human oracles, because they'd no longer be able to do everything smart-contract oracles can do, i.e. registering those special kinds of addresses for themselves.)

---

† If the system was built with slightly more consideration, I would imagine that—like the other kinds of oracle—smart-contract oracles could listen for messages sent to arbitrary addresses, rather than just their own; and maybe—like the other kinds of oracle—they would be able to have one or more associated addresses in their "wallet", rather than a single address. (It wouldn't make sense for them to have zero associated addresses in their wallet, though; then they wouldn't be able to do anything.)

As a hater of the EVM and person directly trying to replace this shit, here is my rebuttal:

First, smart contracts don't have a private key, at least not in the meaning of the word. They do the equivalent of signing by sending a message from their address to another address, or expose a function to indicate that a particular message is authorized by the contract code... but it's impossible to send some packet of data to a contract and (without external communication) have it verify "this data was provably sent by this contract"

Every other system I know of puts contract addresses in some other different namespace. Even looking at Bitcoin, they use the "3" address version for pay-to-scripthash, while "1" is for pay-to-pubkey. Internally Ethereum actually DOES namespace these two different address types implicitly. A normal address has no code and has a public key. A contract address has code and no public key. There are many many if-statements with this logic to handle the multitude of edge cases that come up from using the same address namespace for person-addresses and contracts... and beyond that, this has been the direct cause of several smart contract bugs because checking if a sender is person or contract is not trivial. Even for your purported benefit of being able to send coins to contracts in the same way as a person doesn't really work. You must attach some data when sending to a contract, whereas sending to a person should never contain data.

And for your idea of a contract having multiple addresses, what would be the purpose of this? Technically this is possible but not exposed today by making it so that an address contains both the location of a contract in the blockchain as well as encoding some data. Could be done simply by allowing an ethereum address to have more than 160 bits. The first 160 bits is contract address, the remaining is data to send to the contract.

I can understand Ethereum's design being not great. It was the first one to exist and the designers were not fully aware how it would be used.. but I will never understand the people that defend the design as "oh you just don't understand why this is a good thing"

> oh you just don't understand why this is a good thing

That wasn't my intent at all. I don't think it's a good thing; I just think it's a predictable thing. I was trying to justify it like you'd justify the actions of someone with a mental illness, or like you'd justify an evolutionary adaptation. To "feel the flow of the causal process that resulted in this" (which isn't just the designers not being "fully aware of how it would be used.")

Most people, I find, who are put off by Ethereum's design, don't actively dislike the design; they just find it hard to understand the motivation for its design decisions, finding them obscure. That's what I was trying to help with, there.

It's perfectly okay to understand that motivation and then dislike Ethereum. I do too! (I haven't seen a genuinely good distributed-computation substrate yet, though. Have any recs?)

> There are many many if-statements with this logic to handle the multitude of edge cases that come up from using the same address namespace for person-addresses and contracts

Eh, that's more a fact of the implementations than the design, I think? You could theoretically treat every EVM CALL op as always executing bytecode, with regular addresses being wrapped in an ADT that, when asked for their bytecode, returns a zero-length string; and an EVM interpreter that, when asked to execute a zero-length bytecode string, does so successfully at a cost of zero gas. IIRC, there's nothing in the yellowpaper constraining them from writing the code this way. Whoever wrote the code is just a bunch of mooks who don't understand data-primacy and eliminating (cyclomatic) complexity.

> because checking if a sender is person or contract is not trivial

I'm not too familiar with what is and isn't exposed in Solidity, but at the EVM level, isn't that just 𝑒 ("the present depth of the message-call/contract-creation stack")? If 𝑒=0, a human (or a human/bot oracle) called you; if 𝑒>0, another contract called you.

> And for your idea of a contract having multiple addresses, what would be the purpose of this?

There really isn't a legitimate purpose in a contract having access to multiple [pretend-]signing identities, given that you can always construct a system of contracts that message one-another to accomplish the same task.

The point of my thought was to achieve parity between smart-contract oracles and human/bot oracles, insofar as human/bot oracles can sit there and do things in response to anything happening on the blockchain they're watching, not just something happening to an address they own. Theoretically, contracts could be allowed to subscribe to any log event stream that a node can subscribe to, such that, after any 𝑒=0 call which generated logs successfully returns, the EVM would then be required to run all contracts with active subscriptions that match the logs just written into a transaction receipt, with those contracts paying the gas out of their own accounts to run.