Welcome to the new Provenance Blockchain developer documentation portal!
logo
The hold module serves as a fundamental building block for more complex financial operations on the Provenance blockchain, enabling secure and flexible fund management while maintaining the principles of user ownership and system security.

Concepts

Summary

The x/hold module provides a mechanism for other modules to lock funds in place within accounts by creating hold records that prevent funds from being spent, sent, or delegated while keeping them in the owner's account, with hold management available only through keeper functions and integration with the bank module to properly reflect locked coins in spendable balance calculations.

Holds

"Holds" are an amount of funds in an account that must not be moved out of the account.
When a hold is placed on some funds, a record of them is created in the x/hold module. When funds are released from a hold, those records are updated appropriately.
Funds with a hold on them remain in the owners account but cannot be spent, sent, delegated or otherwise removed from the account until they are released from hold.
A hold can only be placed on funds that would otherwise be spendable. E.g. you can place a hold on vested funds, but not unvested funds.

Managing Holds

The x/hold module does not have any Msg or Tx endpoints for managing holds.
Putting holds on funds and releasing holds are actions that are only available via keeper functions. It is expected that other modules will use the keeper functions (e.g. AddHold and ReleaseHold) as needed.

Locked Coins

The x/hold module injects a GetLockedCoinsFn into the bank keeper in order to tell it which funds have a hold on them.
This allows the bank module and keeper functions to take holds into account when reporting bank account information.
Specifically, the bank keeper functions, LockedCoins, and SpendableCoins will reflect holds, as well as the SpendableBalances query.
The AllBalances query and similar keeper functions will still include the held funds though, since the funds actually are still in the account.

State

Overview

The x/hold module uses key/value pairs to store hold-related data in state. The state management is designed for efficient storage and retrieval of hold information while maintaining optimal performance for fund restriction operations.

State Architecture

Key-Value Store Design

The hold module employs a simple yet efficient key-value storage pattern that enables quick lookups and updates of hold information. This design minimizes storage overhead while providing fast access to hold data.

Holds

Holds on funds are recorded by address and denom using a specific record format that ensures efficient storage and retrieval.

Record Format

The hold module uses a structured key format that enables efficient queries and updates:
plain text
0x00 | len(<address>) | <address> | <denom> -> <amount>
This format provides a hierarchical organization that supports both specific and range queries efficiently.

Key Structure Components

Type Byte

Position: First byte of the key Value: 0x00Purpose: Identifies the record type within the module's state space
Component
Value
Description
Type Byte
0x00
Fixed value of 0 for hold records

Address Length

Position: Second byte of the key Format: Single byte containing the length of the address Encoding: 8-bit byte in big-endian order
Component
Format
Purpose
len(<address>)
Single byte (8-bit)
Length of the following address

Account Address

Position: Third component of the key Format: Raw bytes of the account address Length: Variable, as specified by the length byte
Component
Format
Description
<address>
Raw address bytes
Account that owns the held funds

Denomination

Position: Fourth component of the key Format: String representation of the coin denomination Encoding: UTF-8 string bytes
Component
Format
Description
<denom>
String bytes
Denomination of the held coins

Value Structure

Amount Storage

Format: String representation of the numerical amount being held Storage: Direct string storage for precision and compatibility
Component
Format
Purpose
<amount>
String
Numerical amount of held funds

Messages

Summary

The Hold module provides a single governance-controlled message endpoint for unlocking vesting accounts, allowing the governance module authority to convert one or more vesting accounts back to base accounts by removing their vesting restrictions and returning full control of funds to the account holders.

Governance Endpoints

The Hold module contains governance-proposal-only endpoints that require authority from the governance module account.

UnlockVestingAccounts

Unlock one or more vesting accounts, converting them back to base accounts and removing vesting restrictions.
The authority must be the governance module account to execute this operation.
It is expected to fail if:
  • The provided authority is not the governance module's account
  • One or more addresses are not valid bech32 address strings
  • One or more addresses do not correspond to existing vesting accounts

MsgUnlockVestingAccountsRequest

protobuf
// MsgUnlockVestingAccountsRequest defines the request for unlocking vesting accounts message MsgUnlockVestingAccountsRequest { option (cosmos.msg.v1.signer) = "authority"; option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; // authority is the address that can execute this message (governance module account) string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // addresses is the list of vesting account addresses to convert back to base accounts repeated string addresses = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"]; }

MsgUnlockVestingAccountsResponse

protobuf
// MsgUnlockVestingAccountsResponse defines the response for unlocking vesting accounts message MsgUnlockVestingAccountsResponse {}

Events

Summary

The x/hold module in Provenance emits two specific events to track fund holds: EventHoldAdded when funds are placed on hold with an account address, amount, and reason, and EventHoldReleased when held funds are released back to the account, both providing essential audit trails for fund management operations within the blockchain ecosystem.

EventHoldAdded

This event is emitted when a hold is placed on some funds.
Type: provenance.hold.v1.EventHoldAdded

Attributes

Attribute Key
Attribute Value
address
bech32 string of account with the funds
amount
string of coins newly placed on hold
reason
human readable string
All values are wrapped in double quotes.

Example

json
{ "type": "provenance.hold.v1.EventHoldAdded", "attributes": [ {"key": "address", "value": "\"pb1v9jxgun9wde476twta6xse2lv4mx2mn56s5hm4\""}, {"key": "amount", "value": "\"1000000000nhash,5000musdf\""}, {"key": "reason", "value": "\"order 66\""} ] }

EventHoldReleased

This event is emitted when some held funds are released.
Type: provenance.hold.v1.EventHoldReleased

Attributes

Attribute Key
Attribute Value
address
bech32 string of account with the funds
amount
string of the coins just released
Both values are wrapped in double quotes.

Example

json
{ "type": "provenance.hold.v1.EventHoldReleased", "attributes": [ {"key": "address", "value": "\"pb1v9jxgun9wde476twta6xse2lv4mx2mn56s5hm4\""}, {"key": "amount", "value": "\"1000000000nhash,5000musdf\""} ] }

Queries

Summary

The x/hold module provides two query endpoints for retrieving hold-related data: GetHolds for looking up funds on hold for a specific account address, and GetAllHolds for retrieving all funds on hold across all accounts with pagination support, enabling comprehensive monitoring and auditing of held funds within the Provenance blockchain ecosystem.

GetHolds

Look up the funds on hold for a specific account. The query takes in an address and returns a coins amount.

Request

protobuf
// GetHoldsRequest defines the request structure for the GetHolds query message GetHoldsRequest { // address is the bech32 address string of the account to get holds for string address = 1; }

Response

protobuf
// GetHoldsResponse defines the response structure for the GetHolds query message GetHoldsResponse { // amount is the total coins on hold for the requested address repeated cosmos.base.v1beta1.Coin amount = 1; }
Expected failures:
  • Invalid or missing address
Behavior:
  • If the account doesn't exist, or no coins are on hold for the account, the amount will be empty

GetAllHolds

Get all funds on hold for all accounts. The query takes in pagination parameters and returns a list of address/amount pairs.

Request

protobuf
// GetAllHoldsRequest defines the request structure for the GetAllHolds query message GetAllHoldsRequest { // pagination defines an optional pagination for the request cosmos.base.query.v1beta1.PageRequest pagination = 1; }

Response

protobuf
// GetAllHoldsResponse defines the response structure for the GetAllHolds query message GetAllHoldsResponse { // holds is the list of all account holds repeated AccountHold holds = 1; // pagination defines the pagination in the response cosmos.base.query.v1beta1.PageResponse pagination = 2; }

Related Structures

protobuf
// AccountHold defines an account address and the coins on hold for that account message AccountHold { // address is the bech32 address string of the account string address = 1; // amount is the coins on hold for the account repeated cosmos.base.v1beta1.Coin amount = 2; }
Expected failures:
  • Invalid pagination parameters

Params

No param restrictions exist for the hold module.