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. 接受人向交易所提交報價