LicenseBM.sol
Overview
The LicenseBMContract contract manages licenses within a block management system. It handles ownership control, license associations with block manager wallets, and token withdrawal functionalities. This contract ensures secure interaction between license owners and block manager wallets, enforcing time-based restrictions and owner verification. It also maintains license state, including rewards, slashing sums, and the last interaction time, to support license lifecycle management.
Contract: LicenseBMContract
Purpose
LicenseBMContract represents and manages a single license entity, controlling ownership transfer, wallet associations, and token operations related to the license.
State Variables
Variable Name | Type | Description |
|---|---|---|
|
| Contract version identifier ("1.0.0"). |
|
| Unique identifier for this license (immutable). |
|
| Address of the root contract (immutable). |
|
| Optional public key of the license owner; nullable to allow either pubkey or address ownership. |
|
| Optional address of the license owner. |
|
| Address of the root Block Manager contract. |
|
| Optional address of the associated Block Manager wallet. |
|
| Accumulated rewarded tokens for the license. |
|
| Total slashing sum associated with the license. |
|
| Timestamp (block sequence number) of the last license interaction to enforce cooldown. |
|
| Mapping from code identifiers to their corresponding TVM cells (bytecode). |
Constructor
constructor (
uint256 pubkey,
TvmCell walletCode,
address rootBM
)
Parameters:
pubkey: Owner's public key.walletCode: Bytecode for the wallet contract.rootBM: Address of the root Block Manager contract.
Behavior:
Initializes the contract with the owner public key.
Stores the wallet code in the
_codemapping.Sets the root Block Manager address.
Initializes
_licenseLastTouchto zero.
Modifiers:
senderIs(_root): Ensures constructor caller is_root.accept: Accepts the inbound message.
Key Methods
Ownership Management
setOwnerAddress(address owner)Description: Assigns an
owner_addressto the license, removing the public key ownership.Parameters:
owner: New owner's address.
Restrictions:
Can only be called by current license owner (via
onlyOwnerWalletOptmodifier).Enforces a cooldown period between license interactions (
LICENSE_TOUCH).
Behavior:
Updates
_owner_address.Clears
_owner_pubkey.Updates
_licenseLastTouch.Ensures contract has sufficient balance via
ensureBalance().
Usage:
licenseBM.setOwnerAddress(newOwnerAddress);
setOwnerPubkey(uint256 pubkey)Description: Assigns an owner public key, removing the owner address.
Parameters:
pubkey: New owner's public key.
Restrictions: Same as
setOwnerAddress.Behavior:
Updates
_owner_pubkey.Clears
_owner_address.Updates
_licenseLastTouch.Calls
ensureBalance().
getOwner()Description: Returns current owner public key and address.
Returns:
(optional(uint256), optional(address))Usage:
(pubkey, addr) = licenseBM.getOwner();
Block Manager Wallet Association
addBMWallet(uint256 pubkey)Description: Associates a Block Manager wallet with this license.
Parameters:
pubkey: Public key of the Block Manager wallet to add.
Restrictions:
Only license owner can call.
Wallet must not already exist.
Enforces cooldown.
Behavior:
Calculates Block Manager wallet address using
BlockKeeperLib.calculateBlockManagerWalletAddress.Sends an
addLicensemessage with license number, rewards, and slashing sums.Updates
_licenseLastTouch.
Usage:
licenseBM.addBMWallet(bmPubkey);
removeBMWallet()Description: Removes the associated Block Manager wallet.
Restrictions:
Only license owner.
Wallet must exist.
Enforces cooldown.
Behavior:
Calls
removeLicenseon the Block Manager wallet.Updates
_licenseLastTouch.Ensures balance.
Usage:
licenseBM.removeBMWallet();
deleteWallet(uint128 reward, uint128 slashSum)Description: Called by the Block Manager wallet to disassociate itself and update rewards/slashing.
Parameters:
reward: Amount rewarded.slashSum: Total slashing sum.
Restrictions:
Called only by the current
_bmwallet.
Behavior:
Sets
_rewardedand_slashSum.Clears
_bmwallet.Updates
_licenseLastTouch.Ensures balance.
getBM()Description: Returns the optional Block Manager wallet address.
Returns:
optional(address)Usage:
bmWalletAddress = licenseBM.getBM();
Token Withdrawal
withdrawToken(address to, uint128 value)Description: Withdraw tokens from the license contract directly to an address.
Parameters:
to: Recipient address.value: Amount to withdraw.
Restrictions:
Only owner.
No associated Block Manager wallet must exist.
Enforces cooldown.
Ensures sufficient balance.
Behavior:
Transfers specified tokens to
to.Updates
_licenseLastTouch.Calls
ensureBalance().
toWithdrawToken(address to, uint128 value)Description: Requests the associated Block Manager wallet to withdraw tokens to a specified address.
Parameters: Same as
withdrawToken.Restrictions:
Only owner.
Block Manager wallet must exist.
Enforces cooldown.
Behavior:
Calls
withdrawTokenon the Block Manager wallet.Updates
_licenseLastTouch.Ensures balance.
License Acceptance and Rejection
acceptLicense(uint256 pubkey)Description: Marks acceptance of the license by the Block Manager wallet.
Parameters:
pubkey: Public key of the Block Manager wallet.
Restrictions:
Caller must be the Block Manager wallet (address calculated via
BlockKeeperLib.calculateBlockManagerWalletAddress).
Behavior:
Updates
_bmwalletto the caller.Ensures balance.
notAcceptLicense(uint256 pubkey)Description: Indicates rejection of the license by the Block Manager wallet.
Parameters: Same as
acceptLicense.Behavior:
Only ensures balance.
Restrictions: Same as
acceptLicense.
Internal Helper Functions
ensureBalance()Ensures the contract balance is above a threshold (
FEE_DEPLOY_LICENSE).If balance is insufficient, mints tokens using
gosh.mintshellq().This function is
privateandpure(indicating no state modification, but it calls an external mint function).
Fallback / Receive
receive() external {}— Empty fallback function to accept incoming messages or funds.
Getters
getDetails()Returns key license details:
License number.
Block Manager wallet (optional).
Owner public key (optional).
Owner address (optional).
getVersion()Returns the contract version string and a static label
"LicenseBlockManager".
Key Implementation Details and Algorithms
Owner Control: The contract uses an
onlyOwnerWalletOptmodifier (imported frommodifiers.sol) that validates ownership either by address or public key, enabling flexible owner identification.Cooldown Enforcement: License state changes are restricted by a cooldown period (
LICENSE_TOUCH) enforced via block sequence numbers (block.seqno), preventing rapid successive changes.Wallet Address Calculation: The contract uses
BlockKeeperLib.calculateBlockManagerWalletAddressto deterministically compute the address of Block Manager wallets based on their code, root BM address, and public key. This avoids storing wallet addresses explicitly until they are added.Token Management: The contract supports token withdrawal either directly or via the associated Block Manager wallet, ensuring that token transfers respect ownership and wallet association status.
License Association: Adding and removing Block Manager wallets triggers calls to the respective wallet contracts (
AckiNackiBlockManagerNodeWallet), maintaining synchronization between license and wallet states.Balance Assurance:
ensureBalance()is used extensively to ensure the contract holds enough tokens to perform operations, utilizing token minting if necessary.
Interactions with Other Contracts and Libraries
Modifiers (
modifiers.sol): Provides modifiers such asonlyOwnerWalletOptandsenderIsused to restrict function access based on ownership or sender identity.BlockKeeperLib (
BlockKeeperLib.sol): Used for wallet address calculation withcalculateBlockManagerWalletAddress.LicenseRoot (
LicenseRoot.sol): The_rootaddress points to this contract, which likely serves as the central license management root.AckiNackiBlockManagerNodeWallet (
AckiNackiBlockManagerNodeWallet.sol): Interacted with for adding/removing licenses and token withdrawal requests.
Visual Diagram
classDiagram
class LicenseBMContract {
-string version
-uint256 _license_number
-address _root
-optional(uint256) _owner_pubkey
-optional(address) _owner_address
-address _rootBM
-optional(address) _bmwallet
-uint128 _rewarded
-uint128 _slashSum
-uint64 _licenseLastTouch
-mapping(uint8 => TvmCell) _code
+constructor()
+setOwnerAddress()
+setOwnerPubkey()
+removeBMWallet()
+deleteWallet()
+addBMWallet()
+withdrawToken()
+toWithdrawToken()
+acceptLicense()
+notAcceptLicense()
+getDetails()
+getBM()
+getOwner()
+getVersion()
-ensureBalance()
+receive()
}
LicenseBMContract ..> Modifiers : inherits
LicenseBMContract ..> BlockKeeperLib : uses
LicenseBMContract ..> AckiNackiBlockManagerNodeWallet : interacts
Usage Example
// Assuming licenseBM is an instance of LicenseBMContract
// Set owner to an address (owner must be the current owner)
licenseBM.setOwnerAddress(0x1234...);
// Add a block manager wallet by its public key
licenseBM.addBMWallet(0x5678...);
// Withdraw tokens to a specific address without block manager wallet association
licenseBM.withdrawToken(0x9abc..., 1000);
// Block manager wallet accepts the license
licenseBM.acceptLicense(0x5678...);
This contract is a critical component managing license lifecycle, ownership, and interaction with block manager wallets, coordinating with external contracts and enforcing security through modifiers and cooldowns. For details on ownership modifiers and Block Manager wallet logic, refer to the relevant Modifiers and Block Manager Wallet documentation.