Skip to content

Conversation

@MkDev11
Copy link

@MkDev11 MkDev11 commented Dec 16, 2025

Description

When using transfer_stake, users previously couldn't specify a destination hotkey - the stake would transfer to a new coldkey but remain on the original hotkey. This was problematic because the new coldkey doesn't own that hotkey, so the stake wouldn't show up in btcli commands for the recipient.

This PR adds a destination_hotkey parameter to transfer_stake, allowing users to transfer stake to both a different coldkey AND a different hotkey in a single operation. This makes the transfer actually useful - recipients can now receive stake on their own hotkey.

What changed

The transfer_stake extrinsic now accepts:

  • destination_coldkey - who receives the stake
  • origin_hotkey - the hotkey to take stake from
  • destination_hotkey - the hotkey to put stake on (NEW)
  • origin_netuid / destination_netuid - subnet IDs
  • alpha_amount - amount to transfer

Previously, the single hotkey parameter was used for both origin and destination.

Related Issue(s)

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Other (please describe):

Breaking Change

This is a breaking change for existing callers of transfer_stake:

Before:

transfer_stake(destination_coldkey, hotkey, origin_netuid, destination_netuid, alpha_amount)

After:

transfer_stake(destination_coldkey, origin_hotkey, destination_hotkey, origin_netuid, destination_netuid, alpha_amount)

Migration: Existing callers should pass the same hotkey for both origin_hotkey and destination_hotkey to maintain the previous behavior.

Affected interfaces:

  • Substrate extrinsic (call_index 86)
  • EVM precompile: transferStake(bytes32,bytes32,bytes32,uint256,uint256,uint256)
  • Chain extension (function ID 6)
  • ink! contract interface

Checklist

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have run ./scripts/fix_rust.sh to ensure my code is formatted and linted correctly
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

Screenshots (if applicable)

Screenshot 2025-12-16 095544

Additional Notes

Files changed

File Change
pallets/subtensor/src/macros/dispatches.rs Added destination_hotkey parameter to dispatch
pallets/subtensor/src/staking/move_stake.rs Updated do_transfer_stake to use both hotkeys
pallets/subtensor/src/macros/events.rs Updated StakeTransferred event to include both hotkeys
precompiles/src/staking.rs Updated EVM precompile signature
precompiles/src/solidity/stakingV2.sol Updated Solidity interface
chain-extensions/src/lib.rs Updated chain extension
contract-tests/bittensor/lib.rs Updated ink! contract interface
pallets/transaction-fee/src/lib.rs Updated pattern matching
docs/wasm-contracts.md Updated documentation
Test files Updated all tests + added new test

Why this matters

Before this change, if Alice transferred stake to Bob, the stake would end up on Alice's hotkey but owned by Bob's coldkey. Bob couldn't see or manage this stake easily because his btcli commands filter by his own hotkeys.

Now, Alice can transfer stake directly to Bob's hotkey, making the transfer actually useful for the recipient.

Contribution by Gittensor, learn more at https://gittensor.io/

Closes opentensor#1377

This PR allows users to specify a destination hotkey when transferring stake
to a different coldkey. Previously, transfer_stake only allowed changing the
coldkey while keeping the same hotkey, which caused issues because the new
coldkey wouldn't own the original hotkey.

Changes:
- Add destination_hotkey parameter to transfer_stake dispatch (call_index 86)
- Update do_transfer_stake to use separate origin_hotkey and destination_hotkey
- Update StakeTransferred event to include both hotkeys
- Update precompiles (transferStake now takes 6 params instead of 5)
- Update chain-extensions for new signature
- Update contract interface (ink! contracts)
- Update solidity interface
- Add test for transferring to different hotkey
- Update all existing tests to use new parameter
- Update documentation

This is a breaking change for existing callers of transfer_stake.
@MkDev11 MkDev11 changed the base branch from main to devnet-ready December 16, 2025 15:03
@MkDev11
Copy link
Author

MkDev11 commented Dec 16, 2025

@sam0x17 Please check the PR and let me know the result. Thanks.

@camfairchild
Copy link
Contributor

camfairchild commented Dec 16, 2025

We should avoid updating EVM interfaces because they are breaking
Instead can add a new function and support the old behaviour

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

transfer_stake should be able to transfer to a new hotkey

2 participants