0x-start-project源码学习 - 5

之前说了对取消订单的操作,可以通过传入订单信息,由maker发起取消订单操作,并签名执行。另一种取消订单的方式是可以按时间点取消订单。

cancel_orders_up_to场景中就描述了这种操作,不同的是在创建订单时,不是使用generatePseudoRandomSalt来设置salt而是通过时间戳去设置。

1
2
3
4
5
const order = {
...
salt: new BigNumber(Date.now()),
...
}

这样对订单就添加了时间标记,这是如果需要取消订单那么就可以使用cancelOrdersUpToAsync来取消订单

1
contractWrappers.exchange.cancelOrdersUpToAsync(时间节点,maker)

它会取消在该时间节点之前的所有订单。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Order Info
order1 Fillable
order2 Fillable
order3 Fillable
Transaction
┌──────────────────┬────────────────────────────────────────────────────────────────────┐
│ cancelOrdersUpTo │ 0xc97ad364611e9de56721f1abddbe3034880556e682b5becd7c0d88524c903131 │
├──────────────────┼────────────────────────────────────────────────────────────────────┤
│ targetOrderEpoch │ 1552013245054 │
├──────────────────┼────────────────────────────────────────────────────────────────────┤
│ gasUsed │ 55772 │
├──────────────────┼────────────────────────────────────────────────────────────────────┤
│ status │ Success │
└──────────────────┴────────────────────────────────────────────────────────────────────┘
Logs
CancelUpTo
contract 0x48bacb9266a570d521063ef5dd96e61686dbe788
makerAddress 0x5409ed021d9299bf6814279a6a1411a7e866a631
senderAddress 0x0000000000000000000000000000000000000000
orderEpoch 1552013245055
Order Info
order1 Cancelled
order2 Cancelled
order3 Fillable

该场景中具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
PrintUtils.printScenario('Cancel Orders Up To');
// Initialize the ContractWrappers, this provides helper functions around calling
// 0x contracts as well as ERC20/ERC721 token contracts on the blockchain
const contractWrappers = new ContractWrappers(providerEngine, { networkId: NETWORK_CONFIGS.networkId });
// Initialize the Web3Wrapper, this provides helper functions around fetching
// account information, balances, general contract logs
const web3Wrapper = new Web3Wrapper(providerEngine);
// 获取maker,taker地址
const [maker, taker] = await web3Wrapper.getAvailableAddressesAsync();
const zrxTokenAddress = contractAddresses.zrxToken;
const etherTokenAddress = contractAddresses.etherToken;
const printUtils = new PrintUtils(
web3Wrapper,
contractWrappers,
{ maker, taker },
{ WETH: etherTokenAddress, ZRX: zrxTokenAddress },
);
printUtils.printAccounts();
// 设置交易金额
// the amount the maker is selling of maker asset
const makerAssetAmount = new BigNumber(100);
// the amount the maker wants of taker asset
const takerAssetAmount = new BigNumber(10);
// 设置交易币种
// 0x v2 uses hex encoded asset data strings to encode all the information needed to identify an asset
const makerAssetData = assetDataUtils.encodeERC20AssetData(zrxTokenAddress);
const takerAssetData = assetDataUtils.encodeERC20AssetData(etherTokenAddress);
// Set up the Order and fill it
// 设置交易地址,交易过期时间
const randomExpiration = getRandomFutureDateInSeconds();
const exchangeAddress = contractAddresses.exchange;
// Rather than using a random salt, we use an incrementing salt value.
// When combined with cancelOrdersUpTo, all lesser values of salt can be cancelled
// This allows the maker to cancel many orders with one on-chain transaction
// Create the order
// 创建订单
// salt为10分钟之前的时间戳
const order1: Order = {
exchangeAddress,
makerAddress: maker,
takerAddress: NULL_ADDRESS,
senderAddress: NULL_ADDRESS,
feeRecipientAddress: NULL_ADDRESS,
expirationTimeSeconds: randomExpiration,
salt: new BigNumber(Date.now() - TEN_MINUTES_MS),
makerAssetAmount,
takerAssetAmount,
makerAssetData,
takerAssetData,
makerFee: ZERO,
takerFee: ZERO,
};
// order2为一分钟之前的时间戳
const order2: Order = {
...order1,
salt: new BigNumber(Date.now() - ONE_MINUTE_MS),
};
// order3为现在的时间戳
const order3: Order = {
...order1,
salt: new BigNumber(Date.now()),
};
// Fetch and print the order info
// 打印订单信息
let order1Info = await contractWrappers.exchange.getOrderInfoAsync(order1);
let order2Info = await contractWrappers.exchange.getOrderInfoAsync(order2);
let order3Info = await contractWrappers.exchange.getOrderInfoAsync(order3);
printUtils.printOrderInfos({ order1: order1Info, order2: order2Info, order3: order3Info });
// Maker cancels all orders before and including order2, order3 remains valid
// 取消包括order2之前的所有订单
// order3在order2之后,仍然有效
const targetOrderEpoch = order2.salt;
const txHash = await contractWrappers.exchange.cancelOrdersUpToAsync(targetOrderEpoch, maker, {
gasLimit: TX_DEFAULTS.gas,
});
const txReceipt = await printUtils.awaitTransactionMinedSpinnerAsync('cancelOrdersUpTo', txHash);
printUtils.printTransaction('cancelOrdersUpTo', txReceipt, [['targetOrderEpoch', targetOrderEpoch.toString()]]);
// Fetch and print the order info
// 打印订单信息
order1Info = await contractWrappers.exchange.getOrderInfoAsync(order1);
order2Info = await contractWrappers.exchange.getOrderInfoAsync(order2);
order3Info = await contractWrappers.exchange.getOrderInfoAsync(order3);
printUtils.printOrderInfos({ order1: order1Info, order2: order2Info, order3: order3Info });
// Stop the Provider Engine
providerEngine.stop();