Skip to content

Pluggable VM: A Solidity VM Alternative

All transactions on the blockchain are processed by a central “brain”, which by default is a component called the Ethereum Virtual Machine (“EVM”). The EVM works well for processing most smart contracts; however, there may be some circumstances where a user would want to select an alternate way of processing the transaction information. STRATO contains an alternate “pluggable” VM which is Solidity-based (called SolidVM), which can also be selected as the interpreter for the contract.

Why Introduce a New VM?

Some key differences with the SolidVM:

  1. All data types are variable length (int, string, bytes can all take data of an arbitrary length, and are not limited to 32 bytes, etc). To avoid dangerous overflow conditions, we deliberately do not support fixed length types like int8, etc.
  2. Function arguments and variables are not limited by the 16 stack limit.
  3. Solidity contracts are stored and viewable in their original format.
  4. SolidVM processes Solidity faster, leading to faster transaction times for complex Solidity contracts.
  5. Solidity events are logged in the Cirrus database. Each unique Solidity Event in a contract has a corresponding table in the database, and every time an instance of that event is emitted, a row is added to the table.

How to Select SolidVM as a Contract's VM

To select which VM is used to process the contract, you will need to pass a metadata parameter "metadata":{"VM": "SolidVM"} when first creating the contract on the blockchain, like this:

curl -d'{"src": "<sourceCode>", "metadata":{"VM": "SolidVM"}, "password": "<password>"}' -H "Content-Type: application/json" http://localhost/bloc/v2.2/users/:username/:address/contract?resolve

To enable this feature to an application that uses the block-apps rest framework tool, you would include this option in the options parameter passed in when making the call to create a contract. Example:

  // read Solidity source
  const simpleStorageSrc = fsUtil.get("SimpleStorage.sol");

  const contractArgs = {
    name: 'SimpleStorage',
    source: simpleStorageSrc,
    args: {}, // Any constructor args would go here. We dont have any.
  }

  const solidVMOptions = {
    ...options,
    VM: 'SolidVM'
  }

  // Use the STRATO identity to upload our contract
  const contract = await rest.createContract (stratoUser, contractArgs, solidVMOptions)

To select the VM using the API, we need to add this VM option to the transaction metadata. Example:

curl -X POST \
  -H "authorization: Bearer <token>" \
  --data '{
    "txs": [
        {
          "payload": {
            "contract": "SimpleStorage",
            "src": "<contract-src>",
            "args": {}
          },
          "metadata": {
            "VM": "SolidVM"
          },
          "type": "CONTRACT"
        }
      ],
      "txParams": {
        "gasLimit": 32100000000,
        "gasPrice": 1
      }
    }' \
  "http://<strato_host_address>/strato/v2.3/transaction?resolve=true"

Notes:

  1. If no VM is specified in options, STRATO used the EVM by default
  2. When calling methods on a smart contract that was uploaded using SolidVM, all function calls must also include the VM:'SolidVM' member in their options parameter.