POA Network侧链和主链资产之间的桥梁
介绍
POA Bridge是在两个以太坊链之间转移资产令牌(Native和ERC20 / ERC677令牌)的解决方案。
资产令牌通常有两个目的:
- 货币用途,可以将代币交易,交易所或作为长期投资进行交易
- 可以在Dapp上使用令牌的应用程序用途(投票,堆叠,播放等)
这两种用法都需要不同的网络属性来实现最佳体验,货币使用可能需要强大的网络安全性和活跃性以及访问大型资产网络以促进交易,而应用程序使用需要更快,更便宜的交易以获得更好的用户体验。
作为第2层可扩展性解决方案的一部分,侧链和桥接器为两种用途实现了这两种链的范例,并尝试解决可扩展性和UX问题,因为以太坊主网通常被认为太慢(15 tx / sec)而且过于昂贵为大多数用例(游戏或社交应用程序)提供良好的用户体验的汽油费。在这种情况下,一般流程如下:
- 用户在主链上购买令牌
- 用户通过桥将他的代币转移到侧链(双重表示:锁定在主链上并在侧链上铸造)
- 用户以快速有效的方式使用令牌。也许从其他用户那里赚取或丢失一些令牌
- 用户决定从侧链退出他的代币并通过桥将它们转移回主链(在主链上解锁并在侧链上烧掉的代币)
- 用户在主链上出售他的代币
在本教程中,我们将学习如何在两个网络上部署令牌(RinkeBy网络作为主链,POA Sokol作为侧链),然后部署并使用网桥(ERC20 <> ERC20)让用户从一个网络转移资产到另一个。
要求
要启动,您需要在计算机上安装以下程序:
$npm install -g truffle
步骤1:BRT在主链(Rinkeby网络)上部署名为BRidge代币的ERC20令牌
- 让我们首先为我们的ERC20创建一个项目文件夹BRT并初始化一个Truffle项目。
$mkdir bridge_token $cd bridge_token $truffle init
- 然后我们将安装Open-Zeppelin Solidity库,其中包含许多高质量,经过全面测试和审核的可重用智能合约
$npm init -y $npm install zeppelin-solidity --save-exact
- 创建./contacts/BridgeToken.sol包含的合约文件
// BridgeToken.sol pragma solidity ^0.4.24; import "zeppelin-solidity/contracts/token/ERC20/MintableToken.sol"; contract BridgeToken is MintableToken { string public constant name = "Bridge代币"; string public constant symbol = "BRT"; uint8 public constant decimals = 18; }
这就是Zeppelin团队为以太坊所做的所有工作而感谢它。基本上我们的智能合约继承自MintableToken,它提供所有ERC-20标准功能以及薄荷令牌的功能。我们只需要指定我们的令牌名称“Bridge代币”,其符号“BRT”和小数位数(可分性)。
为了确保您的智能合约可以编译,您可以运行truffle compile。
- 在RinkeBy网络上部署智能合约
注意:确保用于部署合约的帐户由RinkeBy ethers资助(请参阅水龙头)。
一旦我们的智能合约编译,我们需要部署它。为此,我们首先需要完成迁移脚本,创建一个文件./migrations/2_deploy_contract.js
// 2_deploy_contract.js const BridgeToken = artifacts.require("./BridgeToken.sol"); module.exports = function(deployer, network, accounts) { // Deploy the smart contract deployer.deploy(BridgeToken).then(function(instance) { // Mint 100 tokens return instance.mint(accounts[0], 100000000000000000000, {from: accounts[0]}); }); };
迁移脚本部署合约并另外注释并分配100个BRT令牌到部署者帐户。
下一步是配置与RinkeBy网络的连接以部署智能合约。
安装以下依赖项(dotenv用于管理环境变量,而truffle-hdwallet-provider用于从来自助记符的帐户签署事务)
$npm install --save dotenv truffle-hdwallet-provider
创建一个文件./.env来存储一些私人信息,我们不想在任何地方共享(gitignore这个文件)
- Infura是通往以太坊的公共门户。如果您还没有帐户,我建议您在此文件中创建一个并通过您的API密钥。
- 一个助记符,一个12字的短语,象征着私钥。你可以在Metamask中找到它(设置/显示种子词)
// .env INFURA_API_KEY=ABCABC123123 MNEMONIC=twelve words you can find in metamask/settings/reveal seed words
最后,让我们配置与RinkeBy网络的连接。编辑文件./truffle.js
// truffle.js require('dotenv').config(); const HDWalletProvider = require("truffle-hdwallet-provider"); module.exports = { networks: { development: { host: "localhost", port: 8545, network_id: "*" }, rinkeby: { provider: new HDWalletProvider(process.env.MNEMONIC, "https://rinkeby.infura.io/" + process.env.INFURA_API_KEY), network_id: 4, gas: 4500000 } } };
要在RinkeBy网络上部署智能合约,请运行以下命令:
$truffle migrate --network rinkeby Using network 'rinkeby'. Running migration: 1_initial_migration.js Replacing Migrations... ... 0x691457f76fb8003f0e8c483891cf49b642859a431013b43868504b948b7ae829 Migrations: 0x5e7d11f06ecc7b1c86a27d09bac3b31ea348173f Saving successful migration to network... ... 0xcb01107f840a1db14430768eff3e7cdd419d6ceb7d0b7fec23aa020dea299f46 Saving artifacts... Running migration: 2_deploy.js Replacing BridgeToken... ... 0x7c6499672c442590538df72d36e78c45cc885d97cb9bfd0420be190addbe5fc7 BridgeToken: 0x38954e61cc43893c6d4aa1b735c902fd78f85a2f Saving successful migration to network... ... 0x39e13195b76ca4d5bb44dd16a7f4571295be6e334fd3ef7e4b8c38d9d8cbb3a3
因此,我们可以识别我们BridgeToken在地址部署的智能合约0x38954e61cc43893c6d4aa1b735c902fd78f85a2f(参见block explorer)
第2步:配置和部署桥接合约
在第二步中,我们将部署必要的合约以启用ERC20到ERC20桥。
- 克隆POA Bridge Contracts repo
cd ../ $git clone git@github.com:poanetwork/poa-bridge-contracts.git bridge-contracts cd ./bridge-contracts/
- 在中创建配置文件 ./deploy/.env
注1:要更改以下属性
负责部署,管理合约和验证转移的帐户 负责部署,管理合约和验证转移的帐户 上面部署的ERC20令牌的地址。
注2:出于本教程的原因,我们决定尽可能简化配置(一个帐户管理和验证)
注3:确保该帐户ACCOUNT_ADMIN由RinkeByether和POA Sokolether资助。
# The type of bridge. Defines set of contracts to be deployed. BRIDGE_MODE=ERC_TO_ERC # The private key hex value of the account responsible for contracts # deployments and initial configuration. The account's balance must contain # funds from both networks. DEPLOYMENT_ACCOUNT_PRIVATE_KEY=# The "gas" parameter set in every deployment/configuration transaction. DEPLOYMENT_GAS_LIMIT=4000000 # The "gasPrice" parameter set in every deployment/configuration transaction on # Home network (in Wei). HOME_DEPLOYMENT_GAS_PRICE=10000000000 # The "gasPrice" parameter set in every deployment/configuration transaction on # Foreign network (in Wei). FOREIGN_DEPLOYMENT_GAS_PRICE=10000000000 # The timeout limit to wait for receipt of the deployment/configuration # transaction. GET_RECEIPT_INTERVAL_IN_MILLISECONDS=3000 # The name of the ERC677 token to be deployed on the Home network. BRIDGEABLE_TOKEN_NAME="Bridge代币" # The symbol name of the ERC677 token to be deployed on the Home network. BRIDGEABLE_TOKEN_SYMBOL="BRT" # The number of supportable decimal digits after the "point" in the ERC677 token # to be deployed on the Home network. BRIDGEABLE_TOKEN_DECIMALS=18 # The RPC channel to a Home node able to handle deployment/configuration # transactions. HOME_RPC_URL=https://sokol.poa.network # The address of an administrator on the Home network who can change bridge # parameters and a validator's contract. For extra security we recommended using # a multi-sig wallet contract address here. HOME_OWNER_MULTISIG= # The address from which a validator's contract can be upgraded on Home. HOME_UPGRADEABLE_ADMIN_VALIDATORS= # The address from which the bridge's contract can be upgraded on Home. HOME_UPGRADEABLE_ADMIN_BRIDGE= # The daily transaction limit in Wei. As soon as this limit is exceeded, any # transaction which requests to relay assets will fail. HOME_DAILY_LIMIT=30000000000000000000000000 # The maximum limit for one transaction in Wei. If a single transaction tries to # relay funds exceeding this limit it will fail. HOME_MAX_AMOUNT_PER_TX=1500000000000000000000000 # The minimum limit for one transaction in Wei. If a transaction tries to relay # funds below this limit it will fail. This is required to prevent dryout # validator accounts. HOME_MIN_AMOUNT_PER_TX=500000000000000000 # The finalization threshold. The number of blocks issued after the block with # the corresponding deposit transaction to guarantee the transaction will not be # rolled back. HOME_REQUIRED_BLOCK_CONFIRMATIONS=1 # The default gas price (in Wei) used to send Home Network signature # transactions for deposit or withdrawal confirmations. This price is used if # the Gas price oracle is unreachable. HOME_GAS_PRICE=1000000000 # The RPC channel to a Foreign node able to handle deployment/configuration # transactions. FOREIGN_RPC_URL=https://rinkeby.infura.io # The address of an administrator on the Foreign network who can change bridge # parameters and the validator's contract. For extra security we recommended # using a multi-sig wallet contract address here. FOREIGN_OWNER_MULTISIG= # The address from which a validator's contract can be upgraded on Foreign. FOREIGN_UPGRADEABLE_ADMIN_VALIDATORS= # The address from which the bridge's contract can be upgraded on Foreign. FOREIGN_UPGRADEABLE_ADMIN_BRIDGE= # These three parameters are not used in this mode, but the deployment script # requires it to be set to some value. FOREIGN_DAILY_LIMIT=0 FOREIGN_MAX_AMOUNT_PER_TX=0 FOREIGN_MIN_AMOUNT_PER_TX=0 # The finalization threshold. The number of blocks issued after the block with # the corresponding deposit transaction to guarantee the transaction will not be # rolled back. FOREIGN_REQUIRED_BLOCK_CONFIRMATIONS=8 # The default gas price (in Wei) used to send Foreign network transactions # finalizing asset deposits. This price is used if the Gas price oracle is # unreachable. FOREIGN_GAS_PRICE=10000000000 # The address of the existing ERC20 compatible token in the Foreign network to # be exchanged to the ERC20/ERC677 token deployed on Home. ERC20_TOKEN_ADDRESS= # The minimum number of validators required to send their signatures confirming # the relay of assets. The same number of validators is expected on both sides # of the bridge. REQUIRED_NUMBER_OF_VALIDATORS=1 # The set of validators' addresses. It is assumed that signatures from these # addresses are collected on the Home side. The same addresses will be used on # the Foreign network to confirm that the finalized agreement was transferred # correctly to the Foreign network. VALIDATORS=
- 安装依赖项
$npm install
- 部署Bridge配置
$./deploys.sh (...) Deployment has been completed. [ Home ] HomeBridge: 0x2fED8cf9C20f7D409670751d4bbfEf28400362aA at block 6071895 [ Home ] ERC677 Bridgeable代币: 0x9ef00ee05bd04b4cb84906D6b436a036Fd20b27a [ Foreign ] ForeignBridge: 0x555c5a15C89d56FF357cE003eDFBE185E1483d69 at block 3500840 [ Foreign ] ERC20代币: 0x38954e61cc43893c6d4aa1b735c902fd78f85a2f Contracts Deployment have been saved to `bridgeDeploymentResults.json` { "homeBridge": { "address": "0x2fED8cf9C20f7D409670751d4bbfEf28400362aA", "deployedBlockNumber": 6071895, "erc677": { "address": "0x9ef00ee05bd04b4cb84906D6b436a036Fd20b27a" } }, "foreignBridge": { "address": "0x555c5a15C89d56FF357cE003eDFBE185E1483d69", "deployedBlockNumber": 3500840 } }
保存上面的JSON信息。
步骤3:配置和部署Bridge Oracle
- 签出Bridge Oracle代码
$cd ../ $git clone git@github.com:poanetwork/token-bridge.git bridge-oracle $cd bridge-oracle
- 在中创建配置文件 ./.env
注意1:打开保存的JSON文件bridgeDeploymentResults.json以获取本地和外部桥接合约地址和部署块编号。
{ "homeBridge": { "address": "0x2fED8cf9C20f7D409670751d4bbfEf28400362aA", "deployedBlockNumber": 6071895, "erc677": { "address": "0x9ef00ee05bd04b4cb84906D6b436a036Fd20b27a" } }, "foreignBridge": { "address": "0x555c5a15C89d56FF357cE003eDFBE185E1483d69", "deployedBlockNumber": 3500840 } }
注2:要更改以下属性
负责部署,管理合约和验证转移的帐户 负责部署,管理合约和验证转移的帐户 上面部署的ERC20令牌的地址。
注3:出于本教程的原因,我们决定尽可能简化配置(一个帐户管理和验证)
注4:确保该帐户ACCOUNT_ADMIN由RinkeBy ethers和POA sokol ethers资助。
BRIDGE_MODE=ERC_TO_ERC HOME_POLLING_INTERVAL=5000 FOREIGN_POLLING_INTERVAL=1000 ALLOW_HTTP=yes HOME_RPC_URL=https://sokol.poa.network FOREIGN_RPC_URL=https://rinkeby.infura.io HOME_BRIDGE_ADDRESS=FOREIGN_BRIDGE_ADDRESS= ERC20_TOKEN_ADDRESS= VALIDATOR_ADDRESS= VALIDATOR_ADDRESS_PRIVATE_KEY= HOME_GAS_PRICE_ORACLE_URL=https://gasprice.poa.network/ HOME_GAS_PRICE_SPEED_TYPE=standard HOME_GAS_PRICE_FALLBACK=1000000000 HOME_GAS_PRICE_UPDATE_INTERVAL=600000 FOREIGN_GAS_PRICE_ORACLE_URL=https://gasprice.poa.network/ FOREIGN_GAS_PRICE_SPEED_TYPE=standard FOREIGN_GAS_PRICE_FALLBACK=1000000000 FOREIGN_GAS_PRICE_UPDATE_INTERVAL=600000 QUEUE_URL=amqp://127.0.0.1 REDIS_URL=redis://127.0.0.1:6379 REDIS_LOCK_TTL=1000 HOME_START_BLOCK= FOREIGN_START_BLOCK= LOG_LEVEL=info MAX_PROCESSING_TIME=20000 #testing accs USER_ADDRESS= USER_ADDRESS_PRIVATE_KEY= HOME_MIN_AMOUNT_PER_TX=0.001 FOREIGN_MIN_AMOUNT_PER_TX=0.001 HOME_TEST_TX_GAS_PRICE=1000000000 FOREIGN_TEST_TX_GAS_PRICE=1000000000
- 构建桥Oracle(使用Docker和Docker-compose)
$docker-compose build
- 运行Bridge Oracle由3个组件(一个NodeJS应用程序,Reddit DB和Rabbit MQ)和5个工作进程组成。
$docker-compose up $docker-compose run bridge npm run watcher:signature-request $docker-compose run bridge npm run watcher:collected-signatures $docker-compose run bridge npm run watcher:affirmation-request $docker-compose run bridge npm run sender:home $docker-compose run bridge npm run sender:foreign
第4步:配置和部署桥UI
最后一步是部署用户界面以在侧链和主链之间传输令牌。
- 查看Bridge UI代码
$cd ../ $git clone https://github.com/poanetwork/bridge-ui.git brige-ui $cd bridge-ui
- 更新Git子模块
$git submodule update --init --recursive --remote
- 安装依赖项
$npm install
- 在中创建配置文件 ./.env
注意1:打开保存的JSON文件bridgeDeploymentResults.json以获取本地和外部桥接合约地址和部署块编号。
{ "homeBridge": { "address": "0x2fED8cf9C20f7D409670751d4bbfEf28400362aA", "deployedBlockNumber": 6071895, "erc677": { "address": "0x9ef00ee05bd04b4cb84906D6b436a036Fd20b27a" } }, "foreignBridge": { "address": "0x555c5a15C89d56FF357cE003eDFBE185E1483d69", "deployedBlockNumber": 3500840 } }
# HomeBridge address in bridgeDeploymentResults.json REACT_APP_HOME_BRIDGE_ADDRESS=# ForeignBridge address in bridgeDeploymentResults.json REACT_APP_FOREIGN_BRIDGE_ADDRESS= # https public RPC node for Foreign network REACT_APP_FOREIGN_HTTP_PARITY_URL=https://rinkeby.infura.io/mew # public RPC node for Home network REACT_APP_HOME_HTTP_PARITY_URL=https://sokol.poa.network
- 运行Bridge UI
$npm start
- 打开Internet浏览器,使用用于部署BRT令牌的帐户解锁Rinkeby网络上的Metamask,然后转到[http:// localhost:3000 /](http:// localhost:3000 /)
如果您在RinkeBy网络上,您应该看到您在主链(RinkeBy)上拥有100 BRT令牌而在侧链上拥有0(POA Sokol)
您现在可以在主链和侧链之间传输BRT令牌: