Subnet Precompile
This precompile allows you to interact with Bittensor subnets through EVM smart contracts, affording functionality for registering networks, viewing and setting network parameters, and querying network state.
This page:
- described the precompile's available functions on the precompile
- demonstrates the precompile's usage with example scripts.
The subnet precompile is available at address 0x803
(2051 in decimal).
View the source on GitHub
Subnet operations have distinct requirements!
-
Creating a subnet, i.e.
registerNetwork
, requires a coldkey with sufficient TAO to cover the current burn cost. -
Setting subnet hyperparameters requires the private key for the coldkey that owns the subnet (the one that created it, unless this has been transferred).
Available Functions
The subnet precompile provides comprehensive functionality for subnet management and configuration. All functions are categorized below:
Network Registration
registerNetwork
Create/register a new subnet, without setting identity information.
Parameters:
hotkey
(bytes32): The hotkey (32 bytes) that will own the network
Returns:
- None (payable function)
Description: Registers a new subnet on the Bittensor network. The caller becomes the subnet owner and can manage subnet parameters.
registerNetworkWithIdentity
Registers a new subnet with detailed identity information.
Parameters:
hotkey
(bytes32): The hotkey that will own the networksubnetName
(string): Name of the subnet (max 256 chars)githubRepo
(string): GitHub repository URL (max 1024 chars)subnetContact
(string): Contact information (max 1024 chars)subnetUrl
(string): Subnet website URL (max 1024 chars)discord
(string): Discord server invite (max 256 chars)description
(string): Subnet description (max 1024 chars)additional
(string): Additional information (max 1024 chars)
Returns:
- None (payable function)
Description: Registers a new subnet with comprehensive identity metadata that helps users understand the subnet's purpose and how to interact with it.
Rate Limiting
getServingRateLimit
Gets the serving rate limit for a subnet.
Parameters:
netuid
(uint16): The subnetwork ID
Returns:
uint64
: The serving rate limit value
setServingRateLimit
Sets the serving rate limit for a subnet.
Parameters:
netuid
(uint16): The subnetwork IDservingRateLimit
(uint64): The new serving rate limit value
Returns:
- None (payable function)
Difficulty Management
getMinDifficulty
Gets the minimum difficulty for a subnet.
Parameters:
netuid
(uint16): The subnetwork ID
Returns:
uint64
: The minimum difficulty value
setMinDifficulty
Sets the minimum difficulty for a subnet.
Parameters:
netuid
(uint16): The subnetwork IDminDifficulty
(uint64): The new minimum difficulty value
Returns:
- None (payable function)
getMaxDifficulty
Gets the maximum difficulty for a subnet.
Parameters:
netuid
(uint16): The subnetwork ID
Returns:
uint64
: The maximum difficulty value
setMaxDifficulty
Sets the maximum difficulty for a subnet.
Parameters:
netuid
(uint16): The subnetwork IDmaxDifficulty
(uint64): The new maximum difficulty value
Returns:
- None (payable function)
getDifficulty
Gets the current difficulty for a subnet.
Parameters:
netuid
(uint16): The subnetwork ID
Returns:
uint64
: The current difficulty value
setDifficulty
Sets the current difficulty for a subnet.
Parameters:
netuid
(uint16): The subnetwork IDdifficulty
(uint64): The new difficulty value
Returns:
- None (payable function)
Weight Management
getWeightsVersionKey
Gets the weights version key for a subnet.
Parameters:
netuid
(uint16): The subnetwork ID
Returns:
uint64
: The weights version key value
setWeightsVersionKey
Sets the weights version key for a subnet.
Parameters:
netuid
(uint16): The subnetwork IDweightsVersionKey
(uint64): The new weights version key value
Returns:
- None (payable function)
getWeightsSetRateLimit
Gets the weights set rate limit for a subnet.
Parameters:
netuid
(uint16): The subnetwork ID
Returns:
uint64
: The weights set rate limit value
setWeightsSetRateLimit
⚠️ DEPRECATED
Sets the weights set rate limit for a subnet. This function is deprecated. Subnet owners cannot set weight setting rate limits.
Parameters:
netuid
(uint16): The subnetwork IDweightsSetRateLimit
(uint64): The weights set rate limit value (ignored)
Returns:
- None (payable function)
Description: This function still exists for backward compatibility but performs no operation and returns successfully.
getMaxWeightLimit
Gets the maximum weight limit for a subnet.
Parameters:
netuid
(uint16): The subnetwork ID
Returns:
uint16
: The maximum weight limit value
setMaxWeightLimit
Sets the maximum weight limit for a subnet.
Parameters:
netuid
(uint16): The subnetwork IDmaxWeightLimit
(uint16): The new maximum weight limit value
Returns:
- None (payable function)
getMinAllowedWeights
Gets the minimum allowed weights for a subnet.
Parameters:
netuid
(uint16): The subnetwork ID
Returns:
uint16
: The minimum allowed weights value
setMinAllowedWeights
Sets the minimum allowed weights for a subnet.
Parameters:
netuid
(uint16): The subnetwork IDminAllowedWeights
(uint16): The new minimum allowed weights value
Returns:
- None (payable function)
Consensus Parameters
getAdjustmentAlpha
Gets the adjustment alpha parameter for a subnet.
Parameters:
netuid
(uint16): The subnetwork ID
Returns:
uint64
: The adjustment alpha value
setAdjustmentAlpha
Sets the adjustment alpha parameter for a subnet.
Parameters:
netuid
(uint16): The subnetwork IDadjustmentAlpha
(uint64): The new adjustment alpha value
Returns:
- None (payable function)
getKappa
Gets the kappa parameter for a subnet.
Parameters:
netuid
(uint16): The subnetwork ID
Returns:
uint16
: The kappa value
setKappa
Sets the kappa parameter for a subnet.
Parameters:
netuid
(uint16): The subnetwork IDkappa
(uint16): The new kappa value
Returns:
- None (payable function)
getRho
Gets the rho parameter for a subnet.
Parameters:
netuid
(uint16): The subnetwork ID
Returns:
uint16
: The rho value
setRho
Sets the rho parameter for a subnet.
Parameters:
netuid
(uint16): The subnetwork IDrho
(uint16): The new rho value
Returns:
- None (payable function)
getAlphaSigmoidSteepness
Gets the alpha sigmoid steepness parameter for a subnet.
Parameters:
netuid
(uint16): The subnetwork ID
Returns:
uint16
: The alpha sigmoid steepness value
setAlphaSigmoidSteepness
Sets the alpha sigmoid steepness parameter for a subnet.
Parameters:
netuid
(uint16): The subnetwork IDsteepness
(uint16): The new alpha sigmoid steepness value
Returns:
- None (payable function)
getAlphaValues
Gets the alpha low and high values for a subnet.
Parameters:
netuid
(uint16): The subnetwork ID
Returns:
uint16
: The alpha low valueuint16
: The alpha high value
setAlphaValues
Sets the alpha low and high values for a subnet.
Parameters:
netuid
(uint16): The subnetwork IDalphaLow
(uint16): The new alpha low valuealphaHigh
(uint16): The new alpha high value
Returns:
- None (payable function)
Network Activity
getImmunityPeriod
Gets the immunity period for a subnet.
Parameters:
netuid
(uint16): The subnetwork ID
Returns:
uint16
: The immunity period value
setImmunityPeriod
Sets the immunity period for a subnet.
Parameters:
netuid
(uint16): The subnetwork IDimmunityPeriod
(uint16): The new immunity period value
Returns:
- None (payable function)
getActivityCutoff
Gets the activity cutoff for a subnet.
Parameters:
netuid
(uint16): The subnetwork ID
Returns:
uint16
: The activity cutoff value
setActivityCutoff
Sets the activity cutoff for a subnet.
Parameters:
netuid
(uint16): The subnetwork IDactivityCutoff
(uint16): The new activity cutoff value
Returns:
- None (payable function)
Registration Control
getNetworkRegistrationAllowed
Gets whether network registration is allowed for a subnet.
Parameters:
netuid
(uint16): The subnetwork ID
Returns:
bool
: Whether network registration is allowed
setNetworkRegistrationAllowed
Sets whether network registration is allowed for a subnet.
Parameters:
netuid
(uint16): The subnetwork IDregistrationAllowed
(bool): Whether to allow network registration
Returns:
- None (payable function)
getNetworkPowRegistrationAllowed
Gets whether PoW registration is allowed for a subnet.
Parameters:
netuid
(uint16): The subnetwork ID
Returns:
bool
: Whether PoW registration is allowed
setNetworkPowRegistrationAllowed
Sets whether PoW registration is allowed for a subnet.
Parameters:
netuid
(uint16): The subnetwork IDregistrationAllowed
(bool): Whether to allow PoW registration
Returns:
- None (payable function)
Burn Management
getMinBurn
Gets the minimum burn amount for a subnet.
Parameters:
netuid
(uint16): The subnetwork ID
Returns:
uint64
: The minimum burn amount
setMinBurn
⚠️ DEPRECATED
Sets the minimum burn amount for a subnet. This function is deprecated. Subnet owners cannot set the minimum burn anymore.
Parameters:
netuid
(uint16): The subnetwork IDminBurn
(uint64): The minimum burn amount (ignored)
Returns:
- None (payable function)
Description: This function still exists for backward compatibility but performs no operation and returns successfully.
getMaxBurn
Gets the maximum burn amount for a subnet.
Parameters:
netuid
(uint16): The subnetwork ID
Returns:
uint64
: The maximum burn amount
setMaxBurn
⚠️ DEPRECATED
Sets the maximum burn amount for a subnet. This function is deprecated. Subnet owners cannot set the maximum burn anymore.
Parameters:
netuid
(uint16): The subnetwork IDmaxBurn
(uint64): The maximum burn amount (ignored)
Returns:
- None (payable function)
Description: This function still exists for backward compatibility but performs no operation and returns successfully.
Bonds and Moving Averages
getBondsMovingAverage
Gets the bonds moving average for a subnet.
Parameters:
netuid
(uint16): The subnetwork ID
Returns:
uint64
: The bonds moving average value
setBondsMovingAverage
Sets the bonds moving average for a subnet.
Parameters:
netuid
(uint16): The subnetwork IDbondsMovingAverage
(uint64): The new bonds moving average value
Returns:
- None (payable function)
Feature Toggles
getCommitRevealWeightsEnabled
Gets whether commit-reveal weights are enabled for a subnet.
Parameters:
netuid
(uint16): The subnetwork ID
Returns:
bool
: Whether commit-reveal weights are enabled
setCommitRevealWeightsEnabled
Sets whether commit-reveal weights are enabled for a subnet.
Parameters:
netuid
(uint16): The subnetwork IDenabled
(bool): Whether to enable commit-reveal weights
Returns:
- None (payable function)
getCommitRevealWeightsInterval
Gets the commit-reveal weights interval for a subnet.
Parameters:
netuid
(uint16): The subnetwork ID
Returns:
uint64
: The commit-reveal weights interval value
setCommitRevealWeightsInterval
Sets the commit-reveal weights interval for a subnet.
Parameters:
netuid
(uint16): The subnetwork IDinterval
(uint64): The new commit-reveal weights interval value
Returns:
- None (payable function)
getLiquidAlphaEnabled
Gets whether liquid alpha is enabled for a subnet.
Parameters:
netuid
(uint16): The subnetwork ID
Returns:
bool
: Whether liquid alpha is enabled
setLiquidAlphaEnabled
Sets whether liquid alpha is enabled for a subnet.
Parameters:
netuid
(uint16): The subnetwork IDenabled
(bool): Whether to enable liquid alpha
Returns:
- None (payable function)
getYuma3Enabled
Gets whether Yuma3 consensus is enabled for a subnet.
Parameters:
netuid
(uint16): The subnetwork ID
Returns:
bool
: Whether Yuma3 consensus is enabled
setYuma3Enabled
Sets whether Yuma3 consensus is enabled for a subnet.
Parameters:
netuid
(uint16): The subnetwork IDenabled
(bool): Whether to enable Yuma3 consensus
Returns:
- None (payable function)
Transfer Control
toggleTransfers
Toggles transfers on/off for a subnet.
Parameters:
netuid
(uint16): The subnetwork IDtoggle
(bool): Whether to enable or disable transfers
Returns:
- None (payable function)
Example Scripts
Javascript
const { ethers, assert } = require("ethers");
const { ApiPromise, WsProvider, Keyring } = require("@polkadot/api");
const { convertH160ToSS58 } = require("./address-mapping.js");
const { decodeAddress } = require("@polkadot/util-crypto");
// PROTECT YOUR PRIVATE KEYS WELL, NEVER COMMIT THEM TO GITHUB OR SHARE WITH ANYONE
const { ethPrivateKey, subSeed, rpcUrl, wsUrl } = require("./config.js");
const amount1TAO = BigInt("1000000000");
// Connect to the Subtensor node
const provider = new ethers.JsonRpcProvider(rpcUrl);
function sendTransaction(api, call, signer) {
return new Promise((resolve, reject) => {
let unsubscribed = false;
const unsubscribe = call
.signAndSend(signer, ({ status, events, dispatchError }) => {
const safelyUnsubscribe = () => {
if (!unsubscribed) {
unsubscribed = true;
unsubscribe
.then(() => {})
.catch((error) => console.error("Failed to unsubscribe:", error));
}
};
// Check for transaction errors
if (dispatchError) {
let errout = dispatchError.toString();
if (dispatchError.isModule) {
// for module errors, we have the section indexed, lookup
const decoded = api.registry.findMetaError(dispatchError.asModule);
const { docs, name, section } = decoded;
errout = `${name}: ${docs}`;
}
safelyUnsubscribe();
reject(Error(errout));
}
// Log and resolve when the transaction is included in a block
if (status.isInBlock) {
safelyUnsubscribe();
resolve(status.asInBlock);
}
})
.catch((error) => {
reject(error);
});
});
}
// for set
const subnet_contract_abi = [
{
inputs: [
{
internalType: "address",
name: "initialOwner",
type: "address",
},
],
stateMutability: "nonpayable",
type: "constructor",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "previousOwner",
type: "address",
},
{
indexed: true,
internalType: "address",
name: "newOwner",
type: "address",
},
],
name: "OwnershipTransferred",
type: "event",
},
{
inputs: [
{
internalType: "uint16",
name: "netuid",
type: "uint16",
},
],
name: "getHyperParameter",
outputs: [
{
internalType: "uint64",
name: "",
type: "uint64",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "owner",
outputs: [
{
internalType: "address",
name: "",
type: "address",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{
internalType: "bytes",
name: "subnetName",
type: "bytes",
},
{
internalType: "bytes",
name: "githubRepo",
type: "bytes",
},
{
internalType: "bytes",
name: "subnetContact",
type: "bytes",
},
],
name: "registerNetwork",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [],
name: "renounceOwnership",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{
internalType: "uint16",
name: "netuid",
type: "uint16",
},
{
internalType: "uint64",
name: "value",
type: "uint64",
},
],
name: "setHyperParameter",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{
internalType: "address",
name: "newOwner",
type: "address",
},
],
name: "transferOwnership",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
];
// compile with evm version 0.8.3
const subnet_contract_bytecode =
"0x608060405234801561001057600080fd5b50604051610e6d380380610e6d8339818101604052810190610032919061015c565b80600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561006d57600080fd5b61007c8161008360201b60201c565b50506101ce565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050610156816101b7565b92915050565b60006020828403121561016e57600080fd5b600061017c84828501610147565b91505092915050565b600061019082610197565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6101c081610185565b81146101cb57600080fd5b50565b610c90806101dd6000396000f3fe6080604052600436106100555760003560e01c8063290212c11461005a578063715018a614610076578063786fede51461008d57806378b63cb6146100ca5780638da5cb5b146100e6578063f2fde38b14610111575b600080fd5b610074600480360381019061006f919061077b565b61013a565b005b34801561008257600080fd5b5061008b610279565b005b34801561009957600080fd5b506100b460048036038101906100af9190610812565b61028d565b6040516100c19190610a3c565b60405180910390f35b6100e460048036038101906100df919061083b565b6103df565b005b3480156100f257600080fd5b506100fb61051a565b6040516101089190610971565b60405180910390f35b34801561011d57600080fd5b5061013860048036038101906101339190610752565b610543565b005b610142610591565b60006108039050600061080373ffffffffffffffffffffffffffffffffffffffff163463290212c160e01b8787876040516024016101829392919061098c565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516101ec919061095a565b60006040518083038185875af1925050503d8060008114610229576040519150601f19603f3d011682016040523d82523d6000602084013e61022e565b606091505b5050905080610272576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610269906109d8565b60405180910390fd5b5050505050565b610281610591565b61028b60006105d2565b565b600080610803905060008061080373ffffffffffffffffffffffffffffffffffffffff16637444dadc60e01b866040516024016102ca91906109f8565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610334919061095a565b6000604051808303816000865af19150503d8060008114610371576040519150601f19603f3d011682016040523d82523d6000602084013e610376565b606091505b5091509150816103bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103b2906109d8565b60405180910390fd5b6000818060200190518101906103d19190610877565b9050809450505050919050565b6103e7610591565b60006108039050600061080373ffffffffffffffffffffffffffffffffffffffff1663b38e0bbe60e01b8585604051602401610424929190610a13565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161048e919061095a565b6000604051808303816000865af19150503d80600081146104cb576040519150601f19603f3d011682016040523d82523d6000602084013e6104d0565b606091505b5050905080610514576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050b906109d8565b60405180910390fd5b50505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61054b610591565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561058557600080fd5b61058e816105d2565b50565b3373ffffffffffffffffffffffffffffffffffffffff166105b061051a56b73ffffffffffffffffffffffffffffffffffffffff16146105d057600080fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006106a96106a484610a7c565b610a57565b9050828152602081018484840111156106c157600080fd5b6106cc848285610b39565b509392505050565b6000813590506106e381610c15565b92915050565b600082601f8301126106fa57600080fd5b813561070a848260208601610696565b91505092915050565b60008135905061072281610c2c565b92915050565b60008135905061073781610c43565b92915050565b60008151905061074c81610c43565b92915050565b60006020828403121561076457600080fd5b6000610772848285016106d4565b91505092915050565b60008060006060848603121561079057600080fd5b600084013567ffffffffffffffff8111156107aa57600080fd5b6107b6868287016106e9565b935050602084013567ffffffffffffffff8111156107d357600080fd5b6107df868287016106e9565b925050604084013567ffffffffffffffff8111156107fc57600080fd5b610808868287016106e9565b9150509250925092565b60006020828403121561082457600080fd5b600061083284828501610713565b91505092915050565b6000806040838503121561084e57600080fd5b600061085c85828601610713565b925050602061086d85828601610728565b9150509250929050565b60006020828403121561088957600080fd5b60006108978482850161073d565b91505092915050565b6108a981610ae5565b82525050565b60006108ba82610aad565b6108c48185610ab8565b93506108d4818560208601610b48565b6108dd81610bdb565b840191505092915050565b60006108f382610aad565b6108fd8185610ac9565b935061090d818560208601610b48565b80840191505092915050565b6000610926601283610ad4565b915061093182610bec565b602082019050919050565b61094581610af7565b82525050565b61095481610b25565b82525050565b600061096682846108e8565b915081905092915050565b600060208201905061098660008301846108a0565b92915050565b600060608201905081810360008301526109a681866108af565b905081810360208301526109ba81856108af565b905081810360408301526109ce81846108af565b9050949350505050565b60006020820190506109f181610919565b9050919050565b6000602082019050610a0d600083018461093c565b92915050565b6000604082019050610a28600083018561093c565b610a35602083018461094b565b9392505050565b6000602082019050610a51600083018461094b565b92915050565b6000610a61610a72565b9050610a6d8282610b7b565b919050565b6000604051905090565b600067ffffffffffffffff821115610a9757610a96610bac565b5b610aa082610bdb565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b6000610af082610b05565b9050919050565b600061ffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600067ffffffffffffffff82169050919050565b82818337600083830152505050565b60005b83811015610b66578082015181840152602081019050610b4b565b83811115610b75576000848401525b50505050565b610b8482610bdb565b810181811067ffffffffffffffff82111715610ba357610ba2610bac565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f5375626e65742063616c6c206661696c65640000000000000000000000000000600082015250565b610c1e81610ae5565b8114610c2957600080fd5b50565b610c3581610af7565b8114610c4057600080fd5b50565b610c4c81610b25565b8114610c5757600080fd5b5056fea26469706673582212200e657685be0d4a155c28ec7471273753d1c625c562f268b2efdf0a8b2c7e4dbe64736f6c63430008030033";
// Create a signer
const privateKey = ethPrivateKey; // DO NOT HARDCODE YOUR PRIVATE KEY IN PRODUCTION
const signer = new ethers.Wallet(privateKey, provider);
async function createSubnetGetSetParameter() {
try {
// Substrate ss58 address that will receive the transfer
const wsProvider = new WsProvider(wsUrl);
const api = await ApiPromise.create({ provider: wsProvider });
const keyring = new Keyring({ type: "sr25519" });
const account = keyring.addFromUri(subSeed); // Your Substrate address private key/seed
// Destination address can be replaced with any ss58 address here:
const destinationAddress = account.address;
// Get the substrate address public key
const pubk = decodeAddress(destinationAddress);
const hex = Array.from(pubk, (byte) =>
byte.toString(16).padStart(2, "0")
).join("");
const signer = new ethers.Wallet(ethPrivateKey, provider);
const ss58mirror = convertH160ToSS58(signer.address);
let txSudoSetBalance = api.tx.sudo.sudo(
api.tx.balances.forceSetBalance(ss58mirror, BigInt(1e18).toString())
);
await sendTransaction(api, txSudoSetBalance, account);
const txSudoSetWhitelist = api.tx.sudo.sudo(
api.tx.evm.setWhitelist([signer.address])
);
await sendTransaction(api, txSudoSetWhitelist, account);
const contractFactory = new ethers.ContractFactory(
subnet_contract_abi,
subnet_contract_bytecode,
signer
);
const subnet_contract = await contractFactory.deploy(signer.address);
await subnet_contract.waitForDeployment();
console.log("deployed contract address: ", subnet_contract.target);
txSudoSetBalance = api.tx.sudo.sudo(
api.tx.balances.forceSetBalance(
convertH160ToSS58(subnet_contract.target),
BigInt(1e16).toString()
)
);
await sendTransaction(api, txSudoSetBalance, account);
let totalNetwork = Number(await api.query.subtensorModule.totalNetworks());
console.log("total networks is ", totalNetwork);
// there are predefined network 0 and 3.
let netuid;
if (totalNetwork > 3) {
netuid = totalNetwork;
} else {
netuid = totalNetwork - 1;
}
const encoder = new TextEncoder();
let tx = await subnet_contract.registerNetwork(
encoder.encode("name"),
encoder.encode("repo"),
encoder.encode("contact")
);
await tx.wait();
// the network owner is the deployed contract, not the signer
const networkOwner = (
await api.query.subtensorModule.subnetOwner(netuid)
).toHuman();
console.log("networkOwner is ", networkOwner);
// Note: This example uses setHyperParameter which calls setServingRateLimit
// Some other functions like setMinBurn, setMaxBurn, setWeightsSetRateLimit are deprecated
tx = await subnet_contract.setHyperParameter(netuid, 255);
await tx.wait();
// get parameter from chain
let parameter = Number(
await api.query.subtensorModule.servingRateLimit(netuid)
);
assert(parameter == 255);
// get paramter from contract
parameter = await subnet_contract.getHyperParameter(netuid);
// check total networks after registration
console.log(
"total networks is ",
(await api.query.subtensorModule.totalNetworks()).toHuman()
);
process.exit(0);
} catch (error) {
console.error("Error:", error);
process.exit(0);
}
}
async function main() {
await createSubnetGetSetParameter();
}
main().catch(console.error);
Solidity
// SPDX-License-Identifier: GPL-3.0
//
// This example demonstrates calling of ISubnet precompile
// from another smart contract
pragma solidity ^0.8.3;
import "@openzeppelin/contracts/access/Ownable.sol";
address constant ISUBTENSOR_SUBNET_ADDRESS = 0x0000000000000000000000000000000000000803;
interface ISubnet {
/// Registers a new network without specifying details.
// function registerNetwork() external payable;
/// Registers a new network with specified subnet name, GitHub repository, and contact information.
function registerNetwork(
bytes memory subnetName,
bytes memory githubRepo,
bytes memory subnetContact
) external payable;
function getServingRateLimit(uint16 netuid) external view returns (uint64);
function setServingRateLimit(
uint16 netuid,
uint64 servingRateLimit
) external payable;
}
contract Subnet is Ownable {
constructor(address initialOwner) Ownable(initialOwner) {}
function registerNetwork(
bytes memory subnetName,
bytes memory githubRepo,
bytes memory subnetContact
) external payable onlyOwner {
ISubnet subnetPrecompile = ISubnet(ISUBTENSOR_SUBNET_ADDRESS);
(bool success, ) = ISUBTENSOR_SUBNET_ADDRESS.call{value: msg.value}(
abi.encodeWithSelector(
subnetPrecompile.registerNetwork.selector,
subnetName,
githubRepo,
subnetContact
)
);
require(success, "Subnet call failed");
}
function setHyperParameter(
uint16 netuid,
uint64 value
) external payable onlyOwner {
ISubnet subnetPrecompile = ISubnet(ISUBTENSOR_SUBNET_ADDRESS);
(bool success, ) = ISUBTENSOR_SUBNET_ADDRESS.call(
abi.encodeWithSelector(
subnetPrecompile.setServingRateLimit.selector,
netuid,
value
)
);
require(success, "Subnet call failed");
}
function getHyperParameter(uint16 netuid) public returns (uint64) {
ISubnet subnetPrecompile = ISubnet(ISUBTENSOR_SUBNET_ADDRESS);
(bool success, bytes memory data) = ISUBTENSOR_SUBNET_ADDRESS.call(
abi.encodeWithSelector(
subnetPrecompile.getServingRateLimit.selector,
netuid
)
);
require(success, "Subnet call failed");
uint64 value = abi.decode(data, (uint64));
return value;
}
}