0x协议可在以太坊交换资产 支持ERC-20和ERC-721等的加密代币

2019-10-29 17:01:35
来源: 腾讯

  【摘要】 什么是0x协议?0x是一个开放协议,支持在以太坊区块链上的进行点对点资产交换。开源基础架构可以让开发人员和企业建立自己的建交易支持所有ERC-20和ERC-721资产在内

什么是0x协议?

0x是一个开放协议,支持在以太坊区块链上的进行点对点资产交换。开源基础架构可以让开发人员和企业建立自己的建交易支持所有ERC-20和ERC-721资产在内的加密代币产品。

0x协议的特点:

· 安全的非托管交易

· 灵活的订单类型

· 建立业务

安全的非托管交易

· 代币无需存入或提款即可在钱包到钱包之间进行交易。

灵活的订单类型

· 选择以特定的“一口价”出售资产,或允许潜在买家提交出价。

建立您的业务

· 通过对每笔交易收取费用来实现产品的货币化,并加入到越来越多的0X生态系统中。

上面主要是0X的主要特性。

使用0x协议的好处

0x协议使用模块化方法在以太坊区块链上实现交易资产。

· 稳健的智能合约

· 可扩展体系结构

· 高效设计

稳健的智能合约

· 0X协议的智能合约已经通过了两轮严格的安全审核。

可扩展体系结构

· 0x的模块化通道让您可以通过可扩展的API插入自己的智能合约。

高效设计

· 0x具有链上结算功能的链下订单中继是一种高效的P2P交换方法。

0x协议可用于多种用例,例如游戏和收藏品,预测市场,去中心化交易所,去中心化贷款等。

“ 0x协议的智能合约”, 0x使用以太坊区块链的模块化智能合约,可以通过治理进行升级,而不会影响系统的其他组件,也不会引起活跃市场的中断。

0x协议的智能合约

· 交易所合约

· ERC20代理合约

· RC721代理合约

交易所合约

交易所合约包含0x协议的业务逻辑。交易所合约是-

1. 填写订单

2. 取消订单

3. 执行交易

4. 验证签名

5. 将新的AssetProxy合同注册到系统中

ERC20代理合约

该合约负责代表用户转让ERC20代币。因此每个用户(ERC20代币的持有者)都必须批准此合约以代表代币持有者转让代币。

ERC721代理合约

该合约负责转让ERC721代币。因此每个用户(ERC721代币持有者)必须批准此合约才能代表代币持有者转让代币。

为了部署和使用0x智能合约,您需要安装0x.js。 0x.js是一个与0x协议进行交互的JavaScript库。通过使用此库,您可以轻松地调用智能合约来创建,取消或验证订单,检查ERC20和ERC721代币持有者的配额和余额。

0x协议架构

0x协议使用一种称为链上结算的链下订单中继的方法。在这种方法中,加密签名的订单通过任意通信通道在区块链之外广播。感兴趣的对方可以将这些订单中的一个或多个注入到0x协议的交易合约中,以直接在区块链上执行和结算交易。

可以使用0x协议来交换任何ERC20或ERC721资产。上图展示了当接受者提交订单以交换智能合约时代币的实际转移是如何发生的。

1. 接受者使用交换智能合约的fillOrder()函数提交签署的订单以交换智能合约。

2. 交易所合约将订单上的订单传递给相应的ERC20Proxy合约,代币的实际转移将在代理合约上进行。注意:制造商和接受者必须先提交ERC20Proxy合约,然后再提交交换订单。

3. transferFrom()函数从代理合约中调用相应的生产者的代币合约。

4. 恢复生产者的ERC20代币合约失败。

5. 从ERC20代理合约转换为交换合约。

6. 交换合约将订单从交换合约传递到ERC20Proxy合约。

7. transferFrom()函数从代理合约中调用相应的接受者的代币合约。

8. 接受方ERC20代币合约失败后恢复。

9. 从ERC20代理合约转换为交换合约。

10. 返回填充结果。

使用x.js库在以太坊上交易资产的0X智能合约的工作和部署。

Use npm install 0x.js — save to install and save 0x.js library

0x智能合约的部署步骤

要与智能合约交互,我们需要部署x智能合约,并使用智能合约的地址通过x.js库与智能合约交互。

交换智能合约

git上可用的源代码,部署交换智能合约,其中交换合约的构造函数不需要任何参数,智能合约的部署者(msg.sender)将是智能合约的所有者。

所有者可以在交换合约中设置AssetProxy合约地址。

### ERC20代理合约

git上可用的源代码,部署ERC20proxy合约,其中代理合约的构造函数不需要任何参数,智能合约的部署者(msg.sender)将是智能合约的所有者。

所有者可以在ERC20Proxy合约中设置交换合约地址。

ERC721代理合约

git上可用的源代码,部署ERC20proxy合约,其中代理合约的构造函数不需要任何参数,智能合约的部署者(msg.sender)将是智能合约的所有者。

所有者可以在ERC20Proxy合约中设置交换合约地址。

部署上述合约后,您需要将交换合约的地址设置为asset proxy合约,将asset proxy合约的地址设置为交换合约。交换智能合约的调用函数registerassetproxy(地址erc20/erc721 proxy contract)函数将存储AssetProxy Contract的地址,实际交易将在该地址进行,以交换代币。

此功能只能由交换智能合约的所有者调用。

1. 在erc20proxy合约调用函数addauthorizedaddress(address exchnagecontract)上注册交换合约。

2. 要从erc20proxy协定中删除exchange协定,请调用函数removeauthorizedaddress(address exchnagecontract)。

3. 使用exchange和asset proxy contracts的地址通过x.js库进行交互。

let contractConfig = {

contractAddresses: {

erc20Proxy: proxyAddress.toLowerCase(),

erc721Proxy: "0x1d7022f5b17d2f8b695918fb48fa1089c9f85401",

exchange: exchangeAddress.toLowerCase() },

networkId: networkId

};

const contractWrappers = new ContractWrappers(holderEngine, contractConfig);

现在,您可以交互部署在专用或测试网络上的0x协议智能合约。 请记住添加RPC子提供程序以与区块链进行交互。

为了与0x.js库进行交互,我们需要导入相关的软件包,如下所示,最终目标是使用0x.js库从生产者帐户创建订单,并且接管者将使用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 Sub Provider

const holderEngine = new Web3ProviderEngine();

holderEngine.addProvider(holderWallet);

holderEngine.addProvider(new RPCSubprovider(providerUrl));

holderEngine.start();In new RPC sub provider add custom URL to connect

with blockchain that may be ethereum main net, test net or private blockchain.

获取合约地址并实例化合约包装器

/ Instantiate ContractWrappers with the provider

const contractWrappers = new ContractWrappers(holderEngine, contractConfig);

const web3Wrapper = new Web3Wrapper(providerEngine);

const contractAddresses = getContractAddressesForNetworkOrThrow(100);//networkID

选择网络ID,以从0x.js库获取智能合约的地址。

现在,生产者(代币A的持有者)将创建一个报价,接受者(代币持有者B)将提交或填写兑换代币的订单。

//contract Addresses

const tokenAAddress = contractAddresses.tokenA;

const tokenBAddress = contractAddresses.tokenB;

const exchange = contractAddresses.exchange;

所有地址都从0x.js库获取。

//encode all the necessary information about an asset into a single hexadecimal string

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;

现在,生产者和接受者应批准相应的资产代理合约,以代表生茶者和接受者转让代币。

//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);

在生产者和接受者批准资产代理合约之后,分别代表生产者和接受者转让代币。 现在生产者将创建合约并在合约上签字,合约人将提交合约以交换代币。

创建订单

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);

获取订单创建者的哈希后,将使用0x.js库的ecSignHashAsync()函数对订单进行签名。

const signature = await signatureUtils.ecSignHashAsync(providerEngine, orderHashHex, maker);

const signedOrder = { …order, signature };

await contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, takerAssetAmount, taker);

try{

txHash = await contractWrappers.exchange.fillOrderAsync(signedOrder, takerAssetAmount, taker, {TX_DEFAULTS,});

var transaction = await web3Wrapper.awaitTransactionSuccessAsync(txHash);}catch(error){}}

让我们快速回顾一下到目前为止所学到的知识,然后通过介绍已经建立在0x上的项目来结束我们的讨论。

扼要重述

1. 0x协议概述

2. 0x协议的特点

3. 0X智能合约的工作

4. 生产者使用x.js创建报价

5. 接受人向交易所提交报价(链三丰)