Skip to content

Instantly share code, notes, and snippets.

@no-defun-allowed
Last active May 3, 2022 13:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save no-defun-allowed/329d4c083c14b537bab4f8d251f7d938 to your computer and use it in GitHub Desktop.
Save no-defun-allowed/329d4c083c14b537bab4f8d251f7d938 to your computer and use it in GitHub Desktop.
An unfair comparison of Ethereum VM mishaps to Netfarm's VM

Looking through the "checklist" on https://news.ycombinator.com/item?id=14691212. I think I made it out alive.

  1. Everything is 256 bits wide, including the "byte" type. This means that whilst byte[] is valid syntax, it will take up 32x more space than you expect. Storage space is extremely limited in Solidity programs. You should use "bytes" instead which is an actual byte array. The native 256-bit wide primitive type is called "bytes32" but the actual 8-bit wide byte type is called "int8".

Object size is an implementation detail.

  1. Strings. What can we say about this. There is a string type. It is useless. There is no support for string manipulation at all. String concatenation must be done by hand after casting to a byte array. Basics like indexOf() must also be written by hand or implementations copied into your program. To even learn the length of a string you must cast it to a byte array, but see above. In some versions of the Solidity compiler passing an empty string to a function would cause all arguments after that string to be silently corrupted.

There is a string type, and I hope it is not useless. Instruction #103 (string-append) concatenates a list of strings together, without any casting. Also #101 (string-length) and #102 (string-ref); though strings are immutable.

  1. There is no garbage collector. Dead allocations are never reclaimed, despite the scarcity of available memory space. There is also no manual memory management.

There is only garbage collection. I guess, given that scripts are short lived, and allocations are proportional to the "cycle" count, you could use an arena. But GC lets you share and hash-cons to your heart's content.

  1. Solidity looks superficially like an object oriented language. There is a "this" keyword. However there are actually security-critical differences between "this.setX()" and "setX()" that can cause wrong results: ethereum/solidity#583

Using a local function ((f x)) is more different to calling a method ((call-method 'foo receiver x)). Netfarm does have the "implicit transaction" idea, where add/remove-computed-value effects are ignored if the method generating them unwound, still. The issue nonetheless is that, would a function and a method have the same code, a function call will have the same value of (sender) in the caller and callee, whereas a method call to (self) will not.

  1. Numbers. Despite being intended for financial applications like insurance, floating point is not supported. Integer operations can overflow, despite the underlying operation being interpreted and not implemented in hardware. There is no way to do overflow-checked operations: you need constructs like require((balanceOf[_to] + _value) >= balanceOf[_to]);

You only get (signed-byte 256) integers, and overflows cause the script to crash.

  1. You can return statically sized arrays from functions, but not variably sized arrays.

No arrays here.

  1. For loops are completely broken. Solidity is meant to look like JavaScript but the literal 0 type-infers to byte, not int. Therefore "for (var i = 0; i < a.length; i ++) { a[i] = i; }" will enter an infinite loop if a[] is longer than 255 elements, because it will wrap around back to zero. This is despite the underlying VM using 256 bits to store this byte. You are just supposed to know this and write "uint" instead of "var".

Again, only one integer type; and I'll wait until someone blows a 256-bit counter.

  1. Arrays. Array access syntax looks like C or Java, but array declaration syntax is written backwards: int8[][5] creates 5 dynamic arrays of bytes. Dynamically sized arrays work, in theory, but you cannot create multi-dimensional dynamic arrays. Because "string" is a byte array, that means "string[]" does not work.

No array declaration syntax.

  1. The compiler is riddled with mis-compilation bugs, many of them security critical. The documentation helpfully includes a list of these bugs .... in JSON. The actual contents of the JSON is of course just strings meant to be read by humans. Here are some summaries of miscompile bugs:

I am not aware of any bugs; which perhaps is not a good thing, but the Slacker compiler is pretty simple, and doesn't optimise.

  1. In some situations, the optimizer replaces certain numbers in the code with routines that compute different numbers

No optimiser here.

  1. Types shorter than 32 bytes are packed together into the same 32 byte storage slot, but storage writes always write 32 bytes. For some types, the higher order bytes were not cleaned properly, which made it sometimes possible to overwrite a variable in storage when writing to another one.

We don't pack types, because there is no VM-level concept of object layout.

  1. Dynamic allocation of an empty memory array caused an infinite loop and thus an exception

No arrays here, but that wouldn't happen unless the VM was broken, since allocation is a VM "service" in Netfarm.

  1. Access to array elements for arrays of types with less than 32 bytes did not correctly clean the higher order bits, causing corruption in other array elements.

This also would not happen in Netfarm.

As you can see the decision to build a virtual machine with that is natively 256-bit wide led to a huge number of bugs whereby reads or writes randomly corrupt memory. Solidity/EVM is by far the worst programming environment I have ever encountered. It would be impossible to write even toy programs correctly in this language, yet it is literally called "Solidity" and used to program a financial system that manages hundreds of millions of dollars.

Agreed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment