Appearance
Manage Witnet UTXOs
Efficiently manage UTXOs in Witnet with the Witnet SDK.
TIP
The code examples below assume that the environment is properly set up as described in Getting Started. You can easily adapt the examples to pass the URL of the Wit/RPC provider to use, and/or the wallet master key (and the password, if encrypted).
Transactions in Witnet get paid by signing Unspent Transaction Outputs (or UTXOs), pretty much the same as transactions in Bitcoin. And just like Bitcoin, UTXOs in Witnet can be time-locked. Time-locked UTXOs cannot be spent until the time-lock timestamp is reached.
Aside from UTXOs, Witnet addresses may also hold rights to withdraw delegated stake from network validators. Delegated stake can be withdrawn into UTXOs by means of Unstake Transactions (aka. Stake Withdrawal Transactions). Withdrawn UTXOs get time-locked for a minimum of two weeks.
The balance of any Witnet address is therefore divided in three different fields:
locked | Sum of all time-locked UTXOs, in nanowits. Cannot be spent at this moment. |
staked | Funds currently staked into one or more validators, in nanowits. Delegated stake can be eventually withdrawn. Once withdrawn, deposits will remain time-locked for at least two weeks. |
unlocked | Sum of currently unlocked UTXOs, in nanowits. |
List locked and unlocked UTXOs of some random address
javascript
const { Witnet } = require("@witnet/sdk")
const provider = await Witnet.JsonRpcProvider.fromEnv()
const utxos = await provider.getUtxos("wit165ec489lcrt27w5wa7q9je7rgr4dtvyff9vwsc")Get total balance of some random address
javascript
const { utils, Witnet } = require("@witnet/sdk")
const provider = await Witnet.JsonRpcProvider.fromEnv()
const balance = await provider.getBalance("wit165ec489lcrt27w5wa7q9je7rgr4dtvyff9vwsc")Select all spendable UTXOs in a wallet
javascript
const { Witnet } = require("@witnet/sdk")
const wallet = await Witnet.Wallet.fromEnv()
let utxos = await wallet.selectUtxos()Select spendable UTXOs in a wallet as to cover some target value
Different strategies are possible when selecting input UTXOs as for covering some target value:
| UTXO Selection Strategy | Description |
|---|---|
"big-first" | Higher value UTXOs are selected first, until target value is covered. |
"random" | UTXOs are selected randomly, until target value is covered. |
"slim-fit" | The smallest of all UTXOs that individually covers target value is selected. If none fulfills this condition, UTXOs get then selected by following the BigFirst strategy. |
"small-first" | Smaller value UTXOs are selected first, until target value is covered. |
javascript
const { Witnet } = require("@witnet/sdk")
const wallet = await Witnet.Wallet.fromEnv()
const utxos = await wallet.selectUtxos({
strategy: Witnet.UtxoSelectionStrategy.SmallFirst,
value: Witnet.Coins.fromWits(10000.0) // 10,000 Wits
});Joining wallet's spendable UTXOs into a specific wallet account
Joining multiple spendable UTXOs of a wallet into a single UTXO of some specific value is possible by creating a Value Transfer Transaction (or VTT) where all inputs correspond to the spendable UTXOs that are to be joined. The sum of all input UTXOs will then be available as a single UTXO to the recipient of such VTT.
javascript
const { Witnet } = require("@witnet/sdk")
const wallet = await Witnet.Wallet.fromEnv({
strategy: Witnet.UtxoSelectionStrategy.SlimFit,
})
const vtt = await Witnet.ValueTransfers.from(wallet)
const receipt = await vtt.sendTransaction({
recipients: [[
wallet.accounts[0].pkh,
Witnet.Coins.fromWits(10000.0), // 10,000.00 $WIT
]],
})INFO
The more input UTXOs a VTT has, the greater the transaction weight will be. Because no more than 20,000 VTT weight units can be included within a Witnet block, you can get an exception if trying to build a transaction with too many inputs. In such cases, try changing the UTXO selection strategy to either SlimFit or BigFirst , or creating multiple VTTs with lower target values.
Splitting UTXOs
Splitting spendable funds into multiple smaller UTXOs enables automation scripts and bots to eventually handle concurrent data request transactions signed from one specific address.
javascript
const { Witnet } = require("@witnet/sdk")
const wallet = await Witnet.Wallet.fromEnv({
strategy: Witnet.UtxoSelectionStrategy.BigFirst
})
const vtt = await Witnet.ValueTransfers.from(wallet)
let splits = 50
let coins = Witnet.Coins.fromWits(10000.0 / splits) // 200.0 $WIT per split
const receipt = await vtt.sendTransaction({
recipients: Array(splits).fill([ "wit1...", coins ])
})INFO
Due to the VTT weight limitation, the maximum number of output UTXOs in a VTT is restricted to 50.