当前位置: 首页 > 工具软件 > Burrow > 使用案例 >

Hyperledger caliper兼容burrow最新版本方案

东郭展
2023-12-01

1. 引言

caliper 支持的burrow最新版本为0.23.0,而现在最新的版本为0.30.2,不能支持新版本的测试。这里将添加兼容性代码和相关测试用例代码以支撑新版本的测试。

2. 环境

  • os: centos7.6
  • docker-ce:19.03.5
  • docker-compose: 1.18.0
  • nvm: 0.33.11
  • node: v10.20.0
  • npm: 6.14.4
  • npx: 6.14.4
  • solc:0.5.16+commit.9c3226ce.Linux.g++

3. 下载源码

git clone https://github.com/hyperledger/caliper.git
git clone https://github.com/hyperledger/caliper-benchmarks.git

4. 修改源码

4.1 caliper项目

老版本用得js库是@monax/burrow@0.23.0,换成最新的@hyperledger/burrow@0.30.2

packages/caliper-burrow/package.json
    "devDependencies": {
        "@hyperledger/burrow": "0.30.2",
        "chai": "^3.5.0",
        "eslint": "^5.16.0",
        "mocha": "3.4.2",
        "nyc": "11.1.0",
        "rewire": "^4.0.0",
        "sinon": "^7.3.2",
        "license-check-and-add": "2.3.6"
    }
packages/caliper-cli/lib/lib/config.yaml
    burrow:
        0.23.0:
            packages: [ '@monax/burrow@0.23.0' ]
        0.30.2: &burrow-latest
            packages: [ '@hyperledger/burrow@0.30.2' ]
        latest: *burrow-latest

burrow.js这块完全要重写,目前调用合约 js类库不支持,需要将callTx的data传进去。

packages/caliper-burrow/lib/burrow.js
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

const fs = require('fs');
const burrowTS = require('@hyperledger/burrow');
const { BlockchainInterface, CaliperUtils, ConfigUtil, TxStatus } = require('@hyperledger/caliper-core');
const logger = CaliperUtils.getLogger('burrow.js');

/**
    Read the connection details from the config file.
    @param {object} config Adapter config.
    @return {object} url, account Connection settings.
*/
function burrowConnect(config) {
    let host = config.burrow.network.validator.host;
    if (host === null) {
        throw new Error('host url not set');
    }

    let port = config.burrow.network.validator.port;
    if (port === null) {
        throw new Error('grpc port not set');
    }

    let account;
    try {
        account = fs.readFileSync(CaliperUtils.resolvePath(config.burrow.network.validator.address)).toString();
    } catch (err) {
        account = config.burrow.network.validator.address.toString();
    }
    logger.info(`Account: ${account}`);
    if (account === null) {
        throw new Error('no validator account found');
    }

    return {
        url: host + ':' + port,
        account: account,
    };
}

/**
 * Implements {BlockchainInterface} for a Burrow backend.
 */
class Burrow extends BlockchainInterface {

    /**
   * Create a new instance of the {Burrow} class.
   * @param {number} workerIndex The zero-based index of the worker who wants to create an adapter instance. -1 for the master process. Currently unused.
   */
    constructor(workerIndex) {
        super();
        let configPath = CaliperUtils.resolvePath(ConfigUtil.get(ConfigUtil.keys.NetworkConfig));
        this.config = require(configPath);
        this.statusInterval = null;
        this.bcType = 'burrow';
    }

    /**
     * Retrieve the blockchain type the implementation relates to
     * @returns {string} the blockchain type
     */
    getType() {
        return this.bcType;
    }

    /**
     * Initialize the {Burrow} object.
     * @param {boolean} workerInit Indicates whether the initialization happens in the worker process.
     */
    async init(workerInit) {
        return await CaliperUtils.sleep(2000);
    }

    /**
     * Deploy the smart contract specified in the network configuration file.
     * @return {object} Promise execution for namereg.
     */
    async installSmartContract() {
        let connection = burrowConnect(this.config);
        let burrow = new burrowTS.Burrow(connection.url, connection.account);
        let data, abi, bytecode, contract;
        try {
            data = JSON.parse(fs.readFileSync(CaliperUtils.resolvePath(this.config.contract.path)).toString());
            abi = data.Abi;
            bytecode = data.Evm.Bytecode.Object;
            contract = await burrow.contracts.deploy(abi, bytecode);
            logger.info("contract address:",contract.address)
            
        } catch (err) {
            logger.error("deploy contract error",err)
            throw err;
        }
        return  new Promise(function (resolve, reject) {
             burrow.namereg.set('DOUG', contract.address, 50000, 5000,(err, data) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(data);
                }
            })
        },err => {
            logger.info('namereg reject error:',err);
        }).then(function (result) {
            return result;
        }).catch(e => logger.error('namereg catch error',e));
    }

    /**
     * Return the Burrow context associated with the given callback module name.
     * @param {string} name The name of the callback module as defined in the configuration files.
     * @param {object} args Unused.
     * @return {object} The assembled Burrow context.
     * @async
     */
    async getContext(name, args) {
        let context = this.config.burrow.context;
        if (typeof context === 'undefined') {
            let connection = burrowConnect(this.config);
            let burrow = new burrowTS.Burrow(connection.url, connection.account);
            let contractMetaData = JSON.parse(fs.readFileSync(CaliperUtils.resolvePath(this.config.contract.path)).toString());
            // get the contract address from the namereg      
            return  new Promise(function (resolve, reject) {
                    burrow.namereg.get('DOUG', (err, result) => {
                        if(err){
                            reject(err);
                        }else{
                            let address=result.getData()
                            let  contract = new burrowTS.Contract(contractMetaData.Abi,contractMetaData.Evm.Bytecode.Object,address,burrow);
                            context = { account: connection.account, address: address,contract:contract, burrow: burrow };
                            resolve(context);
                        }
                    })
            }).then(function(result){
                return Promise.resolve(result); 
            },err => {
                logger.info('getContext reject error:',err);
                reject(err);
            }).catch(e => function(e){
                logger.info("getContext catch error:",e)
                reject(e);
            });

        }
        return Promise.resolve(context);
    }

    /**
     * Release the given Burrow context.
     * @param {object} context The Burrow context to release.
     * @async
     */
    async releaseContext(context) {
        // nothing to do
    }
    /**
     * Query state from the ledger using a smart contract
     * @param {Object} context context object
     * @param {String} contractID identity of the contract
     * @param {String} contractVer version of the contract
     * @param {Array} args array of JSON formatted arguments
     * @param {Number} timeout request timeout, in seconds
     * @return {Promise} query response object
     */
    async querySmartContract(context, contractID, contractVer, args, timeout) {
       let promises = [];
        args.forEach((item, index) => {
            promises.push(this.doInvoke(context, contractID, contractVer, item, timeout));  
        })
        return await Promise.all(promises);
    }
   /**
   * Invoke a smart contract.
   * @param {Object} context Context object.
   * @param {String} contractID Identity of the contract.
   * @param {String} contractVer Version of the contract.
   * @param {Array} args args {'funName': 'getInt','funArgs': [], data:'callTx.data'}
   * @param {Number} timeout Request timeout, in seconds.
   * @return {Promise<object>} The promise for the result of the execution.
   */
    async invokeSmartContract(context, contractID, contractVer, args, timeout) {
        let promises = [];
        args.forEach((item, index) => {
            if(item.verb==='transfer'){
                promises.push(this.acccountTransfer(context, item, timeout));  
            }else if(item.verb==='invoke'){
                if (!item.hasOwnProperty('funName')) {
                    return Promise.reject(new Error(' missed argument:funName '));
                }
                if (!item.hasOwnProperty('funArgs')) {
                    return Promise.reject(new Error(' missed argument:funArgs '));
                }
                promises.push(this.doInvoke(context, contractID, contractVer, item, timeout));  
            }
        })
        return await Promise.all(promises);
    }

    /**
   * Submit a transaction to the burrow daemon with the specified options.
   * @param {Object} context Context object.
   * @param {String} contractID Identity of the contract.
   * @param {String} contractVer Version of the contract.
   * @param {Array} arg {'funName': 'setInt','funArgs': [1000], data:'callTx.data'}
   * @param {Number} timeout Request timeout, in seconds.
   * @return {Promise<TxStatus>} Result and stats of the transaction invocation.
   */
    async doInvoke(context, contractID, contractVer, arg, timeout) {
        let status = new TxStatus();
        if (context.engine) {
            context.engine.submitCallback(1);
        }
        //let contract = await context.burrow.contracts.address(context.address);
        //Todo: can't get contract with burrow.contracts.address 
       return  context.contract[arg.funName](...arg.funArgs).then(function (result) {
            status.SetStatusSuccess();
            return status;
        },err => {
            status.SetStatusFail();
            logger.info('invoke reject error:',err);
            return status;
        }).catch(e => {
            status.SetStatusFail();
            logger.info("invoke catch error:",e)
            return status;
        });
    }
  /**
   * Submit a transaction to the burrow daemon with the specified options.
   * @param {Object} context Context object.
   * @param {String} arg {toAccount:'',money:''}
   * @param {Number} timeout Request timeout, in seconds.
   * @return {Promise<TxStatus>} Result and stats of the transaction invocation.
   */
  async acccountTransfer(context, arg, timeout) {
        let account=context.account
        let toAccount=arg.toAccount
        let amount= parseFloat(arg.money)
        let status = new TxStatus(toAccount);
        if (context.engine) {
            context.engine.submitCallback(1);
        }
        let callTx=new burrowTS.payload.CallTx()
        callTx.addInputs

        let inputTx=new burrowTS.payload.TxInput()
        inputTx.setAddress(Buffer.from(account, 'hex'))
        inputTx.setAmount(amount)
        
        let sendTx=new burrowTS.payload.SendTx()
        sendTx.addInputs(inputTx)
        let outputTx=new burrowTS.payload.TxInput()
        outputTx.setAddress(Buffer.from(toAccount, 'hex'))
        outputTx.setAmount(amount)
        sendTx.addOutputs(outputTx)
        return new Promise(function (resolve, reject) {
             context.burrow.tc.sendTxSync(sendTx, (err, data) => {
                if(err){
                    status.SetStatusFail();
                    reject(err);
                }else{
                    status.SetID(data.getReceipt().getTxhash_asB64());
                    status.SetStatusSuccess();
                    resolve(data);
                }
              });
        }).then(function (result) {
            return status;
        },err => {
            logger.info('sendTx reject error:',err);
            return status;
        }).catch(e => {
            logger.info("sendTx catch error:",e)
            status.SetStatusFail();
            return status;
        });  
    }

    /**
     * Query the given smart contract according to the specified options.
     * @param {object} context The Burrow context returned by {getContext}.
     * @param {string} contractID The name of the contract.
     * @param {string} contractVer The version of the contract.
     * @param {string} key The argument to pass to the smart contract query.
     * @param {string} [fcn=query] The contract query function name.
     * @return {Promise<object>} The promise for the result of the execution.
     */
    async queryState(context, contractID, contractVer, key, fcn = 'query') {
        let status = new TxStatus();
        if (context.engine) {
            context.engine.submitCallback(1);
        }
        return new Promise(function (resolve, reject) {
            let getAccountParam=new burrowTS.rpcquery.GetAccountParam()
            getAccountParam.setAddress(Buffer.from(context.address, 'hex'))
            context.burrow.qc.getAccount(getAccountParam, function (err, data) {
                if (err) {
                    status.SetStatusFail();
                    reject(err);
                } else {
                    status.SetStatusSuccess();
                    resolve(data);
                }
            });
        }).then(function (result) {
            return status;
        },err => {
            logger.info('queryState reject error:',err);
            return status;
        }).catch(e => function(e){
            logger.info("queryState catch error",e)
            status.SetStatusFail();
            return status;
        });
    }

    /**
   * Get adapter specific transaction statistics.
   * @param {JSON} stats txStatistics object
   * @param {Array} results array of txStatus objects.
   */
    getDefaultTxStats(stats, results) {
        // empty
    }
}
module.exports = Burrow;


详见:https://github.com/itling/caliper

4.2 caliper-benchmark项目

创建benchmarks/burrow/sample文件夹,新增以下文件

benchmarks/burrow/sample/config.yaml
---
test:
  name: simple
  description: This is an example benchmark for caliper, to test the backend DLT's
    performance with simple account transfer & querying transactions& invoking transactions
  workers:
    type: local
    number: 1
  rounds:
  - label: account transfer
    description: Test description for transfering money between accounts
    txNumber: 2
    rateControl:
      type: fixed-rate
      opts:
        tps: 1
    arguments:
      money: 1000,
      toAccount: "2F186F827E9DC641D6D08C98E55DA631556DDB0D"
    callback: benchmarks/samples/burrow/transfer.js
  - label: contract invoke
    description: Test description for the invoke performance of the deployed chaincode
    txNumber: 2
    rateControl:
      type: fixed-rate
      opts:
        tps: 1
    callback: benchmarks/samples/burrow/invoke.js
  - label: contract query
    description: Test description for the query performance of the deployed chaincode
    txNumber: 2
    rateControl:
      type: fixed-rate
      opts:
        tps: 1
    callback: benchmarks/samples/burrow/query.js
monitor:
  type:
  - docker
  docker:
    name:
    - all
  interval: 1
benchmarks/burrow/sample/transfer.js
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


'use strict';

module.exports.info = 'transfering money to account';

let bc, contx;
let initmoney,toAccount;

module.exports.init = function (blockchain, context, args) {
    if (!args.hasOwnProperty('money')) {
        return Promise.reject(new Error('account.transfer - \'money\' is missed in the arguments'));
    }
    bc = blockchain;
    contx = context;
    initmoney = args.money;
    toAccount = args.toAccount
    return Promise.resolve();
};

module.exports.run = function () {
    let args = [{
            'verb':'transfer',
            'toAccount': toAccount,
            'money': initmoney
     }];
    return bc.invokeSmartContract(contx, 'SimpleStorage', 'v0', args, 10);

};

module.exports.end = function () {
    // do nothing
    return Promise.resolve();
};
benchmarks/burrow/sample/invoke,js
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

module.exports.info  = 'invoke contract  set state';

let bc, contx;

module.exports.init = function(blockchain, context, args) {
    bc        = blockchain;
    contx     = context;

    return Promise.resolve();
};

module.exports.run = function() {
    let args = [{
        verb:'invoke',
        funName: 'setInt',
        funArgs: [1000]
    }];
    return bc.invokeSmartContract(contx, 'SimpleStorage', 'v0', args, 10);
};

module.exports.end = function() {
    return Promise.resolve();
};

benchmarks/burrow/sample/query.js
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

module.exports.info  = 'querying contract state';

let bc, contx;

module.exports.init = function(blockchain, context, args) {
    bc       = blockchain;
    contx    = context;
    return Promise.resolve();
};

module.exports.run = function() {
    let args = [{
        funName: 'getInt',
        funArgs: []
    }];
    return bc.querySmartContract(contx, 'SimpleStorage', 'v0', args, 10);
};

module.exports.end = function() {
    // do nothing
    return Promise.resolve();
};

创建src/burrow/sample文件夹,新增以下文件

src/burrow/sample/deploy.yaml
jobs:

- name: buildSimpleStorage
  build:
      contract: storage.sol

storage.sol

pragma solidity >=0.0.0;

contract SimpleStorage {
  bool storedBool;
  bool storedBool2;
  int storedInt;
  uint storedUint;
  address storedAddress;
  bytes32 storedBytes;
  string storedString;

  function setBool(bool x) public {
    storedBool = x;
  }

  function getBool() view public returns (bool retBool) {
    return storedBool;
  }

  function setBool2(bool x) public {
    storedBool2 = x;
  }

  function getBool2() view public returns (bool retBool) {
    return storedBool2;
  }

  function setInt(int x) public {
    storedInt = x;
  }

  function getInt() view public returns (int retInt) {
    return storedInt;
  }

  function setUint(uint x) public {
    storedUint = x;
  }

  function getUint() view public returns (uint retUint) {
    return storedUint;
  }

  function setAddress(address x) public {
    storedAddress = x;
  }

  function getAddress() view public returns (address retAddress) {
    return storedAddress;
  }

  function setBytes(bytes32 x) public {
    storedBytes = x;
  }

  function getBytes() view public returns (bytes32 retBytes) {
    return storedBytes;
  }

  function setString(string memory x) public {
    storedString = x;
  }

  function getString() view public returns (string memory retString) {
    return storedString;
  }
}
src/burrow/sample/storage.bin
{"Abi":[{"constant":true,"inputs":[],"name":"getAddress","outputs":[{"internalType":"address","name":"retAddress","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getBool","outputs":[{"internalType":"bool","name":"retBool","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getBool2","outputs":[{"internalType":"bool","name":"retBool","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getBytes","outputs":[{"internalType":"bytes32","name":"retBytes","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInt","outputs":[{"internalType":"int256","name":"retInt","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getString","outputs":[{"internalType":"string","name":"retString","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getUint","outputs":[{"internalType":"uint256","name":"retUint","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"x","type":"address"}],"name":"setAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bool","name":"x","type":"bool"}],"name":"setBool","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bool","name":"x","type":"bool"}],"name":"setBool2","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"x","type":"bytes32"}],"name":"setBytes","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"int256","name":"x","type":"int256"}],"name":"setInt","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"string","name":"x","type":"string"}],"name":"setString","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"setUint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}],"Devdoc":{"methods":{}},"Evm":{"Bytecode":{"LinkReferences":{},"Object":"608060405234801561001057600080fd5b506106e7806100206000396000f3fe608060405234801561001057600080fd5b50600436106100e95760003560e01c8063627389981161008c57806389ea642f1161006657806389ea642f1461031d578063e30081a0146103a0578063e6748da9146103e4578063ecc55e4b14610412576100e9565b80636273899814610216578063747586b8146102345780637fcaf66614610262576100e9565b80631e26fd33116100c85780631e26fd331461014c57806338cc48311461017c57806348378eea146101c65780634ef65c3b146101e8576100e9565b80620267a4146100ee5780630bcd3b331461010c57806312a7b9141461012a575b600080fd5b6100f6610442565b6040518082815260200191505060405180910390f35b61011461044c565b6040518082815260200191505060405180910390f35b610132610456565b604051808215151515815260200191505060405180910390f35b61017a6004803603602081101561016257600080fd5b8101908080351515906020019092919050505061046c565b005b610184610488565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101ce6104b2565b604051808215151515815260200191505060405180910390f35b610214600480360360208110156101fe57600080fd5b81019080803590602001909291905050506104c8565b005b61021e6104d2565b6040518082815260200191505060405180910390f35b6102606004803603602081101561024a57600080fd5b81019080803590602001909291905050506104dc565b005b61031b6004803603602081101561027857600080fd5b810190808035906020019064010000000081111561029557600080fd5b8201836020820111156102a757600080fd5b803590602001918460018302840111640100000000831117156102c957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506104e6565b005b610325610500565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561036557808201518184015260208101905061034a565b50505050905090810190601f1680156103925780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103e2600480360360208110156103b657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506105a2565b005b610410600480360360208110156103fa57600080fd5b81019080803590602001909291905050506105e6565b005b6104406004803603602081101561042857600080fd5b810190808035151590602001909291905050506105f0565b005b6000600254905090565b6000600454905090565b60008060009054906101000a900460ff16905090565b806000806101000a81548160ff02191690831515021790555050565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060019054906101000a900460ff16905090565b8060028190555050565b6000600154905090565b8060018190555050565b80600590805190602001906104fc92919061060d565b5050565b606060058054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105985780601f1061056d57610100808354040283529160200191610598565b820191906000526020600020905b81548152906001019060200180831161057b57829003601f168201915b5050505050905090565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b8060048190555050565b80600060016101000a81548160ff02191690831515021790555050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061064e57805160ff191683800117855561067c565b8280016001018555821561067c579182015b8281111561067b578251825591602001919060010190610660565b5b509050610689919061068d565b5090565b6106af91905b808211156106ab576000816000905550600101610693565b5090565b9056fea265627a7a72315820ee28ad92df6f4b8687026d2307d4f4698a2ca5ca2175e01daa8f0aa3ec97fa2b64736f6c63430005100032","Opcodes":"PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x6E7 DUP1 PUSH2 0x20 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0xE9 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x62738998 GT PUSH2 0x8C JUMPI DUP1 PUSH4 0x89EA642F GT PUSH2 0x66 JUMPI DUP1 PUSH4 0x89EA642F EQ PUSH2 0x31D JUMPI DUP1 PUSH4 0xE30081A0 EQ PUSH2 0x3A0 JUMPI DUP1 PUSH4 0xE6748DA9 EQ PUSH2 0x3E4 JUMPI DUP1 PUSH4 0xECC55E4B EQ PUSH2 0x412 JUMPI PUSH2 0xE9 JUMP JUMPDEST DUP1 PUSH4 0x62738998 EQ PUSH2 0x216 JUMPI DUP1 PUSH4 0x747586B8 EQ PUSH2 0x234 JUMPI DUP1 PUSH4 0x7FCAF666 EQ PUSH2 0x262 JUMPI PUSH2 0xE9 JUMP JUMPDEST DUP1 PUSH4 0x1E26FD33 GT PUSH2 0xC8 JUMPI DUP1 PUSH4 0x1E26FD33 EQ PUSH2 0x14C JUMPI DUP1 PUSH4 0x38CC4831 EQ PUSH2 0x17C JUMPI DUP1 PUSH4 0x48378EEA EQ PUSH2 0x1C6 JUMPI DUP1 PUSH4 0x4EF65C3B EQ PUSH2 0x1E8 JUMPI PUSH2 0xE9 JUMP JUMPDEST DUP1 PUSH3 0x267A4 EQ PUSH2 0xEE JUMPI DUP1 PUSH4 0xBCD3B33 EQ PUSH2 0x10C JUMPI DUP1 PUSH4 0x12A7B914 EQ PUSH2 0x12A JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xF6 PUSH2 0x442 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x114 PUSH2 0x44C JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x132 PUSH2 0x456 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x17A PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH2 0x162 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD ISZERO ISZERO SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH2 0x46C JUMP JUMPDEST STOP JUMPDEST PUSH2 0x184 PUSH2 0x488 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x1CE PUSH2 0x4B2 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x214 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH2 0x1FE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH2 0x4C8 JUMP JUMPDEST STOP JUMPDEST PUSH2 0x21E PUSH2 0x4D2 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x260 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH2 0x24A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH2 0x4DC JUMP JUMPDEST STOP JUMPDEST PUSH2 0x31B PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH2 0x278 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 PUSH5 0x100000000 DUP2 GT ISZERO PUSH2 0x295 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 ADD DUP4 PUSH1 0x20 DUP3 ADD GT ISZERO PUSH2 0x2A7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP2 DUP5 PUSH1 0x1 DUP4 MUL DUP5 ADD GT PUSH5 0x100000000 DUP4 GT OR ISZERO PUSH2 0x2C9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP2 SWAP1 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY PUSH1 0x0 DUP2 DUP5 ADD MSTORE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND SWAP1 POP DUP1 DUP4 ADD SWAP3 POP POP POP POP POP POP POP SWAP2 SWAP3 SWAP2 SWAP3 SWAP1 POP POP POP PUSH2 0x4E6 JUMP JUMPDEST STOP JUMPDEST PUSH2 0x325 PUSH2 0x500 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP4 DUP2 DUP2 MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x365 JUMPI DUP1 DUP3 ADD MLOAD DUP2 DUP5 ADD MSTORE PUSH1 0x20 DUP2 ADD SWAP1 POP PUSH2 0x34A JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x392 JUMPI DUP1 DUP3 SUB DUP1 MLOAD PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP JUMPDEST POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x3E2 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH2 0x3B6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH2 0x5A2 JUMP JUMPDEST STOP JUMPDEST PUSH2 0x410 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH2 0x3FA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH2 0x5E6 JUMP JUMPDEST STOP JUMPDEST PUSH2 0x440 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH2 0x428 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD ISZERO ISZERO SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH2 0x5F0 JUMP JUMPDEST STOP JUMPDEST PUSH1 0x0 PUSH1 0x2 SLOAD SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x4 SLOAD SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH1 0xFF AND SWAP1 POP SWAP1 JUMP JUMPDEST DUP1 PUSH1 0x0 DUP1 PUSH2 0x100 EXP DUP2 SLOAD DUP2 PUSH1 0xFF MUL NOT AND SWAP1 DUP4 ISZERO ISZERO MUL OR SWAP1 SSTORE POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x3 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x1 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH1 0xFF AND SWAP1 POP SWAP1 JUMP JUMPDEST DUP1 PUSH1 0x2 DUP2 SWAP1 SSTORE POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 SLOAD SWAP1 POP SWAP1 JUMP JUMPDEST DUP1 PUSH1 0x1 DUP2 SWAP1 SSTORE POP POP JUMP JUMPDEST DUP1 PUSH1 0x5 SWAP1 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 PUSH2 0x4FC SWAP3 SWAP2 SWAP1 PUSH2 0x60D JUMP JUMPDEST POP POP JUMP JUMPDEST PUSH1 0x60 PUSH1 0x5 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP1 ISZERO PUSH2 0x598 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x56D JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x598 JUMP JUMPDEST DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 JUMPDEST DUP2 SLOAD DUP2 MSTORE SWAP1 PUSH1 0x1 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0x57B JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP SWAP1 POP SWAP1 JUMP JUMPDEST DUP1 PUSH1 0x3 PUSH1 0x0 PUSH2 0x100 EXP DUP2 SLOAD DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND MUL OR SWAP1 SSTORE POP POP JUMP JUMPDEST DUP1 PUSH1 0x4 DUP2 SWAP1 SSTORE POP POP JUMP JUMPDEST DUP1 PUSH1 0x0 PUSH1 0x1 PUSH2 0x100 EXP DUP2 SLOAD DUP2 PUSH1 0xFF MUL NOT AND SWAP1 DUP4 ISZERO ISZERO MUL OR SWAP1 SSTORE POP POP JUMP JUMPDEST DUP3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 PUSH1 0x1F ADD PUSH1 0x20 SWAP1 DIV DUP2 ADD SWAP3 DUP3 PUSH1 0x1F LT PUSH2 0x64E JUMPI DUP1 MLOAD PUSH1 0xFF NOT AND DUP4 DUP1 ADD OR DUP6 SSTORE PUSH2 0x67C JUMP JUMPDEST DUP3 DUP1 ADD PUSH1 0x1 ADD DUP6 SSTORE DUP3 ISZERO PUSH2 0x67C JUMPI SWAP2 DUP3 ADD JUMPDEST DUP3 DUP2 GT ISZERO PUSH2 0x67B JUMPI DUP3 MLOAD DUP3 SSTORE SWAP2 PUSH1 0x20 ADD SWAP2 SWAP1 PUSH1 0x1 ADD SWAP1 PUSH2 0x660 JUMP JUMPDEST JUMPDEST POP SWAP1 POP PUSH2 0x689 SWAP2 SWAP1 PUSH2 0x68D JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST PUSH2 0x6AF SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH2 0x6AB JUMPI PUSH1 0x0 DUP2 PUSH1 0x0 SWAP1 SSTORE POP PUSH1 0x1 ADD PUSH2 0x693 JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST SWAP1 JUMP INVALID LOG2 PUSH6 0x627A7A723158 KECCAK256 0xEE 0x28 0xAD SWAP3 0xDF PUSH16 0x4B8687026D2307D4F4698A2CA5CA2175 0xE0 SAR 0xAA DUP16 EXP LOG3 0xEC SWAP8 STATICCALL 0x2B PUSH5 0x736F6C6343 STOP SDIV LT STOP ORIGIN ","SourceMap":"26:1258:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;26:1258:0;;;;;;;"}},"Metadata":"{\"compiler\":{\"version\":\"0.5.16+commit.9c3226ce\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"constant\":true,\"inputs\":[],\"name\":\"getAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"retAddress\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getBool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"retBool\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getBool2\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"retBool\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getBytes\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"retBytes\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getInt\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"retInt\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getString\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"retString\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getUint\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"retUint\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"x\",\"type\":\"address\"}],\"name\":\"setAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"bool\",\"name\":\"x\",\"type\":\"bool\"}],\"name\":\"setBool\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"bool\",\"name\":\"x\",\"type\":\"bool\"}],\"name\":\"setBool2\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"x\",\"type\":\"bytes32\"}],\"name\":\"setBytes\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"int256\",\"name\":\"x\",\"type\":\"int256\"}],\"name\":\"setInt\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"string\",\"name\":\"x\",\"type\":\"string\"}],\"name\":\"setString\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"}],\"name\":\"setUint\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"methods\":{}},\"userdoc\":{\"methods\":{}}},\"settings\":{\"compilationTarget\":{\"storage.sol\":\"SimpleStorage\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"storage.sol\":{\"keccak256\":\"0xdf1067754e59bf0e1d9c4099e3f10cbb9cff077829960d4ef167071dae66c0a5\",\"urls\":[\"bzz-raw://6956ec98cbca060ed53682ac7f01bbc49510c1f77952be95c7f6fd579e6a64c4\",\"dweb:/ipfs/QmQSDAQg9kkgLFKdXjkeGytqS34ys3UZLnCS1qg6Ze1Yrf\"]}},\"version\":1}"}

storage.bin编译方法:solc --standard-json --allow-paths /
,再将下面的内容复制到stdin,按Ctrl+D,再将输出的内容复制到storage.bin中,然后再稍作修改(去掉外面的几层{、Abi等首字母大写)。

{"language":"Solidity","sources":{"storage.sol":{"urls":["storage.sol"]}},"settings":{"libraries":{"":{}},"optimizer":{"enabled":false},"outputSelection":{"*":{"*":["abi","evm.bytecode.linkReferences","metadata","devdoc"]}}}}
src/burrow/sample/networks/burrow/simple/burrow_remote.json
{
  "caliper" : {
    "blockchain": "burrow",
    "command" : {
      
    }
  },
  "burrow": {
    "network": {
      "validator": {
        "host": "47.57.XX.XX",
        "port": "31896",
        "address": "4E416FD3D6874846D510B82A040FB2AA69CE8C76"
      }
    }
  },
  "contract": { "path": "src/burrow/sample/storage.bin" },
  "info" : {
    "Version": "develop",
    "Size": "5 Peers",
    "Distribution": "openshift cluster"
  }
}

详见:https://github.com/itling/caliper-benchmarks

4.3 burrow js客户端

新增了导出:payload、rpcquery,caliper的子模块caliper-burrow需要用到。

node_modules/@hyperledger/burrow/dist/index.js
"use strict";
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
    result["default"] = mod;
    return result;
};
exports.__esModule = true;
var Burrow_1 = require("./lib/Burrow");
exports.Burrow = Burrow_1.Burrow;
var contract_1 = require("./lib/contracts/contract");
exports.Contract = contract_1.Contract;
var utils = __importStar(require("./lib/utils/utils"));
exports.utils = utils;
var rpcquery = __importStar(require("../proto/rpcquery_pb"));
exports.rpcquery = rpcquery;
var payload = __importStar(require("../proto/payload_pb"));
exports.payload = payload;
var exec = require('../proto/exec_pb');
exports.TxExecution = exec.TxExecution;
//# sourceMappingURL=index.js.map
node_modules/@hyperledger/burrow/dist/index.d.ts
import { Burrow } from './lib/Burrow';
import { Contract } from './lib/contracts/contract';
import * as utils from './lib/utils/utils';
export * as rpcquery from '../proto/rpcquery_pb';
export * as payload from '../proto/payload_pb'
export { Burrow, Contract, utils, rpcquery,};
export { TxExecution } from '../proto/exec_pb';

5. 安装依赖

npm i && npm run repoclean -- --yes && npm run bootstrap

npm i:安装开发时依赖项,例如Lerna和许可证检查包。
npm run repoclean:清理node_modules存储库中所有软件包的目录。新克隆的存储库不需要。
npm run bootstrap:在存储库中安装所有软件包的依赖关系,并链接这些软件包之间的任何交叉依赖关系

6. 测试代码

目前仓库没有burrow的集成测试用例

BENCHMARK=fabric ./.travis/benchmark-integration-test-direct.sh

7. 启动私有仓库

要设置和启动本地Verdaccio服务器,只需运行以下命令

cd ./packages/caliper-publish
./publish.js verdaccio start

Verdaccio服务器现在正在侦听以下地址: http://localhost:4873

8. 发布软件包到私有仓库

./publish.js npm --registry "http://localhost:4873"
[NPM PUBLISH] Published package @hyperledger/caliper-cli@0.3.1-unstable-20200413123231

记录下版本号

9. 初始化caliper-benchmarks

cd caliper-benchmarks/
npm init -y
npm install --registry=http://localhost:4873 --only=prod \
   @hyperledger/caliper-cli@0.3.1-unstable-20200413123231

10. 运行测试用例

修改networks/burrow/simple/docker-compose.yml,镜像版本号为v0.30.2

npx caliper launch master \
    --caliper-bind-sut burrow:0.30.2 
    
npx caliper launch master \
    --caliper-workspace . \
    --caliper-benchconfig benchmarks/scenario/simple/config.yaml\
    --caliper-networkconfig networks/burrow/simple/burrow.json

11. 修改代码后重新测试

cd caliper
./packages/caliper-publish/publish.js npm --registry "http://localhost:4873"
cd caliper-benchmarks
## caliper-cli的版本为上一步发布的
npm install --registry=http://localhost:4873 --only=prod @hyperledger/caliper-cli@0.3.1-unstable-20200414053322

npx caliper launch master \
    --caliper-bind-sut burrow:0.30.2 
    
npx caliper launch master \
	--caliper-workspace . \
	--caliper-benchconfig benchmarks/samples/burrow/config.yaml \
	--caliper-networkconfig networks/burrow/simple/burrow_remote.json

12. 测试结果

burrow部署在openshfit上,5个节点,每个节点2 核 2G

在节点外部执行,网络延迟较少(都在阿里云香港区)

测试脚本

name: simple
description: >-
  This is an example benchmark for caliper, to test the backend DLT's
  performance with simple account transfer & querying transactions& invoking
  transactions
workers:
  type: local
  number: 10
rounds:
  - label: account transfer
    description: Test description for transfering money between accounts
    txNumber: 20000
    rateControl:
      type: fixed-rate
      opts:
        tps: 1000
    arguments:
      money: 100,
      toAccount: 2F186F827E9DC641D6D08C98E55DA631556DDB0D
    callback: benchmarks/samples/burrow/transfer.js
  - label: contract invoke
    description: Test description for the invoke performance of the deployed chaincode
    txNumber: 20000
    rateControl:
      type: fixed-rate
      opts:
        tps: 300
    arguments:
      data: 747586b80000000000000000000000000000000000000000000000000000000000004e20
    callback: benchmarks/samples/burrow/invoke.js
  - label: contract query
    description: Test description for the query performance of the deployed chaincode
    txNumber: 20000
    rateControl:
      type: fixed-rate
      opts:
        tps: 300
    arguments:
      data: '62738998'
    callback: benchmarks/samples/burrow/query.js
+------------------+-------+------+-----------------+-----------------+-----------------+-----------------+------------------+
| Name             | Succ  | Fail | Send Rate (TPS) | Max Latency (s) | Min Latency (s) | Avg Latency (s) | Throughput (TPS) |
|------------------|-------|------|-----------------|-----------------|-----------------|-----------------|------------------|
| account transfer | 20000 | 0    | 996.7           | 38.89           | 0.51            | 21.13           | 341.3            |
|------------------|-------|------|-----------------|-----------------|-----------------|-----------------|------------------|
| contract invoke  | 20000 | 0    | 300.0           | 15.67           | 0.47            | 6.49            | 249.2            |
|------------------|-------|------|-----------------|-----------------|-----------------|-----------------|------------------|
| contract query   | 20000 | 0    | 299.9           | 12.51           | 0.49            | 5.24            | 264.6            |
+------------------+-------+------+-----------------+-----------------+-----------------+-----------------+------------------+

13. 遇到的问题

  1. 执行npx caliper launch master...的时候报错
Error: Module "@hyperledger/caliper-burrow" could not be loaded: Error: Cannot find module 'google-protobuf'

安装一下依赖即可解决

 npm install --save google-protobuf
  1. mac 下执行npm i && npm run repoclean -- --yes && npm run bootstrap报错
ERROR:root:code for hash md5 was not found.
Traceback (most recent call last):
  File "/usr/local/Cellar/python@2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/hashlib.py", line 147, in <module>

执行以下命令

sudo xcode-select --switch /Library/Developer/CommandLineTools
 类似资料: