Clone or download
Failed to load latest commit information.
.circleci Don't use node-specific KeyClient during GovTx execution. Fix dev Aug 23, 2018
.github Rename to Burrow Apr 4, 2017
acm Fixup for tendermint 0.24 Sep 21, 2018
bcm Fixup for tendermint 0.24 Sep 21, 2018
binary Add test for revert, return nested errors, and convert non-revert errors Aug 7, 2018
cmd/burrow Reduce the number of concurrent solc's we run Sep 14, 2018
config GovTx based validator set changes implemented and tested Jul 23, 2018
consensus Fixup for tendermint 0.24 Sep 21, 2018
core Don't use node-specific KeyClient during GovTx execution. Fix dev Aug 23, 2018
crypto Update against breaking Tendermint changes Aug 21, 2018
deploy Refactor state into refs and tree. Sep 14, 2018
deployment Rationalise GRPC, protobuf, integration testing Jul 18, 2018
docs/images Don't use node-specific KeyClient during GovTx execution. Fix dev Aug 23, 2018
event Fix resubscribe test by adding a buffer so that publish doesn't get Aug 20, 2018
execution Fixup for tendermint 0.24 Sep 21, 2018
forensics Update dump to use amino codec Aug 23, 2018
genesis Handle sequence number checking and incrementation generically for all Jul 28, 2018
governance GovTx based validator set changes implemented and tested Jul 23, 2018
integration nil pointer exception when name does not exist Sep 17, 2018
keys Don't use node-specific KeyClient during GovTx execution. Fix dev Aug 23, 2018
logging Refactor state into refs and tree. Sep 14, 2018
permission Reenable PublicKey initialisation and allow public keys to be unset Jul 27, 2018
process Remove go-wire from codebase completely Jun 13, 2018
project Update changelog Sep 21, 2018
protobuf Make simulated call use same path as call_context Aug 16, 2018
rpc nil pointer exception when name does not exist Sep 17, 2018
scripts solgo: compiles solidity to go with abi Aug 30, 2018
storage Removed debug statement Sep 19, 2018
sync Release lock earlier in BroadcastTxSync and support mempool signing in Jul 25, 2018
tests Move to solidity 0.4.25 Sep 19, 2018
txs Merge branch 'develop' into state Sep 19, 2018
util Make snatives solidity use _camelcase parameters Aug 16, 2018
vendor Vendor tendermint 0.24 Sep 20, 2018
.dockerignore Sort out docker and release builds Aug 20, 2018
.gitignore Refactor rpc/tm to rpcinfo changing various names. Aug 15, 2018
.goreleaser.yml Use hyperledger/burrow and release binaries Aug 16, 2018 Update changelog Sep 21, 2018
Dockerfile Incorporate Casey's dockerfile changes Aug 21, 2018
Gopkg.lock Vendor tendermint 0.24 Sep 20, 2018
Gopkg.toml Vendor tendermint 0.24 Sep 20, 2018 strings.ToUpper(the-license-filename-prefix) Mar 4, 2017
Makefile solgo: compiles solidity to go with abi Aug 30, 2018 Update changelog Sep 21, 2018 Update Sep 5, 2018

Hyperledger Burrow

GoDoc Linux
Master Circle CI
Develop Circle CI (develop)

Hyperledger Burrow is a permissioned Ethereum smart-contract blockchain node. It executes Ethereum EVM smart contract code (usually written in Solidity) on a permissioned virtual machine. Burrow provides transaction finality and high transaction throughput on a proof-of-stake Tendermint consensus engine.

burrow logo

What is Burrow

Hyperledger Burrow is a permissioned blockchain node that executes smart contract code following the Ethereum specification. Burrow is built for a multi-chain universe with application specific optimization in mind. Burrow as a node is constructed out of three main components: the consensus engine, the permissioned Ethereum virtual machine and the rpc gateway. More specifically Burrow consists of the following:

  • Consensus Engine: Transactions are ordered and finalised with the Byzantine fault-tolerant Tendermint protocol. The Tendermint protocol provides high transaction throughput over a set of known validators and prevents the blockchain from forking.
  • Application Blockchain Interface (ABCI): The smart contract application interfaces with the consensus engine over the ABCI. The ABCI allows for the consensus engine to remain agnostic from the smart contract application.
  • Smart Contract Application: Transactions are validated and applied to the application state in the order that the consensus engine has finalised them. The application state consists of all accounts, the validator set and the name registry. Accounts in Burrow have permissions and either contain smart contract code or correspond to a public-private key pair. A transaction that calls on the smart contract code in a given account will activate the execution of that account’s code in a permissioned virtual machine.
  • Permissioned Ethereum Virtual Machine: This virtual machine is built to observe the Ethereum operation code specification and additionally asserts the correct permissions have been granted. Permissioning is enforced through secure native functions and underlies all smart contract code. An arbitrary but finite amount of gas is handed out for every execution to ensure a finite execution duration - “You don’t need money to play, when you have permission to play”.
  • Application Binary Interface (ABI): Transactions need to be formulated in a binary format that can be processed by the blockchain node. Current tooling provides functionality to compile, deploy and link solidity smart contracts and formulate transactions to call smart contracts on the chain.
  • API Gateway: Burrow exposes REST and JSON-RPC endpoints to interact with the blockchain network and the application state through broadcasting transactions, or querying the current state of the application. Websockets allow subscribing to events, which is particularly valuable as the consensus engine and smart contract application can give unambiguously finalised results to transactions within one blocktime of about one second.

Project documentation and Roadmap

Project information generally updated on a quarterly basis can be found on the Hyperledger Burrow Wiki.


  • Install go version 1.10 or above and have $GOPATH set
go get
make build

This will build the burrow and burrow-client binaries and put them in the bin/ directory. They can be executed from there or put wherever is convenient.

You can also install burrow into $GOPATH/bin with make install_burrow,


The end result will be a burrow.toml that will be read in from your current working directory when starting burrow.


Configure Burrow

The quick-and-dirty one-liner looks like:

# Read spec on stdin
burrow spec -p1 -f1 | burrow configure -s- > burrow.toml

which translates into:

# This is a place we can store config files and burrow's working directory '.burrow'
mkdir chain_dir && cd chain_dir
burrow spec --participant-accounts=1 --full-accounts=1 > genesis-spec.json
burrow configure --genesis-spec=genesis-spec.json > burrow.toml

Run Burrow

Once the burrow.toml has been created, we run:

# To select our validator address by index in the GenesisDoc
burrow start --validator-index=0
# Or to select based on address directly (substituting the example address below with your validator's):
burrow start --validator-address=BE584820DC904A55449D7EB0C97607B40224B96E

and the logs will start streaming through.

If you would like to reset your node, you can just delete its working directory with rm -rf .burrow. In the context of a multi-node chain it will resync with peers, otherwise it will restart from height 0.


Logging is highly configurable through the burrow.toml [logging] section. Each log line is a list of key-value pairs that flows from the root sink through possible child sinks. Each sink can have an output, a transform, and sinks that it outputs to. Below is a more involved example than the one appearing in the default generated config of what you can configure:

# This is a top level config section within the main Burrow config
  # All log lines are sent to the root sink from all sources
    # We define two child sinks that each receive all log lines
      # We send all output to stderr
        output_type = "stderr"

      # But for the second sink we define a transform that filters log lines from Tendermint's p2p module
        transform_type = "filter"
        filter_mode = "exclude_when_all_match"

          key_regex = "module"
          value_regex = "p2p"

          key_regex = "captured_logging_source"
          value_regex = "tendermint_log15"

      # The child sinks of this filter transform sink are syslog and file and will omit log lines originating from p2p
          output_type = "syslog"
          url = ""
          tag = "Burrow-network"

          output_type = "file"
          path = "/var/log/burrow-network.log"

Deploy Contracts

Now that the burrow node is running, we can deploy contracts.

For this step, we need two things: one or more solidity contracts, and an deploy.yaml.

Let's take a simple example, found in this directory.

The deploy.yaml should look like:


- name: deployStorageK
    contract: storage.sol

- name: setStorageBaseBool
    val: "true"

- name: setStorageBool
    destination: $deployStorageK
    function: setBool
    data: [$setStorageBaseBool]

- name: queryStorageBool
    destination: $deployStorageK
    function: getBool

- name: assertStorageBool
    key: $queryStorageBool
    relation: eq
    val: $setStorageBaseBool

# tests string bools: #71
- name: setStorageBool2
    destination: $deployStorageK
    function: setBool2
    data: [true]

- name: queryStorageBool2
    destination: $deployStorageK
    function: getBool2

- name: assertStorageBool2
    key: $queryStorageBool2
    relation: eq
    val: "true"

- name: setStorageBaseInt
    val: 50000

- name: setStorageInt
    destination: $deployStorageK
    function: setInt
    data: [$setStorageBaseInt]

- name: queryStorageInt
    destination: $deployStorageK
    function: getInt

- name: assertStorageInt
    key: $queryStorageInt
    relation: eq
    val: $setStorageBaseInt

- name: setStorageBaseUint
    val: 9999999

- name: setStorageUint
    destination: $deployStorageK
    function: setUint
    data: [$setStorageBaseUint]

- name: queryStorageUint
    destination: $deployStorageK
    function: getUint

- name: assertStorageUint
    key: $queryStorageUint
    relation: eq
    val: $setStorageBaseUint

- name: setStorageBaseAddress
    val: "1040E6521541DAB4E7EE57F21226DD17CE9F0FB7"

- name: setStorageAddress
    destination: $deployStorageK
    function: setAddress
    data: [$setStorageBaseAddress]

- name: queryStorageAddress
    destination: $deployStorageK
    function: getAddress

- name: assertStorageAddress
    key: $queryStorageAddress
    relation: eq
    val: $setStorageBaseAddress

- name: setStorageBaseBytes
    val: marmatoshi

- name: setStorageBytes
    destination: $deployStorageK
    function: setBytes
    data: [$setStorageBaseBytes]

- name: queryStorageBytes
    destination: $deployStorageK
    function: getBytes

- name: assertStorageBytes
    key: $queryStorageBytes
    relation: eq
    val: $setStorageBaseBytes

- name: setStorageBaseString
    val: nakaburrow

- name: setStorageString
    destination: $deployStorageK
    function: setString
    data: [$setStorageBaseString]

- name: queryStorageString
    destination: $deployStorageK
    function: getString

- name: assertStorageString
    key: $queryStorageString
    relation: eq
    val: $setStorageBaseString

while our Solidity contract (storage.sol) looks like:

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) {
    storedBool = x;

  function getBool() constant returns (bool retBool) {
    return storedBool;

  function setBool2(bool x) {
    storedBool2 = x;

  function getBool2() constant returns (bool retBool) {
    return storedBool2;

  function setInt(int x) {
    storedInt = x;

  function getInt() constant returns (int retInt) {
    return storedInt;

  function setUint(uint x) {
    storedUint = x;

  function getUint() constant returns (uint retUint) {
    return storedUint;

  function setAddress(address x) {
    storedAddress = x;

  function getAddress() constant returns (address retAddress) {
    return storedAddress;

  function setBytes(bytes32 x) {
    storedBytes = x;

  function getBytes() constant returns (bytes32 retBytes) {
    return storedBytes;

  function setString(string x) {
    storedString = x;

  function getString() constant returns (string retString) {
    return storedString;

Both files (deploy.yaml & storage.sol) should be in the same directory with no other yaml or sol files.

From inside that directory, we are ready to deploy.

burrow deploy --address=F71831847564B7008AD30DD56336D9C42787CF63

where you should replace the --address field with the ValidatorAddress at the top of your burrow.toml.

That's it! You've succesfully deployed (and tested) a Soldity contract to a Burrow node.

Note - that to redeploy the burrow chain later, you will need the same genesis-spec.json and burrow.toml files - so keep hold of them!


We welcome any and all contributions. Read the contributing file for more information on making your first Pull Request to Burrow!

You can find us on:

Future work

For some (slightly outdated) ideas on future work, see the proposals document.


Apache 2.0