Skip to content

Integration Guide

Bytecoin Developers Team edited this page Apr 11, 2018 · 1 revision

Incoming payment processing for e-shop or exchange

Overall description

  • We presume that blockchain will never be reorganized beyond n_confirmations constant, we predefine.

  • We store finality_height in the database with initial value of 0. When the blockchain is advanced, we move finality_height forward, trailing top block height by n_confirmations and getting all transfers between old and new finality_height in the process, then modifying incoming balances of corresponding addresses in the database. When the blockchain is retracted, we keep finality_height as is. Can blockchain be really retracted? First, if some side chain grows beyond main chain, main chain is temporarily retracted. Second, if walletd or bytecoind database is erased (probably as a part of version upgrade), or restored from earlier backup. In any case, blockchain height will soon increase and we will continue advancing our finality_height. Here is an infinite loop to track incoming funds (pseudocode):

    const n_confirmations = 10
    var status
    while true:
      var was_hash = status.top_block_hash
      var was_pool_version = status.transaction_pool_version
      status = WALLETD.get_status(status) // waits for changes to status
      // code to update confirmed transaction in our DB for order processing
      if status.top_block_height > DB.finality_height + n_confirmations:
        result = WALLETD.get_transfers(from_height: DB.finality_height, to_height: status.top_block_height - n_confirmations)
        DB.begin_transaction()
        foreach block in result.blocks:
          foreach tx in block.transactions:
            foreach transfer in tx.transfers:
              if (not transfer.locked) and transfer.ours and transfer.amount > 0:
                DB.add_incoming_confirmed(transfer.address, transfer.amount, tx)
          foreach transfer in result.unlocked_transfers:
            if transfer.ours and transfer.amount > 0:
              DB.add_incoming_confirmed(transfer.address, transfer.amount, null) // this transfer is result of unlock
          DB.finality_height = status.top_block_height - n_confirmations
          DB.commit_transaction()
      // code to update unconfirmed transaction in our DB for showing in user's account web interface
      if status.top_block_hash != was_hash or status.transaction_pool_version != was_pool_version:
        result = WALLETD.get_transfers(from_height: DB.finality_height)
        DB.begin_transaction()
        DB.clear_unconfirmed()
        foreach block in result.blocks:
          foreach tx in block.transactions:
            foreach transfer in tx.transfers:
              if (not transfer.locked) and transfer.ours and transfer.amount > 0:
                DB.add_incoming_unconfirmed(transfer.address, transfer.amount, tx)
          DB.commit_transaction()
    
  • When the order is created by user in e-shop, or user needs a new incoming address on an exchange, we create and associate a new address like this (pseudocode):

      result = WALLETD.create_addresses([""]) // create 1 new address
      DB.begin_transaction()
      DB.save_address_keys(result.spend_keys[0]) // we store keys in our db for backup
      DB.create_order(order_data, result.addresses[0])
      DB.commit_transaction()
    
  • In e-shop when the incoming balance of address corresponding to some order reaches order price, we decrease incoming balance and set the order for shipment. In an exchange, incoming funds become directly available to the user as soon as they are confirmed.

Clone this wiki locally