Skip to main content

2 posts tagged with "WALLET"

View All Tags

· 5 min read
Loubna Benzaama

We use a KMS to manage the wallets that will sign the transactions.

We encourage our users to use their own KMS but we still propose to use our own KMS for an easier onboarding.

An issue arise: what if you started with our KMS and want to migrate to your own later?

If the smart contracts are deployed using wallets hosted on our KMS, then - They likely are the owners of the smart contracts.

So how can you transfer the ownership of these smart contracts to a wallet on your KMS?

How to transfer the ownership

For an easier explanation, let’s call S the wallet hosted on the Starton KMS and U the new wallet which is hosted on the User’s KMS.

We want to transfer ownership on our smart contracts from S to U.

We can only do this for one smart contract at a time so we’ll take the case of a single ERC721 contract below.

Most of the time, you’ll want to change the ownership of the contract while keeping some rights on the wallet S, such as minting rights.

Please note that all the possible rights must be defined in the code of the smart contract.

In the ERC20, ERC721 and ERC1155 templates we propose, the following roles are available:

  • DEFAULT_ADMIN_ROLE
  • PAUSER_ROLE
  • MINTER_ROLE
  • LOCKER_ROLE

A role can be assigned to multiple wallets and a wallet can have multiple roles.

In this example we will:

  • Use the S wallet to give itself the MINTER_ROLE
  • Use the S wallet to give the U wallet the DEFAULT_ADMIN_ROLE
  • Use the S wallet to revoke itself the DEFAULT_ADMIN_ROLE

This way, the S wallet will still be able to mint tokens and won’t have the admin role. The admin role will only be assigned to the U wallet.

How do roles work in smart contracts?

It is important to understand how roles work in smart contracts as the OpenZeppelin standard is not very intuitive.

The most natural way would be to have strings representing the roles and to assign users to them using mappings.

And it looks like it works like this at first sight.

If you actually try to call the MINTER_ROLE view function of the smart contract, you'd end up with this output: 0x9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6

What you would expect is that this value represents the address that has the MINTER_ROLE.

Surprisingly enough, it does not work that way.

You have to remember that multiple addresses could have this role, and multiple roles can be assigned to a wallet so it does not make any sens to have a single value as an answer.

The value 0x9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6 is in fact the keccak256 hash of the string "MINTER_ROLE".

Why would we use such a complicated and confusing way of defining roles you'd say? Why using the hashes of the strings instead of using the strings themselves?

Here is what the OpenZeppelin Community has to say about it:

  • They don't have the issues associated with stings, unless computed off-chain (web3.utils.soliditySha3("ROLE_NAME"))
  • They don't have the issues associated with integers, namely, choosing how to associate a role name to an integer
  • Unlike bytes32 = "string", all 256 bits of the identifier are random-ish, increasing the Hamming distance between them
  • With a consistent convention, clashes are not possible (e.g. by always doing bytes32 constant X_ROLE = keccak256("X"))
  • They don't take up storage by being constant
  • They are reasonably cheap: calling a pure function on a contract that returns such a hash costs ~250 gas (this figure includes the overhead of decoding calldata, jumping based on the function selector, etc.)
  • They can be expanded to be immutable once ​it is released Anyway, we'll need the value of the role hash to grant or revoke roles. Let's see how we can get the hash value for the MINTER_ROLE from our dashboard.

Granting the roles

Now that we have retrieved the hash value of the MINTER_ROLE we can call the grantRole function of our smart contract to give the S wallet the rights to mint. The grantRole function takes two parameters:

  • role: The hash of the role that will be given to the address
  • address: The address that will be granted the role We'll fill the role value with 0x9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6(the MINTER_ROLE hash) and for the address we'll use the Starton KMS wallet which is currently the admin of the smart contract (the S wallet as described earlier). The KMS wallet address can be found in the Wallet tab. Picture of the grantRole function call Now that we gave the S wallet the MINTER_ROLE, we still have to:
  • Use the S wallet to grant the U wallet (your KMS wallet) the DEFAULT_ADMIN_ROLE
  • Use the S wallet to revoke itself the DEFAULT_ADMIN_ROLE
  • For the first part, we need to call the DEFAULT_ADMIN_ROLE view function to get the value of the admin role hash the same way we previously did for the MINTER_ROLE. The hash value of the DEFAULT_ADMIN_ROLE is actually: 0x0000000000000000000000000000000000000000000000000000000000000000 Using the exact same idea that for MINTER_ROLE, we can now call the grantRole function using the DEFAULT_ADMIN_ROLE hash and your KMS wallet address that should be granted the admin rights on the smart contract.

Revoke the admin rights of the Starton KMS wallet (S)

Similar to how we granted the admin role to the U wallet, we can call the renounceRole with the S wallet to revoke itself the admin rights on the contract.

Conclusion

Congratz! We have now transfered the ownership of the smart contract from S to U as:

  • The U wallet has the DEFAULT_ADMIN_ROLE on the smart contract
  • The S wallet has the MINTER_ROLE
  • The S wallet hasn't the DEFAULT_ADMIN_ROLE anymore ​

· 4 min read
Loubna Benzaama

WHAT IS WEB3AUTH?

Web3auth is an open-source authentication library for web3 applications. It allows users to authenticate with wallets using a social login flow. Similarly, Web3auth offers a solution of wallet address from social login, allowing users to discover Web3 while using a login system they are most likely used to.

This tutorial will cover how to create meta transactions with Starton and Web3auth. Meta transactions are a useful way to onboard users to the Web3 ecosystem by allowing them to use their familiar social login system, and execute transactions without having to pay gas fees or have Ether in their wallets.

By using two routes on Starton, you can create meta transactions. This use case is handy when you want to onboard users to web3.

PREREQUISITES

You will need :

  • A smart contract that implements ERC20 interface. Starton Smart contract templates support Metatransactions. To deploy an ERC20 with Starton, go to How to create your own crypto currency.
  • A Starton API key

Installing the project

The project has been set up using a client-side and a server-side so that your API key is not exposed on client. You can also use the server-side to connect a database for metrics.

Creating Starton Project

  1. Clone the project from Starton Metatransactions GitHub.

Setting up the server side

Here we would like to enter the data needed to request funds and set up your metatransactions as well as entering your API, so that you can authenticate safely to the API.

  1. In server, add your Starton API key in .env.
  2. In src > config > startonconfig.ts, set the following parameters:
    • the route to interact with your smart contract call URL (ex: /smart-contract/avalanche-fuji/0xcEB17Bf0E3d198ec985370f456332f10f373CdB3/call)
    • the speed of your transaction (ex: low, average, fast, fastest)
    • the signer wallet
    • the amount of requested funds

Let’s continue with our config files in client.

Setting up our client side

On the client side, we will set up all the information of your smart contract to connect your project to Web3Auth.

  1. Install the client side.

  2. In client, add the port where your server is running in .env.

  3. In src > config >smart-contract go to smartContract.config.ts and set the following parameters:

    • the version of your smart contract
    • the name of your smart contract
    • the chainId of the network on which you deployed your contract
    • the address of your smart contract

    USING FUNCTIONS TO RETRIEVE YOUR SMART CONTRACT INFORMATION

    You can retrieve all of this information using the Interact tab of your smart contract. Learn more

  4. In src>config > smart-contractABI.config.ts, enter the ABI of your contract.

  5. In starton, go to starton.config.ts, enter the value of the meta transaction.

  6. In src > services> ethersRPC.ts, enter the wallet from which to transfer.

  7. In src > hooks> useWeb3AuthInit.ts:

    1. In chainId, replace the value in Number(43113) with the chainId of your network.
    2. In rpcTarget, enter the address of your node, such as 'https://api.avax-test.network/ext/bc/C/rpc'.

    info

    You can find public nodes on https://chainlist.org/

Now that we’re all set, let’s run our project.

Running the project

To run your project, you will need to run commands both on server and client side.

  1. In server, run the command npm run build

  2. Then, run npm run start

  3. In client, run the command npm run build

  4. Then, run npm run start

    Visit http://localhost:3000 to test your project.

Now that you have used our project, visit this guide to learn more about the project How did we build a Meta-Transaction Site with Web3Auth and Starton.