github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/docs/example/basic-app/app.js (about)

     1  const fs = require('fs')
     2  const burrow = require('@monax/burrow')
     3  const express = require('express')
     4  const bodyParser = require('body-parser')
     5  
     6  // Burrow address
     7  let chainURL = '127.0.0.1:10997'
     8  const abiFile = 'bin/simplestorage.bin'
     9  const deployFile = 'deploy.output.json'
    10  const accountFile = 'account.json'
    11  
    12  // Port to run example on locally
    13  const exampleAppPort = 3000
    14  
    15  function slurp (file) {
    16    return JSON.parse(fs.readFileSync(file, 'utf8'))
    17  }
    18  
    19  // Grab the account file that is expected to have 'Address' field
    20  let account = slurp(accountFile)
    21  // Connect to running burrow chain using the account address to identify our input account and return values as an object
    22  // using named returns where provided
    23  let chain = burrow.createInstance(chainURL, account.Address, {objectReturn: true})
    24  // The ABI file produced by the solidity compiler (through burrow deploy) that acts as a manifest for our deployed contract
    25  let abi = slurp(abiFile).Abi
    26  // The deployment receipt written to disk by burrow deploy that contains the deployed address of the contract amongst other things
    27  let deploy = slurp(deployFile)
    28  // The contract we will call
    29  let contractAddress = deploy.simplestorage
    30  // A Javascript object that wraps our simplestorage contract and will handle translating Javascript calls to EVM invocations
    31  let store = chain.contracts.new(abi, null, contractAddress)
    32  
    33  // For this example we use a simple router based on expressjs
    34  const app = express()
    35  // Apparently this needs to be its own module...
    36  app.use(bodyParser.json())
    37  
    38  // Some helpers for parsing/validating input
    39  let asInteger = value => new Promise((resolve, reject) =>
    40      (i => isNaN(i) ? reject(`${value} is ${typeof value} not integer`) : resolve(i))(parseInt(value)))
    41  
    42  let param = (obj, prop) => new Promise((resolve, reject) =>
    43      prop in obj ? resolve(obj[prop]) : reject(`expected key '${prop}' in ${JSON.stringify(obj)}`))
    44  
    45  let handleError = err => {
    46    console.log(err)
    47    return err.toString()
    48  }
    49  
    50  // We define some method endpoints
    51  // Get the value from the contract by calling the Solidity 'get' method
    52  app.get('/', (req, res) => store.get()
    53      .then(ret => res.send(ret.values))
    54      .catch(err => res.send(handleError(err))))
    55  
    56  // Sets the value by accepting a value in HTTP POST data and calling the Solidity 'set' method
    57  app.post('/', (req, res) => param(req.body, 'value')
    58      .then(value => asInteger(value))
    59      .then(value => store.set(value).then(() => value))
    60      .then(value => res.send({value: value, success: true}))
    61      .catch(err => res.send(handleError(err))))
    62  
    63  // Sets a value by HTTP POSTing to the value you expect to be stored encoded in the URL - so that the value can be
    64  // updated atomically
    65  app.post('/:test', (req, res) => param(req.body, 'value')
    66      .then(value => Promise.all([asInteger(req.params.test), asInteger(value)]))
    67      .then(([test, value]) => store.testAndSet(test, value))
    68      .then(ret => res.send(ret.values))
    69      .catch(err => res.send(handleError(err))))
    70  
    71  // Send a little value to an account which has the effect of creating that account if it does not exist
    72  app.post('/send/:recipient', (req, res) => param(req.body, 'amount')
    73      .then(amount =>
    74          chain.transact.SendTxSync(
    75            {
    76              Inputs: [{
    77                Address: Buffer.from(account.Address, 'hex'),
    78                Amount: amount
    79              }],
    80              Outputs: [{
    81                Address: Buffer.from(req.params.recipient, 'hex'),
    82                Amount: amount
    83              }]
    84            }))
    85      .then(txe => res.send({txHash: txe.TxHash.toString('hex'), success: true}))
    86      .catch(err => res.send(handleError(err))))
    87  
    88  const url = `http://127.0.0.1:${exampleAppPort}`
    89  
    90  // Listen for requests
    91  app.listen(exampleAppPort, () => console.log(`Example app listening on ${url}...
    92  
    93  You may wish to try the following: 
    94  # Inspect current stored value
    95    $ curl ${url}
    96    
    97  # Set the value to 2000
    98    $ curl -d '{"value": 2000}' -H "Content-Type: application/json" -X POST ${url}
    99    
   100  # Set the value via a testAndSet operation
   101    $ curl -d '{"value": 30}' -H "Content-Type: application/json" -X POST ${url}/2000
   102    
   103  # Attempt the same testAndSet which now fails since the value stored is no longer '2000'
   104    $ curl -d '{"value": 30}' -H "Content-Type: application/json" -X POST ${url}/2000
   105    $ curl ${url}
   106    `))