Resolving Transaction Failures and Debugging Issues with Chainlink API Calls in a Blockchain Project

99 Views Asked by At

I'm facing challenges with Chainlink in my project, specifically with transaction failures and log erasure when calling APIs from a Chainlink consumer contract.

Issue: Transactions revert when using Chainlink to call APIs, erasing all logs and impeding debugging.

Specific Problem: Success with GET API calls, but POST method (payment API) returns a bad request.

Error Message: "InternalServerErrorException: execution reverted (unknown custom error) (action="estimateGas")".

Documentation Gap: Inadequate guidance on making POST requests via Chainlink Functions.

Seeking advice on resolving these issues, especially for executing POST API calls and retaining logs for debugging.

This below code snippet is where I initiate transaction

**../requestSource.js**
const apiResponse = await Functions.makeHttpRequest({
  url: 'http://localhost:4000/payment/transfer',
  method: 'POST',
  data: {
    jobProposalId: args[0],
    amount: args[1],
    milestoneOrder: args[2],
  },
});
console.log(JSON.stringify(apiResponse));
if (apiResponse.error) {
  throw Error(apiResponse.error);
}
const { data } = apiResponse;
return Functions.encodeString(data);
 const source = readFileSync(
        path.join(__dirname, '../requestSource.js'),
      ).toString();
  
 const args = ['65ad521cfa8f23xxxxxxx', '375', '1'];

 const response = await simulateScript({
        source: source,
        args: args,
        bytesArgs: [], // bytesArgs - arguments can be encoded off-chain to bytes.
        secrets: {}, // no secrets in this example
      });

Simulating this with POST request throws a BadRequest.

Even if the simulation response is successful or not the contract method invocation fails with the error - "InternalServerErrorException: execution reverted (unknown custom error) (action="estimateGas")"

   const tx = await contract.markMilestoneCompleted(
        updateContractDto.contractAddress,
        updateContractDto.milestoneId,
        subscriptionId,
        donId,
        source,
        args,
        gasLimit,
      );
      await tx.wait();

Expected behaviour is marking the milestone completed updating the contract and initiation of the payment that should not return any errors.

2

There are 2 best solutions below

0
Nishanth Gobi On

By the error message, the problem is from interacting with the deployed contract. It seems related to the CALL_EXCEPTION in estimateGas, but hard to confirm as Chainlink doesn't return the complete error message.

If it was a CALL_EXCEPTION in estimateGas, see this for resolution.

0
Derek On

Chainlink community oracle here.

As Frank mentioned, when using Chainlink Functions, your target API will be called multiple times per request, so it's important to consider this when building out your app.

One way around this is to use Chainlink's Any API (ie, Direct Request) pattern, whereby your request will only go through a single Chainlink oracle, therefore ensuring that your API call only occurs once. While there are obvious downsides to using a single Chainlink oracle (ie, you need to trust the oracle company not to manipulate your data), there are many reputable oracles who run their oracles on highly-redundant infrastructure spread over multiple datacenters and regions. This will eliminate the need to run any additional infrastructure yourself in monitoring the blockchain state / posting your request.

If you're interested in finding a Chainlink oracle to serve this type of request, you can A) join the Chainlink Official Discord server and post your requirement to #operator-requests, or B) use the website of a known/reputable Chainlink oracle for a self-service approach (we at LinkWell Nodes provide documentation and code samples for initiating a singular HTTP POST request from your smart contract, including the related oracle address and Job ID).

I hope that helps, and let me know if you have any questions!