github.com/MetalBlockchain/metalgo@v1.11.9/vms/example/xsvm/README.md (about)

     1  # Cross Subnet Virtual Machine (XSVM)
     2  
     3  Cross Subnet Asset Transfers README Overview
     4  
     5  [Background](#avalanche-subnets-and-custom-vms)
     6  
     7  [Introduction](#introduction)
     8  
     9  [Usage](#how-it-works)
    10  
    11  [Running](#running-the-vm)
    12  
    13  [Demo](#cross-subnet-transaction-example)
    14  
    15  ## Avalanche Subnets and Custom VMs
    16  
    17  Avalanche is a network composed of multiple sub-networks (called [subnets][Subnet]) that each contain any number of blockchains. Each blockchain is an instance of a [Virtual Machine (VM)](https://docs.avax.network/learn/platform-overview#virtual-machines), 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)][Coreth] 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).
    18  
    19  ## Introduction
    20  
    21  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 its own chain or other XSVM chains on other subnets.
    22  
    23  ## How it Works
    24  
    25  XSVM utilizes AvalancheGo's [teleporter] package to create and authenticate Subnet Messages.
    26  
    27  ### Transfer
    28  
    29  If you want to send an asset to someone, you can use a `tx.Transfer` to send to any address.
    30  
    31  ### Export
    32  
    33  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.
    34  
    35  ### Import
    36  
    37  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.
    38  
    39  ### Fees
    40  
    41  Currently there are no fees enforced in the XSVM.
    42  
    43  ### xsvm
    44  
    45  #### Install
    46  
    47  ```bash
    48  git clone https://github.com/ava-labs/avalanchego.git;
    49  cd avalanchego;
    50  go install -v ./vms/example/xsvm/cmd/xsvm;
    51  ```
    52  
    53  #### Usage
    54  
    55  ```
    56  Runs an XSVM plugin
    57  
    58  Usage:
    59    xsvm [flags]
    60    xsvm [command]
    61  
    62  Available Commands:
    63    account     Displays the state of the requested account
    64    chain       Manages XS chains
    65    completion  Generate the autocompletion script for the specified shell
    66    help        Help about any command
    67    issue       Issues transactions
    68    version     Prints out the version
    69  
    70  Flags:
    71    -h, --help   help for xsvm
    72  
    73  Use "xsvm [command] --help" for more information about a command.
    74  ```
    75  
    76  ### [Golang SDK](https://github.com/ava-labs/avalanchego/blob/master/vms/example/xsvm/client/client.go)
    77  
    78  ```golang
    79  // Client defines xsvm client operations.
    80  type Client interface {
    81    Network(
    82      ctx context.Context,
    83      options ...rpc.Option,
    84    ) (uint32, ids.ID, ids.ID, error)
    85    Genesis(
    86      ctx context.Context,
    87      options ...rpc.Option,
    88    ) (*genesis.Genesis, error)
    89    Nonce(
    90      ctx context.Context,
    91      address ids.ShortID,
    92      options ...rpc.Option,
    93    ) (uint64, error)
    94    Balance(
    95      ctx context.Context,
    96      address ids.ShortID,
    97      assetID ids.ID,
    98      options ...rpc.Option,
    99    ) (uint64, error)
   100    Loan(
   101      ctx context.Context,
   102      chainID ids.ID,
   103      options ...rpc.Option,
   104    ) (uint64, error)
   105    IssueTx(
   106      ctx context.Context,
   107      tx *tx.Tx,
   108      options ...rpc.Option,
   109    ) (ids.ID, error)
   110    LastAccepted(
   111      ctx context.Context,
   112      options ...rpc.Option,
   113    ) (ids.ID, *block.Stateless, error)
   114    Block(
   115      ctx context.Context,
   116      blkID ids.ID,
   117      options ...rpc.Option,
   118     (*block.Stateless, error)
   119    Message(
   120      ctx context.Context,
   121      txID ids.ID,
   122      options ...rpc.Option,
   123    ) (*teleporter.UnsignedMessage, []byte, error)
   124  }
   125  ```
   126  
   127  ### Public Endpoints
   128  
   129  #### xsvm.network
   130  
   131  ```
   132  <<< POST
   133  {
   134    "jsonrpc": "2.0",
   135    "method": "xsvm.network",
   136    "params":{},
   137    "id": 1
   138  }
   139  >>> {"networkID":<uint32>, "subnetID":<ID>, "chainID":<ID>}
   140  ```
   141  
   142  For example:
   143  
   144  ```bash
   145  curl --location --request POST 'http://34.235.54.228:9650/ext/bc/28iioW2fYMBnKv24VG5nw9ifY2PsFuwuhxhyzxZB5MmxDd3rnT' \
   146  --header 'Content-Type: application/json' \
   147  --data-raw '{
   148      "jsonrpc": "2.0",
   149      "method": "xsvm.network",
   150      "params":{},
   151      "id": 1
   152  }'
   153  ```
   154  
   155  > `{"jsonrpc":"2.0","result":{"networkID":1000000,"subnetID":"2gToFoYXURMQ6y4ZApFuRZN1HurGcDkwmtvkcMHNHcYarvsJN1","chainID":"28iioW2fYMBnKv24VG5nw9ifY2PsFuwuhxhyzxZB5MmxDd3rnT"},"id":1}`
   156  
   157  #### xsvm.genesis
   158  
   159  ```
   160  <<< POST
   161  {
   162    "jsonrpc": "2.0",
   163    "method": "xsvm.genesis",
   164    "params":{},
   165    "id": 1
   166  }
   167  >>> {"genesis":<genesis file>}
   168  ```
   169  
   170  #### xsvm.nonce
   171  
   172  ```
   173  <<< POST
   174  {
   175    "jsonrpc": "2.0",
   176    "method": "xsvm.nonce",
   177    "params":{
   178      "address":<cb58 encoded>
   179    },
   180    "id": 1
   181  }
   182  >>> {"nonce":<uint64>}
   183  ```
   184  
   185  #### xsvm.balance
   186  
   187  ```
   188  <<< POST
   189  {
   190    "jsonrpc": "2.0",
   191    "method": "xsvm.balance",
   192    "params":{
   193      "address":<cb58 encoded>,
   194      "assetID":<cb58 encoded>
   195    },
   196    "id": 1
   197  }
   198  >>> {"balance":<uint64>}
   199  ```
   200  
   201  #### xsvm.loan
   202  
   203  ```
   204  <<< POST
   205  {
   206    "jsonrpc": "2.0",
   207    "method": "xsvm.loan",
   208    "params":{
   209      "chainID":<cb58 encoded>
   210    },
   211    "id": 1
   212  }
   213  >>> {"amount":<uint64>}
   214  ```
   215  
   216  #### xsvm.issueTx
   217  
   218  ```
   219  <<< POST
   220  {
   221    "jsonrpc": "2.0",
   222    "method": "xsvm.issueTx",
   223    "params":{
   224      "tx":<bytes>
   225    },
   226    "id": 1
   227  }
   228  >>> {"txID":<cb58 encoded>}
   229  ```
   230  
   231  #### xsvm.lastAccepted
   232  
   233  ```
   234  <<< POST
   235  {
   236    "jsonrpc": "2.0",
   237    "method": "xsvm.lastAccepted",
   238    "params":{},
   239    "id": 1
   240  }
   241  >>> {"blockID":<cb58 encoded>, "block":<json>}
   242  ```
   243  
   244  #### xsvm.block
   245  
   246  ```
   247  <<< POST
   248  {
   249    "jsonrpc": "2.0",
   250    "method": "xsvm.block",
   251    "params":{
   252      "blockID":<cb58 encoded>
   253    },
   254    "id": 1
   255  }
   256  >>> {"block":<json>}
   257  ```
   258  
   259  #### xsvm.message
   260  
   261  ```
   262  <<< POST
   263  {
   264    "jsonrpc": "2.0",
   265    "method": "xsvm.message",
   266    "params":{
   267      "txID":<cb58 encoded>
   268    },
   269    "id": 1
   270  }
   271  >>> {"message":<json>, "signature":<bytes>}
   272  ```
   273  
   274  ## Running the VM
   275  
   276  To build the VM, run `./scripts/build_xsvm.sh`.
   277  
   278  ### Deploying Your Own Network
   279  
   280  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
   281  P-Chain.
   282  
   283  You can do this by following the [subnet tutorial] or by using the [subnet-cli].
   284  
   285  [teleporter]: https://github.com/ava-labs/avalanchego/tree/master/vms/platformvm/teleporter
   286  [subnet tutorial]: https://docs.avax.network/build/tutorials/platform/subnets/create-a-subnet
   287  [subnet-cli]: https://github.com/ava-labs/subnet-cli
   288  [Coreth]: https://github.com/ava-labs/coreth
   289  [C-Chain]: https://docs.avax.network/learn/platform-overview/#contract-chain-c-chain
   290  [Subnet]: https://docs.avax.network/learn/platform-overview/#subnets
   291  
   292  ## Cross Subnet Transaction Example
   293  
   294  The following example shows how to interact with the XSVM to send and receive native assets across subnets.
   295  
   296  ### Overview of Steps
   297  
   298  1. Create & deploy Subnet A
   299  2. Create  & deploy Subnet B
   300  3. Issue an **export** Tx on Subnet A
   301  4. Issue an **import** Tx on Subnet B
   302  5. Confirm Txs processed correctly
   303  
   304  > **Note:**  This demo requires [avalanche-cli](https://github.com/ava-labs/avalanche-cli) version > 1.0.5, [xsvm](https://github.com/ava-labs/xsvm) version > 1.0.2 and [avalanche-network-runner](https://github.com/ava-labs/avalanche-network-runner) v1.3.5.
   305  
   306  ### Create and Deploy Subnet A, Subnet B
   307  
   308  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.
   309  
   310  Steps
   311  
   312  Build the [XSVM](https://github.com/ava-labs/xsvm)
   313  
   314  ### Create a genesis file
   315  
   316  ```bash
   317  xsvm chain genesis --encoding binary > xsvm.genesis
   318  ```
   319  
   320  ### Create Subnet A and Subnet B
   321  
   322  ```bash
   323  avalanche subnet create subnetA --custom --genesis <path_to_genesis> --vm <path_to_vm_binary>
   324  avalanche subnet create subnetB --custom --genesis <path_to_genesis> --vm <path_to_vm_binary>
   325  ```
   326  
   327  ### Deploy Subnet A and Subnet B
   328  
   329  ```bash
   330  avalanche subnet deploy subnetA --local
   331  avalanche subnet deploy subnetB --local
   332  ```
   333  
   334  ### Issue Export Tx from Subnet A
   335  
   336  The SubnetID and ChainIDs are stored in the sidecar.json files in your avalanche-cli directory. Typically this is located at $HOME/.avalanche/subnets/
   337  
   338  ```bash
   339  xsvm issue export --source-chain-id <SubnetA.BlockchainID> --amount <export_amount> --destination-chain-id <SubnetB.BlockchainID>
   340  ```
   341  
   342  Save the TxID printed out by running the export command.
   343  
   344  ### Issue Import Tx from Subnet B
   345  
   346  > 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.
   347  > Run `xsvm issue transfer --chain-id <SubnetB.BlockchainID> --amount 1000`  to issue simple Txs on SubnetB
   348  
   349  ```bash
   350  xsvm issue import --source-chain-id <SubnetA.BlockchainID> --destination-chain-id <SubnetB.BlockchainID> --tx-id <exportTxID> --source-uris <source_uris>
   351  ```
   352  
   353  > The <source_uris> can be found by running `avalanche network status`. The default URIs are
   354  "http://localhost:9650,http://localhost:9652,http://localhost:9654,http://localhost:9656,http://localhost:9658"
   355  
   356  **Account Values**
   357  To check proper execution, use the `xsvm account` command to check balances.
   358  
   359  Verify the balance on SubnetA decreased by your export amount using
   360  
   361  ```bash
   362  xsvm account --chain-id <SubnetA.BlockchainID>
   363  ```
   364  
   365  Now verify chain A's assets were successfully imported to SubnetB
   366  
   367  ```bash
   368  xsvm account --chain-id <SubnetB.BlockchainID> --asset-id <SubnetA.BlockchainID>
   369  ```