(Part 6) Decentralized Exchange - Fetching Data From Book, And Filling Multiple Arrays Using Nested Loops (PT 6)

in #utopian-io6 years ago

Repository

https://github.com/igormuba/DEX/tree/master/Class6

What Will I Learn?

  • Iterate through deployed data structures
  • Nested loops
  • Fetching and storing data into arrays using loops

Requirements

  • Internet connection.
  • Code editor.
  • Browser.

Difficulty

  • Advanced.

Tutorial Contents

We have already built the data structures and manipulated data structures on Solidity on this series, now we will visualize and iterate through the data structures we have been building and modifying in the previous tutorials.

The function for the exchange implemented here will be used to retrieve data from the buy book. It is a view function, which means it does not write data to the blockchain, it just reads. Usually, view functions are "cheap", but that is not the case when we are working with complex data structures. Also, the cost of the gas can be high and is not fixed, differently from most functions, because we can't guess the size of the order book. The bigger the book, more nodes it has, and more expensive the transaction cost will be.

The function

function getBuyOrders(address _token) public view returns(uint[] memory, uint[] memory){
Token storage loadedToken = tokenList[_token];
}

The only argument this function has to receive is the token address. Our exchange works with token addresses, not names. It returns 2 arrays, the first is the array of prices, in order, from the lowest to the highest. The second array is the array of volume, again, following the order.

For example:
First array:
[1, 4, 5, 10, 13, 15]
Second array:
[10, 4, 24, 3, 4, 9]

That means that the sum of buy orders at the value of 1 each is 10 tokens. The volume of the buy orders at the price of 4 each is 4 tokens. For the price 5 is 24...

And there might be many buy orders, for multiple buyers, at the same price, our function will take that into consideration!

The variables we will return

This are the variables we will return. We are just declaring them here, we will fill them with values in the future:

uint[] memory ordersPrices = new uint[](loadedToken.amountBuyPrices);
uint[] memory ordersvolumes = new uint[](loadedToken.amountBuyPrices);

We are saying new uint[](loadedToken.amountBuyPrices) on both, so that the returned array has the size of the buybook.

The loop to fill the prices

Our function will have two while loops, an outer loop, that will jump from one price on the price linked list to another, and an inner loop, that will sum the volumes of the orders on the queue at that price.

Right below the arrays, we have declared with the intention to return them, add the code:

uint buyPrice = loadedToken.minBuyPrice;
uint counter = 0;

    if (loadedToken.maxBuyPrice>0){
        while(buyPrice<loadedToken.maxBuyPrice){
            ordersPrices[counter]=buyPrice;
        }    
    }

buyPrice is the "current" buy price on this round of the loop. Remember, we are going from the cheapest price to the most expensive.
uint counter = 0; is the counter to keep track of which "run" of the loop we are at so that the fetched price gets stored in the right position on the array.
if (loadedToken.maxBuyPrice>0) ensures we won't try to loop on an empty book
while(buyPrice<loadedToken.maxBuyPrice) will stop running after we process the highest price in the buy book, on the last run.

And finally, ordersPrices[counter]=buyPrice; stores the price of the current iteration of the loop in the position of the number of the current iteration of the loop.

The loop to fill the volume

This is the inner loop, that will check all the orders on the queue at the given price point and sum them.

uint priceVolume=0;
uint offerPointer=loadedToken.buyBook[buyPrice].offerPointer;
                
    while(offerPointer<=loadedToken.buyBook[buyPrice].offerLength){
    }

Again, we are using variables to store the sum and the "pointer" to keep track at which position of the queue we are. priceVolume stores the volume of buy orders at that given price. offerPointer goes up one at a time to move the pointer. We also are assigning the offerPointer to start at loadedToken.buyBook[buyPrice].offerPointer, which is the beginning of the queue.

Inside the loop we add the current element of the queue to the sum of volume, and move the pointer up:

priceVolume+=loadedToken.buyBook[buyPrice].offers[offerPointer].amount;
offerPointer++;

Finishing the loops

After closing the inner loop we do:

if (buyPrice==loadedToken.buyBook[buyPrice].higherPrice){
    break;
}else{
    buyPrice=loadedToken.buyBook[buyPrice].higherPrice;
}
counter++;

If the "higher price" of the current price equals the current price, that means we have actually reached the end of the linked list, so. we break out of it.

If we haven't reached the end yet, we jump to the next node, by storing the current nodes higherPrice as the buyPrice.

And, regardless, we move the counter up.

Returning

We have already, in the inner and outer loops, filled the arrays we want to return, so, this is step is just closing the outer loop and the if statement, and returning the results we have got:

return(ordersPrices, ordersvolumes);

How the DEX looks so far

Let us take a review on the logic we have implemented so far, and see how everything connects so far!

When a user requests to make a deposit in tokens o the exchange, he is actually calling a function on the exchange that will use the API to call the transaction function on the outside token contract.
Captura de Tela 20190130 às 18.29.01.png

With the balance already on the exchange, the user can place an order. The order book is a linked list of prices. Inside of each price, there is a queue of orders, waiting to be filled (first come first serve).

If the orders not filled (we haven't implemented the filling functionality yet) the order will be stored in the book, on the top, bottom or somewhere in the middle.

But only if it is the first of its price.

If it is not, it will simply be added to the queue of its price, represented. here by the nodes "1st offer", "2nd offer" and "3rd offer"
Captura de Tela 20190130 às 18.34.38.png

The path implemented in this tutorial was the reverse, to fetch data on already created and modified data structures.

Curriculum

Latest tutorial of the series:

First tutorial of the series:

Beneficiaries

This post has as beneficiaries

using the SteemPeak beneficiary tool

Captura de Tela 20190122 às 16.07.11.png

Sort:  

Thank you for your contribution.

  • Again I love the work you do on the visuals in terms of decision charts!
  • Did you run any tests on those loops with large number of orders? how well do they perform?
  • The tutorial was a bit too short on content, but still I like the progress being done there.

Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, click here.


Need help? Chat with us on Discord.

[utopian-moderator]

Thank you for your review, @mcfarhat! Keep up the good work!

Hi @igormuba!

Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server

Hey, @igormuba!

Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!

Coin Marketplace

STEEM 0.17
TRX 0.15
JST 0.028
BTC 59425.55
ETH 2345.78
USDT 1.00
SBD 2.44