These instructions describes how to run the bridge between an Ethereum-based chain and the Binance Chain testnet.
This demo supports two ways of dealing with the Ethereum side of a bridge:
- Using development EVM-base chains (ganache)
- Using public networks (predefined configs use Kovan testnet and Sokol POA testnet)
As part of this demo two EVM-based chains (ganache) will be started:
- Home chain - it keeps an ERC20 contract (
0xd5fE0D28e058D375b0b038fFbB446Da37E85fFdc
) and the bridge contract (0x44c158FE850821ae69DaF37AADF5c539e9d0025B
). - Side chain - the MPC orchestration contract (
0xd5fE0D28e058D375b0b038fFbB446Da37E85fFdc
) is located here Both chains are run in separate docker containers. JSON-RPC ports are mapped to the host (7545 - side chain, 8545 - home chain)
Local Binance network within separate docker container will be used. In addition, some part of Binance accelerated node HTTP API will be emulated, since a regular full-node API does not provide all required features. APIs and NODE RPC ports are mapped to the host (26657 - RPC, 8080 - api-server, 8000 - emulated accelerated node api)
As part of this demo two EVM-based public chains will be used:
- Home chain - Kovan testnet keeps an ERC20 contract and the bridge contract.
- Side chain - Sokol POA testnet keeps the MPC orchestration contract. Interaction with chains is done by using public available RPC urls.
Public Binance testnet will be used for demo purposes. Interaction with chain is done by using a public available HTTP API endpoint.
Three validators will be run and only two validators are required to confirm the transfer. Every validator node is a set of docker containers (eth-watcher
, bnc-watcher
, signer
, proxy
, redis
, rabbitmq
).
The public Binance Chain testnet will keep a BEP2 token.
- Preparation
- (1.1) Clone the repo and initialize git submodules:
git clone --recurse-submodules https://github.com/k1rill-fedoseev/eth-to-bnc-bridge.git
- (1.2) Build TSS to be used in the bridge oracles:
docker build -t tss ./src/tss
- (1.3) Generate several private keys for bridge testing. (e. g.
openssl rand -hex 32
) - (1.4) Get Ethereum and Binance addresses for recently created accounts via running
./src/test-services/getAddresses/run.sh <PRIVATE_KEY>
- (1.1) Clone the repo and initialize git submodules:
- Run test environment
- (2.1) Modify
src/deploy/deploy-test/.env.development
and specify the amount of tokens to mint in the parameterTOKEN_INITIAL_MINT
. - (2.2) Run Ethereum testnets and deploy contracts
This command will also mint tokens, the owner of tokens is the address that corresponds to the private key specified in
TARGET_NETWORK=development ./demo/start-ethereum-environment.sh
HOME_PRIVATE_KEY
ofsrc/deploy/deploy-test/.env.development
(0xA374DC09057D6B3253d04fACb15736B43fBc7943
). - (2.4) Run Binance testnet and api services
This command will also issue a BEP2 token, the owner of tokens is the address that corresponds to the private key specified in
./demo/start-binance-environment.sh
FOREIGN_PRIVATE_KEY
ofsrc/test-services/binanceSend/.env.development
(tbnb1z7u9f8mcuwxanns9xa6qgjtlka0d392epc0m9x
). The balance oftbnb1z7u9f8mcuwxanns9xa6qgjtlka0d392epc0m9x
will contain 10000 BNB and 10000 Test Tokens. - (2.5) Send few tokens and coins from the current token owner to the first account. Coins are needed to pay transaction fees.
./src/test-services/ethereumSend/run.sh <first account Ethereum address> 5 0.5
- (2.6) Check that the tokens were transferred properly:
./src/test-services/ethereumBalance/run.sh <first account Ethereum address>
- (2.1) Modify
- Run validators nodes:
- (3.1) Run three validators in separate terminal sessions.
Wait for when the line like the following appears:
N=1 ./demo/validator-demo.sh N=2 ./demo/validator-demo.sh N=3 ./demo/validator-demo.sh
The line contains the address of the bridge address in the Binance Chain.keygen_1 | Generated multisig account in binance chain: tbnb1mutgnx9n9devmrjh3d0wz332fl8ymgel6tydx6
- (3.1) Run three validators in separate terminal sessions.
- Initialize the state of the bridge account in the Binance Chain
- (4.1) Fill the balance Fund with BNB coins as so the account will be able to make transactions:
To check the balance of the bridge account use
./src/test-services/binanceSend/run.sh <address of the bridge account> 100 1
./src/test-services/binanceBalance/run.sh <address of the bridge account>
- (4.1) Fill the balance Fund with BNB coins as so the account will be able to make transactions:
- Transfer tokens from Ethereum-based chain to the Binance Chain:
- (5.1) Send some amount of tokens to the bridge contract, for
PRIVATE_KEY
use some of the keys from step (1.3):PRIVATE_KEY=<test account private key> ./src/test-services/ethereumSend/run.sh bridge 5
- (5.2) The validators will catch the event and start the process to sign the transaction.
- (5.3) As soon as the signature is generated and sent, the balance of the bridge account in both chains will be changed:
should report non-zero balance,
./src/test-services/ethereumBalance/run.sh <ethereum bridge address>
should report about the balance reduction../src/test-services/binanceBalance/run.sh <binance bridge address>
- (5.4) Check that the tokens were transferred properly to the test account:
./src/test-services/binanceBalance/run.sh <test account address>
- (5.1) Send some amount of tokens to the bridge contract, for
- Transfer tokens from the Binance Chain to Ethereum-based chain:
- (6.1) Send some amount of tokens to the bridge account:
PRIVATE_KEY=<test account private key> ./src/test-services/binanceSend/run.sh <binance bridge address> 3
- (6.2) Check the balances of the test account on both sides of the bridge to see that the funds were transferred properly using commands from (5.3), (5.4).
- (6.1) Send some amount of tokens to the bridge account:
- Bridge supports changing the list of validators and required voting threshold via voting process, and then keys regeneration.
- (7.0) Obtain information about current epoch, current list validators, upcoming epoch information, bridge state via:
Where
curl http://localhost:$PORT/info
$PORT
is specific port for some validator oracle. The response object contains lots of useful information about current bridge state.{ // current epoch number, in which bridge is operating "epoch": 2, // next epoch number, for which votes and keygen operations are applied "nextEpoch": 3, // threshold number for current epoch, // at least threshold votes are required for any changes in next epoch "threshold": 2, // threshold number for next epoch "nextThreshold": 2, // current bridge addresses in home and foreign networks "homeBridgeAddress": "0x44c158FE850821ae69DaF37AADF5c539e9d0025B", "foreignBridgeAddress": "tbnb19z22khee969yj05dckg9usvmwndkucpyl543xk", // current set of validators "validators": [ "0x99Eb3D86663c6Db090eFFdBC20510Ca9f836DCE3", "0x6352e3e6038e05b9da00C84AE851308f9774F883" ], // set of validators for the next epoch "nextValidators": [ "0x99Eb3D86663c6Db090eFFdBC20510Ca9f836DCE3", "0x6352e3e6038e05b9da00C84AE851308f9774F883", "0xAa006899B0EC407De930bA8A166DEfe59bBfd3DC" ], // balances of bridge in both networks "homeBalance": 50, "foreignBalanceTokens": 100, "foreignBalanceNative": 0.0994, // current bridge status, can be one of: ready, voting, keygen, funds_transfer "bridgeStatus": "ready", // current votes count for starting voting, starting/cancelling keygen // -1 means that enough confirmations are already collected "votesForVoting": 0, "votesForKeygen": 0, "votesForCancelKeygen": 0, // collected confirmations for changing epoch to nextEpoch // -1 means that enough confirmations are already collected "confirmationsForFundsTransfer": 0 }
- (7.1) Start voting process for next epoch, via sending
$THRESHOLD
requests to/vote/startVoting
url. Bridge state should be successfully changed tovoting
. - 7.2 Changing next epoch bridge validators / threshold
- (7.2.1) Add / remove validator in next validators list, via sending
$THRESHOLD
requests to/vote/addValidator/$ADDRESS
//vote/removeValidator/$ADDRESS
. - (7.2.2) Change threshold for the next epoch, via sending
$THRESHOLD
requests to/vote/changeThreshold/$THRESHOLD
.
- (7.2.1) Add / remove validator in next validators list, via sending
- (7.3) Start keygen process for next epoch, via sending
$THRESHOLD
requests to/vote/startKeygen
url. Bridge state should be successfully changed tokeygen
, and in some time tofunds_transfer
, and then toready
. - (7.4) If keygen process at some state was stopped(i. e. one validator turned off his oracle),
it can be cancelled via via sending
$THRESHOLD
requests to/vote/cancelKeygen
url. After keygen cancellation, bridge state will return tovoting
, and later it can be restarted manually once again.
- (7.0) Obtain information about current epoch, current list validators, upcoming epoch information, bridge state via:
Staging mode demo is similar to development mode demo, but requires additional manual actions for preparing demo. Make sure, to first run demo in development mode, before trying to run it in the staging environment.
- Preparation
- (1.1) Download
tbnbcli
from https://github.com/binance-chain/node-binary/tree/master/cli. - (1.2) Create a new account through the web-interface in the Binance testnet wallet. Copy the private key and mnemonic phrase. The private key will be used to import it in an Ethereum Wallet. The mnemonic phrase is to recover the BNB with
tbnbcli
. - (1.3) Recover the account in the console with the mnemonic.
./tbnbcli keys add test_account1 --recover
- (1.4) Create few BNB accounts from the console. They will be donors to provide enough funds to issue a BEP2 tokens (500 BNB required).
./tbnbcli keys add test_account2 ./tbnbcli keys add test_account3
- (1.5) Register on the Binance site and fund the accounts from the testnet faucet.
- (1.6) Re-arrange funds on the accounts as so the first account will have 550 BNB and others 10-20 BNBs to make transactions.
./tbnbcli send --from test_account2 --to <address of the first account> \ --amount 18500000000:BNB --chain-id=Binance-Chain-Nile \ --node=data-seed-pre-2-s1.binance.org:80 --memo "donate" ./tbnbcli send --from test_account3 --to <address of the first account> \ --amount 18500000000:BNB --chain-id=Binance-Chain-Nile --node=data-seed-pre-2-s1.binance.org:80 --memo "donate"
- (1.7) Issue the BEP2 token from the first account.
3141500000000000
corresponds to31415000.0
tokens.In the real deployment most probably the token must not be mintable../tbnbcli token issue --token-name "ERC20toBEP2Bridge" --total-supply 3141500000000000 \ --symbol ETB0819 --mintable --from test_account1 --chain-id=Binance-Chain-Nile \ --node=data-seed-pre-2-s1.binance.org:80 --trust-node
- (1.8) Get the BEP2 token ID in
denom
field (in this example it isETB0819-863
)../tbnbcli account <address of the first account> \ --chain-id=Binance-Chain-Nile --node=data-seed-pre-2-s1.binance.org:80 --trust-node
- (1.9) Clone the repo and initialize git submodules:
git clone --recurse-submodules https://github.com/k1rill-fedoseev/eth-to-bnc-bridge.git
- (1.10) Build TSS to be used in the bridge oracles:
docker build -t tss ./src/tss
- (1.1) Download
- Run test environment
- (2.1) Prepare three private keys for validators. Get the Ethereum account addresses for these keys.
- (2.2) Modify
src/deploy/deploy-home/.env.staging
and specify the token contract address in the Kovan network viaHOME_TOKEN_ADDRESS
(use empty address0x
if you want to create new ERC20 contract while deployment).
SetVALIDATOR_ADDRESS_*
to Ethereum addresses obtained in the previous step. - (2.3) Modify
src/deploy/.keys.staging
and specify private keys for prefunded accounts in both networks. These accounts are used for contract deployment. Usesrc/deploy/.keys.staging.example
as an example. - (2.4) Deploy contracts
This command will deploy ERC20 contract and also mint tokens if you left
TARGET_NETWORK=staging ./demo/start-ethereum-environment.sh
HOME_TOKEN_ADDRESS
empty, the owner of tokens is the address that corresponds to the private key specified inHOME_PRIVATE_KEY
ofsrc/deploy/.keys.staging
.
Deployed contract addresses will be automatically updated in all required validators and test services configs. - (2.5) Prefund validator accounts in home network (Kovan):
TARGET_NETWORK=staging ./src/test-services/ethereumSend/run.sh <Nth validator address> 0 0.5
- (2.6) Prefund validator accounts in side network (Sokol):
TARGET_NETWORK=staging ./src/test-services/sidePrefund/run.sh <Nth validator address> 1
- (2.7) Send few tokens and coins from the current token owner to the first account. Coins are needed to pay transaction fees.
TARGET_NETWORK=staging ./src/test-services/ethereumSend/run.sh <first account Ethereum address> 5 0.5
- (2.8) Check that the tokens were transferred properly:
TARGET_NETWORK=staging ./src/test-services/ethereumBalance/run.sh <first account Ethereum address>
- Run validators nodes:
- (3.1) Modify the parameter
FOREIGN_ASSET
indemo/validator1/.env.staging
,demo/validator2/.env.staging
anddemo/validator3/.env.staging
to the identificator of the token (step 1.8) that the oracle will track.
For staging environment additionally specifyVALIDATOR_PRIVATE_KEY
in thedemo/validator<N>/.keys.staging
(step 2.2.1) - (3.2) Run three validators in separate terminal sessions.
Wait for when the line like the following appears:
N=1 TARGET_NETWORK=staging ./demo/validator-demo.sh N=2 TARGET_NETWORK=staging ./demo/validator-demo.sh N=3 TARGET_NETWORK=staging ./demo/validator-demo.sh
The line contains the address of the bridge address in the Binance Chain.keygen_1 | Generated multisig account in binance chain: tbnb1mutgnx9n9devmrjh3d0wz332fl8ymgel6tydx6
- (3.1) Modify the parameter
- Initialize the state of the bridge account in the Binance Chain
- (4.1) Fill the balance Fund with BNB coins as so the account will be able to make transactions:
./src/test-services/binanceSend/run.sh <address of the bridge account> 100 1
./src/test-services/binanceBalance/run.sh
or Binance Testnet Explorer. It should report about two assets owned by the account. - (4.1) Fill the balance Fund with BNB coins as so the account will be able to make transactions:
- Transfer tokens from Ethereum-based chain to the Binance Chain:
- (5.1) Send some amount of tokens to the bridge contract, for
PRIVATE_KEY
use some of the keys from step (1.3):TARGET_NETWORK=staging PRIVATE_KEY=<test account private key> ./src/test-services/ethereumSend/run.sh bridge 5
- (5.2) The validators will catch the event and start the process to sign the transaction.
- (5.3) As soon as the signature is generated and sent, the balance of the bridge account in both chains will be changed:
should report non-zero balance,
./src/test-services/ethereumBalance/run.sh <ethereum bridge address>
should report about the balance reduction../src/test-services/binanceBalance/run.sh <binance bridge address>
- (5.4) Check that the tokens were transferred properly to the test account:
The balance and transactions related to the bridge account in the Binance Chain could be checked in Binance Testnet Explorer.
./src/test-services/binanceBalance/run.sh <test account address>
- (5.1) Send some amount of tokens to the bridge contract, for
- Transfer tokens from the Binance Chain to Ethereum-based chain:
- (6.1) Send some amount of tokens to the bridge account:
TARGET_NETWORK=staging PRIVATE_KEY=<test account private key> ./src/test-services/binanceSend/run.sh <binance bridge address> 3
- (6.2) Check the balances of the test account on both sides of the bridge to see that the funds were transferred properly using commands from (5.3), (5.4).
- (6.1) Send some amount of tokens to the bridge account:
- Steps for updating validators list are exactly the same for both demo modes. Check the steps from development mode.
- Stop all validator instances by pressing
^C
in the terminal. - Stop the local testnets (if any):
docker kill binance-testnet_http-api_1 docker kill binance-testnet_node_1 docker kill binance-testnet_api-server_1 docker kill ethereum-testnet_ganache_home_1 docker kill ethereum-testnet_ganache_side_1 docker kill ethereum-testnet_side-oracle_1
- Remove testnets and validators data:
TARGET_NETWORK=development ./demo/clean.sh
In these tools, run.sh
file simply builds and runs a docker container for interacting with test blockchains. Every tool contains the file .env
where parameters (RPC urls and private keys) are kept.
./src/test-services/binanceSend/run.sh TO TOKENS NATIVE
- Sends specified amount of tokens and BNBs to the bridge account.
TO
- receiver address in the Binance Chain.TOKENS
- amount of tokens to send.NATIVE
- amount of BNB tokens to send, if present, the transaction is considered as a funding one.
./src/test-services/ethereumSend/run.sh TO TOKENS NATIVE
- Transfers specified amount of tokens and coins to the an Ethereum account on the home network.
TO
- receiver address in the Ethereum-based chain, specifybridge
to send tokens to the bridge address.VALUE
- amount of tokens to transfer and exchange.NATIVE
- amount of coins to send (inether
). Could be omitted.
./src/test-services/sidePrefund/run.sh TO NATIVE
- Transfers specified amount of tokens and coins to the an Ethereum account on the side network.
TO
- receiver address in the Ethereum-based chain.NATIVE
- amount of coins to send (inether
). Could be omitted.
./src/test-services/binanceBalance/run.sh ADDRESS
(it is recommended to usetbnbcli
instead)- Gets current BEP2 token and BNB balances of the specified account.
ADDRESS
- account address in the Binance Chain.
./src/test-services/ethereumBalance/run.sh ADDRESS
- Gets current ERC20 token balance of the specified account.
ADDRESS
- Ethereum address of the account.
- For each validator, a specific port is mapped outside of the docker
container for listening GET requests
- 5001 - first validator
- 5002 - second validator
- 5003 - third validator
- Retrieving bridge state
- Voting for bridge state changes
- http://localhost:5001/vote/startKeygen
- After enough votes are collected, keygen process starts, and ends with the transfer of all remained funds in the Binance Chain to the new generated bridge account.
- http://localhost:5001/vote/addValidator/ADDRESS
ADDRESS
- Ethereum address of a validator.- After enough votes are collected, validator is added into the next validators list for the next epoch.
- http://localhost:5001/vote/addValidator/ADDRESS
ADDRESS
- Ethereum address of a validator.- After enough votes are collected, validator is removed from the next validators list for the next epoch.
- http://localhost:5001/vote/startKeygen