Git Product home page Git Product logo

chainsafe / chainbridge Goto Github PK

View Code? Open in Web Editor NEW
471.0 40.0 301.0 20.9 MB

๐ŸŒ‰ Modular Multi-Directional Blockchain Bridge to interact with Multiple Networks; Ethereum, Ethereum Classic, Substrate, based chains. Stay tuned for ChainBridge Hub!

License: GNU Lesser General Public License v3.0

Go 99.31% Makefile 0.19% Shell 0.45% Dockerfile 0.06%
ethereum substrate cosmos celo polygon

chainbridge's Introduction

Archiving notice:

This library is no longer in use and maintenance. All further development related to chainbridge will happen in the new repo. More detailed information about chainbridge-core you can find in its readme or Discussions.

If you already running an old ChainBridge version please consider checking chainbridge-migration scripts that allow migrating to a newer version of chainbridge.

ChainBridge

discord build status

Contents

Getting Started

Installation

Dependencies

  • Subkey: Used for substrate key management. Only required if connecting to a substrate chain.

Building

make build: Builds chainbridge in ./build.

or

make install: Uses go install to add chainbridge to your GOBIN.

Docker

The official ChainBridge Docker image can be found here.

To build the Docker image locally run:

docker build -t chainsafe/chainbridge .

To start ChainBridge:

  • docker run -v uses an absolute path rather than a relative one.
docker run -v $(pwd)/config.json:/config.json chainsafe/chainbridge

Configuration

Note: TOML configs have been deprecated in favour of JSON

A chain configurations take this form:

{
    "name": "eth",                      // Human-readable name
    "type": "ethereum",                 // Chain type (eg. "ethereum" or "substrate")
    "id": "0",                          // Chain ID
    "endpoint": "ws://<host>:<port>",   // Node endpoint
    "from": "0xff93...",                // On-chain address of relayer
    "opts": {},                         // Chain-specific configuration options (see below)
}

See config.json.example for an example configuration.

Ethereum Options

Ethereum chains support the following additional options:

{
    "bridge": "0x12345...",          // Address of the bridge contract (required)
    "erc20Handler": "0x1234...",     // Address of erc20 handler (required)
    "erc721Handler": "0x1234...",    // Address of erc721 handler (required)
    "genericHandler": "0x1234...",   // Address of generic handler (required)
    "maxGasPrice": "0x1234",         // Gas price for transactions (default: 20000000000)
    "minGasPrice": "0x1234",         // Minimum gas price for transactions (default: 0)
    "gasLimit": "0x1234",            // Gas limit for transactions (default: 6721975)
    "gasMultiplier": "1.25",         // Multiplies the gas price by the supplied value (default: 1)
    "http": "true",                  // Whether the chain connection is ws or http (default: false)
    "startBlock": "1234",            // The block to start processing events from (default: 0)
    "blockConfirmations": "10"       // Number of blocks to wait before processing a block
    "useExtendedCall": "true"        // Extend extrinsic calls to substrate with ResourceID. Used for backward compatibility with example pallet. *Default: false*
    "egsApiKey": "xxx..."            // API key for Eth Gas Station (https://www.ethgasstation.info/)
    "egsSpeed": "fast"               // Desired speed for gas price selection, the options are: "average", "fast", "fastest"
}

Substrate Options

Substrate supports the following additonal options:

{
    "startBlock": "1234" // The block to start processing events from (default: 0)
}

Blockstore

The blockstore is used to record the last block the relayer processed, so it can pick up where it left off.

If a startBlock option is provided (see Configuration), then the greater of startBlock and the latest block in the blockstore is used at startup.

To disable loading from the blockstore specify the --fresh flag. A custom path for the blockstore can be provided with --blockstore <path>. For development, the --latest flag can be used to start from the current block and override any other configuration.

Keystore

ChainBridge requires keys to sign and submit transactions, and to identify each bridge node on chain.

To use secure keys, see chainbridge accounts --help. The keystore password can be supplied with the KEYSTORE_PASSWORD environment variable.

To import external ethereum keys, such as those generated with geth, use chainbridge accounts import --ethereum /path/to/key.

To import private keys as keystores, use chainbridge accounts import --privateKey key.

For testing purposes, chainbridge provides 5 test keys. The can be used with --testkey <name>, where name is one of Alice, Bob, Charlie, Dave, or Eve.

Metrics

See metrics.md.

Chain Implementations

  • Ethereum (Solidity): chainbridge-solidity

    The Solidity contracts required for chainbridge. Includes deployment and interaction CLI.

    The bindings for the contracts live in bindings/. To update the bindings modify scripts/setup-contracts.sh and then run make clean && make setup-contracts

  • Substrate: chainbridge-substrate

    A substrate pallet that can be integrated into a chain, as well as an example pallet to demonstrate chain integration.

Docs

MKdocs will generate static HTML files for Chainsafe markdown files located in Chainbridge/docs/

make install-mkdocs: Pull the docker image MkDocs

make mkdocs: Run MkDoc's docker image, building and hosting the html files on localhost:8000

Testing

Unit tests require an ethereum node running on localhost:8545 and a substrate node running on localhost:9944. E2E tests require an additional ethereum node on localhost:8546.

A docker-compose file is provided to run two Geth nodes and a chainbridge-substrate-chain node in isolated environments:

$ docker-compose -f ./docker-compose-e2e.yml up

See chainbridge-solidity and chainbridge-substrate-chain for more information on testing facilities.

All Go tests can be run with:

$ make test

Go tests specifically for ethereum, substrate and E2E can be run with

$ make test-eth
$ make test-sub
$ make test-e2e

ChainSafe Security Policy

Reporting a Security Bug

We take all security issues seriously, if you believe you have found a security issue within a ChainSafe project please notify us immediately. If an issue is confirmed, we will take all necessary precautions to ensure a statement and patch release is made in a timely manner.

Please email us a description of the flaw and any related information (e.g. reproduction steps, version) to security at chainsafe dot io.

chainbridge's People

Contributors

alirezaly avatar ansermino avatar anthonychernyak avatar dependabot-preview[bot] avatar dependabot[bot] avatar gregthegreek avatar mario-sangar avatar mikiquantum avatar noot avatar orangemio avatar p1sar avatar polycarpik avatar priom avatar ryry79261 avatar spacesailor24 avatar steviezhang avatar tolak avatar vezenovm avatar waymobetta avatar winor30 avatar ysfkel avatar zivkovicmilos avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

chainbridge's Issues

Refactor chain start

The current chain start (found in main.go) independently creates the chains from the config, it would be much cleaner if it iteratively created them all.

Use chainId from RPC instead of harcoded

Things to do:

  1. Add a flag --gethdev. This is used incase someone uses geth --dev, which uses the default Clique settings (found here) basically triggers every hardfork at block 0
  2. If the --gethdev flag is passed on this line use:
signer: ethtypes.MakeSigner(ethparams.AllCliqueProtocolChanges, ethparams.AllCliqueProtocolChanges.HomesteadBlock),
  1. if --geth is not passed use mainnet config
  2. call the rpc method to get the chain id and override the chain ID accordingly

Add chain specific config

Right now we make use of a single ChainConfig Which is found in core/chain.go we should refactor this out for chain specific configs

start chains from a specific block

Currently a the bridge starts fromthe current block, in reality it should start from the block when the contract was deployed.

The end result should be that any event emitted before the bridge booted up should be processed.

This can be done by either:

  • having it a param in the config (less ideal)
  • starting from block 0 (more ideal)

Test key chain

Goal: Provide reproducible keys for testing (go tests and testing environment).

Case 1:
Inside a test we want to use keys that are easy to manage and update as necessary.

Case 2:
When we run two or more instances, we need to have multiple validator identities, we want this to be easy to configure on the fly.

Proposed Solution:

  • Add 5 identities to the Go code
    • Alice, Bob, Charlie, Dave, Eve
    • These keys also need to be added to the Javascript side (just secp)
    • They should match the keys used by substrate
    • Each identity will have an associated secp, sr25519 and ed25519 keypair
  • Provide a way to access these keys within Go code
    • eg. TestKeystore.Alice.PublicKey()
  • Provide flags to start bridge using a specific identity
    • eg --Alice, --Eve

Producing Keys
We want to use the name (eg "bob") as the private key. We will need to represent this as bytes and should verify that we are producing the same keys as substrate (ideally).

Proposed Structure
We should implement this as a separate package that contains the go code to access these keys, likely keystore/keyring.

We also need to modify the keystore to have the option of using these keys. This will remove the need for our existing test keystore (need to update the tests using it as well).

Add Centrifuge NFT event

We need an event emitted from the Centrifuge chain so we can capture it on the bridge and tranfer it to Ethereum

EVM Tests

Further tests for Emitter.sol focusing on the locking mechanism of the Safe.sol

Execute proposal check

Refer to #118 for epic information.

The main goal is to prevent a bridge validator from submitting a transaction (that will revert/fail) because the deposit has already been finalized (VoteStatus.finalized).

The check should probably occur in the writer and skip the current write if that proposal is already finalized.

Implement Message Router

Needs to pass messages from a Listener to the correct Writer based on the protocol/message ID.

Basic Connections

The writers and listeners need to share a connection to their respective network. Before implementing the adapters we should establish connection components for each network that provide:

  • setting listeners for events
  • submitting txs (state changing or otherwise)

These also need to be configurable, so we can specify the node, what keys to use etc.

Implement Chain Type

Chains will store their respective Connection, Listener, and Pusher as well as source and destination addrs and their chain identifier.

Add HTTP RPC Support

In order to handle Ethermint connections we need the option of using HTTP RPC with ethereum chains.

This simply requires we use a different rpc client. rpc.DialHttp() will give us an HTTP connection instead of WS. We should provide an optional config option to use HTTP instead of WS. It is anticipated that this will required no additional changes to how we are using the client.

https://github.com/ChainSafe/ChainBridgeV2/blob/ccc38b2c9a4db9105508ee5cc5ae9252c95a5e8c/chains/ethereum/connection.go#L46-L60

releaseErc and releaseNFT methods in Safe.sol are unable to be called

Both releaseErc and releaseNFT in Safe.sol have the function modifier onlyOwner. Because Emitter.sol constructs Safe.sol with address(this) (making it the owner of Safe.sol), and Emitter.sol has no methods to call releaseErc or releaseNFT, these methods are uncallable once contracts are deployed.

In the branch wyatt/evm-tests there is a test that currently fails because of this issue.

Vote proposal check

Refer to #118 for epic information.

The main goal is to prevent a bridge validator from submitting a transaction (that will revert/fail) because the vote has already been made. The required check is to ensure the current relayer has not already voted on a specific proposal.

The check should probably occur in the writer and skip the current write if that person has already voted

Refactor test mnemonic

The current mnemonic is scrambled across two spots(I think):

  • The test scripts have it hard coded: start_ganahce.sh
  • The test scripts for solidity have the private keys outright exposed: deploy_local.js

We should instead:

  1. Make an ENV variable in the makefile
  2. pass the ENV variable to the different commands as they need them

Special case for deploy_local.js:

  • We need to derive the wallets into the correct public/private keys, and maintain the current array structure (to reduce re-writing everything). Ping me if this becomes tricky, ive done it a lot.

Allow Chain-specific Configs

Presently all chains have the same fields in the config file. It would be nice to be able to provide arbitrary config options to allow for chain-specific options. Perhaps this can take the form of an opts field, which can then take key/values that are later interpreted by that chains listener/writer. We should also replace id with type to specify which chain type we want.
An example case is the contract addresses required for ethereum.

Current toml lib: https://github.com/naoina/toml

Create deposit check

Refer to #118 for epic information.

The main goal is to prevent a bridge validator from submitting a transaction (that will revert/fail) because the deposit has already been made.

The check should probably occur in the writer and skip the current write if that proposal already exists on chain

Add Ethereum Key Import Command

It would be very useful if we could import existing keystore files. We can start with ethereum keystores and look at adding other support later.

We can utilize geth to be able to import the key format, then we just need to create a new keystore file for the bridge with the same private key.

Importing a key will look something like: chainbridge accounts --import --ethereum /path/to/key....

start_eth --silent as ENV variable

Currently start_eth accepts a value of --silent to be passed in as an argument. we should change it to be an env variable so that we can do SILENT=true make_start eth. This allows us to use make start_eth in the CI runs.

Make build and run dont work

d@P51:~/dev/ChainBridgeV2$ make build
  >  Building binary... 
cd cmd && env GOARCH=amd64 go build -o ./bridge
build .: cannot find module for path .
Makefile:33: recipe for target 'build' failed
make: *** [build] Error 1
d@P51:~/dev/ChainBridgeV2$ make run
  >  Running main.go... 
go run -v cmd/chainbridge/main.go
ChainBridgeV2/core
ChainBridgeV2/chains/ethereum
command-line-arguments
# command-line-arguments
cmd/chainbridge/main.go:18:2: undefined: ConfigFileFlag
cmd/chainbridge/main.go:19:2: undefined: VerbosityFlag
cmd/chainbridge/main.go:20:2: undefined: KeystorePathFlag
cmd/chainbridge/main.go:48:46: undefined: VerbosityFlag
cmd/chainbridge/main.go:50:52: undefined: VerbosityFlag
cmd/chainbridge/main.go:66:14: undefined: getConfig
Makefile:37: recipe for target 'run' failed
make: *** [run] Error 2

Define Interfaces

We need to define Connection, Listener and Pusher interfaces based on todays discussions.

Refactor ChainId

The chainID should be an optional flag and configuration file option. Currently we have gethDev and kovan which need to be removed.

Some things to consider:

  • makeSigner uses chainConfig but only actually takes the ChainID parameter, so we should make use of the underlying function to build the signerObject.
  • we may also want to add a block number parameter, this is for the second parameter in the makeSigner object (it may not be needed) otherwise default should be instanbulBlock

Start bridge via config file

We need to configure the bridge contract addresses and the node connections (ws/http). It might make sense to use the chain identifiers here, which are also used with the system to distinguish destination chains.

[Ethereum] Add checks to prevent failed txs

Once #112 gets merged, we'll run into problems because our validators are currently not smart. If a deposit happens on chain A, a validator will see that event and create a proposal on chain B. Another validator would also see that event, and try to make a proposal, it will fail, and the validator will lose some gas from the failed transaction.

We need a suit of functions to help make our validators smarter. All of these functions should return booleans and not be integrated into the bridge logic yet (we will integrate them later, but compartmentalizing them will make testing easier). These functions are linked below:

An example would be:

func proposalExists(chainId, depositId) boolean {
  value := queryChainForDeposit()
  if value return true
  else return false
}

Keystore

We should utilize a keystore to provide easy & secure access to signing keys. For example, we could have a master password that encrypts all private keys for every network.

This should also make it easier to pass around keys. If adapters can interact with the keystore they could sign and verify for their own network as well as the destination/source if required.

This can also be used in the deployment infrastructure to establish new keys and load them into the bridge,

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.