github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/docs/example/basic-app-website/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  app.use(express.static('public'))
    38  app.use(bodyParser.urlencoded({ extended: true }))
    39  app.set('view engine', 'ejs')
    40  
    41  // Some helpers for parsing/validating input
    42  let asInteger = value => new Promise((resolve, reject) =>
    43    (i => isNaN(i) ? reject(`${value} is ${typeof value} not integer`) : resolve(i))(parseInt(value)))
    44  
    45  let param = (obj, prop) => new Promise((resolve, reject) =>
    46    prop in obj ? resolve(obj[prop]) : reject(`expected key '${prop}' in ${JSON.stringify(obj)}`))
    47  
    48  let handlerError = err => { console.log(err); return err.toString() }
    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.render('index', {valueIs: ret.values.value, error: null}))
    54    .catch(err => res.send(handlerError(err))))
    55  
    56  // this next get occurs when the user presses the get value button on the website
    57  // Get the value from the contract by calling the Solidity 'get' method
    58  app.get('/getValue', (req, res) => store.get()
    59    .then(ret => res.render('index', {valueIs: ret.values.value, error: null}))
    60    .catch(err => res.send(handlerError(err))))
    61  
    62  // Sets the value by accepting a value in HTTP POST data and calling the Solidity 'set' method
    63  app.post('/', (req, res) => param(req.body, 'valueNum')
    64    .then(valueNum => asInteger(valueNum))
    65    .then(valueNum => store.set(valueNum))
    66    .then(ret => res.render('index', {valueIs: 'logged', error: null}))
    67  
    68    .catch(err => res.send(handlerError(err))))
    69  
    70  // Sets a value by HTTP POSTing to the value you expect to be stored encoded in the URL - so that the value can be
    71  // updated atomically
    72  app.post('/:test', (req, res) => param(req.body, 'value')
    73    .then(value => Promise.all([asInteger(req.params.test), asInteger(value)]))
    74    .then(([test, value]) => store.testAndSet(test, value))
    75    .then(ret => res.send(ret.values))
    76    .catch(err => res.send(handlerError(err))))
    77  
    78  const url = `http://127.0.0.1:${exampleAppPort}`
    79  
    80  // Listen for requests
    81  app.listen(exampleAppPort, () => console.log(`Example app listening on ${url}...
    82  
    83  You may wish to try the following: 
    84  # Inspect current stored value
    85    $ curl ${url}
    86    
    87  # Set the value to 2000
    88    $ curl -d '{"value": 2000}' -H "Content-Type: application/json" -X POST ${url}
    89    
    90  # Set the value via a testAndSet operation
    91    $ curl -d '{"value": 30}' -H "Content-Type: application/json" -X POST ${url}/2000
    92    
    93  # Attempt the same testAndSet which now fails since the value stored is no longer '2000'
    94    $ curl -d '{"value": 30}' -H "Content-Type: application/json" -X POST ${url}/2000
    95    $ curl ${url}
    96    `))