bm_contract_root.rs
Overview
This file provides functionality for interacting with a blockchain smart contract referred to as the Block Manager Contract Root. It primarily focuses on retrieving blockchain object codes (BOCs) and querying the owner wallet address of a Block Manager node based on a provided public key. The file leverages HTTP requests to an API server, contract ABI execution through a TVM client, and asynchronous Rust features for network communication.
Key responsibilities include:
Constructing and sending HTTP requests to fetch BOCs from a blockchain API.
Decoding and deserializing responses containing blockchain data.
Executing local smart contract methods to retrieve wallet addresses.
Managing contract ABI and address constants for interaction.
Constants and Static Variables
BM_CONTRACT_ROOT_ADDR: &str
Represents the hardcoded blockchain address of the Block Manager Contract Root.
Format: A hexadecimal string prefixed with "0:" representing the contract's unique on-chain address.
BM_CONTRACT_ROOT_ABI: &str
Contains the JSON ABI (Application Binary Interface) of the Block Manager Contract Root.
Loaded at compile time from a relative path to the contract ABI JSON file.
Used to decode and encode contract method calls.
BK_API_TOKEN: LazyLock<String>
Lazily loaded environment variable
BK_API_TOKENthat holds the API token for authentication with the blockchain API.Ensures the token is loaded only once and reused for all API requests.
Panics if the environment variable is not set, ensuring that API calls have valid authorization.
Structs
AddressResponse
#[derive(Deserialize, Debug)]
struct AddressResponse {
boc: String,
}
Represents the JSON response from the blockchain API endpoint when querying account data.
Contains a single field:
boc: A string containing the serialized blockchain object code.
WalletAddress
#[derive(Deserialize)]
struct WalletAddress {
wallet: Option<String>,
}
Represents the deserialized JSON output from the smart contract method that returns a wallet address.
Contains:
wallet: An optional string holding the wallet address. May beNoneif no wallet is associated.
Functions
build_fetch_boc_request
pub fn build_fetch_boc_request(host: SocketAddr, address: &str) -> RequestBuilder
Builds an HTTP GET request to fetch the blockchain object code (BOC) for a given account address.
Parameters:
host: The socket address (IP and port) of the blockchain API server.address: The blockchain account address whose BOC is to be fetched.
Returns: A
reqwest::RequestBuilderconfigured with the appropriate URL and bearer authentication header.Usage:
let request = build_fetch_boc_request(api_host, "0:abcdef123456...");Implementation detail:
Constructs the URL using the provided host and account address.
Adds the
BK_API_TOKENas a Bearer token for authentication.
fetch_boc
pub async fn fetch_boc(host: SocketAddr, address: &str) -> Result<String, Error>
Asynchronously sends an HTTP request to retrieve the BOC for the specified blockchain address.
Parameters:
host: The API server socket address.address: The blockchain account address.
Returns:
Ok(String): The BOC as a serialized string on success.Err(Error): An error if the HTTP request or JSON deserialization fails.
Usage:
let boc = fetch_boc(api_host, bm_contract_root_addr).await?;Implementation detail:
Uses
build_fetch_boc_requestto prepare the request.Sends the request asynchronously.
Parses the JSON response into an
AddressResponse.Extracts and returns the
bocfield.
get_bm_owner_wallet_addr
pub async fn get_bm_owner_wallet_addr(
api_host: SocketAddr,
wallet_pubkey: &String,
) -> anyhow::Result<Option<String>>
Retrieves the wallet address associated with a Block Manager node owner by invoking the smart contract method
getAckiNackiBlockManagerNodeWalletAddress.Parameters:
api_host: The API server socket address to fetch blockchain data.wallet_pubkey: The public key of the wallet whose owner address is requested, provided as a hex string.
Returns:
Ok(Some(wallet_address)): The owner's wallet address as a string if found.Ok(None): If the wallet address is not present in the contract response.Err: When contract interaction or data retrieval fails.
Usage:
let owner_wallet = get_bm_owner_wallet_addr(api_host, &pubkey).await?;Implementation detail:
Loads the contract ABI from the embedded JSON string.
Creates an
Accountinstance representing the Block Manager Contract Root.Sets up a
ClientContextfor contract execution.Fetches the current BOC of the contract to provide state for local execution.
Calls the contract's local method
getAckiNackiBlockManagerNodeWalletAddresswith the provided public key parameter.Parses the returned JSON value into a
WalletAddress.Returns the wallet address if present.
Implementation Details and Algorithms
Uses the
reqwestHTTP client for asynchronous communication with the blockchain API.Employs
serdefor JSON deserialization of API responses and contract call results.Utilizes
tvm_clientandsdk_wrappercrates to interact with the smart contract ABI and execute local contract methods without requiring on-chain transactions.The contract method invocation is performed locally using the fetched BOC to simulate contract state.
The public key parameter passed to the contract is formatted with a
0xprefix, consistent with hexadecimal notation.Lazy loading of the API token ensures environment configuration is validated only once, ahead of any network operations.
Interaction with Other System Components
Blockchain API Server: This file interacts with a blockchain node or API server, specified by
SocketAddr, to:Fetch the BOC of accounts/contracts.
Authenticate using an API token.
Smart Contract ABI (BlockManagerContractRoot.abi.json): The embedded ABI file defines contract methods and data structures, enabling typed interaction with the Block Manager contract.
tvm_client and sdk_wrapper Crates: These crates provide abstractions for contract calls, managing context and account state.
Environment Variables: The
BK_API_TOKENenvironment variable must be set externally to authorize API requests.Other Files: The ABI file is stored outside this module and included at compile time, linking contract method definitions with runtime logic.
Visual Diagram: Structure of bm_contract_root.rs
classDiagram
class bm_contract_root {
<<module>>
+BM_CONTRACT_ROOT_ADDR: &str
+BM_CONTRACT_ROOT_ABI: &str
+BK_API_TOKEN: LazyLock<String>
+build_fetch_boc_request(host: SocketAddr, address: &str): RequestBuilder
+fetch_boc(host: SocketAddr, address: &str): Result<String, Error>
+get_bm_owner_wallet_addr(api_host: SocketAddr, wallet_pubkey: &String): anyhow::Result<Option<String>>
}
class AddressResponse {
-boc: String
}
class WalletAddress {
-wallet: Option<String>
}
bm_contract_root --> AddressResponse : uses for deserialization
bm_contract_root --> WalletAddress : uses for deserialization
This diagram illustrates the module bm_contract_root encapsulating three main public functions and two internal data structures used for JSON deserialization during blockchain API interaction and contract method invocation. The constants and static variables provide configuration and authentication support.