Updated README.md. Moved tools to docker containers
This commit is contained in:
parent
38dee19559
commit
e990f4dec3
73
README.md
73
README.md
|
@ -8,20 +8,22 @@ two are enough to sign any transaction in the Binance Chain,
|
|||
confirm token transfer on the Ethereum Side, or vote for state changes.
|
||||
|
||||
ERC20 Token is used on the Ethereum side of the bridge.
|
||||
All ERC20 tokens are located on address associated with DEPLOY_PRIVATE_KEY.
|
||||
All ERC20 tokens are initially located on the address associated
|
||||
with ```DEPLOY_PRIVATE_KEY```.
|
||||
|
||||
BEP2 Token is used on the Binance Chain side.
|
||||
|
||||
#### Running demo:
|
||||
1) Build tss from local source.
|
||||
```docker build -t tss -f ./src/tss/Dockerfile-local ./src/tss```
|
||||
2) Run test environment (home and side blockchains, contracts deployment)
|
||||
```./demo/start-environment.sh```
|
||||
3) Run three validators in separate terminal sessions
|
||||
```N=1 ./demo/validator-demo.sh```
|
||||
```N=2 ./demo/validator-demo.sh```
|
||||
```N=3 ./demo/validator-demo.sh```
|
||||
All parts of this demo are docker containers.
|
||||
|
||||
#### Running demo:
|
||||
1) Build tss from local source. (TSS cryptographic executables are taken from this image) \
|
||||
```docker build -t tss -f ./src/tss/Dockerfile-local ./src/tss```
|
||||
2) Run test environment. (home and side ganache-cli blockchains, contracts deployment)
|
||||
```./demo/start-environment.sh```
|
||||
3) Run three validators in separate terminal sessions.\
|
||||
```N=1 ./demo/validator-demo.sh```\
|
||||
```N=2 ./demo/validator-demo.sh```\
|
||||
```N=3 ./demo/validator-demo.sh```
|
||||
|
||||
#### Interacting with validators, sending votes, retrieving bridge information
|
||||
* For each validator, a specific port is mapped outside of the docker
|
||||
|
@ -30,33 +32,38 @@ container for listening GET requests
|
|||
- 5002 - second validator
|
||||
- 5003 - third validator
|
||||
* Retrieving bridge state
|
||||
- http://localhost:5000/info
|
||||
- http://localhost:5001/info
|
||||
* Voting for bridge state changes
|
||||
- http://localhost:5000/vote/startEpoch/NEW_EPOCH
|
||||
- ```NEW_EPOCH``` should be equal nextEpoch + 1
|
||||
- http://localhost:5001/vote/startKeygen
|
||||
- After enough votes are collected, keygen process starts, and
|
||||
ends with transfer of all remained funds in the Binance Chain
|
||||
to the new generated account
|
||||
- http://localhost:5000/vote/addValidator/ADDRESS
|
||||
- ```ADDRESS``` is the Ethereum address of a validator
|
||||
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 pending validators list for the next epoch
|
||||
- http://localhost:5000/vote/addValidator/ADDRESS
|
||||
- ```ADDRESS``` is the Ethereum address of a validator
|
||||
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 pending validators list for the next epoch
|
||||
the next validators list for the next epoch.
|
||||
|
||||
#### Tools for sending transactions on both sides of the bridge
|
||||
#### Testing tools for both sides of the bridge
|
||||
|
||||
Run this scripts from ```src/oracle``` dir
|
||||
In this tools, ```run.sh``` file simply builds and runs a docker container
|
||||
for interacting with test blockchains.
|
||||
|
||||
* ```node testBinanceSend.js TO VALUE_TOKEN [VALUE_BNB]```
|
||||
- ```TO``` - receiver address, current bridge address in the Binance Chain
|
||||
- ```VALUE_TOKEN``` - amount of tokens to send
|
||||
- ```VALUE_BNB``` - amount of BNB tokens to send, if present, the
|
||||
transaction is considered as a funding one
|
||||
* ```node testEthereumSend.js TO VALUE```
|
||||
- Approves specified amount of tokens to the bridge account and calls
|
||||
needed method for starting exchange process
|
||||
- ```TO``` - receiver address in the Binance Chain
|
||||
- ```VALUE``` - amount of tokens to transfer and exchange
|
||||
* ```./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 TOKENS```
|
||||
- Transfers specified amount of tokens to the bridge account.
|
||||
- ```VALUE``` - amount of tokens to transfer and exchange.
|
||||
* ```./src/test-services/binanceBalance/run.sh ADDRESS```
|
||||
- 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.
|
||||
|
|
|
@ -219,6 +219,7 @@ contract Bridge {
|
|||
status = 1;
|
||||
|
||||
nextEpoch++;
|
||||
states[nextEpoch].validators = getValidators();
|
||||
emit NewEpoch(epoch, nextEpoch);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
require('dotenv').config()
|
||||
|
||||
const Bnc = require('@binance-chain/javascript-sdk')
|
||||
const axios = require('axios')
|
||||
const Transaction = require('./tss-sign/tx')
|
||||
const crypto = require('crypto')
|
||||
const ecc = require('tiny-secp256k1')
|
||||
const utils = require('ethers').utils
|
||||
|
||||
const { FOREIGN_URL, FOREIGN_ASSET, FOREIGN_PRIVATE_KEY } = process.env
|
||||
const amount = process.argv[3]
|
||||
const addressTo = process.argv[2]
|
||||
const addressFrom = Bnc.crypto.getAddressFromPrivateKey(FOREIGN_PRIVATE_KEY)
|
||||
const bnbs = process.argv[4]
|
||||
const realBnbs = bnbs || '0'
|
||||
const publicKeyStr = utils.computePublicKey(`0x${FOREIGN_PRIVATE_KEY}`)
|
||||
const publicKey = {
|
||||
x: publicKeyStr.substr(4, 64),
|
||||
y: publicKeyStr.substr(68, 64)
|
||||
}
|
||||
|
||||
if (bnbs)
|
||||
console.log(`Funding from ${addressFrom} to ${addressTo}, ${amount} tokens, ${realBnbs} BNB'`)
|
||||
else
|
||||
console.log(`From ${addressFrom} to ${addressTo}, ${amount} tokens'`)
|
||||
const httpClient = axios.create({ baseURL: FOREIGN_URL })
|
||||
httpClient
|
||||
.get(`/api/v1/account/${addressFrom}`)
|
||||
.then((res) => {
|
||||
const { sequence, account_number } = res.data
|
||||
const tx = new Transaction({
|
||||
from: addressFrom,
|
||||
to: addressTo,
|
||||
accountNumber: account_number,
|
||||
sequence,
|
||||
tokens: amount,
|
||||
asset: FOREIGN_ASSET,
|
||||
bnbs: realBnbs,
|
||||
memo: bnbs ? 'funding' : 'exchange'
|
||||
})
|
||||
const hash = crypto.createHash('sha256').update(tx.getSignBytes()).digest('hex')
|
||||
const signature = ecc.sign(Buffer.from(hash, 'hex'), Buffer.from(FOREIGN_PRIVATE_KEY, 'hex'))
|
||||
const sig = {
|
||||
r: signature.toString('hex').substr(0, 64),
|
||||
s: signature.toString('hex').substr(64, 64)
|
||||
}
|
||||
|
||||
return tx.addSignature(publicKey, sig)
|
||||
})
|
||||
.then(signed => {
|
||||
console.log('sending')
|
||||
return httpClient.post(`/api/v1/broadcast?sync=true`, signed, {
|
||||
headers: {
|
||||
'content-type': 'text/plain'
|
||||
}
|
||||
})
|
||||
})
|
||||
.then((result) => {
|
||||
if (result.status === 200) {
|
||||
console.log('success', result.data)
|
||||
} else {
|
||||
console.error('error', result)
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('error', error)
|
||||
})
|
|
@ -1,37 +0,0 @@
|
|||
require('dotenv').config()
|
||||
|
||||
const Web3 = require('web3')
|
||||
|
||||
const { HOME_RPC_URL, HOME_BRIDGE_ADDRESS, HOME_CHAIN_ID, DEPLOY_PRIVATE_KEY, HOME_TOKEN_ADDRESS } = process.env
|
||||
const web3 = new Web3(HOME_RPC_URL, null, { transactionConfirmationBlocks: 1 })
|
||||
const abiToken = require('../deploy/deploy-home/build/contracts/IERC20').abi
|
||||
const token = new web3.eth.Contract(abiToken, HOME_TOKEN_ADDRESS)
|
||||
|
||||
const amount = parseInt(process.argv[2])
|
||||
const query = token.methods.transfer(HOME_BRIDGE_ADDRESS, amount)
|
||||
|
||||
let nonce
|
||||
const deployAddress = web3.eth.accounts.privateKeyToAccount(`0x${DEPLOY_PRIVATE_KEY}`).address
|
||||
|
||||
async function main () {
|
||||
console.log(`Transfer from ${deployAddress} to ${HOME_BRIDGE_ADDRESS}, ${amount} tokens`)
|
||||
nonce = await web3.eth.getTransactionCount(deployAddress)
|
||||
console.log(await sendQuery(query, HOME_TOKEN_ADDRESS))
|
||||
}
|
||||
|
||||
async function sendQuery (query, to) {
|
||||
const encodedABI = query.encodeABI()
|
||||
const tx = {
|
||||
data: encodedABI,
|
||||
from: deployAddress,
|
||||
to,
|
||||
nonce: nonce++,
|
||||
chainId: parseInt(HOME_CHAIN_ID)
|
||||
}
|
||||
tx.gas = Math.min(Math.ceil(await query.estimateGas(tx) * 1.5), 6721975)
|
||||
const signedTx = await web3.eth.accounts.signTransaction(tx, DEPLOY_PRIVATE_KEY)
|
||||
|
||||
return await web3.eth.sendSignedTransaction(signedTx.rawTransaction)
|
||||
}
|
||||
|
||||
main()
|
|
@ -0,0 +1,2 @@
|
|||
FOREIGN_URL=https://testnet-dex.binance.org/
|
||||
FOREIGN_ASSET=KFT-94F
|
|
@ -0,0 +1,11 @@
|
|||
FROM node:10.16.0-alpine
|
||||
|
||||
WORKDIR /test
|
||||
|
||||
COPY package.json /test/
|
||||
|
||||
RUN npm install
|
||||
|
||||
COPY testGetBinanceBalance.js /test/
|
||||
|
||||
ENTRYPOINT ["node", "testGetBinanceBalance.js"]
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name": "binance-balance",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"axios": "0.19.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
cd $(dirname "$0")
|
||||
|
||||
docker build -t binance-balance . > /dev/null
|
||||
|
||||
docker run --rm --env-file .env binance-balance $@
|
|
@ -1,5 +1,3 @@
|
|||
require('dotenv').config()
|
||||
|
||||
const axios = require('axios')
|
||||
|
||||
const { FOREIGN_URL, FOREIGN_ASSET } = process.env
|
||||
|
@ -9,5 +7,8 @@ const httpClient = axios.create({ baseURL: FOREIGN_URL })
|
|||
|
||||
httpClient
|
||||
.get(`/api/v1/account/${address}`)
|
||||
.then(res => console.log(parseFloat(res.data.balances.find(x => x.symbol === FOREIGN_ASSET).free)))
|
||||
.then(res => {
|
||||
console.log(`BNB: ${parseFloat(res.data.balances.find(x => x.symbol === 'BNB').free)}`)
|
||||
console.log(`${FOREIGN_ASSET}: ${parseFloat(res.data.balances.find(x => x.symbol === FOREIGN_ASSET).free)}`)
|
||||
})
|
||||
.catch(console.log)
|
|
@ -0,0 +1,4 @@
|
|||
FOREIGN_URL=https://testnet-dex.binance.org/
|
||||
FOREIGN_ASSET=KFT-94F
|
||||
|
||||
FOREIGN_PRIVATE_KEY=b92a59209e28149e5cee8e54dfceb80a08ea08e654261bdb9d264b15dee2525c
|
|
@ -0,0 +1,13 @@
|
|||
FROM node:10.16.0-alpine
|
||||
|
||||
WORKDIR /test
|
||||
|
||||
RUN apk add build-base python
|
||||
|
||||
COPY package.json /test/
|
||||
|
||||
RUN npm install
|
||||
|
||||
COPY testBinanceSend.js /test/
|
||||
|
||||
ENTRYPOINT ["node", "testBinanceSend.js"]
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name": "binance-send",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"@binance-chain/javascript-sdk": "2.14.4"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
cd $(dirname "$0")
|
||||
|
||||
docker build -t binance-send . > /dev/null
|
||||
|
||||
docker run --rm --env-file .env binance-send $@
|
|
@ -0,0 +1,50 @@
|
|||
const Bnc = require('@binance-chain/javascript-sdk')
|
||||
|
||||
const { FOREIGN_URL, FOREIGN_ASSET, FOREIGN_PRIVATE_KEY } = process.env
|
||||
|
||||
const client = new Bnc(FOREIGN_URL)
|
||||
|
||||
async function main () {
|
||||
client.chooseNetwork('testnet')
|
||||
await client.setPrivateKey(FOREIGN_PRIVATE_KEY)
|
||||
|
||||
await client.initChain()
|
||||
|
||||
const from = client.getClientKeyAddress()
|
||||
const to = process.argv[2]
|
||||
const tokens = parseFloat(process.argv[3])
|
||||
let bnbs = process.argv[4]
|
||||
let receipt
|
||||
|
||||
if (bnbs) {
|
||||
bnbs = parseFloat(bnbs)
|
||||
console.log(`Funding from ${from} to ${to}, ${tokens} ${FOREIGN_ASSET}, ${bnbs} BNB'`)
|
||||
const outputs = [{
|
||||
to,
|
||||
coins: []
|
||||
}]
|
||||
if (tokens) {
|
||||
outputs[0].coins.push({
|
||||
denom: FOREIGN_ASSET,
|
||||
amount: tokens
|
||||
})
|
||||
}
|
||||
if (bnbs) {
|
||||
outputs[0].coins.push({
|
||||
denom: 'BNB',
|
||||
amount: bnbs
|
||||
})
|
||||
}
|
||||
receipt = await client.multiSend(from, outputs, 'funding')
|
||||
} else {
|
||||
console.log(`From ${from} to ${to}, ${tokens} ${FOREIGN_ASSET}'`)
|
||||
receipt = await client.transfer(from, to, tokens, FOREIGN_ASSET, 'exchange')
|
||||
}
|
||||
|
||||
if (receipt.status === 200)
|
||||
console.log(receipt.result[0].hash)
|
||||
else
|
||||
console.log(receipt)
|
||||
}
|
||||
|
||||
main()
|
|
@ -0,0 +1,2 @@
|
|||
HOME_RPC_URL=http://ganache_home:8545
|
||||
HOME_TOKEN_ADDRESS=0x44c158FE850821ae69DaF37AADF5c539e9d0025B
|
|
@ -0,0 +1,11 @@
|
|||
FROM node:10.16.0-alpine
|
||||
|
||||
WORKDIR /test
|
||||
|
||||
COPY package.json /test/
|
||||
|
||||
RUN npm install
|
||||
|
||||
COPY testGetEthereumBalance.js IERC20.json /test/
|
||||
|
||||
ENTRYPOINT ["node", "testGetEthereumBalance.js"]
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name": "ethereum-balance",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"web3": "1.0.0-beta.55"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
cd $(dirname "$0")
|
||||
|
||||
docker build -t ethreum-balance . > /dev/null
|
||||
|
||||
docker run --network blockchain_home --rm --env-file .env ethreum-balance $@
|
|
@ -1,12 +1,14 @@
|
|||
require('dotenv').config()
|
||||
|
||||
const Web3 = require('web3')
|
||||
|
||||
const { HOME_RPC_URL, HOME_TOKEN_ADDRESS } = process.env
|
||||
|
||||
const abiToken = require('./IERC20').abi
|
||||
|
||||
const web3 = new Web3(HOME_RPC_URL, null, { transactionConfirmationBlocks: 1 })
|
||||
const abiToken = require('../deploy/deploy-home/build/contracts/IERC20').abi
|
||||
const token = new web3.eth.Contract(abiToken, HOME_TOKEN_ADDRESS)
|
||||
|
||||
const address = process.argv[2]
|
||||
|
||||
token.methods.balanceOf(address).call().then(x => console.log(x.toNumber()))
|
||||
token.methods.balanceOf(address).call()
|
||||
.then(x => console.log(x.toNumber()))
|
||||
.catch(() => console.log(0))
|
|
@ -0,0 +1,6 @@
|
|||
HOME_RPC_URL=http://ganache_home:8545
|
||||
HOME_BRIDGE_ADDRESS=0x94b40CC641Ed7db241A1f04C8896ba6f6cC36b85
|
||||
HOME_CHAIN_ID=44
|
||||
HOME_TOKEN_ADDRESS=0x44c158FE850821ae69DaF37AADF5c539e9d0025B
|
||||
|
||||
HOME_PRIVATE_KEY=e2aeb24eaa63102d0c0821717c3b6384abdabd7af2ad4ec8e650dce300798b27
|
|
@ -0,0 +1,11 @@
|
|||
FROM node:10.16.0-alpine
|
||||
|
||||
WORKDIR /test
|
||||
|
||||
COPY package.json /test/
|
||||
|
||||
RUN npm install
|
||||
|
||||
COPY testEthereumSend.js IERC20.json /test/
|
||||
|
||||
ENTRYPOINT ["node", "testEthereumSend.js"]
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name": "ethereum-send",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"web3": "1.0.0-beta.55"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
cd $(dirname "$0")
|
||||
|
||||
docker build -t ethreum-send . > /dev/null
|
||||
|
||||
docker run --network blockchain_home --rm --env-file .env ethreum-send $@
|
|
@ -0,0 +1,33 @@
|
|||
const Web3 = require('web3')
|
||||
|
||||
const { HOME_RPC_URL, HOME_BRIDGE_ADDRESS, HOME_CHAIN_ID, HOME_PRIVATE_KEY, HOME_TOKEN_ADDRESS } = process.env
|
||||
|
||||
const abiToken = require('./IERC20').abi
|
||||
|
||||
const web3 = new Web3(HOME_RPC_URL, null, { transactionConfirmationBlocks: 1 })
|
||||
const token = new web3.eth.Contract(abiToken, HOME_TOKEN_ADDRESS)
|
||||
|
||||
const amount = parseInt(process.argv[2])
|
||||
|
||||
const deployAddress = web3.eth.accounts.privateKeyToAccount(`0x${HOME_PRIVATE_KEY}`).address
|
||||
|
||||
async function main () {
|
||||
console.log(`Transfer from ${deployAddress} to ${HOME_BRIDGE_ADDRESS}, ${amount} tokens`)
|
||||
|
||||
const query = token.methods.transfer(HOME_BRIDGE_ADDRESS, amount)
|
||||
const encodedABI = query.encodeABI()
|
||||
const tx = {
|
||||
data: encodedABI,
|
||||
from: deployAddress,
|
||||
to: HOME_TOKEN_ADDRESS,
|
||||
nonce: await web3.eth.getTransactionCount(deployAddress),
|
||||
chainId: parseInt(HOME_CHAIN_ID)
|
||||
}
|
||||
tx.gas = Math.min(Math.ceil(await query.estimateGas(tx) * 1.5), 6721975)
|
||||
const signedTx = await web3.eth.accounts.signTransaction(tx, HOME_PRIVATE_KEY)
|
||||
|
||||
const receipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction)
|
||||
console.log(receipt.transactionHash)
|
||||
}
|
||||
|
||||
main()
|
Loading…
Reference in New Issue