koinos-mock-vm v1.0.3
koinos-mock-vm
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.
Requirements:
You need to install NodeJS v16 or higher download
Installation:
# with npm
npm install -g koinos-mock-vm
# with yarn
yarn global add koinos-mock-vmInteract with the 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_typewith theint32_valueproperty set with the entry point - used by the system call
get_entry_point
- object of type
contract_arguments:- object of type
bytesset with the contract arguments - used by the system call
get_contract_argument
- object of type
contract_result:- object of type
bytesset with the contract result - used by the system call
set_contract_result
- object of type
contract_id:- object of type
bytesset with the contract id - usde by the system call
get_contract_id
- object of type
head_info:- object of type
koinos.chain.head_infoset with the head info - used by the system call
get_head_info
- object of type
caller:- object of type
koinos.chain.caller_dataset with the caller data info - used by the system call
get_caller
- object of type
last_irreversible_block:- object of type
koinos.chain.value_typewith theuint64_valueproperty 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.transactionset with the transaction info - used by the system calls
get_transactionandget_transaction_field
- object of type
block:- object of type
koinos.protocol.blockset with the block info - used by the system calls
get_blockandget_block_field
- object of type
authority:- object of type
koinos.chain.list_type. Eachkoinos.chain.value_typeelements represent an authorization:int32_value: value of thekoinos.chain.authorization_typebytes_value: bytes of the account addressbool_value: "autorized" boolean
- used by the system call
require_authority:- will use the
require_authorityarguments (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_typeelements 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_typeto return a call result. The call contract results are FIFO meaning that the firstcall_contractwill 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_typehas itsstring_valueset with a log - used by the system call
log
- object of type
events:- object of type
koinos.chain.list_type. Eachkoinos.chain.value_typehas itsbytes_valueset with akoinos.protocol.event_dataobject - 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
begin_transaction:- whatever object as argument
- will start a database transaction (useful when trying to build unit tests around transaction reversions)
- it basically backs up the database so that ic can be rolledback to the backedup state if the transaction reverts
rollback_transaction:- whatever object as argument
- will restore the backup made via
begin_transaction
commit_transaction:- whatever object as argument
- will clear the backup made via
begin_transaction(hence make it impossible to rollback)
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: 1DQzuCcTKacbs9GGScRTU1Hc8BsyARTPqeUsage as a CLI
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>Usage as a NodeJS package
See index.js file in the bin folder.
CLI Example
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