【DeFi/DEX】0x协议JS对接教程
时间: 2020-08-05来源:OSCHINA
前景提要
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
什么是0x协议,它的工作机制是怎样的?在这个教程中,我们将介绍0x协议的基本概念,例如其链下订单中继、去中心化交易中继器等,学习如何使用0x智能合约在以太坊公链或私链上实现自己的去中心化交易所(DEX),掌握如何利用0x.js实现0x资产交易委托订单的链下创建与签名、链上验证及执行。如果你是Go工程师,可以使用这个 0x协议Golang开发包 - ZrxTool 。 用自己熟悉的语言学习 以太坊DApp开发 : Java | Php | Python | .Net / C# | Golang | Node.JS | Flutter / Dart
1、什么是0x协议
0x是一种开放协议,支持以太坊区块链上点对点的资产交换。其主要特性为: 安全的非托管交易:无需存入或从中心化平台取出,就可以直接实现钱包对钱包的资产交易。 灵活的订单类型:支持立即购买,或允许潜在买家提交出价。 有助于建立可持续的业务:每笔交易可以收取服务费,有助于生态的扩展
0x协议使用模块化方式在以太坊区块链上交易资产,其主要优势在于: 可靠的智能合约:0x协议的智能合约已通过两轮严格的安全审核。 可扩展架构:0x的模块化流水线支持开发者在通过扩展API插入自己的智能合约。 高效设计:0x的具有链上结算功能的链下订单中继是一种节省手续费的P2P方式的委托单交换方法。
0x协议可用于多种用例,例如游戏和收藏品,预测市场,去中心化交易的订单簿,去中心化贷款等。同时,0x使用以太坊区块链的模块化智能合约,可以通过治理进行升级,而不会影响系统的其他组件,也不会引起活跃市场的中断。
利用0x协议所提供的开源基础架构,开发人员能够轻松构建支持ERC-20和ERC-721资产的去中心化交易所。
2、0x协议的智能合约
0x协议的智能合约主要包括以下类别: 资产交换合约:包含0x协议的业务逻辑,提供订单执行、订单取消、交易执行、签名验证、新资产注册等功能 ERC20资产代理合约:代表用户转让ERC20资产。因此,每个用户都需要授权该合约可以操作自己持有的ERC20代币。 ERC721资产代理合约:代表用户转让ERC721资产。因此,每个用户都需要授权该合约可以操作自己持有的ERC721资产
为了部署、使用0x协议的智能合约,我们需要先安装0x.js。0x.js是一个与0x协议进行交互的JavaScript库,利用它就可以轻松地调用0x协议的智能合约来创建、取消或验证订单,或者检查ERC20和ERC721资产持有者的授权额度和余额。
0x协议采用链下订单中继、链上结算的模式,密码学签名的订单可以通过任意通信渠道在区块链之外传播。感兴趣的对手方可以将这些订单中的一个或多个注入到0x的资产交换合约中,在区块链上执行和结算交易。

可以使用0x协议来交换任何ERC20或ERC721资产。上图显示了当Taker向0x资产交换智能合约 提交订单时资产转移的实际处理流程: Taker调用资产交换智能合约的 fillOrder() 方法提交签名订单 资产交换合约将订单传递给相应的ERC20Proxy资产代理合约,实际的资产转移是在代理合约上进行的。 注意:Maker和Taker必须先授权ERC20Proxy合约,然后才能提交订单。 在资产代理合约中调用Maker资产合约的 transferFrom() 方法 如果Maker的ERC20资产合约调用失败,则交易回滚。 如果ERC20代理合约转换为交换合同。 资产交换合约将订单传递到ERC20Proxy合同。 在资产代理合约中调用Taker资产合约的 transferFrom() 方法 接受方ERC20代币合同失败后恢复。 从ERC20代理合约转换为资产交换合约 返回订单执行结果
3、部署0x智能合约
要与智能合约进行交互,我们需要部署0x智能合约,并使用智能合约的地址通过0x.js库与智能合约进行交互。
首先安装0x.js: Use npm install 0x.js — save to install and save 0x.js library
资产交换合约 :利用 源代码 部署交换智能合约,其中交换合约的构造函数不需要任何参数,智能合约的部署者(msg.sender)将是智能合约的所有者。所有者将能够在交换合约中设置assetProxy合约的地址。
ERC20资产代理合约 :利用 源代码 部署ERC20proxy合约,其中代理合约的构造函数不需要任何参数,智能合约的部署者(msg.sender)将是智能合约的所有者。所有者将能够在ERC20Proxy合约中设置资产交换合约的地址。
ERC721资产代理合约 :利用 源代码 部署ERC20proxy合约,其中代理合约的构造函数不需要任何参数,智能合约的部署者(msg.sender)将是智能合约的所有者。所有者将能够在ERC20Proxy合约中设置交换合约的地址。
部署以上合约后,需要在交换合约中设置资产代理合约的地址,在资产代理合约中设置交换合约的地址。
调用资产交换合约的 registerAssetProxy(assetProxyAddress) 方法将存储资产代理合约的地址,在该地址将发生实际交易以交换代币资产。该方法只能由资产交换智能合约的所有者调用。
调用ERC20Proxy合约的 addAuthorizedAddress(exchangeAddress) 方法注册交换合约。调用ERC20Proxy合约的 removeAuthorizedAddress(exchangeAddress) 方法删除交换合约。
使用资产交换合约和资产代理合约的地址通过0x.js库进行交互: let contractConfig = { contractAddresses: { erc20Proxy: proxyAddress.toLowerCase(), erc721Proxy: "0x1d7022f5b17d2f8b695918fb48fa1089c9f85401", exchange: exchangeAddress.toLowerCase() }, networkId: networkId }; const contractWrappers = new ContractWrappers(holderEngine, contractConfig);
现在就可以交互部署在专用或测试网络上的0x协议智能合约。请记住添加RPC子提供程序以与区块链进行交互。
4、使用0x.js访问0x合约
为了与0x.js库进行交互,我们需要导入相关的软件包,如下所示,最终目标是使用0x.js库用Maker帐户创建订单,并且Taker将使用 fillOrder() 方法提交执行交易: const { assetDataUtils,BigNumber,ContractWrappers, generatePseudoRandomSalt,orderHashUtils,signatureUtils } = require('0x.js'); const TX_DEFAULTS = { gas: 400000 }; const { RPCSubprovider, Web3ProviderEngine } = require('0x.js'); let newWallet = new ethers.Wallet(wallet.signingKey.privateKey, prov); const holderWallet = new PrivateKeyWalletSubprovider(wallet.signingKey.privateKey.slice(2));
添加RPC子提供程序: const holderEngine = new Web3ProviderEngine(); holderEngine.addProvider(holderWallet); holderEngine.addProvider(new RPCSubprovider(providerUrl)); holderEngine.start();
在RPC子提供程序中,可以使用自定义URL分别连接以太坊主网、测试网或私有区块链的区块链连接。
获取0x合约地址并实例化合约包装器: const contractWrappers = new ContractWrappers(holderEngine, contractConfig); const web3Wrapper = new Web3Wrapper(providerEngine); const contractAddresses = getContractAddressesForNetworkOrThrow(100);//networkID
现在,Maker将创建订单,而Taker将执行订单以交换Maker的资产: const tokenAAddress = contractAddresses.tokenA; const tokenBAddress = contractAddresses.tokenB; const exchange = contractAddresses.exchange;
所有地址都可以从0x.js库获取到。 const makerAssetData = assetDataUtils.encodeERC20AssetData(tokenAAddress); const takerAssetData = assetDataUtils.encodeERC20AssetData(tokenBAddress); const makerAssetAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(100), DECIMALS); const takerAssetAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(200), DECIMALS); const NULL_ADDRESS = '0x0000000000000000000000000000000000000000'; const ZERO = new BigNumber(0); const DECIMALS = 18;
现在,Maker和Taker应该授权相应的资产代理合约,以分别代表Maker和Taker转让代币资产: //Allow ERC20 Proxy to move tokenA on behalf of makerAccount const makerApprovalTxHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync( tokenAAddress, maker, ); await web3Wrapper.awaitTransactionSuccessAsync(makerApprovalTxHash); // Allow ERC20 Proxy to move tokenB on behalf of takerAccount const takerApprovalTxHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync( tokenBAddress, taker, ); await web3Wrapper.awaitTransactionSuccessAsync(takerApprovalTxHash);
在Maker和Taker批准资产代理合约之后,代理合约就可以分别代表Maker和Taker转让代币资产。现在,Maker将创建一个委托订单并在链下签名,而Taker将在链上执行订单。
5、0x订单的创建、签名、验证与执行
创建订单: const order = { exchangeAddress: exchangeAddress, makerAddress: maker,//address of maker takerAddress: taker,//address of taker senderAddress: taker,//address of sender feeRecipientAddress: NULL_ADDRESS,//fee in the form of native currency of platform expirationTimeSeconds: randomExpiration,//expire time of order salt: generatePseudoRandomSalt(),//random no to differentiate order makerAssetAmount,//maker asset amount takerAssetAmount,//taker asset amount makerAssetData,//encoded address of tokenA takerAssetData,//encoded address of tokenB makerFee: ZERO,//fee if required takerFee: ZERO,//fee if required };
现在我们创建了一个资产交换委托订单。接下来在调用0x.js库的 getOrderHash() 函数获得订单哈希值以便进行签名。根据EIP712对订单计算哈希: const orderHashHex = orderHashUtils.getOrderHashHex(order);
获取订单的哈希后,Maker使用0x.js库的 ecSignHashAsync() 方法签名订单。 const signature = await signatureUtils.ecSignHashAsync(providerEngine, orderHashHex, maker); const signedOrder = { …order, signature };
Taker可以使用资产交易合约的validateFillOrder方法验证订单是否可以执行: await contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync( signedOrder, takerAssetAmount, taker );
Taker最终调用资产交易合约的fillOrder方法执行订单: try{ txHash = await contractWrappers.exchange.fillOrderAsync( signedOrder, takerAssetAmount, taker, {TX_DEFAULTS,} ); var transaction = await web3Wrapper.awaitTransactionSuccessAsync(txHash); }catch(error){}
原文链接: 0x协议对接开发教程 — 汇智网

科技资讯:

科技学院:

科技百科:

科技书籍:

网站大全:

软件大全:

热门排行