Ethereum’s design concept: uncle block reward, update difficulty algorithm, gas fee, etc.

An alternative to strict gas counting is time limits, but it is unlikely to be useful because they are too subjective (some computers are faster than others, and even if everyone’s computers are the same, there may still be differences).

Uncle blocks (uncle blocks) rewards

The GHOST agreement is a remarkable innovation, first proposed by Yonatan Sompolinsky and Aviv Zohar in October 2013. It is the first serious attempt to solve the problems associated with rapid block production.

The intention of GHOST is to solve such a problem: a shorter block time (so the confirmation speed will be faster) will lead to more blocks “stale” and therefore security will be reduced-because the block will take a certain time to propagate in the network , If miner A digs a block and broadcasts it to the entire network, and B also digs out the block on the way of broadcasting, then B’s block is out of date, and B’s current mining does not contribute to the security of the network .

In addition, there is a centralization problem: if A is a mining pool, it has 30% of the computing power, and B has 10% of the computing power. A has 70% of the time to generate obsolete blocks (because the other 30% of the time will generate the latest block, it can be considered that TA got the latest block data “immediately” without waiting for the block to propagate), while B has 90% of the time Time produces obsolete blocks. If the block’s output time interval is very short, then the obsolescence rate will become higher, and A will make mining more efficient by virtue of its greater computing power. Therefore, the block generation is too fast, and it is easy to cause the mining pool with large network computing power to monopolize the mining process in fact.

According to the description of Sompolinsky and Zohar, GHOST solves the problem of network security degradation caused by obsolete blocks in the process of calculating which chain is the longest chain. In other words, not only the parent block and earlier blocks, but also obsolete side-branch blocks (in Ethereum, we call them “uncle blocks”) are also added to calculate which block has the largest total workload Proof.

In order to solve the second problem: the centralization problem, we adopted another strategy: provide block rewards for obsolete blocks: the reward for mining obsolete blocks is 7/8 of the basic reward of the block; The nephew of the time block will receive 1/32 of the basic reward as a bounty. However, the transaction fee will not be rewarded to the uncle block and nephew block.

In Ethereum, obsolete blocks can only be included as uncle blocks by direct descendant blocks within 7 generations of their sibling blocks. The reason for this restriction is that, firstly, if the GHOST protocol does not limit the generation distance of obsolete blocks, it will spend a lot of money on calculating the effectiveness of obsolete blocks; secondly, unlimited obsolete block incentive policies will allow miners Lost the enthusiasm for mining on the main chain; in the end, calculations show that the obsolete block reward policy is limited to 7 layers to provide most of the required effects without negative effects.

Proofreading note: The technical form of “include” here is: the nephew block references the block hash value of the uncle block in the block header, and then includes the block header of the uncle block in the block body.

The design decisions of the block time algorithm include:

  • Block time 12s : 12 seconds is chosen because this is already the shortest time interval longer than the network delay. In a 2013 paper on measuring Bitcoin network latency, it was determined that 12.6 seconds is the time for a newly generated block to propagate to 95% of nodes; however, the paper also pointed out that the propagation time is proportional to the block size, so In faster currencies, we can expect the propagation time to be greatly reduced. The propagation interval time is constant, about 2 seconds. However, for the sake of safety, in our analysis, we assume that the propagation of the block takes 12 seconds
  • Limitations within the 7th generation of ancestors : The purpose of this design is to keep only a small number of blocks, and clear the earlier blocks. It has been proved that the quotable range of 7 generations can provide most of the required effects.
  • Limitation of 1 generation descendant : (for example, if c = child and p = parent, it  c(c(p(p(p(head))))) is invalid): This is also a design goal for simplicity, and the above simulator shows that this will not bring great centralization risk. (Proofreading note: This sentence is difficult to understand; one possible meaning is: the offspring of the uncle block cannot be used as the uncle block, that is, only the side branch of the main chain can be used as the uncle block.)
  • The uncle block must be valid  : the uncle block must be a valid header, not a valid block. This is also done to simplify, keeping the blockchain model as a linear data structure (and not becoming a DAG). However, requiring the uncle block to be a valid block is also an effective method.
  • Bonus distribution : 7/8 of the mining basic rewards are allocated to uncle blocks, 1/32 to nephew blocks, and their transaction fees are all 0%. If the cost is the majority, from a centralized point of view, this will invalidate the uncle block incentive mechanism; however, this is why Ethereum will continue to issue Ether as long as we continue to use PoW.

Difficulty update algorithm

At present, Ethereum uses the following rules to update the difficulty:

Coinworld-Ethereum's design concept: uncle block reward, update difficulty algorithm, gas fee, etc.

The design goals of the difficulty update rule are as follows:

  • Quick update : The time between blocks should be adjusted quickly as the hash power increases or decreases;
  • Low volatility : If the mining power is constant, the difficulty should not fluctuate sharply;
  • Simple : the implementation of the algorithm should be relatively simple;
  • Low memory : Algorithms should not rely on too many historical blocks, and use as few “memory variables” as possible. Assuming that there are the latest ten blocks, add the memory variables stored in the heads of these ten blocks, and these blocks can be used for the calculation of the algorithm;
  • No blasting : The algorithm should not give miners too much incentive to tamper with the timestamp or the mining pool to repeatedly add or delete computing power

Our current algorithm is not ideal in terms of low volatility and blast resistance. Recently, we plan to change the timestamp parameter to compare with the parent block and grandfather block, so miners only have the motivation to modify the timestamp when they dig 2 blocks in a row. Another more powerful simulation formula: 

Gas and fees

All transactions in Bitcoin are roughly the same, so their network costs are simulated with a single unit. Transactions in Ethereum are more complex, so transaction fees need to take into account many aspects of the account, including network bandwidth fees, storage fees, and computing fees. It is especially important that the Ethereum programming language is Turing complete, so transactions will use any amount of bandwidth, storage and computing costs; and how many will be used in the end cannot be reliably predicted (because of the so-called “Turing outage problem” ) (Proofreading note: that is, there is no reliable way to assert whether any program that can be executed on a Turing machine will terminate within a limited number of steps). Preventing someone from using an infinite loop to implement a denial of service attack is a key goal of ours.

The basic mechanism of Ethereum transaction fees is as follows :

  • Each transaction must specify the amount of gas it is willing to consume (that is, the specified  startgas value) and the fee (that is gasprice ) that it is willing to pay for each unit of gas  . At the beginning of the transaction execution, the ether of startgas * gasprice value will be removed from the sender’s account Deduction; (Proofreading Note: This is  startgas what we are used to now  gaslimit .)
  • All operations during transaction execution, including reading and writing databases, sending messages, and each step of calculation will consume a certain amount of gas;
  • If the transaction is completed and the consumed gas value is less than the specified limit value, the transaction is executed normally, and the remaining gas value is assigned to the variable  gas_rem ; after the transaction is completed, the sender will receive the returned gas_rem * gasprice value of ether, and The reward for miners is (startgas-gas_rem) * gasprice value of ether;
  • If the gas is used up during the transaction execution, all executions will be restored to the original state, but the transaction is still valid, but the only result of the transaction is to pay the startgas * gasprice value of ether to the miner, and the others remain unchanged;
  • When one contract sends a message to another contract, a gas limit can be set for the sub-execution caused by this message. If the sub-execution runs out of gas, the sub-execution returns to its original state, but the gas is still consumed. (Proofreading note: As of the time of proofreading this article (July 9, 2021), this has not changed, but it may change in the future.

The points mentioned above must be met, for example :

  • If the transaction does not need to specify a gas limit, then a malicious user will send a transaction with a multi-billion-step cycle. No one can handle such a transaction, because it may take a long, long time to process such a transaction; but no one can tell the miners on the network in advance, which will lead to a denial of service vulnerability.
  • An alternative to strict gas counting is time limits, but it is unlikely to be useful because they are too subjective (some computers are faster than others, and even if everyone’s computers are the same, there may still be differences).
  • The entire value of startgas * gasprice should be set at the beginning, so as not to cause the account to “bankrupt” during transaction execution and unable to continue to pay gas fees. It is also not good to check the balance at the same time, because the account can put the balance in another place.
  • If the transaction execution will not be completely restored (rolled back) when the gas is not enough, the contract must adopt strong security measures to prevent the contract from changing.
  • If the sub-restriction does not exist, the malicious account can perform a denial of service attack on other contracts. The attacker can first reach an agreement with the victim contract, and then insert an infinite loop at the beginning of the calculation process, then sending a message to the victim contract or any attempt to remedy the victim contract will deadlock the entire transaction. (Proofreading note: This sentence is also difficult to understand.)
  • The transaction sender is required to pay for gas instead of the contract, which greatly increases the operability for developers. In the early version of Ethereum, contracts paid for gas, which caused a very serious problem: each contract must implement the “door guard” code to ensure that each incoming message provides enough ether for the contract to consume. .

Gas consumption calculation has the following characteristics :

  • For any transaction, a basic fee of 21000 gas will be charged. These fees can be used to pay for the cost of running the elliptic curve algorithm (the algorithm is designed to recover the sender’s address from the signature) and the hard disk and bandwidth space spent on storage transactions.
  • Transactions can include an unlimited amount of “data”. Certain opcodes in the virtual machine can allow contracts that receive such transactions to access these data. The “fixed consumption” rule for data is: 4 gas per zero byte and 68 gas per non-zero byte. This formula is generated because most of the transaction data sent by the user to the contract consists of a series of 32-byte parameters, most of which have many leading zero bytes. This structure may seem inefficient, but due to the existence of the compression algorithm, it is actually very efficient. We hope that this structure can replace other more complex mechanisms: these mechanisms strictly pack parameters according to the expected number of bytes, resulting in a significant increase in the complexity of the compilation phase. This is an exception to the complex sandwich model, but it is also a reasonable model due to the cost-benefit ratio.
  • The consumption of the operation code SSTORE used to set the account storage item is: 1) When the zero value is changed to a non-zero value, it consumes 20000 gas; 2) When the zero value is changed to a zero value, or a non-zero value is changed to a non-zero value, the consumption 5000 gas; 3) Change the non-zero value to zero and consume 5000 gas; in addition, after the transaction is executed successfully (that is, the transaction is executed without exhausting gas), 15000 gas will be returned. The maximum refund amount is 50% of the total gas consumed by the transaction. This gives people a small incentive to clear storage items. We have noticed that precisely because of the lack of such incentives, the storage space of many contracts has not been used effectively, which has led to the rapid expansion of stored data. This design can provide most of the benefits of the “continuous rental of storage items” model without losing the guarantee that the contract can exist forever once the contract is established. The delayed refund mechanism is necessary because it can prevent denial of service attacks: the attacker can send a transaction with a small amount of gas, and clear a large number of storage items in a loop until the gas is used up, which consumes a lot of verification computing power, but in reality The storage is not really cleared, and there is no need to pay a lot of gas. The 50% upper limit is to ensure that the miners of the packaged transaction can still determine the upper limit of the calculation time for executing the transaction.
  • (Proofreading note: First of all, the gas consumption of state access opcodes such as SSTORE has been changed many times with the hard fork of Ethereum. As of July 2021, the latest value can be found in the “Overview of Berlin Upgrade Content”; in the foreseeable In the future, the value of this opcode will continue to change; secondly, the gas refund mechanism here proves not to start alleviating the problem of state data inflation, but worsens the problem, because people can write when the gas price is low A large amount of junk data is cleared when the gas price is high to obtain gas. This is the principle of “GasToken”. It is currently determined that the gas refund mechanism will be changed in the “London” fork.
  • There is no cost for the message data provided by the contract. Because there is no need to copy any data during the message call, the call data can be simply regarded as a pointer to the memory of the parent contract, and the pointer will not change when the child process executes.
  • Memory is an array that can be expanded indefinitely. However, each expansion of 32 bytes of memory will consume 1 gas cost, and less than 32 bytes is counted as 32 bytes. (Proofreading note: memory is generally translated as memory, but in the context of Ethereum, it is one of the three types of EVM for storing data, so it is not translated to show its particularity.)
  • The calculation time of some opcodes is extremely dependent on parameters, and the gas cost calculation is dynamically changing. For example, the cost of EXP is exponential (10 gas + 10 gas/byte, that is, x^0 = 1 gas, x^1… x^255 = 2 gas, x^256… x^65535 = 3 gas ,and many more). The cost of copying opcodes (such as CALLDATACOPY, CODECOPY, EXTCODECOPY) is 1 gas + 1 gas/32 bytes (rounded up; rules for LOG opcodes are similar). The overhead of Memory expansion is not included here. If included, it will become a square attack vector (50,000 CALLDATACOPY, each time consuming 50,000 gas, the calculation amount should be 50,000^2, but if you do not use dynamic charging rules, you only need to pay ~50,000 gas).
  • If the value is not zero, the opcode CALL (and CALLCODE) will consume an additional 9000 gas. This is because any value transfer will cause the historical storage of the archive node to increase significantly. Please note that the actual cost  of the operation  is 6700; but on this basis, we force to increase a gas value automatically given to the receiver, the minimum value is 2300. This is done so that the wallet that accepts the transaction has at least enough gas to generate the log.

Another important part of the gas mechanism is the economic principles embodied in the gas price itself. In Bitcoin, the default method is to adopt a purely voluntary charging method, where miners play the role of gatekeeper and dynamically set the minimum fee. Ethereum allows transaction senders to set any number of gas. This method is very popular in the Bitcoin community because it is a manifestation of the “market economy”: it allows miners and traders to determine prices based on supply and demand. However, the problem with this approach is that transaction processing does not follow market principles. Although transaction processing can be regarded as a service provided by miners to senders (which sounds intuitive), in fact every transaction processed by miners must be processed by every node in the network, so most of the transaction processing The cost is borne by a third-party agency, not the miner who decides whether to deal with it. Therefore, the “tragedy of the commons” problem is likely to occur.

Currently, due to the lack of clear information about the behavior of miners in practice, we will adopt a very simple and fair method: a voting system to set the total amount of gas that can be consumed by a single block. Miners have the right to change 0.0975% (1/1024) of the gas limit of the latest block as the gas limit of the current block. So the final gas upper limit should be the middle value set by the miners. We hope that in the future, we can use a soft fork method to use more precise algorithms.

virtual machine

The Ethereum Virtual Machine is an engine that executes transaction codes, and it is also the core difference between Ethereum and other systems. Please note that the virtual machine should be considered separately from the “contract and message model”. For example, the SIGNEXTEND opcode is a function of the virtual machine, but in fact “a contract can call other contracts and specify the gas limit value of sub-calls” is part of the “contract and message model”.

The design goals of EVM are as follows:

  • Simple : as few opcodes as possible and low-level; as few data types as possible; as few virtual machine structures as possible;
  • The result is clear : In the VM specification, there is no room for ambiguity, and the result should be completely certain. In addition, the calculation steps should be accurate so that the consumption of gas can be measured;
  • Save space : EVM components should be as compact as possible;
  • Specialized for the intended use : The application built on the VM should be able to handle 20-byte addresses and 32-bit custom encryption values, with modulus operations for custom encryption, reading blocks and transaction data, and State interaction and other capabilities;
  • Simple and safe : In order to prevent the VM from being used, it should be easy to establish a set of gas consumption cost model operations;
  • Optimization-friendly : It should be easy to optimize so that just-in-time compilation (JIT) and accelerated versions of VM can be built.

At the same time, EVM also has the following special designs :

  • The difference between temporary/permanent storage : Let’s first take a look at what is temporary storage and permanent storage. Temporary storage: exists in every instance of the VM and disappears after the execution of the VM. Permanent storage: exists in the state layer of the blockchain. Suppose the following tree is executed (S stands for permanent storage, M stands for temporary storage):
  1. A calls B;
  2. B settings  B.S[0]=5,B.M[0]=9 ;
  3. B calls C;
  4. C calls B.At this point, if B tries to read  B.S[0] , it will get the data stored in front of B, which is 5; but if B tries to read  B.M[0] , it will get 0, because BM is a temporary storage, and it is a virtual machine when it is read A new instance. In an internal call (inner call), if the B.M[0] = 13 sum  is set  B.S[0] = 17 , then both the internal call and the call of C terminate and return to the outer call of B. At this time, read M and you will see  B.M[0] = 9 (this value is in examples of the last execution of the same VM set),  B.S[0] = 17 . If the external call of B ends, then A calls B again, you will see  B.M[0] = 0,B.S[0] = 17 . The purpose of this distinction is: 1. Each execution instance is allocated with memory space, which will not be degraded due to loop calls, which makes safe programming easier. 2. Provide a memory form that can be operated quickly: Because the tree needs to be modified, storage updates must be very slow.
  • Stack/memory mode : In the early days, there were three types of calculation states (except the program counter pointing to the next instruction): stack (stack, a 32-byte standard LIFO stack), memory (memory, infinitely extending temporary byte array), Storage items (storage, permanent storage). On the temporary storage side, the alternative to stack and memory is a memory-only paradigm, or a mixture of registers and memory (there is not a big difference, and registers are essentially a kind of memory). In this case, each instruction has three parameters, for example:  ADD R1 R2 R3: M[R1] = M[R2] + M[R3] . The reason for choosing the stack paradigm is obvious. It reduces the code by 4 times.
  • The word size is 32 bytes : In most structures, such as Bitcoin, the word size is 4 or 8 bytes. 4 or 8 bytes are too restrictive for storage addresses and encryption calculations. Without restricting the size, it is difficult to establish a correspondingly safe gas model. 32 bytes is an ideal size, because it is enough to store the large values ​​and addresses required by many cryptographic algorithms, and it will not cause inefficiency because it is too large.
  • We have our own virtual machine : our virtual machine is developed in languages ​​such as java, Lisp and Lua. We think it is worthwhile to develop a professional virtual machine because: 1) Our VM specification is much simpler than many other virtual machines, because other virtual machines pay less for complexity, which means they are easier to change However, every additional bit of complexity in our scheme will bring obstacles to intensive development and bring potential security flaws, such as consensus errors, which makes our complexity cost high; 2 ) Our VM is more specialized, such as supporting 32 bytes; 3) We will not have complicated external dependencies, which will cause our installation to fail; 4) Complete review mechanism, which can be specific to special security requirements; Even if you use an external VM, you can’t save much work.
  • Use a variable and expandable memory size : a fixed memory size is an unnecessary restriction, and it is not appropriate to be too small or too large. If the memory size is fixed, every time you access the memory, you need to check whether the access exceeds the boundary. Obviously this is not efficient.
  • 1024 call depth limit : Many programming languages ​​crash because the call depth is too deep before the memory overflows. Therefore, it is not enough to use only the upper limit of block gas.
  • No type : just for brevity. However, DIV, SDIV, MOD, SMOD will use signed or unsigned opcodes (it turns out that for opcodes ADD and MUL, signed and unsigned are equivalent); conversion to fixed-point arithmetic in all The situation is very simple, for example, under the 32-bit length a * b -> (a * b) / 2^32, a / b -> a * 2^32 / b , +,-and * do not change under the integer.
  • ADDMOD, MULMOD : In most cases  mulmod(a, b, c) = a * b % c , but in the elliptic curve algorithm, 32-byte modulus arithmetic is used. Direct execution is  a * b % c actually executing  ((a * b) % 2^256) % c and will get completely different results. a * b % c The consensus of performing 32-byte numerical calculations in a 32-byte space is  very difficult and cumbersome.
  • SIGNEXTEND : The function of the SIGNEXTEND opcode is to facilitate the type conversion from a large signed integer to a small signed integer. Small signed integers are useful because future JIT virtual machines may be able to detect long-running code blocks that mainly deal with 32-byte integers. Small signed integers can speed up processing.
  • SHA3 : In the Ethereum code, SHA3 is widely used as a secure, high-strength, variable-length data hash mapping method. Generally, when using memory, you need to use the Hash function to prevent malicious conflicts, and you also need to use the Hash function when verifying Merkel trees and similar Ethereum data structures. It is important that hash functions similar to SHA3, such as SHA256, ECRECVOR, and RIPEM160, are not included in the form of opcodes, but in the form of pseudo contracts. The purpose of this is to put them in a separate category, if we later propose an appropriate “native plug-in” system, we can add more such contracts without the need for extended opcodes.
  • ORIGIN : The ORIGIN opcode is provided by the sender of the transaction, and its main function is to allow the contract to return the paid gas.
  • COINBASE : The main functions of COINBASE are: 1) Allow sub-currencies to contribute to network security; 2) Enable miners as a decentralized economy to set up sub-consensus-based applications, such as Schellingcoin.
  • PREVHASH : PREVHASH can be used as a semi-secure source of randomness. In addition, it allows the contract to evalute the Merkel tree state proof of the previous block without the need for a highly complex “Ethereum Light Client” recursive structure.
  • EXTCODESIZE, EXTCODECOPY : The main function is to let the contract check the code of other contracts based on the template, and even simulate them before interacting with other contracts. See:
  • JUMPDEST : When the jump destination is limited to a few indexes (especially, the computational complexity of the dynamic destination jump is O(log (the number of effective challenge destinations)), and the static jump is always constant), The JIT virtual machine is simpler to implement. Therefore, we need to: 1) limit the effective variable jump destinations; 2) encourage the use of static rather than dynamic jumps. In order to achieve these two goals, we have set the following rules: 1) The jump immediately after push can jump to any place, not just another jump; 2) Other jumps can only jump to JUMPDEST. The restriction on the jump is necessary, so that you can determine whether it is a static jump or a dynamic jump by looking at the previous operation in the code. The lack of demand for static jumps is what motivates their use. Prohibiting jumps into push data will also speed up the compilation and execution of the JIT virtual machine.
  • LOG : LOG is the log of events.
  • CALLCODE : This opcode allows the contract to use its own storage items to call the “functions” of other contracts in a separate stack space and memory. In this way, standard library codes can be flexibly implemented on the blockchain.
  • SELFDESTRUCT : Allow the contract to delete itself, provided it no longer needs to exist. SELFDESTRUCT is not executed immediately, but after the transaction is executed. This is because if SELFDESTRUCT is allowed to roll back after execution, it will greatly increase the complexity of the cache, which is not conducive to efficient VM implementation.
  • PC : Although PC opcode is not required in theory, because all instances of PC opcode can be implemented by adding the index of the push operation to the actual program counter instead, the location of independent code can be created using PC (copy and paste to other contracts) If they end with different indexes, they will not be interrupted).

Posted by:CoinYuppie,Reprinted with attribution to:
Coinyuppie is an open information publishing platform, all information provided is not related to the views and positions of coinyuppie, and does not constitute any investment and financial advice. Users are expected to carefully screen and prevent risks.

Like (0)
Donate Buy me a coffee Buy me a coffee
Previous 2021-07-09 10:50
Next 2021-07-09 10:52

Related articles