My earlier article presenting Ethereum Script 2.0 garnered a variety of reactions, some highly favorable while others proposed that we adopt their preferred stack-based / assembly-based / functional model, along with several specific critiques that we are currently examining closely. Perhaps the most prominent criticism this time originated from Sergio Damian Lerner, a Bitcoin security analyst, developer of QixCoin, to whom we extend our appreciation for his examination of Dagger. Sergio specifically critiques two elements of the transition: the fee structure, which shifts from a straightforward one-variable model where everything scales as a fixed multiple of the BASEFEE, and the elimination of the crypto opcodes.
The crypto opcodes are the more crucial element of Sergio’s argument, and I will address that topic first. In Ethereum Script 1.0, the opcode collection consisted of opcodes tailored for various cryptographic functions – for instance, there was an opcode SHA3, which would take a specified length and a starting memory index from the stack and subsequently push the SHA3 of the string derived from the designated number of blocks in memory beginning from the starting index. There were comparable opcodes for SHA256 and RIPEMD160, as well as crypto opcodes focused on secp256k1 elliptic curve operations. In ES2, those opcodes have been eliminated. Instead, they are supplanted by a flexible system in which users will need to manually code SHA256 in ES (in practice, we would provide a commission or bounty for this), and later on, advanced interpreters can effortlessly replace the SHA256 ES script with a conventional machine-code (or even hardware) version of SHA256 similar to what occurs when you invoke SHA256 in C++. From an external perspective, ES SHA256 and machine code SHA256 are indistinguishable; both perform the same computation and therefore enact identical adjustments to the stack, the sole distinction being that the latter is significantly faster, providing us with efficiency akin to that of an opcode. A versatile fee system can thus also be implemented to make SHA256 more economical due to its diminished computation duration, ideally rendering it as inexpensive as an opcode currently is.
Sergio, however, favors an alternative method: providing numerous crypto opcodes out of the box and employing hard-forking protocol modifications to introduce new ones if necessary later on. He notes:
First, after three years of closely observing Bitcoin, I have come to realize that a cryptocurrency is not merely a protocol, nor a contract, nor a computer network. A cryptocurrency is a community. Aside from a limited set of constants, like the money supply function and the global balance, everything can be modified in the future, provided the changes are communicated ahead of time. The Bitcoin protocol has functioned well thus far, but we understand that it will encounter scalability challenges in the long run and will need to adapt accordingly. Short-term advantages, such as the protocol’s simplicity and the code base, have allowed Bitcoin to gain worldwide acceptance and a network effect. Is the reference code of Bitcoin version 0.8 as straightforward as version 0.3? Not in the slightest. Today, numerous caches and optimizations exist to achieve peak performance and enhanced DoS security, yet this does not concern anyone (and it shouldn’t). A cryptocurrency is initiated with a simple value proposition that is effective in the short to medium term.
This viewpoint is frequently raised concerning Bitcoin. However, as I delve deeper into the actual developments occurring in Bitcoin, I grow increasingly firm in my belief that, except for very nascent cryptographic protocols at an early stage and demonstrating minimal practical application, this argument is entirely untrue. Numerous flaws presently exist in Bitcoin that could be rectified if we collectively willed it. To illustrate a few examples:
- The 1 MB block size limit. At present, there exists a strict limitation that prevents a Bitcoin block from containing more than 1 MB of transactions – an upper cap of roughly seven transactions per second. We’re already approaching this limit, with about 250 KB in each block, which is currently exerting pressure on transaction fees. Throughout most of Bitcoin’s history, fees hovered around $0.01, and each time the price increased, the default BTC-denominated fee accepted by miners was adjusted downward. However, the fee is now fixed at $0.08, and the developers seemingly are not reducing it, likely because lowering the fee back down to $0.01 would lead to the number of transactions nearing the 1 MB limit. Removing this constraint, or at the very least adjusting it to a more appropriate value like 32 MB, is a simple modification; it comprises merely a single number in the source code and would undoubtedly contribute greatly to ensuring Bitcoin’s continued use in the medium term. Yet, Bitcoin developers have entirely neglected to implement it.
- The OP_CHECKMULTISIG bug. A well-documented bug exists in the OP_CHECKMULTISIG operator used for implementing multisig transactions in Bitcoin, which necessitates an additional dummy zero as an argument that is simply popped off the stack and not utilized. This is quite non-intuitive and perplexing; when I was working to implement multisig for pybitcointools, I was stuck for several days trying to determine whether the dummy zero was meant to be positioned first or substituted for the missing public key in a 2-of-3 multisig, and if two dummy zeroes were to be included in a 1-of-3 multisig. Eventually, I figured it out, but I would have done so much quicker had the operation of the OP_CHECKMULTISIG operator been more intuitive. Nevertheless, the bug has yet to be resolved.
- The bitcoind client. The bitcoind client is infamous for being a cumbersome and non-modular construct; in fact, the issue is so critical that those attempting to create a scalable and enterprise-friendly alternative to bitcoind are not utilizing it at all, but rather starting from square one. This is not related to a core protocol issue, and in theory, altering the bitcoind client should not necessitate any hard-fork changes, yet the necessary reforms remain unaddressed.
None of these issues exist because the Bitcoin developers lack competence. They do not; indeed, they are adept programmers with extensive knowledge of cryptography and the database and networking challenges intrinsic to cryptocurrency client design. These problems arise because the Bitcoin developers fully understand that Bitcoin is a 10-billion-dollar train racing along at 400 kilometers per hour, and if they attempt to modify the engine mid-course and even the slightest bolt becomes loose, the entire operation could come crashing down. A modification as straightforward as swapping the database back in March 2011 nearly did. Thus, in my view, it is reckless to maintain an inadequately crafted, non-future-proof protocol, and merely assert that the protocol can be revised when necessary. Conversely, the protocol should be engineered to possess a suitable level of adaptability from the outset, allowing alterations to be made by consensus automatically without requiring any software updates.
Now, addressing Sergio’s second concern, his primary issue regarding adjustable fees: if fees can fluctuate, it becomes increasingly challenging for contracts to establish their own fees, and if a fee rises unexpectedly, it could create a vulnerability through which an attacker might even force a contract into insolvency. I appreciate Sergio for highlighting this point; it is something I had not yet adequately contemplated, and we will need to thoroughly consider it during our design process. However, his proposed solution, manual protocol updates, is arguably no improvement; updates that alter fee structures can introduce new economic vulnerabilities into contracts as well, and they may be even more difficult to mitigate due to the absence of any limitations on the content that manual protocol updates can include.
So what are our options? First and foremost, there exist numerous intermediate solutions between Sergio’s method – which involves a restricted fixed set of opcodes that can only be added through a hard-forking protocol change – and the concept I suggested in the ES2 blog post about miners voting on dynamically adjusting fees for each script. One possibility might be to make the voting system more discrete, establishing a clear distinction between a script that must pay 100% fees and a script being “promoted” to an opcode that only requires a 20x CRYPTOFEE. This could be achieved through a combination of usage tracking, miner voting, ether holder voting, or other strategies. Essentially, this would provide a built-in method for implementing hard forks that does not technically necessitate any source code alterations to enact, making it much more fluid and less disruptive than a manual hard fork method. Secondly, it is crucial to reiterate that the capability to efficiently perform strong cryptography has not vanished, even from the genesis block; when we launch Ethereum, we will establish a SHA256 contract, a SHA3 contract, etc., and “premine” them into pseudo-opcode status right from the outset. Thus, Ethereum will arrive with batteries included; the difference is that the batteries will be incorporated in a manner that seamlessly facilitates the addition of more batteries in the future.
However, it is essential to point out that I regard this capability to incorporate efficient optimized crypto operations in the future as essential. Theoretically, it would be feasible to have a “Zerocoin” contract within Ethereum or a contract utilizing cryptographic proofs of computation (SCIP) and totally homomorphic encryption, allowing Ethereum to serve as the “decentralized Amazon EC2 instance” for cloud computing that many currently misunderstand it to be. Once quantum computing emerges, we may need to transition to contracts that depend on NTRU; when SHA4 or SHA5 are introduced, we might need to shift towards contracts that rely on them. Once obfuscation technology matures, contracts will aim to depend on that for securely storing private information. However, to make all of this possible with anything less than a $30 transaction fee, the underlying cryptography would need to be implemented in C++ or machine code, and there would need to be a fee framework that appropriately lowers the fee for operations once the optimizations are executed. This poses a challenge for which I currently see no straightforward solutions, and feedback and proposals are highly welcomed.