AIP: 81 Title: CORE-VM module specifications Authors: Kristjan Kosic Status: Draft, Rejected or Active Discussions-To: https://github.com/arkecosystem/AIPS/issues/81 Address: Ark address used to collect votes for the specific AIP Type: Standards Category only required for Standards Track: Created: 2019-04-09 Last Update: 2019-05-08 Requires: AIP-11, AIP-18, AIP-29 Replaces: AIP-12
Table of Contents
- -
- Check items list/Questions/To Address
- Motivation
- Technical Specification(initial/will be further updated/aligned with reference implementation)
- Reference implementation
- References
The purpose of this document is to define specifications and expectations related to building ARK VM in terms of ARK’s technology stack, namely running as a core-plugin and enabling virtual machine execution inside a core-module.
- AIP: define transaction outside of core-mode, e.g. inside our new module (store contract transaction)
- Size, memory, execution stack limitations
- Size of script
- Number and size of storage options
- Private smart-contracts (e.g. whitelisting addresses)
- Rebuild from zero - saving data on the blockchain
- Storage
The goal of this AIP is to enable script execution inside the core
technology landscape and run this as a module, if enabled.
In comparison to AIP-29 that provides custom application logic in the form of scripts/smart-contracts delivered via plugin. This introduces a difference between trust-less execution or internal transfers and state and "normal" transaction broadcast (transfer transaction validation and execution), such as:
- no special plugin installation and deployment is needed for ark-script to work
- modifications are possible via REST endpoints, no need for node operators to manage and update plugin logic
- automated trust-less execution
- AIP-29 requires transactions to be signed/emitted to the network, thus making automated execution of secure functionalities (internal transfers) a bit more difficult as compared to the
internal calls
that change state while being executed (for example as with ETH smart contracts). This adds additional layer of security, as every transaction needs to be signed. By doing so we limit the automation capability of trust-less execution. - state storage - custom transaction implementation via AIP-29 introduces options for additional storage, but is still limited within its implementation and replication capabilities (related to transaction type). By introducing a new VM Engine we need to introduce script state storage. Storage must be fully deterministic via blockchain replay logic.
Pros | Cons |
---|---|
javascript / typescript codebase | running VM environment not as big as ETH |
isolated running environment | rebuilding logic/protocol level |
adding custom behavior in our control (destroy contract, retire) | tooling? |
allowing more functionality inside script instead of introducing new tx types for each new functionality/or plugin deployment | |
no need to run a sidechain (less issues when searching for delegates) | |
The goal of this proposal is to launch VM engine inside the core
technology landscape and run it as a module, if enabled. Looking further at the virtual machine life-cycle and core execution lifecycle we have the following interaction points with our core.
A smart contract can be thought of as an script, as it is both, an Application and supports decentralized execution. SmartContracts can be invoked when a transaction is added to a blockchain (e.g. sending funds to a specifics smart contract address with parameters). Besides running in a decentralized way and supporting transfer of funds via internal message calls, smart contracts also support storing of state data related to script execution.
Deployment stage introduces new transaction types (see below). Deployment stage must validate, test, store new script. Introducing of new transaction types will be needed.
Smart contract/script deployment consists of several steps:
- compiling the contract
- validating the contract
Script execution during block creation stage. A script function call is sent via script call transaction.
script is executed inside the virtual-machine(isolated-vm
) thus changing the state/storage options.
For the execution engine we looked at several options, but wanted to stay on the javascript
code base. The following isolated environments where taken into account:
- Isolated-VM - https://github.com/laverdet/isolated-vm (based on first research, looks like the most viable and secure option - using Google's V8 OSS JavaScript Engine)
- VM2 - https://github.com/patriksimek/vm2 (used in desktop wallet)
- NodeJs VM - https://nodejs.org/api/vm.html. (basic and limited functionality of nodejs)
VM execution engine was selected based on the security and memory management and overall execution in an isolated environment. State should be passed into the vm
and used as
the current source of truth. Currently the best candidate is isolated-vm
.
Virtual Machine will introduce a new storage option for scripts to store state in a secure and distributed way. A Light key-value database can be used, as state can be reproduced via rebuild - from transactions (blockchain replay). All script calls need to be stored (calls and parameters) so we can replay and execute on each node (part of protocol).
- core-blockchain
- core-state
script data history (any calls with all the details) must be saved on the blockchain. We could use our asset field where we store this. Add the execution/loading logic into SPV process, when chain is validated and rebuilt from 0.
- size limitations related to overall script size
- memory usage limitations
- isolated running environments per script
- memory limitations
- CPU time limitations (
while (true) {}
limit)
- strict logging of outcomes
- rebuilding relevant data must be added on the blockchain
- a separate execution log of the VM engine
- sandboxed environment
- timeout
- limited number of operations and execution scope
- private contracts (limited by white-listed senders)
- general class implementation / as guideline and access to blockchain (wallet-manager)
General timeout for all execution points. Has to be “executed” in a predefined timeout. Confirmation and compilation stage will be done in the deployment phase.
The technical specification should describe the syntax and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations.
THIS IS WIP, AND IT WILL CHANGE ALONG THE LINES AS REFERENCE IMPLEMENTATION CHANGES
New transaction types need to be implemented in order to support interaction with the blockchain in terms of sending/loading script to the blockchain and giving possibilities to call the smart contract methods. This part references AIP-12 and continues on the definition of new transaction types related to dApp deployment and calling of their methods (execution).
Transaction type scriptDeployment will send dApp payload to the chain post/transactions
endpoint.
script developer implements dApp following the predefined interface provided from core-vm
. SmartContract interface defines the structure and the methods an ARK smart contract must implement, as well as access to super class (TBD/Link).
A return value is status of script deployment, and return address if successfully deployed.
Size of the source code and duration of compilation(computing power needed) will be taken into account. Dynamic fee will be strongly affected by size.
Description | Size | Sample |
---|---|---|
type | ||
fee | ||
interface | var | |
source-code | var |
- interface - descriptions and definition of public script methods, that will be available via message call functionality
- source code - javascript source code to be compiled and run
Also think about saving already compiled VM script - to save on blockchain size?
When script Deployment transaction enters the pool, we test it against internal compiled method from the virtual machine. If script is successfully compiled we accept it into the pool and it will be forged when its turn. If not we will return error code to the user sending the dApp.
When transaction is successfully deployed, it holds all the required information for anyone to execute the script (if allowed by the contract code).
Description | Size | Sample |
---|---|---|
type | ||
fee | ||
amount | ||
contract-address | ||
method-name | ||
arguments |
- contract-address
- method-name (name of one of the methods specified via abi)
- arguments (k/v pairs of arguments accepted by script call). Must be aligned with dApp abi specifications
- Integrate
isolated-vm
in the new plugincore-vm
- Implement first sync mechanism to share state
- Solve - return call logic (to provide a base for internal calls and execution)
- Make basic code run
- Sync Variables
- Initialize a class
- Run methods from class
- Save data to common storage/outside of secure execution - just return
- Prepare internal transaction calls - based on script output
One of the decision to use isolated-vm
was also to ensure deterministic execution on all nodes/hardware configurations. We will introduce the same logic as we have in the transaction validation mechanism:
- internal message call
internal-trans action
will be a function injected into thevirtual-machine
engine at bootstrap time - store value call
save-value
will be injected during the bootstrap process
// Get a Reference{} to the global object within the context.
let jail = context.global;
// This make the global object available in the context as `global`. We use `derefInto()` here
// because otherwise `global` would actually be a Reference{} object in the new isolate.
jail.setSync('global', jail.derefInto());
// The entire ivm module is transferable! We transfer the module to the new isolate so that we
// have access to the library from within the isolate.
jail.setSync('_ivm', ivm);
// We will create a basic `log` function for the new isolate to use.
jail.setSync('_internalTransfer', new ivm.Reference(function(...args) {
// WalletManager logic here
console.log(...args);
}));
// We will create a basic `log` function for the new isolate to use.
jail.setSync('_storeValue', new ivm.Reference(function(...args) {
// Storage logic here (also via wallet manager)
console.log(...args);
}));
// This will bootstrap the context.
let bootstrap = isolate.compileScriptSync('new '+ function() {
// Grab a reference to the ivm module and delete it from global scope. Now this closure is the
// only place in the context with a reference to the module. The `ivm` module is very powerful
// so you should not put it in the hands of untrusted code.
let ivm = _ivm;
delete _ivm;
// Now we create the other half of the `log` function in this isolate. We'll just take every
// argument, create an external copy of it and pass it along to the log function above.
let internalTransfer = _internalTransfer;
delete _internalTransfer;
global.internalTransfer = function(...args) {
internalTransfer.applySync(undefined, args.map(arg => new ivm.ExternalCopy(arg).copyInto()));
};
let storeValue = _storeValue;
delete _storeValue;
global.storeValue = function(...args) {
storeValue.applySync(undefined, args.map(arg => new ivm.ExternalCopy(arg).copyInto()));
};
});
// we execute and share running environments
bootstrap.runSync(context);
script will be deployed as a normal javascript(transpiled typescript) source-code to the core. Both options can be supported. This will give use the power to leverage the huge community of js/ts developers.
- Determine to be run locally or on the node/ currently node is preferred / possible errors can be returned?
- Additional tooling support
- Output results of script execution are storage updates or transaction execution - transfer from contract to another contract or normal address.
- We will be running already pre-compiled scripts (execution time)
Based on research and some demo stuff, currently isolated-vm
looks like most promising.
- https://github.com/kristjank/virtual-machine/
- https://github.com/kristjank/virtual-machine/packages/core-vm
MIT License
- Ethereum notes for outgoing transaction https://ethereum.stackexchange.com/questions/24031/how-ethereum-contracts-transfer-ether-without-a-blockchain-confirmation
- https://www.mobilefish.com/developer/blockchain/blockchain_quickguide_ethereum_related_tutorials.html
- https://github.com/takenobu-hs/ethereum-evm-illustrated
- https://ethereum.stackexchange.com/questions/20781/at-which-point-the-smart-contracts-get-executed
- https://ethereum.stackexchange.com/questions/765/what-is-the-difference-between-a-transaction-and-a-call
- https://github.com/laverdet/isolated-vm
- https://github.com/gianluca-venturini/isolated-vm-actors/blob/master/src/index.ts
- https://v8.dev
- https://v8docs.nodesource.com/