Making BNS ready for prime time


BNS is currently the most popular contract in the STX ecosystem. As one of the first contracts that were launched, it is filled with tons of limitations, but it doesn’t mean it’s wrong; it is important to remember that certain design decisions were made by brilliant engineers and there are several good reasons why one-name-per-address; you can have more context on this GH issues #37 and #2211

:thinking: The Main Problem

The million-dollar question is, “How do we upgrade the BNS contract?” currently, it has the following constraints:

  • It is a hassle to take BNS handles into custodial. According to @friedger someone deployed 500 contracts in a marketplace before, which is not ideal. (chain congestion due to STX limitations)
  • Another pain point is the UX from Hiro Wallet, where users see a lot of code.
  • Currently, BNS only allows 1 handle per address. This results in a lot of dormant addresses being created in STX, and we don’t want that as an ecosystem. A user sometimes owns 300 addresses just for this.
  • ATM, the current BNS working group, is also missing in action @larry

The Proposed Solution vs. The New?

There are various conversations about the approach, and we keep going back and forth; it’s been two years, people, let’s bite it, keep building and solve this.

One approach was from @jude who proposed we do not need to change BNS

One-name-per-address in BNS does not prevent you from making separate identifiers, nor does it stop you from writing an app that registers names to your BNS keychain.

There is no client-side algorithm to stop users from accidentally sending multiple in-flight name-registration transactions to the same address. Please stop assuming that there is. I’m not going to entertain technical solutions that depend on this mythical algorithm’s existence. The best we can do is deal with the consequences. - Jude Nelson

Ask: Make BNS names tradeable.
Solution: Due to the existence of a block limit, there can be at most N name trades per block. So, we can instantiate a set of N escrow contracts to facilitate pair-wise trades. The seller transfers ownership of the name to an agreed-upon contract, and if the contract is paid by the buyer within B blocks, it transfers the name to the buyer and transfers the payment to the seller. There only need to be NB such contracts, and they only need to be instantiated once. Any pair of users Alice and Bob can decide which contract to use together in a decentralized way. One really simple way is to label all contracts from 0 through NB - 1, and have Alice and Bob each calculate i = SHA256(name ++ alice_address ++ bob_address ++ sale_price) % (N * B) to select escrow contract i to use. If it’s in use, then they calculate (i + 1) % (N * B) until they either find an available contract, or they determine that there’s no such contract free and will have to try again later (blocks would be full anyway).

Ask: Make it possible for there to be multiple identifiers per address.
Solution: Deploy additional naming contracts that point additional names to BNS state. Each naming contract can have its own identifiers and its own rules; the example I used in the previous thread showed how to bind a telephone number to an address. When a user transfers a name in BNS to a new address as part of a re-key operation, they will do so for each other naming contract they happen to use so that all their names continue to point to the key (assuming that’s even desired). There would probably need to be a trait written up somewhere that defines the standard naming contract APIs (along with a SIP that describes it) to help identity wallets do these transfers, but I’m certain this can be done. I’m happy to help guide this process if someone wants to take a crack at it.

:eye: The New Approach

Think of identities as assets since they are NFTs; Why are we making this complicated by building more contracts? Let’s fast forward to the future → STX will get expensive, and the last thing that we want is to put the burden on users where they spend too much on a simple marketplace listing. Second, for people who are concerned with privacy above all else, they should not (and likely won’t be) sharing private keys. If you have the same private keys and are sending STX between your accounts to fund other accounts, the blockchain will expose your identities anyway - prioritizing privacy above all else is forcing us to sacrifice UX.

The proposed solution is to simply take a page on ENS playbook, the most successful domain name. Let’s be honest here they succeed in identities more than we ever did on namecoin.

ENS Documentation

We create a whole new BNS contract and get everyone onboard so that one account can own more than one like ENS and a couple more features to make it more innovative.

Friedger already started to work on BNS v2, but needs help on how we should handle migration from v1 to v2.

  • Mark from Megapont proposed a strategy where we can just make people burn the v1 to get the v2. For example, lock all reg v1 names for like 180days or something.
  • we can airdrop the v2, give everyone fresh five years

@whoabuddy has a nice proposal about a DAO to deploy a registry and we let this DAO set new versions of the BNS interface that owns .btc

  • The registry is simple.
  • The app would need to call the update BNS version function. Is that possible for the eco DAO?
  • a base dao
  • an extension for the bns registry v1
  • an extension to interact with the original BNS contract
    Then you could start adding small pieces. Define an escrow contract, then deploy a few as extensions.

For upgrades, extensions can be disabled and new extensions implemented.
The main DAO and the extensions have access to all contract assets by default (though is-dao-or-extension), so migrating BNS names between registries should be possible. And a way for the people in control to submit changes - whether that be simulated multisig, by vote, etc

:face_in_clouds: Other or Short-term Approaches

  1. proposed a strategy that involves generating ad hoc private keys. Basically, like an atomic swap, a secret is revealed that allows recalculating the key. There must be some clever math for it or something ZK. Thru this, we can also build a BNS marketplace that relies on ad-hoc contract deploys.
    Here’s the user story:
    Since a user has to send a Tx anyway to “list” or transfer the BNS name to escrow, might as well get the user to deploy a contract (if it doesn’t already exist). Little painful, but at least it is compatible.

    • The contract can just contain the name transfer on the top level.

    • This wouldn’t feel any different for the user from a UX perspective as they wouldn’t even need to know they’re deploying a contract.

  2. The short-term solution for marketplaces: Daniel from Tradeport would probably be easier to build something that just deploys a new contract every time (instead of reusing), at least in practice would be easier.

    • The tradeoff is way easier for us but more expensive for the end user. A registry contract with a linked list could keep track of the last empty contract.

    • This is pretty much the same as what @Jude Nelson suggested the use of a reusable escrow contract with a public function that

      (1) takes possession of the seller’s name
      (2) takes possession of the buyer’s money
      (3) exchanges the two.

      If Bob wants to buy a name from Alice, Bob will submit payment to the escrow contract (which would hold it for a time-out period, should the seller not submit the name), and once Alice sees the money arrive, she would send a transaction that transfers her name to the escrow (which gives it to Bob), and verifies that her account’s token balance increases by the appropriate amount.

    From Friedger: The escrow contract is really simple.

  3. @dartman also built one master controller with many servant contracts holding one name each:Transaction - Stacks Explorer by Hiro

The question here is, why are we deploying more contracts here :point_down: do we want a simple marketplace listing to get super expensive = cost hundreds of dollars and congest our network?

:hushed: TLDR;

Now, as a community, we need to achieve consensus on “what’s the right solution and what’s the best approach for this?” time to vote, decentralization, FTW. :metal:

Shoutout to @nickgamma for providing insights and comments on this forum post.
Tagging other respective parties @markmhendrickson @muneeb @Jamil

I enthusiastically support finding a solution to the issues with BNS. The great Ryder team has helped us secure the .trajan handle. We see tremendous potential in integrating the handle with our Trajan reputation and identity platform. I lack the technical knowledge to provide worthwhile feedback on software tweaks. But I can comment on UX/UI issues and use cases.


I vote in favor of upgrading the BNS contract to follow the ENS approach. I agree that the initial proposed solutions are way too complicated for most users. If BNS is going to be a staple of decentralized identity, which I hope it will be for the next millions (billions?!?) of users, it will need to be extremely simple. ENS already does this; no need to reinvent the wheel unless there would be major benefits from the other solutions, but it doesn’t seem like there will be.

I also vote in favor of @whoabuddy’s suggestion to form a DAO (based on the ExecutorDAO framework) to manage the BNS contracts. Decentralized identity requires decentralized governance. We also agree with @whoabuddy that using the ExecutorDAO framework for this DAO would be the way to go (indeed, it is the framework that StackerDAO Labs builds all of its product on) because it includes automatic smart contract execution, is extremely modular, and its structure can be easily changed as time goes on.

A DAO could be deployed that first functions as a multisig with members of the BNS working group as members. Then, as time goes on, different extensions can be enabled and disabled, allowing for progressive decentralization. For example, the working group can then add an extension to enable anyone with a .btc NFT to submit a proposal, but only the working group multisig signers could vote on proposals. This will allow more participation from the community, but still keep control among the multisig members in the early stage. Then, when it’s ready, the DAO can disable the multisig extension and enable an extension allowing .btc holders to vote on proposals (or issue a token like ENS and use that), achieving full decentralization.

StackerDAO Labs has actually just developed a product called Teams that uses the ExecutorDAO framework for this very purpose–a multisig primitive to manage assets and smart contracts. We have one Team being used by a small NFT project live on mainnet right now. The BNS working group could use a Team on our app, and then continue to use the StackerDAOs app when ready to decentralize to a full DAO. We would also happily facilitate the development of a UI for governance of the DAO on the BNS site if the community would prefer that governance lives there instead.

The benefit of this approach is that the core, which will own the BNS contracts, and the treasury contracts remain the same. Thus, there will be no need to transfer ownership of the BNS contracts or assets from the multisig to the DAO as they will be using the same core and treasury contracts–significantly reducing the potential for error when moving assets and changing contract ownership.


Thanks for the initiative here Louise!

I think an improved BNS contract is the way to go too, one that takes the learnings from v1 to improve it. Modelling it after ENS seems like a great idea too with our own improvements on top sounds brilliant.

I think one of the things I would love to see in the new contract is non-custodial listing because that also removes the need for custodial/escrow contracts and still have the benefit of not requiring approval after a bid is made.

If a replacement contract is made I think airdropping the v2’s will be preferred, it will give the best user experience: even users that do not check in as often aren’t surprised by lost BNS names because they missed an arbitrary (180 days) window to burn the old one.
If you do not burn the old names it can also help in the period where software that relies on BNS has not been fully upgrade to BNSv2 (i.e. it can default to showing the BNSv1 name as long as it is not burned but left in the wallet).


Thanks for starting this thread!

I’m generally in the camp of working on BNS v2 and figuring out migration e.g., a snapshot of BNS v1 taken at a pre-announced block can work and v2 can just import all the state from the snapshot.

A general rule of thumb should be that devs shouldn’t be afraid to make re-write contracts and make them better. The ecosystem is in a relatively early stage and it’s easier to make more drastic changes now vs say years down the road.


+1. This is the way. (at-block ...) is your friend.


I like the snapshot idea, and a big believer in following ENS as closely as possible. At this point that’s now the user expectation.

Since we are upgrading BNS, I would like to propose an additional product requirement that would be immensely helpful not only to .btc names but Stacks in general?

Being able to send/receive BTC using .btc names.

The v2 contract should include a registry of addresses that correspond to each name. And users should be able to update it via contract calls. This should not be limited to Bitcoin addresses, it should support addresses for other blockchains as well.


@ yukan, I think it’s really a good idea! :+1:

I believe there are too many people who want this feature, and if implemented, spring is coming soon for Stacks! And is expected to break into the top 10 cryptocurrency rankings

A snapshot would be a terrible way to handle migrating from V1 to V2.

  1. What happens to NFTs listed in smart contracts, including the marketplace ones?
  2. There is a social attack vector for a new entrant into Stacks to be sold a worthless V1 post snapshot.
1 Like

The snapshot approach essentially means that each BNS operation (including lookups) are gated at a particular block. For lookups, this is straightforward: if the name doesn’t exist in BNSv2, then fall back to looking at BNSv1 as it was at the snapshot block and compensate for name expiration in the present.

For mutations (transfers, updates, revokes, renews), the logic is a little bit more involved. Basically, you’d lazily mint the name’s NFT in BNSv2 and copy over its state on its first post-snapshot mutation:

  • If this is the first mutation on this name since BNSv2 went live (synonymous with the snapshot block), then look up the name’s state from BNSv1 as of the snapshot, instantiate the name’s record and NFT in BNSv2, and carry out the operation on it in BNSv2.
  • Otherwise, just carry out the operation in BNSv2.

Looking at the BNSv1 code, there’s not much we can do for users whose preorder and register happens to straddle the snapshot since there’s no public function for querying BNSv1’s preorders (same for namespaces). Instead, name registrars and wallets would need to put up a banner informing users of the transition and/or temporarily suspend new registrations until BNSv2 went live.

If BNSv2 ever comes into existence, the creators would create a SIP for it so as to coordinate the transition in order to minimize the chance that users would be duped. The announcement would get blasted out on all the usual social channels as well.

I’m not too worried about this tbh, because this “attack” exists today, is trivial to pull off, and yet isn’t a problem in practice: today, someone could just make a fraudulent BNS site that eats your STX and mints you an NFT that originates from a copy of BNS they deployed for the purpose.

Will @friedger be the only person and Stacks resource applied here?
Where does Hiro and the Stacks Foundation stand today with regards to the storage and identity parts of the Stacks “Web3” platform? Is the future of these two explained in a roadmap or other doc somewhere? Maybe I missed it.
Granted, I realize v2.1 and subnets is the focus atm,
but it would be nice to know what the longer term plan is.
@HeroGamer maybe this info was put forth in Hiro Engr meetings but not shared more broadly?
Was there consensus among the growing Stacks ecosystem entities that these things would no longer have much attention/work/resources?

I’m generally supportive of the BNS v2 approach laid out here as well. We’d look to support it fully in Hiro Wallet (with graceful fallbacks to v1 in the UX where needed).

We’re additionally looking to support BTC and STX transfers to BNS names (.btc and otherwise) in Hiro Wallet, so I’m also in favor of @yukan’s suggestion that we address those either as part of this v2 upgrade or soon after as part of the new DAO’s subsequent work.


This will be :fire: human friendly addressing in crypto, once ubiquitous, is such a big UX unlock for mass adoption. It makes you wonder why it has been so long in coming, at least to the Bitcoin and Ethereum ecosystems. Stacks bringing this to Bitcoin is a BIG deal! :partying_face:

1 Like

Big +1 to this. You can think this as a directory or a phone book. muneeb.btc can point to my Bitcoin address and/or Lightning address and only I can update it in the registry/directory. The directory is stored on the global ledger of the Stacks layer (because you don’t want to store such extra data on the Bitcoin base layer) but the data on the Stacks layer is itself secured by Bitcoin (we can get into exactly how it is secured by Bitcoin and the answer will be different for 2.1 and earlier version and the next major upgrade that can bring Bitcoin finality).

I think the issue is similar to contract upgrades of other systems where it’s not possible to shutdown the v1. So there needs to be some social consensus e.g., if Hiro wallet, Gamma, explorer.stacks etc all start using BNS v2 and not v1 then you’ve hard forked to the new version.

Such a hardfork happened successfully when BNS moved from the earlier version implemented directly on Bitcoin to this version implemented on the Stacks layer. Theoretically, someone can go and register names on the old BNS on Bitcoin mainchain but practically it’s a non issue as that feature is not supported by any wallet, marketplace, CLI etc.

I’m supportive of more resources going to this. The Stacks Foundation is independent and can decide to do more grants for this (looking at you @blocks8 and @cuevasm!) but I’m happy to personally contribute grants and/or get some more engineering resources. I’d assume the Hiro wallet and Xverse wallet team have a business interest in this and would like to see movement on this front as well.

@larry wanted to work on a BNS working group back in the day. If there is enough demand, which I think there is, then I’d suggest forming a quick working group. Pulling in all the relevant parties and start making rapid progress towards the BNSv2. Excited!

Yes! We will need to educate people on the privacy implications though. Attaching these names to your main wallet can leak your transactions history to the world i.e., tie it with your identity.


Thanks for surfacing this again @louiseivan

Agree with @muneeb and @jude that writing a v2 and convincing people to switch is probably the best approach.

Sending assets to names is of course great - Stacks got started as “whitepages for bitcoin” back in the pre-Stacks v1.0 Onename days, so it’s awesome to see that there’s finally demand for the original functionality!

While we’re making product requests, I request that BNS stands for The Bitcoin Name System and that we figure out how to make v2 integrate more closely with Bitcoin.

Any group member (or anymore) can set up a meeting - there’s no need to ask my permission to do so. My goal was to herd all of the interested cats into the same virtual room.

Still happy to help and excited to contribute…either through a new group or the existing one.

It would be epic for BNS to support native BTC sending and receiving functions, but there would still be a question of how people would think the wallet was secure, how they would feel comfortable storing large amounts of BTC in Hiro wallets, whether there would be security audits, etc. In addition, the introduction of Hiro Wallet, a mobile client, will be more convenient

1 Like

allow 1 more names will be a big mistake update, only in the early age people will hold a lot of names, one day there are billion people use BNS, most people will own only 1 name. And compared to the huge ammount user,name trade transation will much less , 1 adress 1 name hold a big advatage is that people dont need to resolve their address to domain in order to use like ENS,wilch will cause much more congestion problem in the future, because most people dont have the demand to trade names,but most people have to resolve name on chain. 1 name 1 address also provide porfect perfect anonymity ,people dont want to expose all thier tansation in a address.

1 Like

allowing 1 more names will be a big mistake update, only at the early stage people will hold a lot of names, one day there are billion people using BNS, most people will own only 1 name, because 1 name 1 address reducing extra idea when people want to resgister more names due to the complex operation. At 1 MB Stacks block size ,now Stacks only support about 30million transactions every year, if there are billion BNS users, 1 name n address needs every BNS users to resolve BNS to address, that will cause really serious congestion problem.

And name trade transactions will be much less compared to the big quantity users. 1 address 1 name hold a big advatage that people dont need to resolve their address to domain in order to use like ENS, which will cause much more serious congestion problem in the future, because most people dont have the demand to trade their names,but most people have to resolve name on chain to use and show their name. 1 address n names also impedes BNS integrating with bitcoin and lightning, it will makes BNS users make a more step of resolving .btc to bitcoin address, that’s super inconvenient and not as safe as 1 native bitcoin address mapping 1 .btc name. 1 name 1 address leave users free from the resolving step,that will save huge block space for Stacks and makes BNS more convenient to use

1 name 1 address also provide perfect perfect anonymity, people dont want to expose all thier transactions in a address.