The new koinos system call is now live in the testnet!

in #koinos8 months ago

In a previous post I explained the need of a new system call to increase the security of the tokens in Koinos. Since then, I've been working in this system call and also discussing with the community for its implementation (see the code here). Now it's time to test it.

Right now the new check_authority2 system call is available in the testnet and the results are the expected ones. It is working very good and it can be used to increase the security of the tokens. Specially for Koin and VHP, which are the most important ones.

It's important to mention that this change in the blockchain is not updating any contract. The code of Koin and VHP remain intact for the moment. And they will be updated in the future once the community devs digest the importance of this new system call and they update some token contracts to see the improvements and realize the impact in the user experience, front end development, wallets, smart contracts, etc.

What is the difference between check_authority and the new check_authority2 system call?

This table summarizes the difference in the logic of both system calls:

stepcheck_authoritycheck_authority2
1---Accept the user as caller
2Call the authorize function if it is overridenCall the authorize function if it is overriden
3---Do not accept contract calling a contract
4Check if the signature is presentCheck if the signature is present

The principal feature we want to introduce here is the step 3, which rejects a transaction when the operation is not approved by the user explicitly.

Why is it needed?

To understand the need of this system call let's see an example by using the default check_authority. In this example Alice uses a typical account (Alice doesn't have a smart contract wallet) and she interacts with a scam contract:

  • Alice signs a transaction that calls the Token X to mint 1000 tokens.
  • The Token X calls the Koin Contract to take the Koins from Alice.
  • The Koin Contract calls the check_authority function to see if this transfer is approved by Alice.
  • This function returns true because the Alice's signature is present in the transaction.

In conclusion, Alice called the Token X and this contract was able to take her Koins without an explicit consent.

With the new system call this example would fail because the new check_authority2 function do not accept a contract calling a contract (token X calling koin contract).

If the caller cannot be a contract, how could a DEX be implemented?

You maybe wondering that the previous example is very similar to the functionality implemented in a DEX. Alice calls the DEX and this contract calls the Koin contract to move the tokens from Alice. Then, how could a DEX be implemented?

The Koin contract needs to implement "allowances". In fact, this is the process used in the ERC-20 tokens of Ethereum. Allowances means that before calling the DEX, the user has to call the Koin Contract to allow the DEX to spend a specific amount of Koins. When the Koin contract calls the new check authority function it will return false because the caller is the DEX. However, after that, the Koin contract checks if there is an allowance. It will find the one set in the previous operation by the user and the transfer will be accepted.

I've seen tokens with allowances that don't require this function, so...

A good observer has probably notice that in koinos there are some tokens that already support allowances, and he is maybe wondering why these tokens can work without this new system call? What is the added value of this system call? That's a fair question and the answer is simple: They don't support the authorize function of smart contract wallets.

This do not mean that smart wallets cannot work with these tokens anymore. It's just that there are less options, and the generic one proposed by Koinos Group will not be present. Let me explain you in more details.

When creating a smart wallet, there are 3 ways you can choose to interact with tokens:

  1. The first one is the "direct call". You develop a function that calls the token contract directly when making transfers. Since the caller is the smart wallet itself the authority is resolved.
  2. The second one are allowances. You develop a logic that makes sure to set allowances in the token contract so third parties can spends specific amounts.
  3. The third one is the authorize function. The previous 2 options are the ones you can select when developing smart wallets on ethereum. And they are fine in general terms. But on koinos it was decided to go a step further by using an authorize function: Third parties can call the token contract, and the token contract calls the authorize function of the smart wallet to see if the operation is approved. So, it's a different way of approving transactions. This is not only for token contracts, it's a general way to authorize operations.

Well, the tokens that today support allowances in koinos do not support this third option.

The difficulty of supporting it is that you need to know un advance if the account has an smart contract wallet or not before calling it. But this information is not accessible from normal contracts, only system contracts can check that. And apart from that, the authorize function can not be called by any contract directly. It needs an special access as well.

Here is where the new system call comes in. It allows you to implement allowances in your token and at the same time it supports the authorize function. So the initial design of Koinos Group with respect to smart wallets and authorities remains the same.

Does this new system call replaces the old one?

No. Both system calls will co-exist and the developers will be free to select any of them for their contracts. However, it is recommended to use the new one for the reasons explained above.

The new system call will use the ID 607, next to the default check_authority. See the different system call IDs in koinos-proto.

How to test it

I deployed 3 simple contracts to make different tests:

  1. Assets Contract 1BVnntutihDsvq7zjZogAAzgpGaAidYtXH: This is a contract that has assets from the users and uses check_authority2 to verify the user. See the source code here.
  2. Third Party Contract 1Mf6GnnyfY6sWSyxCuttmgTR6V22PqD2i2: This is a contract that calls the Assets Contract to operate with the assets of the user. See the source code here.
  3. Wallet Contract 17WsDUkrbrJ7iWwdoXBY9WJzVhQEQLx8YV: This is a smart contract wallet. It has the authority function overridden, and it also has a direct_call function to call the Assets contract directly. See the source code here.

To test these 3 contracts you need Kondor installed in your browser. We will perform all the tests in https://harbinger.koinosblocks.com/, please go there and connect your wallet. Use your wallet to sign all transactions.

It's preferable to have tKoins in your account. If not you can use the "free mana" option available in kondor (each time you see the popup to send a transaction click advanced and select free mana).

Test #1: Interact with the Assets Contract

  • Open the Assets Contract.
  • Click operate assets and insert your account.
  • Sign and send.

You called the assets contract directly, then it should work. Now click in "show transaction receipt". You should see this phrase in the logs "authorized to operate with the assets".

Test #2: Interact with the Third Party Contract

  • Open the Third Party Contract.
  • Click operate external assets and insert your account.
  • Sign and send.

You called the third party contract and this contract called the assets contract. It should fail because the check_authority2 function does not accept a caller other than the user itself. And by the way, this is the most important behaviour we want to introduce with this new system call in order to protect the assets of the user.

If the use case requires this type of third party access for normal accounts the Assets Contract needs to implement allowances (this part will not be tested here since it's out of scope of the current system call).

Test #3: Smart wallet calling the Assets Contract

  • Open the Wallet Contract.
  • Click set allowance and put true.
  • Sign and send (it doesn't matter if you are not the owner of this smart wallet. The set allowance function can be called by anyone just for testing purposes).
  • Open the Assets Contract.
  • Click operate assets and insert the account of the smart wallet (17WsDUkrbrJ7iWwdoXBY9WJzVhQEQLx8YV).
  • Sign and send.

The Assets contract called the check_authority2 function, and this function called the authorize function of the smart wallet to approve the transaction. Since it was configured to accept it then it should work.

Click in "show transaction receipt". You should see several logs. In particular: "authorize called" and "authorized to operate with the assets".

Now repeat the whole test again but this time leave the field empty in allowance, which is the same as setting it to false. In this case it should fail.

Test #4: Third party calling the Assets Contract in name of the Smart wallet

  • Open the Wallet Contract.
  • Click set allowance and put true.
  • Sign and send.
  • Open the Third Party Contract.
  • Click operate external assets and insert the account of the smart wallet (17WsDUkrbrJ7iWwdoXBY9WJzVhQEQLx8YV).
  • Sign and send.

This test is very similar to the previous one. The third party calls the Assets contract and this one triggers the authorize function which returns true. Then the third party is authorized to access the assets.

Please note that here the check_authority2 function returns true despite of the fact that the third party is a contract calling another contract. This is because the rule of "rejecting a contract calling a contract" is only applicable when the account doesn't have smart wallets (see the table presented at the top).

Now click in "show transaction receipt". You should see similar logs as the previous test with the difference that now it says "caller: 1Mf6GnnyfY6sWSyxCuttmgTR6V22PqD2i2", because it was triggered by a third party.

Repeat the whole test but set the allowance to false (remember that you have to leave the field empty). It should fail.

Test #5: Smart wallet as caller

In this test you call the direct_call function, and this function calls the Assets contract. It works because the caller of the assets contract is the wallet itself.

Check the logs in "show transaction receipt". Please note that the authorize function is never called. So even if the allowance of the wallet is set to false it will work because it's the wallet itself the account that is calling the assets contract (see the table at the top).

Function arguments

The authorize function (in the smart wallet) receives 5 values in the arguments:

  1. type
  2. contract_id
  3. entry_point
  4. caller
  5. data

The unique one that is computed in the check_authority2 function is the contract_id, that is, the address of the assets contract. The rest must be provided by the assets contract.

This means that the contract_id is a trusted argument and the other ones could be faked by the assets contract. However, it's in the best interest of the assets contract to provide the correct information in these values to be able to operate its assets. Then the authorize function can trust in these values as well.

This part is done in this way for technical reasons. It would be good to build the rest of the arguments inside the check_authority2 function but this is not possible in the current framework.

This means that the developers have to provide this information when using the new authority function. As we know that this is a tedious work prone to errors, we will provide a function in the SDK that will make sure to build the parameters, so the developer will not have to worry about it.

When mainnet?

We are close to launch this proposal in the mainnet. First, I'm going to let some time pass so that recognized members of the community and developers have time to test this new system call in the testnet. I will be answering questions and giving support if needed. After that, if everything continues well then I will submit the proposal in the mainnet and it will be applied the next month in case it is accepted by the node operators.

I pass the ball to you ⚽️ now it's your time to test it and see the advantages of this new system call 🚀

Sort:  

Congratulations @jga! You have completed the following achievement on the Hive blockchain And have been rewarded with New badge(s)

You distributed more than 47000 upvotes.
Your next target is to reach 48000 upvotes.

You can view your badges on your board and compare yourself to others in the Ranking
If you no longer want to receive notifications, reply to this comment with the word STOP