hedera-sdk-js icon indicating copy to clipboard operation
hedera-sdk-js copied to clipboard

Signature map creation for calling precompile results in INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE

Open ed-marquez opened this issue 2 years ago • 2 comments

Description

The Issue: When performing approved transfers (allowances) for FTs via the precompiles, the process does not complete as expected. The approved transfer via the precompile results in INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE.

The FT example:

  • 5 entities are involved: Operator, Treasury, Alice, Bob, and the token
  • The Treasury of the token approves an allowance for Alice of 50 FT units calling the approve precompile ✅
  • Alice should send bob 10 FT units from the allowance via the transferToken precompile ❌

Steps to reproduce

  1. Open the following GitPod: https://gitpod.io/#https://github.com/ed-marquez/hedera-example-allowances-solidity-precompiles

  2. Add a .env file with your own testnet credentials

  3. Open and run the file: 0_test_precompile_FT.js

  4. Notice from the token balances in the console that the delegated transfer of FT does not go through

  5. See this error INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE in HashScan in Alice's account when trying to perform the approved transfer from Treasury to Bob (https://hashscan.io/#/testnet/transactionsById/0.0.48611794-1665689598-806197477)

Additional context

External users have also reported running into this error. Here's some input from bugbytes (Jason from Calaxy): If you're calling a smart contract and it is in turn calling a precompiled contract, I believe you need to add the full 32bytes of public key in the signature map. Native hedera transactions do not typically need the full public key value to disambiguate signatures, but smart contracts don't have access to the key requirements like a native node transaction context does -- in other words, when calling a contract, always use the full 32bytes of the public key for the prefix to be safe.

@Nana-EC also suggested that it could be an issue arising from how the signature map is created in the SDK. Please help confirm if this is the case so we can provide appropriate guidance to other users seeing this issue.

==================

As additional context, from this other open issue, it does seem that there are two problems when a user wants to call a contract that in turn call the precompile (aka. JavaScript file that uses the SDK => Contract A => HTS Precompile):

  1. INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE error when executing the child transaction (approved transfer) due to the signature map creation in the SDK
  2. tokenTransfer precompile not supporting approved transfer

I believe problems 1 and 2 to be decoupled. Please advise if that's not the case. This GH issue is about problem 1.

Hedera network

testnet

Version

2.18.3

Operating system

Windows

ed-marquez avatar Oct 13 '22 22:10 ed-marquez

Actually, I think this could potentially have more to do with the use of delegatecall within the contract and a potential mismatch between the key being signed with.

If it was an SDK signing issue it would likely affect all the call attempts.

Also noting the contract code in 0_test.sol

    function ftTransferApproved(address _tokenAddress, address _owner, address _receiver, int64 _amount) external returns (int) {
        // int responseCode = HederaTokenService.approve(_tokenAddress, _spender, _amount); 
        htsPrecompiles.delegatecall(abi.encodeWithSelector(IHederaTokenService.transferToken.selector, _tokenAddress, _owner, _receiver, _amount)); 
        
        // if (responseCode != HederaResponseCodes.SUCCESS) {
        //     // revert ("allowance Failed");
        //     return responseCode;
        // }
        // return responseCode;
    }

For an approval transfer you should be using transferFrom selector not transfer Given transferFrom was only recently added in 0.31 your only current option would be to utilize IERC20.transferFrom()

Nana-EC avatar Oct 13 '22 23:10 Nana-EC

In follow up the sdk-js should have examples that map to calls for the contract functions under here

A current general example exists but it might be better to have examples for each method

Nana-EC avatar Oct 13 '22 23:10 Nana-EC

Up until now, several scenarios were implemented on top of the provided code example to test different setups:

  1. The delegatecall was replaced with a normal call in order to see if the issue comes from a mismatch between the key being signed with, as mentioned This basically resulted with the same outcome -> INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE when trying to execute the approved transfer Thus, I assume that the issue does not come from the delegatecall itself

  2. I saw that the transferFrom function was implemented in the hedera-services but when trying to call it from the IHederaTokenService replacing the tokenTransfer with it, there is not even a child transaction to the Contract Call transaction in hashscan, so I would assume it is still not on testnet

Furthermore, it is true that if you're calling a smart contract and it is in turn calling a precompiled contract you need to provide the full 32bytes of public key in the signature map source But, I believe that this is the default behavior for our SDK right now

We are still investigating the issue..

petreze avatar Oct 24 '22 17:10 petreze

Quick update: you can achieve the wanted result by calling the transferFrom instead of tokenTransfer. Currently, the functionality can be tested only by running a local node locally or on previewnet, since the feature is present only on previewnet atm. Should be alive on testnet soon

I think the issue may be closed, since the tokenTransfer should not support allowance transfers by design, correct me if I'm wrong @Nana-EC

petreze avatar Oct 25 '22 06:10 petreze

@ed-marquez Can you try to test what @petreze listed here as a possible solution.

ochikov avatar Oct 25 '22 07:10 ochikov

Thanks for looking into and addressing this. Sounds good. I will try transferFrom on previewnet. I think this issue can be closed. I'll report back if any issues are found.

ed-marquez avatar Oct 25 '22 12:10 ed-marquez