[Active] Wrapping AENS names into AEX-141 NFTs

setting arbitrary strings as pointers will be possible once Ceres hardfork is activated. definitely the naming system can support a lot of use cases, but it is up to developers and businesses to utilize this feature :wink:

2 Likes

I have updated the diagrams and I am currently aiming for the “simple” approach which allows any user to set a global reward config as well as an NFT specific reward config.

read more about rewarding users for extending names here:

also, I have added a sequence diagram which showcases an example where almost all possible actions are executed:

Waiting for more feedback now. Will define the concrete contract interface based on the current state early next week and if nobody raises concerns I would start with the implementation right after that. At least I will analyze the max. amount of AENS names that can be wrapped into an NFT based on the current proposal.

Maybe there will be some iterations required in development, but I think that’s ok.


Additionally I found sth. interesting recently which we might take a look at in the future. This is brand new stuff and has been announced 2 days ago:
https://twitter.com/AlchemixFi/status/1649085593257668608?s=20

Alchemix has build a solution for ENS that allows users to never lose their ENS names again. This is actually sth. I would also like to focus on here. But let’s start with a simple solution first and get it out in the hands of the users :sweat_smile:

2 Likes

Week 16 (Apr 17 - Apr 23)

  • repository set up with MkDocs: GitHub - marc0olo/aens-nfts
  • ideation mindmap
  • several diagrams based on first ideas and forum discussion
  • full example sequence diagram

Time spent: 22.00

2 Likes

here the currently proposed contract interface that extends the AEX-141 standard interface:

again, any feedback is appreciated! :pray: :slight_smile:

3 Likes

I just got some very valuable feedback from @hanssv.chain and discussed several things with him. I will consider following things:

  • fix revokeAll naming
    • I accidentially used revokeMultiple twice
  • allow minting of empty NFTs
    • previously I didn’t consider this
    • this would allow to set up empty NFTs where the owner or somebody else could add / transfer AENS names to
  • add config param to allow/prevent receiving NFTs of strangers
    • will use reward_config for this and rename it just to config
    • if no config is set, receiving NFTs of strangers is considered not to be allowed
  • a more restrictive SPAM prevention where delegation signature for a specific name can be handed over off-chain to the desired new owner who then can use this signature to just “claim” the name to one of his NFTs
  • don’t extend all wrapped names by default, instead perform an update on the transferred names to match the expiration of the already wrapped names
    • this is a way more efficient approach
    • we agreed, that expiration consistency of all AENS names wrapped into a specific NFT makes sense
2 Likes

diagrams & contract interface updated accordingly :white_check_mark:

2 Likes

Week 17 (Apr 24 - Apr 30)

  • feedback-loop
  • updates to contract interface & diagrams

Time spent: 10.5h

1 Like

Week 18 (May 1 - May 7)

  • updates to contract interface & diagrams
  • development setup

Time spent: 3.5h


Week 19 (May 8)

Time spent: 2.5h


Total time spent for scope 1: 38.5h


As of today, I consider phase 1 (scope definition) finished and will start with phase 2 (contract development).

At start of phase 2, I will also do some gas calculations to define appropriate limits.

2 Likes

Week 20-23 (May 15 - June 11)

  • busy with other topics + vacation

Time spent: 0h

Making some progress :sunglasses:

    /// @notice wraps AENS names into a fresh minted NFT, adds NFT metadata, extends all names
    /// @param names_delegation_sigs a map (key = AENS name, value = delegation signature)
    /// @return the NFT id
    stateful entrypoint wrapAndMint(names_delegation_sigs: map(string, signature)) : int =
        let token_id = mint_internal(Call.caller, None)
        let names_delegation_sigs_list: list(string * signature) = Map.to_list(names_delegation_sigs)
        List.foreach(names_delegation_sigs_list, (val) => claim_and_assign(val, token_id))
        token_id
  describe('AENS Wrapping', () => {
    it('wrapAndMint', async () => {
      await claimNames(aensNames);

      const namesDelegationSigs = new Map(
        await Promise.all(
          aensNames.map(async (name) => [name, await aeSdk.createDelegationSignature(contractId, [name])])
        )
      );

      await expectNameOwnerProtocol(aensNames, aeSdk.selectedAddress);
      await expectNameOwnerContract(aensNames, undefined);
      await expectNameNftId(aensNames, undefined);

      const wrapAndMintTx = await contract.wrapAndMint(namesDelegationSigs);
      console.log(`Gas used (wrapAndMint): ${wrapAndMintTx.result.gasUsed} for ${aensNames.length} names`);

      await expectNameOwnerProtocol(aensNames, contractAccountAddress);
      await expectNameOwnerContract(aensNames, aeSdk.selectedAddress);
      await expectNameNftId(aensNames, 1);

      const nftMetadataDryRun = await contract.metadata(1);
      assert.equal(nftMetadataDryRun.decodedResult.MetadataMap[0].size, aensNames.length);
    });
  });
});
Claiming 2 names for ak_fUq2NesPXcYZ1CcqBcGC3StpdnQw3iVxMA3YSeCNAwfN4myQk
Gas used (wrapAndMint): 42793 for 2 names
      ✔ wrapAndMint (3911ms)

AENS wrapping limit per NFT

As previously discussed there will definitely be a max limit of AENS names to wrap into an NFT. I am wondering about the desires of the community in that regards.

Let’s assume we can add a lot of AENS names into an NFT. How many names would you like to manage within an NFT for batch updates etc.?

Currently I am considering to keep it quite low with ~21 AENS names (I like the number :wink: ). Of course I could also make it configurable and increase later on.

For wrapping only, each additional name consumes 12692 gas according to current logic. Of course we also need to make sure that other entrypoints with different actions (especially updating/extending names) won’t run out of gas, too.

Looking forward to hear what the community thinks about the AENS limit :slight_smile:

2 Likes

I would say minimum 10 AENS names at least, but I assume there might be also some sort of AENS name “traders” who might want to be able to batch update let’s say 50 names. Would that be too much to handle?

Actually I will first implement the whole logic and then start testing the limits. But I want to get some opinions from the community first.

For the “first version” (pre Ceres hardfork) of the contract a user has to provide a unique delegation signature for each name. So I expect this in general to be more an UX issue than anything else.

However, depending what kind of batch actions we allow I think we can go a lot higher. I will consult with core devs and especially @hanssv.chain in that regards.

Also I am already thinking about how to migrate NFTs to a future contract (after Ceres hardfork) where there will be new possibilities for AENS names and where users will be able to enjoy a better UX by providing a single delegation signature only, see allow an AENS delegate signature to handle all names owned by account · Issue #4080 · aeternity/aeternity · GitHub

2 Likes

I think 50 is at least close to the ballpark - it could work. But I think the easiest way to decide on the limit is, just like Marco suggestss, to actually implement and test :+1:

3 Likes

yeah, especially as I currently haven’t considered the topic to keep names in sync when wrapping names (initially). wrapAndMint needs to update all names. I am on the topic ;D

looking forward to see what the limits actually are and if the 50 is a good guess :stuck_out_tongue:

happy to share another update. the logic for wrap_and_mint as well as wrap_single is finished and tested :sunglasses:

for me this was a crucial first step and I think from now on I can continue faster in development.

    AENS Wrapping
Gas used (wrap_and_mint with 3 names): 100704
      ✔ wrap_and_mint (5558ms)
Gas used (wrap_single): 33498
      ✔ wrap_single (7068ms)

  2 passing (16s)

I have also been in first discussions with @michele already and I will provide him further information along the way to see how this can be smoothly integrated into aeScan.io

my goal is to deliver this stuff as soon as possible and also provide a minimal UI to interact with the contracts and make those actually usable :sweat_smile:

wish you all a nice weekend!

4 Likes

Week 24 (Jun 12 - Jun 18)

  • introduced new read-only entrypoint to get name expiration by nft id. more might be added during development
/// @notice returns the expiration height of names that are wrapped into the provided nft id
/// @param nft_id the NFT id
/// @return the (fixed) height where all names wrapped into the nft will expire
entrypoint get_expiration_by_nft_id : (int) => option(int)
  • introduced events. those are still subject to change and more might be added during development
  // AENS Wrapping
  // nft_id, owner, name, new_ttl
  | NameWrap(int, address, string, int)
  // nft_id, current_owner, name, recipient
  | NameUnwrap(int, address, string, address)
  // nft_id, caller, new_ttl
  | NameExtend(int, address, int)

Time spent: 20.00h

3 Likes

Week 25 (Jun 19 - Jun 25)

Time spent: 24.00h

2 Likes

Week 26 (Jun 26 - Jul 2)

Time spent: 10.25h

2 Likes

Amazing Project !! Looking forward !

I just deployed the first shot that includes all initially defined functionalities on testnet :partying_face: :tada:

ContractCreateTx

Note:

  • The deployment is handled with this script and requires the bytecode and ACI to be generated before (see below).

Contract ID

Note:

  • I will let you know in case I deploy an updated version somewhere else :wink:

Bytecode & ACI

Note:

  • In case of further changes I will make sure to keep the bytecode and aci updated :ok_hand:
  • There is a script in the repo that generates the artifacts.

The first AENS wrap into an AEX-141 NFT :partying_face:

The first AENS name that has been wrapped is TheVeryFirstWrappedName.chain.

The wrapping has been executed by this transaction using this script that printed the following log:

$ node claimAndWrapName.js
NFT ID: 1
NFT data: {"id":"1","owner":"ak_dwYGBWwLbuMTSmg8BL1STffp1Hnk4qziQYhSE36Y41vYFsyqS","names":["TheVeryFirstWrappedName.chain"],"expiration_height":"979622"}

As you can see on æScan the owner of TheVeryFirstWrappedName.chain is now the account that is associated with the AENSWrapping contract whereas the contract returns the real owner of the AENS name when fetching the nft data from the contract.

What’s next?

  • Define a maximum amount of AENS names to be wrapped per NFT by doing some calculations. I currently aim for 100 AENS names.
  • More tests (currently I mostly tested the happy paths)
  • Considering to implement (and test) a migration to a future contract that runs on Ceres protocol upgrade which ships important features that can currently not be accessed. I had a first chat about this today with @hanssv.chain)
  • Deployment on mainnet :fire:
  • Implement a basic UI to allow everybody to play around with the contract and give feedback. This depends on the amount of approved hours that remain. But I think this is a crucial step I need to tackle.
    • Note: From current grant approval perspective the UI has not been included.

Feedback

I am always happy to get feedback. Everybody familiar with the SDK and contract interaction can now already play around with the contract on testnet :slight_smile:

Independent of that I am happy to hear some ideas on how to deal with the migration of existing NFTs (including metadata) to a new contract :pray:

4 Likes