The gas cost of memory expansion is defined in the Yellow Paper
Appendix H, as follows,
G_memory is 3, and a
is the number of 256-bit words (int
s) allocated.
For a=24^2 this comes to 3 * 576 + 648 = 2,376. So it looks like memory cost is not your main problem.
It's much better to write a new virtual machine specifically for this task for several reasons:
Determinism
Ethereum, like all blockchains, is a trustless and decentralized network. Each node in the network must be able to validate all transactions and their code execution on their own. They have to do this to determine how much Ether each address owns after each transaction, and to decide whether or not to relay a transaction to other nodes. To accomplish this, all nodes have to agree with eachother what the exact execution flow of a contract execution was and what the state of the blockchain is.
For example, in the JVM you can request a random number, read a file or load data from the internet. These operations can return completely different results depending on which computer is executing them. They are therefore not deterministic. The JVM was not designed with determinism in mind. Most existing virtual machines do not guarantee determinism.
It is less work to write a new virtual machine from scratch than it would be to modify an existing virtual machine to fit the strict and precise requirements of Ethereum.
Execution speed
As mentioned before, something like the JVM comes loaded with lots of features that aren't really useful in the case of Ethereum. This can only serve to slow down the execution of smart contracts. The execution speed of smart contracts is crucial to make the network affordable to use. If a contract executes twice as slowly, it would cost twice the transaction fees to use it.
Security
The Ethereum virtual machine needs perfect security in very specific ways. For example, one contract should not be able to change the state of another contract. Using an existing virtual machine would be dubious because they were not written with Ethereum's special requirements in mind.
Measuring execution effort
In a system like Ethereum, one would like small transactions that take very few CPU cycles to have small transaction fees. Large transactions that do a lot of computation should cost more, proportionally. To accomplish this, you need to measure how much effort it took to execute a contract code. You can't just measure time or CPU cycles, because those are implementation and machine-dependent. We want all the nodes on the network to agree on exactly how much effort it took.
Therefore, Ethereum uses the unit gas
to measure the effort it took to execute a transaction. Each opcode in the EVM takes a certain universally agreed-upon amount of gas
.
This dynamic transaction fee system provides the necessary economic incentive to senders of transactions and writers of contracts to reduce the use of storage space and CPU time on all nodes.
Pretty much no existing virtual machines come with such a counter.
Binary size
Having less opcodes (only the ones needed for this specific purpose) means programs can be packed more tightly. This reduces blockchain size and transaction fees.
I hope this helps :-)
Best Answer
The EVM supports POP as an opcode, but that's not what you want. That just pops an item from the stack and discards it, which has nothing to specifically do with arrays. The feature you want, the ability to pop from an array and return the element, is something implemented in a high-level language, like Solidity or Vyper. There is no native support in Solidity to pop, and Vyper doesn't even support dynamic sized arrays, only fixed ones, so pop wouldn't even make sense. There aren't plans to support it afaik in either language. That said, it is very simple to do what you want without dropping into assembly, and with fewer LOC even: