MCPcopy Index your code
hub / github.com/ava-labs/xsvm

github.com/ava-labs/xsvm @v1.0.3

Chat with this repo
repository ↗ · DeepWiki ↗ · release v1.0.3 ↗ · + Follow
221 symbols 572 edges 44 files 10 documented · 5%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Cross Subnet Virtual Machine (XSVM)

Cross Subnet Asset Transfers README Overview

Background

Introduction

Usage

Running

Demo

Avalanche Subnets and Custom VMs

Avalanche is a network composed of multiple sub-networks (called subnets) that each contain any number of blockchains. Each blockchain is an instance of a Virtual Machine (VM), much like an object in an object-oriented language is an instance of a class. That is, the VM defines the behavior of the blockchain where it is instantiated. For example, Coreth (EVM) is a VM that is instantiated by the C-Chain. Likewise, one could deploy another instance of the EVM as their own blockchain (to take this to its logical conclusion).

AvalancheGo Compatibility

[v1.0.3] AvalancheGo@v1.9.9
[v1.0.2] AvalancheGo@v1.9.6-v1.9.8
[v1.0.1] AvalancheGo@v1.9.5
[v1.0.0] AvalancheGo@v1.9.5

Introduction

Just as Coreth powers the C-Chain, XSVM can be used to power its own blockchain in an Avalanche Subnet. Instead of providing a place to execute Solidity smart contracts, however, XSVM enables asset transfers for assets originating on it's own chain or other XSVM chains on other subnets.

How it Works

XSVM utilizes AvalancheGo's teleporter package to create and authenticate Subnet Messages.

Transfer

If you want to send an asset to someone, you can use a tx.Transfer to send to any address.

Export

If you want to send this chain's native asset to a different subnet, you can use a tx.Export to send to any address on a destination chain. You may also use a tx.Export to return the destination chain's native asset.

Import

To receive assets from another chain's tx.Export, you must issue a tx.Import. Note that, similarly to a bridge, the security of the other chain's native asset is tied to the other chain. The security of all other assets on this chain are unrelated to the other chain.

Fees

Currently there are no fees enforced in the XSVM.

xsvm

Install

git clone https://github.com/ava-labs/xsvm.git;
cd xsvm;
go install -v ./cmd/xsvm;

Usage

Runs an XSVM plugin

Usage:
  xsvm [flags]
  xsvm [command]

Available Commands:
  account     Displays the state of the requested account
  chain       Manages XS chains
  completion  Generate the autocompletion script for the specified shell
  help        Help about any command
  issue       Issues transactions
  version     Prints out the version

Flags:
  -h, --help   help for xsvm

Use "xsvm [command] --help" for more information about a command.

Golang SDK

// Client defines xsvm client operations.
type Client interface {
  Network(
    ctx context.Context,
    options ...rpc.Option,
  ) (uint32, ids.ID, ids.ID, error)
  Genesis(
    ctx context.Context,
    options ...rpc.Option,
  ) (*genesis.Genesis, error)
  Nonce(
    ctx context.Context,
    address ids.ShortID,
    options ...rpc.Option,
  ) (uint64, error)
  Balance(
    ctx context.Context,
    address ids.ShortID,
    assetID ids.ID,
    options ...rpc.Option,
  ) (uint64, error)
  Loan(
    ctx context.Context,
    chainID ids.ID,
    options ...rpc.Option,
  ) (uint64, error)
  IssueTx(
    ctx context.Context,
    tx *tx.Tx,
    options ...rpc.Option,
  ) (ids.ID, error)
  LastAccepted(
    ctx context.Context,
    options ...rpc.Option,
  ) (ids.ID, *block.Stateless, error)
  Block(
    ctx context.Context,
    blkID ids.ID,
    options ...rpc.Option,
   (*block.Stateless, error)
  Message(
    ctx context.Context,
    txID ids.ID,
    options ...rpc.Option,
  ) (*teleporter.UnsignedMessage, []byte, error)
}

Public Endpoints

xsvm.network

<<< POST
{
  "jsonrpc": "2.0",
  "method": "xsvm.network",
  "params":{},
  "id": 1
}
>>> {"networkID":<uint32>, "subnetID":<ID>, "chainID":<ID>}

For example:

curl --location --request POST 'http://34.235.54.228:9650/ext/bc/28iioW2fYMBnKv24VG5nw9ifY2PsFuwuhxhyzxZB5MmxDd3rnT' \
--header 'Content-Type: application/json' \
--data-raw '{
    "jsonrpc": "2.0",
    "method": "xsvm.network",
    "params":{},
    "id": 1
}'

{"jsonrpc":"2.0","result":{"networkID":1000000,"subnetID":"2gToFoYXURMQ6y4ZApFuRZN1HurGcDkwmtvkcMHNHcYarvsJN1","chainID":"28iioW2fYMBnKv24VG5nw9ifY2PsFuwuhxhyzxZB5MmxDd3rnT"},"id":1}

xsvm.genesis

<<< POST
{
  "jsonrpc": "2.0",
  "method": "xsvm.genesis",
  "params":{},
  "id": 1
}
>>> {"genesis":<genesis file>}

xsvm.nonce

<<< POST
{
  "jsonrpc": "2.0",
  "method": "xsvm.nonce",
  "params":{
    "address":<cb58 encoded>
  },
  "id": 1
}
>>> {"nonce":<uint64>}

xsvm.balance

<<< POST
{
  "jsonrpc": "2.0",
  "method": "xsvm.balance",
  "params":{
    "address":<cb58 encoded>,
    "assetID":<cb58 encoded>
  },
  "id": 1
}
>>> {"balance":<uint64>}

xsvm.loan

<<< POST
{
  "jsonrpc": "2.0",
  "method": "xsvm.loan",
  "params":{
    "chainID":<cb58 encoded>
  },
  "id": 1
}
>>> {"amount":<uint64>}

xsvm.issueTx

<<< POST
{
  "jsonrpc": "2.0",
  "method": "xsvm.issueTx",
  "params":{
    "tx":<bytes>
  },
  "id": 1
}
>>> {"txID":<cb58 encoded>}

xsvm.lastAccepted

<<< POST
{
  "jsonrpc": "2.0",
  "method": "xsvm.lastAccepted",
  "params":{},
  "id": 1
}
>>> {"blockID":<cb58 encoded>, "block":<json>}

xsvm.block

<<< POST
{
  "jsonrpc": "2.0",
  "method": "xsvm.block",
  "params":{
    "blockID":<cb58 encoded>
  },
  "id": 1
}
>>> {"block":<json>}

xsvm.message

<<< POST
{
  "jsonrpc": "2.0",
  "method": "xsvm.message",
  "params":{
    "txID":<cb58 encoded>
  },
  "id": 1
}
>>> {"message":<json>, "signature":<bytes>}

Running the VM

To build the VM, run ./scripts/build.sh.

Deploying Your Own Network

Anyone can deploy their own instance of the XSVM as a subnet on Avalanche. All you need to do is compile it, create a genesis, and send a few txs to the P-Chain.

You can do this by following the subnet tutorial or by using the subnet-cli.

Cross Subnet Transaction Example

The following example shows how to interact with the XSVM to send and receive native assets across subnets.

Overview of Steps

  1. Create & deploy Subnet A
  2. Create & deploy Subnet B
  3. Issue an export Tx on Subnet A
  4. Issue an import Tx on Subnet B
  5. Confirm Txs processed correctly

Note: This demo requires avalanche-cli version > 1.0.5, xsvm version > 1.0.2 and avalanche-network-runner v1.3.5.

Create and Deploy Subnet A, Subnet B

Using the avalanche-cli, this step deploys two subnets running the XSVM. Subnet A will act as the sender in this demo, and Subnet B will act as the receiver.

Steps

Build the XSVM

Create a genesis file

xsvm chain genesis --encoding binary > xsvm.genesis

Create Subnet A and Subnet B

avalanche subnet create subnetA --custom --genesis <path_to_genesis> --vm <path_to_vm_binary>
avalanche subnet create subnetB --custom --genesis <path_to_genesis> --vm <path_to_vm_binary>

Deploy Subnet A and Subnet B

avalanche subnet deploy subnetA --local
avalanche subnet deploy subnetB --local

Issue Export Tx from Subnet A

The SubnetID and ChainIDs are stored in the sidecar.json files in your avalanche-cli directory. Typically this is located at $HOME/.avalanche/subnets/

xsvm issue export --source-chain-id <SubnetA.BlockchainID> --amount <export_amount> --destination-chain-id <SubnetB.BlockchainID>

Save the TxID printed out by running the export command.

Issue Import Tx from Subnet B

Note: The import tx requires snowman++ consensus to be activated on the importing chain. A chain requires ~3 blocks to be produced for snowman++ to start. Run xsvm issue transfer --chain-id <SubnetB.BlockchainID> --amount 1000 to issue simple Txs on SubnetB

xsvm issue import --source-chain-id <SubnetA.BlockchainID> --destination-chain-id <SubnetB.BlockchainID> --tx-id <exportTxID> --source-uris <source_uris>

The can be found by running avalanche network status. The default URIs are "http://localhost:9650,http://localhost:9652,http://localhost:9654,http://localhost:9656,http://localhost:9658"

Account Values To check proper execution, use the xsvm account command to check balances.

Verify the balance on SubnetA decreased by your export amount using

xsvm account --chain-id <SubnetA.BlockchainID>

Now verify chain A's assets were successfully imported to SubnetB

xsvm account --chain-id <SubnetB.BlockchainID> --asset-id <SubnetA.BlockchainID>

Extension points exported contracts — how you extend this code

Server (Interface)
Server defines the xsvm API server. [2 implementers]
api/server.go
Client (Interface)
Client defines the xsvm API client. [2 implementers]
api/client.go
Unsigned (Interface)
(no doc) [3 implementers]
tx/unsigned.go
Visitor (Interface)
(no doc) [2 implementers]
tx/visitor.go
Chain (Interface)
(no doc) [1 implementers]
chain/chain.go
Block (Interface)
(no doc) [1 implementers]
chain/block.go
Builder (Interface)
(no doc) [1 implementers]
builder/builder.go

Core symbols most depended-on inside this repo

New
called by 20
factory.go
Flatten
called by 12
state/keys.go
DecreaseBalance
called by 6
state/storage.go
Bytes
called by 5
chain/block.go
NewClient
called by 5
api/client.go
GetBlock
called by 4
state/storage.go
Nonce
called by 4
api/client.go
ID
called by 4
tx/tx.go

Shape

Method 106
Function 70
Struct 38
Interface 7

Languages

Go100%

Modules by API surface

api/server.go36 symbols
vm.go23 symbols
state/storage.go21 symbols
api/client.go21 symbols
chain/block.go16 symbols
chain/chain.go12 symbols
builder/builder.go9 symbols
tx/tx.go5 symbols
execute/expects_context.go5 symbols
tx/visitor.go4 symbols
tx/payload.go4 symbols
genesis/genesis.go4 symbols

For agents

$ claude mcp add xsvm \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page