Quantum Optimization Solver (QOS)

Introduction #

QCentroid QOS (Quantum Optimization Solver) connects your smart contracts to our Quantum based APIs.

If you are new to the QCentroid Embedded Framework and Smart Contracts, we recommend to start with the Quick start guide to learn the basics and build your first smart contract on Polygon.

What is quantum optimization? #

Quantum optimization algorithms are quantum algorithms that are used to solve optimization problems. Mostly, the optimization problem is formulated as a minimization problem, where one tries to minimize an error which depends on the solution: the optimal solution has the minimal error.

Requirements #

This guide assumes that you know how to create and deploy smart contracts on Ethereum/Polygon testnets using the following tools:

  • The Remix IDE
  • MetaMask
  • Polygon Mumbai testnet MATIC

Note on Funding Contracts
Making a QRF request will fail unless your deployed contract has enough MATIC to pay for it

Portfolio Optimization #

This guide explains how to use the QCentroid Embedded Framework with the Portfolio Optimization Solver. In this example we send a list of assets and their covariance matrix, as well as the budget we have, and the solver will provide us with the most efficient portfolio. This problem can be used as well for asset allocation.

Table of contents

  1. Create and deploy a QOS v1 Consumer contract
  2. Get the optimization result

Limit in optimization result
Due to current limitations in oracle’s features, the optimization result must fit in 64 bytes, a bytes32 variable, which is a 32 characters string. Responses larger than this will be cropped.

1. Create and deploy a QOS v1 Consumer contract #

For this example, use the QOSConsumer.sol sample contract. This contract imports the following dependencies:

  • Ownable.sol
  • QOSProviderInterface.sol

The Ownable import is used to add security to the contract. We strongly recommend you to use it.

QOS Consumer Interface #

Your contract must comply with the QOS Consumer Interface. The QOS Provider fulfills the request and returns the optimization result values to your contract in a callback to the optimizationResultCallback() function.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract IQOSConsumer {
    function optimizationResultCallback(bytes calldata bestResult) public {}

optimizationResultCallback function

Your contract must include this function to be able receive the optimization result.

  * Receive the response in the form of a bytes array
function optimizationResultCallback(bytes calldata bestResult) public 
    uint[] uintBestResult;

    //Create an instance of a QOSProviderInterface to use the decodeResponse function
    IQOSProvider qos = IQOSProvider(_QOSProviderAddress);

    // Decode the bytes array into a uint[]
    uintBestResult = qos.decodeResponse(bestResult);

    // Insert your code here to use the received result

The QOS Provider contract also offers a public pure function, decodeResponse(), that you can use to decode the received result, which comes as a bytes array. This method converts the result into a usable uint array, uint[].

QOS Provider Interface #

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract IQOSProvider {
    struct QOSPortfolioPayload{
        uint[] exp;
        uint[][] cov;
        uint[] cost;
        uint budget; 

    function optimizePortfolio(QOSPortfolioPayload memory payload) public payable returns (bytes32) {}

    function decodeResponse(bytes memory input) public pure returns (uint[] memory){}

The contract also includes pre-configured values for the necessary request parameters such as _QOSProviderAddress or _gasLimit and _QOSFee.

The Payload struct #

struct QOSPortfolioPayload{
        uint[] exp;
        uint[][] cov;
        uint[] cost;
        uint budget; 

The paramaters needed in this example are sent packed in a struct QOSPortfolioPayload with the following variables:

  • exp The expected return for each asset
  • cov The covariance matrix between the assets
  • cost The cost of each asset
  • budget The budget we have to invest

The optimizePortfolio() function #

 * The QOS request is paid from the contract's balance
function optimizePortfolio(uint[] memory exp, uint[][] memory cov, uint[] memory cost, uint budget) external returns (bytes32) 
    require( address(this).balance >= _QOSFee, "The contract doesn't have enough funds to call the provider" );

    IQOSProvider.QOSPortfolioPayload memory payload;

    payload.exp = exp;
    payload.cov = cov;
    payload.cost = cost;
    payload.budget = budget;

    // Define the external contract using the interface
    IQOSProvider qos = IQOSProvider(_QOSProviderAddress);

    // Call the Provider method. The request is paid from the contract's balance
    _lastRequestId = qos.optimizePortfolio{value: _QOSFee}(payload);

    return _lastRequestId;

This function receives four parameter to fill the QOSPayload which is a struct defined in the QOSProviderInterface and sends them to the Quantum Optimization Solver.

Build and deploy the contract on Mumbai. #

  1. Open the QOSConsumer.sol contract in Remix.
  2. On the Compile tab in Remix, compile the QOSConsumer.sol contract.
  3. Configure your deployment. On the Deploy tab in Remix, select the Injected Web3 Environment, select the QOSConsumer contract from the contract list.
  4. Click the Deploy button to deploy your contract on-chain (testnet). MetaMask opens and asks you to confirm the transaction.
  5. After you deploy your contract, you’ll see your contract’s address and functions.

Your example contract is deployed and ready to use the QOS Provider. Next, execute and optimization requesst to the QCentroid QOS srevice.

2. Execute an optimization request #

The deployed contract rquests random values from QCentroid QOS, receives those values, and sotres them in the _lastBestResult variable. Run the optimizePortfolio() function on your contract to start the request.

  1. Return to Remix and view your deployed contract functions in the Deployed Contracts list.
  2. Add funds to pay for the request:

    In the testnet, the cost is 10 Wei. This cost can be different in the main net.
  3. Expand the optimizePortfolio() function, fill the input data (exp, cov, cost, budget) and click transact button to send the request to the QCentroid QOS.

    MetaMask opens and asks you to confirm the transaction. After you approve the transaction, QCentroid QOS processes your request.
  4. QCentroid QOS fulfills the request and returns the best result to your contract’s callback function: optimizationResultCallback().
    Depending on current testnet conditions, it might take a few minutes for the callback to return the requested result to your contract.
  5. After the QCentroid QOS returns the best result values to your contract, the  _lastBestResult variable stores the last requested result returned. Click to check the value.

After this steps, you deployed a simple contract that can execute and optimization request and receive the best result from the QCentroid QOS. See the Example Contracts section for the complete code of this example.

Input and result #

For example, we can use the following input values:

    "exp": [1,2,3,2,6],
    "cov": [ [1,3,2,1,4],
             [2,2,3,2,2] ],
    "cost": [12,11,10,3,2],
    "budget": 35

And we will receive the following result, which is the most efficient portfolio, given the input data:


This response will come as a bytes array, such this one:


Use the function decodeResponse() exposed by the IQOSProvider to convert this bytes array into the uint array shown above.

Routes Optimization #

Coming soon . Contact us if you’re interested in this use case or your own custom solver.

DeFI,  ReFI, DAO Optimization #

Coming soon. Contact us if you’re interested in this use case or your own custom solver.

Knapsack Optimization #

Coming soon. Contact us if you’re interested in this use case or your own custom solver.

Example contracts #

The full code used in the examples above is shown below.

Portfolio Optimization consumer contract #

In this example, you created a consumer contract that calls the QOS Portfolio Provider. The consumer contract uses static configuration parameters.

// Full example code coming soon

Contract addresses #

Here are the addresses of the contracts deployed on chain.

Polygon Testnet (Mumbai) #

QOS Provider address: 

Glossary #

  • QOS. Quantum Optimization Solver.
  • QOS Provider. The smart contract deployed by QCentroid that provides the optimization results to the blockchain.
  • QOS Consumer. Any smart contract that consumes quantum optimization through requests to the QOS Provider.
  • Callback. A function that is invoked by an external smart contract (in our case, the QOS Provider) in response a previous request.