什么是0x協(xié)議?0x是一個(gè)開放協(xié)議,支持在以太坊區(qū)塊鏈上的進(jìn)行點(diǎn)對(duì)點(diǎn)資產(chǎn)交換。開源基礎(chǔ)架構(gòu)可以讓開發(fā)人員和企業(yè)建立自己的建交易支持所有E
什么是0x協(xié)議?
0x是一個(gè)開放協(xié)議,支持在以太坊區(qū)塊鏈上的進(jìn)行點(diǎn)對(duì)點(diǎn)資產(chǎn)交換。開源基礎(chǔ)架構(gòu)可以讓開發(fā)人員和企業(yè)建立自己的建交易支持所有ERC-20和ERC-721資產(chǎn)在內(nèi)的加密代幣產(chǎn)品。
0x協(xié)議的特點(diǎn):
· 安全的非托管交易
· 靈活的訂單類型
· 建立業(yè)務(wù)
安全的非托管交易
· 代幣無需存入或提款即可在錢包到錢包之間進(jìn)行交易。
靈活的訂單類型
· 選擇以特定的“一口價(jià)”出售資產(chǎn),或允許潛在買家提交出價(jià)。
建立您的業(yè)務(wù)
· 通過對(duì)每筆交易收取費(fèi)用來實(shí)現(xiàn)產(chǎn)品的貨幣化,并加入到越來越多的0X生態(tài)系統(tǒng)中。
上面主要是0X的主要特性。
使用0x協(xié)議的好處
0x協(xié)議使用模塊化方法在以太坊區(qū)塊鏈上實(shí)現(xiàn)交易資產(chǎn)。
· 穩(wěn)健的智能合約
· 可擴(kuò)展體系結(jié)構(gòu)
· 高效設(shè)計(jì)
穩(wěn)健的智能合約
· 0X協(xié)議的智能合約已經(jīng)通過了兩輪嚴(yán)格的安全審核。
可擴(kuò)展體系結(jié)構(gòu)
· 0x的模塊化通道讓您可以通過可擴(kuò)展的API插入自己的智能合約。
高效設(shè)計(jì)
· 0x具有鏈上結(jié)算功能的鏈下訂單中繼是一種高效的P2P交換方法。
0x協(xié)議可用于多種用例,例如游戲和收藏品,預(yù)測(cè)市場(chǎng),去中心化交易所,去中心化貸款等。
“ 0x協(xié)議的智能合約”, 0x使用以太坊區(qū)塊鏈的模塊化智能合約,可以通過治理進(jìn)行升級(jí),而不會(huì)影響系統(tǒng)的其他組件,也不會(huì)引起活躍市場(chǎng)的中斷。
0x協(xié)議的智能合約
· 交易所合約
· ERC20代理合約
· RC721代理合約
交易所合約
交易所合約包含0x協(xié)議的業(yè)務(wù)邏輯。交易所合約是-
1. 填寫訂單
2. 取消訂單
3. 執(zhí)行交易
4. 驗(yàn)證簽名
5. 將新的AssetProxy合同注冊(cè)到系統(tǒng)中
ERC20代理合約
該合約負(fù)責(zé)代表用戶轉(zhuǎn)讓ERC20代幣。因此每個(gè)用戶(ERC20代幣的持有者)都必須批準(zhǔn)此合約以代表代幣持有者轉(zhuǎn)讓代幣。
ERC721代理合約
該合約負(fù)責(zé)轉(zhuǎn)讓ERC721代幣。因此每個(gè)用戶(ERC721代幣持有者)必須批準(zhǔn)此合約才能代表代幣持有者轉(zhuǎn)讓代幣。
為了部署和使用0x智能合約,您需要安裝0x.js。 0x.js是一個(gè)與0x協(xié)議進(jìn)行交互的JavaScript庫。通過使用此庫,您可以輕松地調(diào)用智能合約來創(chuàng)建,取消或驗(yàn)證訂單,檢查ERC20和ERC721代幣持有者的配額和余額。
0x協(xié)議架構(gòu)
0x協(xié)議使用一種稱為鏈上結(jié)算的鏈下訂單中繼的方法。在這種方法中,加密簽名的訂單通過任意通信通道在區(qū)塊鏈之外廣播。感興趣的對(duì)方可以將這些訂單中的一個(gè)或多個(gè)注入到0x協(xié)議的交易合約中,以直接在區(qū)塊鏈上執(zhí)行和結(jié)算交易。
可以使用0x協(xié)議來交換任何ERC20或ERC721資產(chǎn)。上圖展示了當(dāng)接受者提交訂單以交換智能合約時(shí)代幣的實(shí)際轉(zhuǎn)移是如何發(fā)生的。
1. 接受者使用交換智能合約的fillOrder()函數(shù)提交簽署的訂單以交換智能合約。
2. 交易所合約將訂單上的訂單傳遞給相應(yīng)的ERC20Proxy合約,代幣的實(shí)際轉(zhuǎn)移將在代理合約上進(jìn)行。注意:制造商和接受者必須先提交ERC20Proxy合約,然后再提交交換訂單。
3. transferFrom()函數(shù)從代理合約中調(diào)用相應(yīng)的生產(chǎn)者的代幣合約。
4. 恢復(fù)生產(chǎn)者的ERC20代幣合約失敗。
5. 從ERC20代理合約轉(zhuǎn)換為交換合約。
6. 交換合約將訂單從交換合約傳遞到ERC20Proxy合約。
7. transferFrom()函數(shù)從代理合約中調(diào)用相應(yīng)的接受者的代幣合約。
8. 接受方ERC20代幣合約失敗后恢復(fù)。
9. 從ERC20代理合約轉(zhuǎn)換為交換合約。
10. 返回填充結(jié)果。
使用x.js庫在以太坊上交易資產(chǎn)的0X智能合約的工作和部署。
Use npm install 0x.js — save to install and save 0x.js library
0x智能合約的部署步驟
要與智能合約交互,我們需要部署x智能合約,并使用智能合約的地址通過x.js庫與智能合約交互。
交換智能合約
git上可用的源代碼,部署交換智能合約,其中交換合約的構(gòu)造函數(shù)不需要任何參數(shù),智能合約的部署者(msg.sender)將是智能合約的所有者。
所有者可以在交換合約中設(shè)置AssetProxy合約地址。
### ERC20代理合約
git上可用的源代碼,部署ERC20proxy合約,其中代理合約的構(gòu)造函數(shù)不需要任何參數(shù),智能合約的部署者(msg.sender)將是智能合約的所有者。
所有者可以在ERC20Proxy合約中設(shè)置交換合約地址。
ERC721代理合約
git上可用的源代碼,部署ERC20proxy合約,其中代理合約的構(gòu)造函數(shù)不需要任何參數(shù),智能合約的部署者(msg.sender)將是智能合約的所有者。
所有者可以在ERC20Proxy合約中設(shè)置交換合約地址。
部署上述合約后,您需要將交換合約的地址設(shè)置為asset proxy合約,將asset proxy合約的地址設(shè)置為交換合約。交換智能合約的調(diào)用函數(shù)registerassetproxy(地址erc20/erc721 proxy contract)函數(shù)將存儲(chǔ)AssetProxy Contract的地址,實(shí)際交易將在該地址進(jìn)行,以交換代幣。
此功能只能由交換智能合約的所有者調(diào)用。
1. 在erc20proxy合約調(diào)用函數(shù)addauthorizedaddress(address exchnagecontract)上注冊(cè)交換合約。
2. 要從erc20proxy協(xié)定中刪除exchange協(xié)定,請(qǐng)調(diào)用函數(shù)removeauthorizedaddress(address exchnagecontract)。
3. 使用exchange和asset proxy contracts的地址通過x.js庫進(jìn)行交互。
let contractConfig = {
contractAddresses: {
erc20Proxy: proxyAddress.toLowerCase(),
erc721Proxy: "0x1d7022f5b17d2f8b695918fb48fa1089c9f85401",
exchange: exchangeAddress.toLowerCase() },
networkId: networkId
};
const contractWrappers = new ContractWrappers(holderEngine, contractConfig);
現(xiàn)在,您可以交互部署在專用或測(cè)試網(wǎng)絡(luò)上的0x協(xié)議智能合約。 請(qǐng)記住添加RPC子提供程序以與區(qū)塊鏈進(jìn)行交互。
為了與0x.js庫進(jìn)行交互,我們需要導(dǎo)入相關(guān)的軟件包,如下所示,最終目標(biāo)是使用0x.js庫從生產(chǎn)者帳戶創(chuàng)建訂單,并且接管者將使用fillOrder()函數(shù)提交以交換代幣。
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.
獲取合約地址并實(shí)例化合約包裝器
/ Instantiate ContractWrappers with the provider
const contractWrappers = new ContractWrappers(holderEngine, contractConfig);
const web3Wrapper = new Web3Wrapper(providerEngine);
const contractAddresses = getContractAddressesForNetworkOrThrow(100);//networkID
選擇網(wǎng)絡(luò)ID,以從0x.js庫獲取智能合約的地址。
現(xiàn)在,生產(chǎn)者(代幣A的持有者)將創(chuàng)建一個(gè)報(bào)價(jià),接受者(代幣持有者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;
現(xiàn)在,生產(chǎn)者和接受者應(yīng)批準(zhǔn)相應(yīng)的資產(chǎn)代理合約,以代表生茶者和接受者轉(zhuǎn)讓代幣。
//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);
在生產(chǎn)者和接受者批準(zhǔn)資產(chǎn)代理合約之后,分別代表生產(chǎn)者和接受者轉(zhuǎn)讓代幣。 現(xiàn)在生產(chǎn)者將創(chuàng)建合約并在合約上簽字,合約人將提交合約以交換代幣。
創(chuàng)建訂單
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
};
現(xiàn)在我們創(chuàng)建了一個(gè)報(bào)價(jià); 我們將在調(diào)用0x.js庫的getOrderHash()函數(shù)獲得訂單哈希值后對(duì)要約進(jìn)行簽名。 根據(jù)EIP712規(guī)范對(duì)訂單進(jìn)行哈希處理。
const orderHashHex = orderHashUtils.getOrderHashHex(order);
獲取訂單創(chuàng)建者的哈希后,將使用0x.js庫的ecSignHashAsync()函數(shù)對(duì)訂單進(jìn)行簽名。
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){}}
讓我們快速回顧一下到目前為止所學(xué)到的知識(shí),然后通過介紹已經(jīng)建立在0x上的項(xiàng)目來結(jié)束我們的討論。
扼要重述
1. 0x協(xié)議概述
2. 0x協(xié)議的特點(diǎn)
3. 0X智能合約的工作
4. 生產(chǎn)者使用x.js創(chuàng)建報(bào)價(jià)
5. 接受人向交易所提交報(bào)價(jià)(鏈三豐)