How does the App make use of Chainlink to interact with off-chain data & computation?
The use of Chainlink services enables the contracts both to query off-chain data, and to benefit from intensive computing processes that would otherwise not be achievable on the blockchain.
Specifically, it allows us to:
  • make requests to the Twitter API, to verify a Twitter account for an Ethereum address (Twitter account verification);
  • generate a proof that a promise was created using the App, thus assuring the persistence and immutability of a content sent to IPFS & Arweave (IPFS & Arweave verification).
Additionaly, the process being channeled through a blockchain, such operations otherwise opaque are completely transparent and verifiable by the user. This is actually what makes promise a trust-minimized application: you don't need to trust the process, you can rather track its execution, and even skip the actual App to interact with the Node yourself.
The only discomfort here is the IPFS & Arweave hashes verification. To get it verified, the user must create the promise through the App ; it is a bit inconvenient given that we want to keep the alternative of a straight interaction with the contract equal. However, the promise can still be created from the contract in the same way, and other users will be able to pin the content on IPFS to make it more secure. We could have followed the path of a subsequent verification, by reading the content of the supplied IPFS CID, and then sending it to Arweave. But this solution is far too expensive in computing resources.

The verification process

The procedure is basically the same for both operations. The main difference is that anyone can make a request to the VerifyTwitter contract, whereas only the PromiseFactory is allowed to make a request to the VerifyStorage contract (which is made when a promise is created).
Although further explanation is available in the following pages, the steps of the process can be roughly outlined as follows:
  1. 1.
    The user (or the PromiseFactory) requests a verification to the ChainlinkClient implementation (VerifyTwitter / VerifyStorage).
  2. 2.
    The latter builds that request, and transmits it to the Operator contract, including a job ID, a request ID and a previously specified amount of LINK.
  3. 3.
    The Operator receives the request, emits an event and triggers the Node to pick it up.
  4. 4.
    The Node grabs the request, chooses a job corresponding to the provided ID, and follows its instructions. At some point, it will use a bridge to trigger the External Adapter, while accurately delivering the parameters that have been carried to this point.
  5. 5.
    The External Adapter retrieves the parameters, and performs any operation it's been supplied with - API request, computation, or anything else. After, completing its tasks, it's ready to transmit the result back to the Node.
  6. 6.
    The Node receives the result, and proceeds to fulfilling the request. It calls the Operator contract with either fulfillOracleRequest or fulfillOracleRequest2 (see the note below), along the same request ID, which helps to identify it.
  7. 7.
    Once the fulfillment function called, the Operator transmits it to our ChainlinkClient implementation, using the function selector that it was initially supplied with. It, however, keeps the LINK as payment for its facilitation.
  8. 8.
    The custom fulfillment function is called, in the very same contract that triggered the initial request.
The Operator can make both oracle and operator requests. The oracleRequest allows a single word response, while the operatorRequest allows a multi-word response. A request fulfillment will be called with fulfillOracleRequest for the first one, or fulfillOracleRequest2 for the second one.
In this case, both verifications are made through operator requests.


While initially hosted on Google cloud Platform, the Chainlink Node is currently hosted on Chainlink Node as a Service, from LinkPool.
The External Adapters are both hosted as serverless computing functions on AWS Lambda.