github.com/aychain/blockbook@v0.1.1-0.20181121092459-6d1fc7e07c5b/CONTRIBUTING.md (about)

     1  # Blockbook Contributor Guide
     2  
     3  Blockbook is back-end service for Trezor wallet. Although it is open source, design and development of core packages
     4  is done by Trezor developers in order to keep Blockbook compatible with Trezor.
     5  
     6  Bug fixes and support for new coins are welcome. Please take note that non-fixing pull requests that change base
     7  packages or another coin code will not be accepted. If you will have to change some of existing code, please file
     8  an issue and discuss your request with Blockbook maintainers.
     9  
    10  ## Development environment
    11  
    12  Instructions to set up your development environment and build Blockbook are described in separated
    13  [document](/docs/build.md).
    14  
    15  ## How can I contribute?
    16  
    17  ### Reporting bugs
    18  
    19  A great way to contribute to the project is to send a detailed report when you encounter an issue. We always appreciate
    20  a well-written, thorough bug report, and will thank you for it!
    21  
    22  Check that [our issue database](https://github.com/trezor/blockbook/issues) doesn't already include that problem or
    23  suggestion before submitting an issue. If you find a match, you can use the "subscribe" button to get notified on
    24  updates. Do not leave random "+1" or "I have this too" comments, as they only clutter the discussion, and don't help
    25  resolving it. However, if you have ways to reproduce the issue or have additional information that may help resolving
    26  the issue, please leave a comment.
    27  
    28  Include information about Blockbook instance which is exposed at internal HTTP port. Ports are listed in
    29  [port registry](/docs/ports.md). For example execute `curl -k https://localhost:9030` for Bitcoin.
    30  
    31  Also include the steps required to reproduce the problem if possible and applicable. This information will help us
    32  review and fix your issue faster. When sending lengthy log-files, consider posting them as a gist
    33  (https://gist.github.com).
    34  
    35  ### Adding coin support
    36  
    37  Trezor harware wallet supports over 500 coins, see https://trezor.io/coins/. You are free to add support for any of
    38  them to Blockbook. Actually implemented coins are listed [here](/docs/ports.md).
    39  
    40  You should follow few steps bellow to get smooth merge of your PR.
    41  
    42  > Although we are happy for support of new coins we have not enough capacity to run them all on our infrastructure.
    43  > Actually we can run Blockbook instances only for coins supported by Trezor wallet. If you want to have Blockbook
    44  > instance for your coin, you will have to deploy your own server.
    45  
    46  #### Add coin definition
    47  
    48  Coin definitions are stored in JSON files in *configs/coins* directory. They are single source of Blockbook
    49  configuration, Blockbook and back-end package definition and build metadata. Since Blockbook supports only single
    50  coin index per running instance, every coin (including testnet) must have single definition file.
    51  
    52  All options of coin definition are described in [config.md](/docs/config.md).
    53  
    54  Because most of coins are fork of Bitcoin and they have similar way to install and configure their daemon, we use
    55  templates to generate package definition and configuration files during build process. Similarly, there templates for Blockbook
    56  package. Templates are filled with data from coin definition. Although normally all package definitions are generated automatically
    57  during the build process, sometimes there is a reason to see them. You can create them by calling
    58  `go run build/templates/generate.go coin`, where *coin* is name of definition file without .json extension. Files are
    59  generated to *build/pkg-defs* directory.
    60  
    61  Good examples of coin configuration are
    62  [*configs/coins/bitcoin.json*](configs/coins/bitcoin.json) and
    63  [*configs/coins/ethereum.json*](configs/coins/ethereum.json) for Bitcoin-like coins and different coins, respectively.
    64  
    65  Usually you have to update only few options that differ from Bitcoin definition. At first there is base information
    66  about coin in section *coin* – name, alias etc. Then update port information in *port* section. We keep port series as
    67  listed in [the port registry](/docs/ports.md). Select next port numbers in the series. Port numbers must be unique across all
    68  port definitions.
    69  
    70  In the section *backend* update information how to build and configure back-end service. When back-end package is built,
    71  build process downloads installation archive, verifies and extracts it. How it is done is described in
    72  [build guide](/docs/build.md#on-back-end-building). Naming conventions and versioning are described
    73  also in [build guide](/docs/build.md#on-naming-conventions-and-versioning). You have to update *package_name*,
    74  *package_revision*, *system_user*, *version*, *binary_url*, *verification_type*, *verification_source*,
    75  *extract_command* and *exclude_files*. Also update information whether service runs mainnet or testnet network in
    76  *mainnet* option.
    77  
    78  In the section *blockbook* update information how to build and configure Blockbook service. Usually they are only
    79  *package_name*, *system_user* and *explorer_url* options. Naming conventions are are described
    80  [here](/docs/build.md#on-naming-conventions-and-versioning).
    81  
    82  Update *package_maintainer* and *package_maintainer_email* options in the section *meta*.
    83  
    84  Execute script *go run contrib/scripts/check-and-generate-port-registry.go -w* that checks mandatory ports and
    85  uniqueness of ports and updates registry of ports *docs/ports.md*.
    86  
    87  Now you can try to generate package definitions as described above in order to check outputs.
    88  
    89  #### Add coin implementation
    90  
    91  Coin implementation is stored in *bchain/coins* directory. Each coin must implement interfaces *BlockChain* and
    92  *BlockChainParser* (both defined in [bchain/types.go][/bchain/types.go]) and has registered factory function by
    93  *init()* function of package *blockbook/bchain/coins* ([bchain/coins/blockchain.go](/bchain/coins/blockchain.go)).
    94  
    95  There are several approaches how to implement coin support in Blockbook, please see examples below.
    96  
    97  Bitcoin package *blockbook/bchain/coins/btc* is a reference implementation for Bitcoin-like coins. Most of the functionality
    98  is usually the same so particular coin should embed it and override just different parts.
    99  
   100  Bitcoin uses binary WIRE protocol thus decoding is very fast but require complex parser. Parser translate whole
   101  pubkey-script to database ID and therefore it is usually possible store transactions without change.
   102  
   103  ZCash package *blockbook/bchain/coins/zec* on the other side uses JSON version of RPCs therefore it doesn't require
   104  specialized parser. Only responsibility that parser has is to translate address to Address Descriptor (used as 
   105  address ID in the database) and vice versa.
   106  
   107  Ethereum package *blockbook/bchain/coins/eth* has own stand alone implementation because Ethereum uses totally
   108  different concept than Bitcoin.
   109  
   110  ##### BlockChain interface
   111  
   112  Type that implements *bchain.BlockChain* interface ensures communication with block chain network. Because
   113  it calls node RPCs it usually has suffix RPC.
   114  
   115  Initialization of object is separated into two stages. At first there is called factory method (details described
   116  in next section) and then *bchain.BlockChain.Initialize()* method. Separated initialization method allows you call
   117  inherited methods during initialization. However it is common practice override fields of embedded structure in factory
   118  method.
   119  
   120  During initialization, there is usually loaded chain information, registered message queue callback and created mempool
   121  and parser objects.
   122  
   123  BitcoinRPC uses *btc.RPCMarshaller* ([btc/codec.go](/bchain/coins/btc/codec.go)) in order to distinguish API version of
   124  Bitcoin RPC. Current API (*btc.JSONMarshalerV2*) uses JSON object with method arguments. Older API (*btc.JSONMarshalerV1*)
   125  uses JSON array with method arguments and some arguments are defined differently (e.g. bool vs int).
   126  
   127  For example see [zec/zcashrpc.go](/bchain/coins/zec/zcashrpc.go).
   128  
   129  ##### BlockChain factory function
   130  
   131  Factory function must be *coins.blockChainFactory* type ([coins/blockchain.go](/bchain/coins/blockchain.go)). It gets
   132  configuration as JSON object and handler function for PUSH notifications. All factory functions have registered by
   133  *init()* function of package *blockbook/bchain/coins* ([coins/blockchain.go](/bchain/coins/blockchain.go)). Coin name
   134  must correspond to *coin.name* in coin definition file (see above).
   135  
   136  Configuration passed to factory method is coin specific. For types that embed *btc.BitcoinRPC,* configuration must
   137  contain at least fields referred in *btc.Configuration* ([btc/bitcoinrpc.go](/bchain/coins/btc/bitcoinrpc.go)).
   138  
   139  For types that embed base struct it is common practise call factory method of embedded type in order to
   140  create & initialize it. It is much more robust than simple struct composition.
   141  
   142  For example see [zec/zcashrpc.go](/bchain/coins/zec/zcashrpc.go).
   143  
   144  ##### BlockChainParser interface
   145  
   146  Type that implements *bchain.BlockChainParser* interface ensures parsing and conversions of block chain data. It is
   147  initialized by *bchain.BlockChain* during initialization.
   148  
   149  There are several groups of methods defined in *bchian.BlockChainParser*:
   150  
   151  * *GetAddrDescFromVout* and *GetAddrDescFromAddress* – Convert transaction addresses to *Address Descriptor* that is used as database ID.
   152    Most of coins use output script as *Address Descriptor*.
   153  * *GetAddressesFromAddrDesc* and *GetScriptFromAddrDesc*  – Convert *Address Descriptor* to addresses and output script. Note that
   154    *btc.BitcoinParser* uses pointer to function *OutputScriptToAddressesFunc* that is called from *GetAddressesFromAddrDesc*
   155    method in order to rewrite implementation by types embedding it.
   156  * *PackTxid* and *UnpackTxid* – Packs txid to store in database and vice versa.
   157  * *ParseTx* and *ParseTxFromJson* – Parse transaction from binary data or JSON and return *bchain.Tx*.
   158  * *PackTx* and *UnpackTx* – Pack transaction to binary data to store in database and vice versa.
   159  * *ParseBlock* – Parse block from binary data and return *bchain.Block*.
   160  
   161  Base type of parsers is *bchain.BaseParser*. It implements method *ParseTxFromJson* that should be the same for all
   162  Bitcoin-like coins. Also implements *PackTx* and *UnpackTx* that pack and unpack transactions using protobuf. Note
   163  that Bitcoin stores transactions in more compact binary format.
   164  
   165  *bchain.BaseParser* stores pointer to function *bchain.AddressFactoryFunc* that is responsible for making human readable
   166  address representation. See [*bch.bcashparser*](/bchain/coins/bch/bcashparser.go) for example of implementation that uses
   167  different approach for address representation than Bitcoin.
   168  
   169  #### Add tests
   170  
   171  Add unit tests and integration tests. PR without passing tests won't be accepted. 
   172  Tests are described [here](/docs/testing.md).
   173  
   174  #### Deploy public server
   175  
   176  Deploy Blockbook server on public IP address. Blockbook maintainers will check implementation before merging.