BANCOR学习:如何开发自己的BANCOR去中心化交易平台?

论坛 期权论坛 区块链     
宇宙永恒   2018-11-20 23:37   3339   0
            
image1摘要 基于以太坊的交易所BANCOR算法实现-转换算法框架》 讲解了以太坊solidity实现的BancorConverter转换主合约的逻辑和代码,但是没有涉及核心互换及计算代码,而是通过interface类的方式进行隔离。
本文详细描述一下内容,能跑的程序才是真分享:
(1)BancorNetwork网络的文件框架和功能;
(2)BancorConverter合约测试执行流程;
(3)2个连接器通证ERC1-ERC22的转换验证结果;
(4)ETH-CLB(彩贝)的转化验证结果
2BancorNetwork网络的文件框架和功能BancorProtocol工程是一个带有TRUFFLE框架的solidity智能合约Bancor算法实现框架。文件列表如下:
  1. |   package.json|   README.md|   trace.log|   |   |   BancorProtocol.iml|   |   encodings.xml|   |   misc.xml|   |   modules.xml|   |   workspace.xml|   |   |   \---copyright|           profiles_settings.xml|           \---solidity    |   truffle-config.js    |       +---contracts    |   |   BancorNetwork.sol    |   |   ContractIds.sol    |   |   FeatureIds.sol    |   |   IBancorNetwork.sol    |   |       |   +---build    |   |       BancorConverter.abi    |   |       BancorConverter.bin    |   |       BancorConverterFactory.abi    |   |       BancorConverterFactory.bin    |   |       BancorConverterUpgrader.abi    |   |       BancorConverterUpgrader.bin    |   |       BancorFormula.abi    |   |       BancorFormula.bin    |   |       BancorGasPriceLimit.abi    |   |       BancorGasPriceLimit.bin    |   |       BancorNetwork.abi    |   |       BancorNetwork.bin    |   |       BancorPriceFloor.abi    |   |       BancorPriceFloor.bin    |   |       ContractFeatures.abi    |   |       ContractFeatures.bin    |   |       ContractIds.abi    |   |       ContractIds.bin    |   |       ContractRegistry.abi    |   |       ContractRegistry.bin    |   |       CrowdsaleController.abi    |   |       CrowdsaleController.bin    |   |       ERC20Token.abi    |   |       ERC20Token.bin    |   |       EtherToken.abi    |   |       EtherToken.bin    |   |       FeatureIds.abi    |   |       FeatureIds.bin    |   |       IBancorConverter.abi    |   |       IBancorConverter.bin    |   |       IBancorConverterExtended.abi    |   |       IBancorConverterExtended.bin    |   |       IBancorConverterFactory.abi    |   |       IBancorConverterFactory.bin    |   |       IBancorFormula.abi    |   |       IBancorFormula.bin    |   |       IBancorGasPriceLimit.abi    |   |       IBancorGasPriceLimit.bin    |   |       IBancorNetwork.abi    |   |       IBancorNetwork.bin    |   |       IContractFeatures.abi    |   |       IContractFeatures.bin    |   |       IContractRegistry.abi    |   |       IContractRegistry.bin    |   |       IERC20Token.abi    |   |       IERC20Token.bin    |   |       IEtherToken.abi    |   |       IEtherToken.bin    |   |       IOwned.abi    |   |       IOwned.bin    |   |       ISmartToken.abi    |   |       ISmartToken.bin    |   |       ITokenHolder.abi    |   |       ITokenHolder.bin    |   |       IWhitelist.abi    |   |       IWhitelist.bin    |   |       Managed.abi    |   |       Managed.bin    |   |       Owned.abi    |   |       Owned.bin    |   |       SmartToken.abi    |   |       SmartToken.bin    |   |       SmartTokenController.abi    |   |       SmartTokenController.bin    |   |       TokenHolder.abi    |   |       TokenHolder.bin    |   |       Utils.abi    |   |       Utils.bin    |   |       Whitelist.abi    |   |       Whitelist.bin    |   |           |   +---converter    |   |   |   BancorConverter.sol    |   |   |   BancorConverterFactory.sol    |   |   |   BancorConverterUpgrader.sol    |   |   |   BancorFormula.sol    |   |   |   BancorGasPriceLimit.sol    |   |   |       |   |   \---interfaces    |   |           IBancorConverter.sol    |   |           IBancorConverterFactory.sol    |   |           IBancorFormula.sol    |   |           IBancorGasPriceLimit.sol    |   |    |   +---crowdsale    |   |       CrowdsaleController.sol    |   |           |   +---helpers    |   |       Migrations.sol    |   |       TestBancorFormula.sol    |   |       TestCrowdsaleController.sol    |   |       TestERC20Token.sol    |   |       TestFeatures.sol    |   |       TestUtils.sol    |   |           |   +---legacy    |   |       BancorPriceFloor.sol    |   |           |   +---token    |   |   |   ERC20Token.sol    |   |   |   EtherToken.sol    |   |   |   SmartToken.sol    |   |   |   SmartTokenController.sol    |   |   |        |   |   \---interfaces    |   |           IERC20Token.sol    |   |           IEtherToken.sol    |   |           ISmartToken.sol    |   |             |   \---utility    |       |   ContractFeatures.sol    |       |   ContractRegistry.sol    |       |   Managed.sol    |       |   Owned.sol    |       |   TokenHolder.sol    |       |   Utils.sol    |       |   Whitelist.sol    |       |       |       \---interfaces    |               IContractFeatures.sol    |               IContractRegistry.sol    |               IOwned.sol    |               ITokenHolder.sol    |               IWhitelist.sol    |                   +---migrations    |       1_initial_migration.js    |       2_deploy_contracts.js    |           +---python    |   |   BenchmarkTestPurchase.py    |   |   BenchmarkTestSale.py    |   |   CoverageExpTestPurchase.py    |   |   CoverageExpTestSale.py    |   |   CoverageUniTestPurchase.py    |   |   CoverageUniTestSale.py    |   |   EmulationExpTestCrossConnector.py    |   |   EmulationExpTestPurchase.py    |   |   EmulationExpTestSale.py    |   |   EmulationUniTestCrossConnector.py    |   |   EmulationUniTestPurchase.py    |   |   EmulationUniTestSale.py    |   |   MongoExpTestPurchase.py    |   |   MongoExpTestSale.py    |   |   MongoUniTestPurchase.py    |   |   MongoUniTestSale.py    |   |   PerformanceExpTestCrossConnector.py    |   |   PerformanceExpTestPurchase.py    |   |   PerformanceExpTestSale.py    |   |   PerformanceUniTestCrossConnector.py    |   |   PerformanceUniTestPurchase.py    |   |   PerformanceUniTestSale.py    |   |   RandomTestCrossConnector.py    |   |   RandomTestPower.py    |   |   RandomTestPurchase.py    |   |   RandomTestSale.py    |   |   RandomTestTrade.py    |   |      |   +---AutoGenerate    |   |   |   PrintFileFormulaConstants.py    |   |   |   PrintFunctionBancorFormula.py    |   |   |   PrintFunctionGeneralExp.py    |   |   |   PrintFunctionOptimalExp.py    |   |   |   PrintFunctionOptimalLog.py    |   |   |   PrintIntScalingFactors.py    |   |   |   PrintLn2ScalingFactors.py    |   |   |   PrintMaxExpPerPrecision.py    |   |   |       |   |   \---common    |   |           constants.py    |   |           functions.py    |   |           __init__.py    |   |                  |   +---FormulaNativePython    |   |       __init__.py    |   |              |   +---FormulaSolidityPort    |   |       __init__.py    |   |           |   +---InputGenerator    |   |       __init__.py    |   |           |   +---Utilities    |   |   +---Changer    |   |   |       Decrease.py    |   |   |       Increase.py    |   |   |           |   |   \---Converter    |   |         |   example_commands.json    |   |       |   example_model.json    |   |       |   run.py    |   |       |           |   |       \---engine    |   |               __init__.py    |   |    |   \---Web3Wrapper    |           __init__.py    |             \---test        |   BancorConverter.js        |   BancorConverterUpgrader.js        |   BancorFormula.js        |   BancorNetwork.js        |   ContractFeatures.js        |   ContractRegistry.js        |   CrowdsaleController.js        |   ERC20Token.js        |   EtherToken.js        |   Managed.js        |   Owned.js        |   SmartToken.js        |   SmartTokenController.js        |   TokenHolder.js        |   Utils.js        |   Whitelist.js        |           \---helpers                FormulaConstants.js                Utils.js
复制代码
其中的智能合约代码量实在繁多,限于篇幅限制,就不一一介绍了,辉哥介绍其中主要的几个文件。
2.1 BancorNetwork.sol
功能描述:
BancorNetwork合约是bancor通证转换的主入口。
通过提供转换路径,它允许通过唯一的方法在bancor network中的任何通证转换为其他的通证。
转换路径注意点:
1>,转换路径是一种数据结构,用于在bancor network中把一种通证转换为另一种通知。有时一次转换可能不够,需要多个跳转。
这个路径定义了哪些转换会被使用,每个步骤会做哪一种转换。
2>,这个路径格式不包含复杂的结构。相反,它已单一数组的方式呈现,其中每一个跳转(hop)包含2个数组元素 -智能通证和目标通证。
另外,第一个元素总是源通证。智能通证只作为指向转换器的指针使用(因为转换器地址很可能会变)。
关键函数:
1)
  1. function registerEtherToken(IEtherToken _token, bool _register)
复制代码
注册EtherToken。如果转换路径包括ETH,则需要定义EtherToken来替换。
2)
  1. function verifyTrustedSender(IERC20Token[] _path, uint256 _amount, uint256 _block, address _addr, uint8 _v, bytes32 _r, bytes32 _s) private
复制代码
通过从椭圆签名算法还原关联的公钥,验证签名地址是可信的。如果有错误则返回0值。
注意:签名只在一次转换有效,这个给定的区块后会失效。
3)
  1. function convertFor(IERC20Token[] _path, uint256 _amount, uint256 _minReturn, address _for) public payable
复制代码
在bancor网络中,根据预定义的转换路径,把通证转换为其他通证,并把转换得到的通证打给目标账户。
注意:转换器必须已经有源通证的管理权限。
4)
  1. function getReturnByPath(IERC20Token[] _path, uint256 _amount) public view returns (uint256)
复制代码
返回给定转换路径的目标通证的数量
5)
  1. function convertForMultiple(IERC20Token[] _paths, uint256[] _pathStartIndex, uint256[] _amounts, uint256[] _minReturns, address _for) public payable
复制代码
通过预定义的转换路径,把计算出来的结果通证给目标账号。该函数在一个单一的原子转换中也允许多次转换。
注意:转换器应该已经控制源通证。
6)
  1. function claimAndConvert(IERC20Token[] _path, uint256 _amount, uint256 _minReturn) public returns (uint256)
复制代码
声明调用者的通知,通过预定义的转换路径把通证转换为其他通证 。
2.2 ContractIds.sol
功能描述:
定义一些常量
关键函数:
  1. bytes32 public constant CONTRACT_FEATURES = "ContractFeatures";bytes32 public constant BANCOR_NETWORK = "BancorNetwork";bytes32 public constant BANCOR_FORMULA = "BancorFormula";bytes32 public constant BANCOR_GAS_PRICE_LIMIT = "BancorGasPriceLimit";bytes32 public constant BANCOR_CONVERTER_FACTORY = "BancorConverterFactory";
复制代码
2.3 BancorNetwork.sol
功能描述:
Bancor Network interface,3个空函数定义
关键函数:
  1. function convert(…) public payablefunction convertFor(…) public payablefunction convertForPrioritized2(…) public payable
复制代码
2.4  BancorConverter.sol
见《基于以太坊的交易所BANCOR算法实现-转换算法框架》文件描述。
2.5 BancorConverterFactory.sol
功能描述:
根据参数增加一个新的转换器,把所有权和管理权限转给发送者。
关键函数:
  1. function createConverter(_token,_registry,_maxConversionFee,_connectorToken,_connectorWeight) public returns(converterAddress)
复制代码
2.6 BancorConverterUpgrader.sol
功能描述:
Bancor转换升级器允许把旧的Bancor转换器(0.4 或者更高)升级到最新的版本。
为了开始升级流程,首先把转换器的所有权转让给升级合约,然后调用升级函数。
在升级流程的最后,最新升级的转换器的所有权要转让归还给原始所有者。新转换器的地址在ConverterUpgrade事件中是有效的。
核心函数:
1)
  1. function upgrade(IBancorConverterExtended _oldConverter, bytes32 _version)
复制代码
把旧的转换器升级到新的版本。
在调用本函数前,如果所有权没有被转移给升级器合约将会抛出异常。新转换器的所有权将会被转移给原始的所有者。
2)
  1. function readConnector(IBancorConverterExtended _converter, _address, _isLegacyVersion)
复制代码
读取连接器的配置
2.7 BancorFormula.sol
功能描述:转换器的算法。
核心函数:
1)
  1. function calculatePurchaseReturn(uint256 _supply, uint256 _connectorBalance, uint32 _connectorWeight, uint256 _depositAmount) public view returns (uint256)
复制代码
根据给定的一个token供应量,连接器余额,权重和存入的数量(连接器代币),计算出一个给定转换的反馈。 公式:
  1. Return = _supply * ((1 + _depositAmount / _connectorBalance) ^ (_connectorWeight / 1000000) - 1)
复制代码
2)
  1. function calculateSaleReturn(uint256 _supply, uint256 _connectorBalance, uint32 _connectorWeight, uint256 _sellAmount) public view returns (uint256)
复制代码
根据给定的一个token供应量,连接器余额,权重和卖出的数量(目标通证),计算出一个给定转换的连接器通证的结果。公式:
  1. Return = _connectorBalance * (1 - (1 - _sellAmount / _supply) ^ (1 / (_connectorWeight / 1000000)))
复制代码
3)
  1. function calculateCrossConnectorReturn(uint256 _fromConnectorBalance, uint32 _fromConnectorWeight, uint256 _toConnectorBalance, uint32 _toConnectorWeight, uint256 _amount) public view returns (uint256)
复制代码
根据给定的2个连接器通证的余额/权重,第一个连接器通证的售卖数量,计算出把第一个连接器通证转换为第二个连接器通证的转换数量。
公式:
  1. Return = _toConnectorBalance * (1 - (_fromConnectorBalance / (_fromConnectorBalance + _amount)) ^ (_fromConnectorWeight / _toConnectorWeight))
复制代码
2.8 BancorGasPriceLimit.sol
功能描述:
BancorGasPriceLimit合约充当一个额外的前台运行的攻击减缓机制。它在所有的bancor转换器上设置了一个最大的gas费用。
以便阻止想抢先交易的用户插队。gas费用上限对所有的转换器都适用。并且它可以被所有者更新,以便能跟当前网络的gas费用相符合。
核心函数:
1)
  1. function setGasPrice(uint256 _gasPrice) public ownerOnly
复制代码
更新gas上限;
2)
  1. function validateGasPrice(uint256 _gasPrice)
复制代码
判断输入gas是否不超过gas上限。
2.9  CrowdsaleController.sol
功能描述:
智能通证控制器的众筹版本,允许捐赠者用ether交换Bancor通证。众筹期间价格恒定。
注意:20%的捐赠者是用ETH连接器通证余额的BNT通证。
核心函数:
1) function() payable public  ->  function processContribution() private
转移ETH给收益账户;发行智能代币给捐赠者;1个ETH反回100个智能代币。
2.10  BancorPriceFloor.sol
功能描述
bancor底价合约是一个简单的合约,以一个恒定的ETH价格售卖智能代币。
核心函数
1)
  1. function sell() public returns (uint256 amount)
复制代码
把发送者的所有智能代币转给底价合约,发送(智能代币/100)给发送者
2)
  1. function withdraw(uint256 _amount) public ownerOnly
复制代码
管理员提取一定数量的ETH
2.11 SmartToken.sol
功能描述:智能代币
核心函数:
1)
  1. function issue(address _to, uint256 _amount)
复制代码
对某个账户地址增加智能代币余额 _amount,增加发行总量_amount
2)function destroy(address _from, uint256 _amount)
对某个账户地址销毁智能代币余额_amount,减少发行总量_amount
  1. function transfer(address _to, uint256 _value) public transfersAllowed
复制代码
智能代币转账函数
4)
  1. function transferFrom(address _from, address _to, uint256 _value) public transfersAllowed
复制代码
授权后的转移
2.12 SmartTokenController.sol
功能描述:
智能合约控制器是智能合约可升级的一部分,它允许修改BUG,增加功能。    一旦接受了TOKEN的管理权限,它就变成了该TOKEN的唯一控制器,可以执行任何TOKEN的相关函数。
为了升级控制器,管理权限包括任何相关数据,必须转移给新的控制器。
智能代币必须在构建函数设置,而且之后不可修改。
核心函数:
1)
  1. function transferTokenOwnership(address _newOwner) public ownerOnly:
复制代码
管理账号操作,更新控制权
2)
  1. function acceptTokenOwnership() public ownerOnly
复制代码
管理账号操作,接受控制权
3)
  1. function withdrawFromToken(IERC20Token _token, address _to, uint256 _amount ) public ownerOnly
复制代码
管理账号操作,收回代币到特定账号
2.13 ContractFeatures.sol
功能描述:
一般合约允许区块链上的每个合约定义它支持的功能。
其他合约可以查询这个合约,找出一个区块链上的特定合约是否支持特定的功能。
每个合约类型可以定义它自己的功能列表标志。合约定义的功能只能够被标识为可以/不可以。
可以使用bit位标识函数功能,例如:
uint256 public constant FEATURE1 = 1  {        let converter = await initConverter(accounts, true);        let returnAmount = await converter.getReturn.call(connectorTokenAddress, connectorTokenAddress2, 500);        console.log("The returnAmount is : %d",returnAmount.toNumber());                await connectorToken.approve(converter.address, 500);        let purchaseRes = await converter.convert(connectorTokenAddress, tokenAddress, 500, 1);        let purchaseAmount = getConversionAmount(purchaseRes);        console.log("The purchaseAmount is : %d", purchaseAmount);        let saleRes = await converter.convert(tokenAddress, connectorTokenAddress2, purchaseAmount, 1);        let saleAmount = getConversionAmount(saleRes);        console.log("The saleAmount is : %d",saleAmount);        // converting directly between 2 tokens is more efficient than buying and then selling        // which might result in a very small rounding difference        assert(returnAmount.minus(saleAmount).absoluteValue().toNumber() < 2);    });[/code]3.2.4 运行结果
在TRUFFLE下运行测试文件BanncorConverter2.js,可以验证算法代码实现结果等同于上面的算法结果。
  1. The returnAmount is : 1175、The purchaseAmount is : 482The saleAmount is : 1174     verifies that getReturn returns the same amount as buy -> sell when converting between 2 connectors (1899ms)
复制代码
如果对truffle命令和测试运行不了解的,可参考文档《以太坊开发框架Truffle从入门到实战》(https://www.jianshu.com/p/2e2b3b12eb0e)。
4CLB(一种ERC20)和ETH兑换测试场景4.1 场景:1种连接器通证CLOB和ETH的兑换测试
对于自己搭建的交易所,更常见的场景为ERC20通证兑换为ETH,解决长尾代币的流通性问题。
假设有一种ERC20和ETH在BANCOR转换器中,其中
  • CLB 90000个,90% CW权重,市价1元/个;
  • ETH 10个, 10% CW权重,市价1000元/个;
  • 初始发行智能代币 TKN1 1000个,PRICE 0.1 (个/ETH);   PRICE 100 (个/CLOB);
请问,1000个CLOB可以兑换多少个ETH呢?
我们先来手工拆解计算下,然后用程序运行来验证正确性。
1000个CLOB可以兑换多少个TKN1?
  • SmartTokenAmount = SmartTokenTokenSupply *((1 + ConnectorToken / ConnectorTokenBalance)^ CW - 1)
    = 1000 * (( 1 + 1000 / 90000 )^ 0.9 - 1 )
    =  9.99446694706181297191051400502(个TNK1)
9.994466947个TKN1可以兑换多少个ETH呢?
  • connectorTokenAmount = ConnectorTokenBalance *(1 - (1 - SmartTokenAmount / SmartTokenTokenSupply)^ (1 / CW) )
  • connectorTokenAmount = 10 * (1 - (1 - (9.994466947 / (1000 + 9.994466947)))^ (1 / 0.1) )
    = 10 * (1 - (1 - (9.994466947 / (1000 + 9.994466947)))^ (1 / 0.1) )
    = 10 * (1 - (1 - (0.00989556603929837667128805564395))^ (1 / 0.1) )
    = 10 * (1 - (1 - (0.00989556603929837667128805564395))^ (1 / 0.1) )
    = 10 * (1 - 0.99010443396070162332871194435605 ^ 10 )
    = 10 *  (1 - 0.90533655025365121589722721359431)
    = 0.94663449746348784102772786405694(个ETH)
兑换结论:1000个CLB可以兑换0.946个ETH
按照假设的市价,两者的价值均为1000元左右,符合期望。
4.2 测试代码
针对上面兑换算法的公式描述如下:
  1. /* 创建智能通证,名称为TKN1,符号为Token1  */    token = await SmartToken.new('Token1', 'TKN1', 2);    tokenAddress = token.address;    /* 发行ERC20连接器通证CLOB */    connectorToken = await TestERC20Token.new('ColorBay Token', 'CLB', '1000000000000000000000000000');    connectorTokenAddress = connectorToken.address;    /* 从accounts[0]给etherToken存入10个ETH */    etherToken = await EtherToken.new();   /* 获取以太坊的余额 */    let EtherBalance = await web3.eth.getBalance(accounts[0]);    console.log("The EtherBalance of accounts[0] is : %d",EtherBalance);     //etherToken.address.transfer(1000);    /* 往etherToken存10个ETH */    await etherToken.deposit({ value: '10000000000000000000' });    /* 创建Bancor转换器,添加CLOB作为连接器代币,权重为90% */    let converter = await BancorConverter.new(        tokenAddress,        contractRegistry.address,        maxConversionFee,        connectorTokenAddress,        900000    );    /* 设置ETH作为连接器代币,权重为10%*/    let converterAddress = converter.address;    await converter.addConnector(etherToken.address, 100000, false);    /* 给账号accounts[0]发行1000个TKN1智能代币 ,给转换器地址转账90000个CLOB*/    await token.issue(accounts[0], '1000000000000000000000');    await connectorToken.transfer(converterAddress, '90000000000000000000000');    /* 给转换器地址转账10个ETH */    await etherToken.transfer(converter.address, '10000000000000000000');    if (activate) {        await token.transferOwnership(converterAddress);        await converter.acceptTokenOwnership();    }    /* 设置跟ETH的转换路径 */    clobQuickBuyPath = [connectorTokenAddress, token.address, etherToken.address];    /* 授权连接器通证CLOB 1000个 */    await connectorToken.approve(converter.address, '1000000000000000000000');    let purchaseRes = await converter.convert(connectorTokenAddress, tokenAddress, '1000000000000000000000', 1);    let purchaseAmount = getConversionAmount(purchaseRes);    console.log("The purchaseAmount is : %d", purchaseAmount);    let saleRes = await converter.convert(tokenAddress, etherToken.address, purchaseAmount, 1);    let saleAmount = getConversionAmount(saleRes);    console.log("The saleAmount is : %d",saleAmount);
复制代码
4.3 运行结果
  1. The EtherBalance of accounts[0] is : 82637441999919870000The purchaseAmount is : 9994466947061813000The saleAmount is : 946634497469028600     verifies that user can get ETH through sell CLB (2408ms)
复制代码
如上所示,此处代码以wei为单位,处于10^18,得到的结果为0.9466个ETH,同手工计算结果。
5总结从白皮书,算法公式验证到代码实现,辉哥从技术穿刺的角度讲透了BANCOR算法在以太坊环境的实现。
本文作者:HiBlock区块链技术布道群-辉哥
原文发布于论坛
加微信baobaotalk_com,加入技术布道群

image         
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:40
帖子:314
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP