Bytom Dapp Development Notes: Dapp Demo Front-end Source Analysis

This chapter will focus on the dapp-demo provided by the original official, analysis of the front-end source code, analysis of the entire demo process, and then for the pits encountered in the development process, add some personal opinions and solutions.

A Brief Description of Savings Dividend Contract

To facilitate understanding, here is a brief description of the contents of the savings dividend contract, which can be seen in detail. Detailed description of savings dividend contract Savings dividend, as the name implies, is after saving, when a certain time, according to the proportion of return to the principal and interest meaning, so demo divided into saving (saving) and profit (withdrawal) two pages, this chapter is for the submission of contract transactions, so only for the savings page description.

Description of Dapp-demo

Official demo address

1) Prerequisites for access need to be opened with chrome Official demo address At the same time, install the bycoin plug-in to search in the application store.

2) After installing bycoin, user information needs to be initialized, new or imported backup files to restore users;

3) Fill in the specified amount of assets and click to confirm.

4) Pop up the special page for contract transactions, fill in the password, and click to confirm.

5) Check the flow of transactions

Front-end source code analysis

Source code: Savings Dividend Contract Front-end Source Code (This chapter explains the latest version of the code on July 10, 2009)

The front-end code is based on the front-end framework react, which is easy to read. The structure is as follows. Let's take a look at Bytom-Dapp-Demo1src component slayoutsaveindex.jsx as a saving page.

//Submitted method
    FixedLimitDeposit(amount, address) //####### 1.
      .then(()=> {
          //####### 2.
          this.refs.btn.removeAttribute("disabled");
          this.setState({
            error:'',
            msg:`Submit success!!! you spent ${amount} deposite asset,and gain ${amount} billasset.`
          })
        }).catch(err => {
          //####### 3.
          this.refs.btn.removeAttribute("disabled");
          this.setState({
            error:err,
            msg: ''
          })
        })

1) Received the amount of input box, and the address of the current user;

2) Successful hints;

3) Prompt content after failure;

Next to the Fixed Limit Deposit method

export function FixedLimitDeposit(amount, address) {
  const object = { 
    address: address,
    amount: amount,
    parameter: [amount, address]
  }
  return submitContract(listDepositUTXO, createContractTransaction, updateDatatbaseBalance, object)  //####### 1.
}

1) Three methods are passed in: list Deposit UTXO (find all UTXO of the current contract), create ContractTransaction (create contract parameters before submission), update Datatbase Balance (update user's submission list).

SubitControl Method Entering Dapp-Demo1srccomponentslayoutsaveaction.js

return new Promise((resolve, reject) => {
    //list available utxo
    return listDepositUTXO().then(resp => { //####### 1.

      //create the Contract Transaction
      return createContractTransaction(resp, amount, address).then(object =>{ //####### 2.
        const input = object.input
        const output = object.output
        const args = object.args

        const utxo = object.utxo

        //Lock UTXO
        return updateUtxo({"hash": utxo}) //####### 3.
          .then(()=>{

            //Transactions
            return window.bytom.send_advanced_transaction({input, output, gas: GetContractArgs().gas*100000000, args}) //####### 4.
              .then((resp) => {
                  //Update Balance
                  return updateDatatbaseBalance(resp, ...updateParameters).then(()=>{//####### 5.
                    resolve()
                  }).catch(err => {
                    throw err
                  })
              })
              .catch(err => {
                throw err.message
              })
          })
          .catch(err => {
            throw err
          })
      }).catch(err => {
        throw err
      })
    }).catch(err => {
      reject(err)
    })
  })

1) First, call list Deposit UTXO to get all UTXO information of current saving lock, which will be explained in detail later.

2) Call the createContractTransaction method to assemble the corresponding information parameters of the contract.

3) After selecting the UTXO to be used, call updateUtxo to tell bufferserver that the UTXO has been used to change the state and prevent other people from calling it.

4) Execute the window.bytom.send_advanced_transaction method for reference Plug-in Wallet API It's a high-level transaction method. This is the original method of bycoin plug-in. It calls up the page to submit the transaction and lets the user enter the password.

5) Update Datatbase Balance is called to submit the data to the back end after the transaction is confirmed.

Let's look at the list Deposit UTXO method of api.js. All the interfaces that interact with bufferserver are written in this file:

function listDepositUTXO() {
  return listDappUTXO({//****** 1.
    "program": GetContractArgs().depositProgram,   
    "asset": GetContractArgs().assetBill,         
    "sort": {
      "by":"amount",
      "order":"desc"
    }
  })
}

//Api call from Buffer server
export function listDappUTXO(params)
{
  let url
  switch (window.bytom.net){
    case "testnet":
      url = "/dapptestnet/list-utxos"
      break
    default:
      url = "/dapp/list-utxos"
  }
  return post(url, params).then(resp => resp.data)
}

It's obvious that the final call is to call bufferserver's / list-utxos method, which is very simple and worth mentioning.

1) The structure inside searches UTXO according to program (contract code) and asset (asset ID). In fact, the bottom layer is to call the official blockcenter interface, which will be detailed later.

Continue to look at the createContractTransaction method of Dapp-Demo1src component slayoutsaveaction.js

function createContractTransaction(resp, amount, address){
  return new Promise((resolve, reject) => {
    //utxo pre calculation
    const limit = GetContractArgs().radio * 100000000   //****** 1.
    if (resp.length === 0) {
      reject( 'Empty UTXO info, it might be that the utxo is locked. Please retry after 60s.')
    } else if (amount < limit) {
      reject( `Please enter an amount bigger or equal than ${limit}.`)
    }

    const result = matchesUTXO(resp, amount) //****** 2.
    const billAmount = result.amount
    const billAsset = result.asset
    const utxo = result.hash

    //contract calculation
    if (amount > billAmount) {
      reject('input amount must be smaller or equal to ' + billAmount + '.')
    } else {
      const input = []
      const output = []

      const args = contractArguments(amount, address) //****** 3.
      
      input.push(spendUTXOAction(utxo)) //****** 4.
      input.push(spendWalletAction(amount, GetContractArgs().assetDeposited)) //****** 5.

      if (amount < billAmount) { //****** 6.
        output.push(controlProgramAction(amount, GetContractArgs().assetDeposited, GetContractArgs().profitProgram))
        output.push(controlAddressAction(amount, billAsset, address))
        output.push(controlProgramAction((BigNumber(billAmount).minus(BigNumber(amount))).toNumber(), billAsset, GetContractArgs().depositProgram))
      } else {
        output.push(controlProgramAction(amount, GetContractArgs().assetDeposited, GetContractArgs().profitProgram))
        output.push(controlAddressAction(billAmount, billAsset, address))
      }

      resolve({ //****** 7
        input,
        output,
        args,
        utxo
      })
    }
  })
}

This method is rather complicated. Let's go step by step.

Let's look at 7 first. The final content returned is input, output, args, utxo, which corresponds to input, output and args in the sending transaction page, as shown in Figure K.


(Fig. K)

As mentioned in the previous chapter, all transactions over the original chain must have the conservation of mass. input corresponds to the sum of output. The execution method in contract transactions must require parameters. Here args represent the incoming parameters, and utxo represents the id of utxo.

1) Make restrictions and set minimum values.

2) matches UTXO, according to the above content, just got all available UTXO lists through list Deposit UTXO, at this time, according to the amount of user input, select a UTXO at least greater than or equal to the amount of amount;

3) contractArguments, the construction of args, is the parameters of the method in the contract;

4) Usually the contract transaction will have its own asset input, contract UTXO input, here is to unlock the utxo input;

5) This is the input of wallet assets;

6) As mentioned in the previous chapter, unlocking contract transactions must calculate the corresponding results according to the logic in the contract, so the logic here is the same as that in the contract. Detailed description of savings dividend contract Fig.

The logic of judgment is the same. The structure of the plug-in wallet is different from that of the pc wallet interface described in the previous chapter, but the principle is the same.

Finally, let's look at the updateDatatbaseBalance method of SRC component slayoutsaveaction. JS

function updateDatatbaseBalance(resp, amount, address){
 return updateBalances({
    "tx_id": resp.transaction_hash,
    address,
    "asset": GetContractArgs().assetDeposited,
    "amount": -amount
  }).then(()=>{
    return updateBalances({
      "tx_id": resp.transaction_hash,
      address,
      "asset": GetContractArgs().assetBill,
      "amount": amount
    })
  }).catch(err => {
    throw err
  })
}


export function updateBalances(params)
{
  let url
  switch (window.bytom.net) {
    case "testnet":
      url = "/dapptestnet/update-balance"
      break
    default:
      url = "/dapp/update-balance"
  }
  return post(url, params)
}

The same is called bufferserver, where the update-balance method is called to submit the successful transaction to the back end.

Summary

The content of dapp-demo front-end code is introduced above, and the method in it is introduced. Except the call of plug-in api is more complex, all of them are ordinary application logic calls. They mainly understand the conservation of quality, and the rest are the data auditing problems, which are very simple.

Pits encountered

Readers with application development should be able to understand the core of the problem at once. Now I'm talking about the pit inside.

1) UTXO lock interface is easy to be brushed; if a developer knows this interface and brushes UTXO of your interface lock application, the application will be paralyzed for a long time.

Solution: This should be considered from the aspect of application, such as interface plus some one-time authentication code, refer monitoring, authorization and so on, back-end plus transaction monitoring, to maintain the state of UTXO in various situations, abstract and complex, but this is necessary;

2) Concurrency problems; as in 1) Even if I am a normal user, after I choose a UTXO unlock, I even tell the back end to lock through the http interface and call up the input password page (Figure K). At this time, if the user does not enter the password and does not submit, the UTXO is not unlocked on the original chain, but buffers server. It's locked up.

Solution: Back-end source code is locked for a period of time, if it is not used, it will be unlocked regularly. This situation also requires the application of monitoring and judgment to maintain the state of all utxo. Personal suggestion is to issue multiple UTXO lock contracts when contract is issued, the available UTXO will become more. At this time, some students ask, TPS If you have used fire coins, you will know that block chain trading does not pay much attention to TPS, and the transaction of fire coins must exceed 60-100 blocks to determine a transaction, which depends on how the application developers judge and choose.

3) User transaction information interface is easy to be brushed; like 1) After the transaction is completed, I submit data directly through the http interface, I brush wildly, is it not a billionaire?

Solution: If you want user's transaction information and generate transaction bills, you can use the plug-in interface directly, but you need to filter out by contract coding. The author is through monitoring all transactions of block chain browser and entering the database transaction table, so that you can monitor all transactions from time to time.

4) Chain errors are easy to occur; here dapp-demo sends a contract UTXO. If a user submits a transaction, a new UTXO will be generated, but the UTXO has not been confirmed yet, the list-utxo interface of bufferserver will solve the problem of concurrency, but I am a developer who knows the contract. At this time, bufferserver also returns the UTXO which is sure to fail to the front end. It has been chained to produce a bunch of transactions, which is easy to produce chain failure.

Solution: 1) I have deeply discussed with the elder than the original official. Of course, the best solution is to set a password for the contract itself. The input parameters must be added incode secret according to the password. The contract itself is decode d and verified when it is interpreted to ensure that the entry and exit parameters are official. Well, there will be no attack... but the conclusion is that the contract engine in the original chain does not support it for the time being.

2) Be sure to hide the contract logic. Others will not be able to maliciously call malicious usage, such as front-end code obfuscation, or args parameter is back-end generation. In addition, it is suggested that the build-transaction interface parameters of the original blockcenter can be encrypted so as to hide the contract logic.

PS: This is the author's thinking about the above problems, there are better solutions, welcome to discuss together.

summary

This kind of content mainly talks about the source code analysis of the front-end code, as well as the logic pit of the design. The concrete solution should be communicated with the official developers and discussed. The transaction of block chain does not pursue large concurrency, but also needs certain concurrency. In the fourth chapter, according to the content of bufferserver, the author aims at it. Face the problem, make some personal opinions and suggestions.

Keywords: Go React REST Database

Added by paragkalra on Wed, 28 Aug 2019 06:22:00 +0300