Koinos-Mock-VM is a NodeJS application/package that allows you to run WASM Koinos smart contracts without deploying the contracts to the Koinos blockchain. It is a tool that you can leverage to build unit tests for your smart contracts.
You need to install NodeJS v16 or higher download
# with npm
npm install -g @roamin/koinos-mock-vm
# with yarn
yarn global add @roamin/koinos-mock-vm
koinos-mock-vm leverages the Koinos system calls to enable a wasm contract to interact with the mock vm, which means that any
Koinos wasm contract can use it out of the box.
The put_object
system call is used to insert mock data in the database powering the mock vm. When calling a system call, like get_entry_point
, the mock vm will pull the mock data that was initially set in the database.
The metadata system space is used to store the mock data. (space zone = "", space id = 0, system = true)
List of keys used to store the mock data:
entry_point
:- object of type
koinos.chain.value_type
with theint32_value
property set with the entry point - used by the system call
get_entry_point
- object of type
contract_arguments
:- object of type
bytes
set with the contract arguments - used by the system call
get_contract_argument
- object of type
contract_result
:- object of type
bytes
set with the contract result - used by the system call
set_contract_result
- object of type
contract_id
:- object of type
bytes
set with the contract id - usde by the system call
get_contract_id
- object of type
head_info
:- object of type
koinos.chain.head_info
set with the head info - used by the system call
get_head_info
- object of type
caller
:- object of type
koinos.chain.caller_data
set with the caller data info - used by the system call
get_caller
- object of type
last_irreversible_block
:- object of type
koinos.chain.value_type
with theuint64_value
property set with the last irreversible block height - used by the system call
get_last_irreversible_block
- object of type
transaction
:- object of type
koinos.protocol.transaction
set with the transaction info - used by the system calls
get_transaction
andget_transaction_field
- object of type
operation
:- object of type
koinos.protocol.operation
set with the operation info - used by the system calls
get_operation
- object of type
block
:- object of type
koinos.protocol.block
set with the block info - used by the system calls
get_block
andget_block_field
- object of type
authority
:- object of type
koinos.chain.list_type
. Eachkoinos.chain.value_type
elements represent an authorization:int32_value
: value of thekoinos.chain.authorization_type
bytes_value
: bytes of the account addressbool_value
: "autorized" boolean
- used by the system call
require_authority
:- will use the
require_authority
arguments (type and account) to lookup the autorization in the previously setkoinos.chain.list_type
- will use the
- object of type
call_contract_results
:- object of type
koinos.chain.list_type
. Eachkoinos.chain.value_type
elements represent a contract call result:bytes_value
: bytes of the contract call result
- used by the system call
call_contract
:- will use the previously set
koinos.chain.list_type
to return a call result. The call contract results are FIFO meaning that the firstcall_contract
will use the first element you set in the list, the second call the second element in the list, etc...
- will use the previously set
- object of type
logs
:- object of type
koinos.chain.list_type
. Eachkoinos.chain.value_type
has itsstring_value
set with a log - used by the system call
log
- object of type
events
:- object of type
koinos.chain.list_type
. Eachkoinos.chain.value_type
has itsbytes_value
set with akoinos.protocol.event_data
object - used by the system call
event
- object of type
exit_code
:- object of type
koinos.chain.exit_contract_arguments
- used by the system call
exit_contract
- object of type
The following keys are additional commands that allow you to interact with the mock vm's database:
reset
:- whatever object as argument
- will reset the database
rollback_transaction
:- whatever object as argument
- will restore the backup made in the previous
commit_transaction
commit_transaction
:- whatever object as argument
- will save a backup of the actual state of the database (useful when trying to build unit tests around transaction reversions)
Example for setting the contract id in an AssemblyScript Koinos smart contract:
const metadataSpace = new chain.object_space();
metadataSpace.system = true;
metadataSpace.id = 0;
System.putBytes(metadataSpace, 'contract_id', Base58.decode('1DQzuCcTKacbs9GGScRTU1Hc8BsyARTPqe'));
const contractId = System.getContractId();
System.log('contractId: ' + Base58.encode(contractId));
// will print contractId: 1DQzuCcTKacbs9GGScRTU1Hc8BsyARTPqe
You can execute multiple smart contracts in one run, they will be executed in the order they appear in the command parameters. The koinos-mock-vm database will be shared between each execution allowing you to build complex executions cases that involve several contracts.
koinos-mock-vm <path to contract wasm 1> <path to contract wasm 2> ... <path to contract wasm n>
See index.js
file in the bin
folder.
koinos-mock-vm contract.wasm
[Starting VM] 1 contracts to execute
[Execution started] contract.wasm
[Log] entryPoint: 3282800625
[Log] contract_arguments: myArgs
[Log] contract_id: 1DQzuCcTKacbs9GGScRTU1Hc8BsyARTPqe
[Execution completed] in 16.232577ms contract.wasm
[Stopping VM] exit code 0