译文/Translated:
Eosfinex的核心是交易合约。Eosfinex交易合约能够保证链上价值即时和安全的交易,它是esofinex的核心。
本文我们将通过合约ABI来直接了解交易合约。
在我们即将发布之际,加入我们新建的eosfinex Telegram频道获取更多信息。
The exchange contract supports fully on-chain limit order books, as well as matching and trade settlement. A user can interact with the exchange contract through a WebSocket gateway as described in the last installment of our weekly blog series, or directly with the contract ABI through a public facing EOS node that is running the standard HTTP plugin.
交易合约支持完全链上的限价委托单簿、配对和贸易结算。正如我们上期在每周博客中提到的,用户可以通过一个WebSocket网关接触交易合约,或者也可以通过使用标准HTTP插件的、面向大众的EOS节点直接使用合约ABI。
eosfinex: 基于EOS的链上交易WebSockets
我们马上就要发布eosfinex,现在我们想带大家看看这背后的机制……medium.com
下面的例子使用的是cleos—默认的EOS命令行软件—但是下面的例子也很容易应用在其它客户和其它库中。
要大概感受智能合约,我们可以从公共节点开始查询它的ABI。
cleos -u http://[public_eosfinex_node] get abi [exchange_account]
…
“actions”: [{
“name”: “place”,
“type”: “place”,
“ricardian_contract”: “”
},{
“name”: “cancel”,
“type”: “cancel”,
“ricardian_contract”: “”
},{
“name”: “withdraw”,
“type”: “withdraw”,
“ricardian_contract”: “”
}, …]
…
“tables”: [{
“name”: “orders”,
“index_type”: “i64”,
“key_names”: [
“id”,
“price”
],
“key_types”: [
“uint64”,
“uint64”
],
“type”: “order”
},{
“name”: “accounts”,
“index_type”: “i64”,
“key_names”: [
“currency”
],
“key_types”: [
“uint64”
],
“type”: “account”
}
]
…
上面是查询结果节选,这里重点放的是必要的交易合约动作和表格。
我们关注三个动作:放置、取消和撤销以及两个表格:订单和账户。当我们了解这个的时候,我们就准备进行交易了。那么让我们从一些例子里面具体看看相关情况。
为方便讨论,接下来的例子去掉了指向公共端点的URL,并继续用占位符表示账户名。这些例子中,我还假设用户持有包含必要的私人密钥的未解锁的钱包。
账户表
账户表记录用户在交易所中某个具体货币的可用余额。用户交易之前,他必须先在交易所转入资金。
cleos transfer [user_account] [exchange_account] “20.00000000 EOS” “Transfer some EOS onto the exchange”
cleos transfer [user_account] [exchange_account] “5.00000000 EOX” “Transfer some EOX onto the exchange”
现在资金已经被转到交易所,用户就可以查询他们在交易所的账户余额。简单的查询交易余额的方式和任何标准代币合约的查询方式一致。
cleos get currency balance [exchange_account] [user_account]
20.00000000 EOS
5.00000000 EOX
交易所上有了一定资金之后,用户就可以发送订单了。
放置动作
合约被送往交易所使用的是合约的“放置”动作。以下是ABI定义的放置动作细节:
{
“name”: “place”,
“base”: “”,
“fields”: [
{“name”:”account”, “type”:”name”},
{“name”:”clId”, “type”:”uint64"},
{“name”:”scope”, “type”:”name”},
{“name”:”price”, “type”:”uint64"},
{“name”:”qty”, “type”:”uint64"},
{“name”:”flags”, “type”:”uint8"}
]
}
我们仔细看看这些字段。
Account:这是一个放置订单的账户。交易必须通过这个账户的私人密钥赋值,而用户必须在交易前保证有足够的资金。
Clid:这是客户订单ID,客户每个订单要求会生成的唯一ID。交易合约获得这个ID之后,用户可以用它来识别订单。
Scope:订单范围整合了交易对和订单方。范围模式如下:X.Y.Z。所有的值都是小写的,而X是交易对的基准货币,Y是交易对的标价货币,Z是订单方(不管是标的方’b’还是询价方’a’)。比如说,给eox.eos.b设定范围,就会向eox.eos交易对发出购买订单。
Price:这是订单限价的整数表达。Eosfinex订单支持精确到小数点后4位。这个整数通过把浮点价格乘以10000获得。比如说,限价4.1250的整数表达是41250 (4.1250 * 10000)。
Qty:这是订单大小的整数表达。和price一样,eosfinex的订单支持小数点侯四位的订单。要把小数变成整数表达,同样也是乘以10000。比如,订单大小是100.05,它的整数表达就是1000500(100.05 * 10000)。
Flags: Flag字段用来用来具体化订单选择。八个字节的字段中,每个字节都代表不同的选择,可以通过设定字节为真启用。这就让同一个订单获得多个选择。
以下是不同的选择和相应的字节列表:
00000001只邮寄:该订单会收到反应制造商折让的价格。
00000010 立即交易或取消:不能马上达到交易额就取消订单。
00000100 市场:忽略限价,以最佳价格交易。
00001000 自行匹配防范:同一账户不能进行订单交易。
01000000 交易后发放:交易后从交易所转移新资金
10000000 流动抵押:当交易取消时把抵押余额转移出交易所
比如说,如果flags=11000010,这就是一个立即交易或取消订单,在订单完成以后,整个抵押余额以及所有从交易中获得的资产都会被转走。
我们用一个例子说得更清楚下。我们假设用户有以下的交易余额:
cleos get currency balance [exchange_account] [user_account]
20.00000000 EOS
5.00000000 EOX
我们假设用户希望用EOS购买3.0000EOX,再假设用户希望每个EOX最多1.5EOS。这个情况下,用户会发出以下命令
cleos push action exchange_account place ‘[user_account 1 eox.eos.b 15000 30000 0]’
我们假设交易发出之后未能马上实现,它就停留在订单账本上。如果我们查询用户的交易钱包余额,我们就会看到一些EOS币已经被作为抵押冻结,从而支持刚刚发出的订单。
cleos get currency balance [exchange_account] [user_account]
15.50000000 EOS
5.00000000 EOX
接着,我们就可以查询订单表看看我们刚刚放置的订单。
订单表
这张表记录了每个交易对的限价单账本。限价单任何一笔未完成的订单都会被放在限价单账本上。您可以通过以下命令查询限价单账本。
cleos get table [exchange_account] [order_scope] orders
以上命令中,order_scope和用来发出订单的范围一致。比如说,假设有个用户发出了如下eox.eos购买订单。
cleos push action exchange_account place ‘[user_account 1 eox.eos.b 15000 30000 0]’
如果这个订单未完成,它就会被放在eox.eos购买限价单账本,我们就可以这样查询限价单账本:
cleos get table [exchange_account] eox.eos.b orders
{
“rows”: [{
“id”: “1234567”,
“account”: “user_account”,
“clId”: 1,
“price”: 15000,
“qty”: 30000,
“reserved”: 0,
“flags”: 0
}],
“more”: false
}
储存的限价单的所有字段和我们预期的一样。
在储存的订单结构中,我们唯一没有识别到的字段是“id”字段。这个字段由交易所赋值。注意Price和qty都是以整数形式储存,这和放置订单的情况一样。订单会一直留在订单账本中,除非有人进行交易或者订单被取消。
取消动作
取消动作是用来取消订单账本上的一个订单的。取消动作的ABI定义如下:
{
“name”: “cancel”,
“base”: “”,
“fields”: [
{“name”:”account”, “type”:”name”},
{“name”:”id”, “type”:”uint64"},
{“name”:”clId”, “type”:”uint64"},
{“name”:”scope”, “type”:”name”}
]
}
这些字段是发出订单动作加上交易所赋值的”id”字段之后的子集。假设我们的eox.eos购买订单的id是1234567,它现在存放在订单账本,我们可以用以下命令取消订单:
cleos push action [exchange_account] cancel ‘[user_account 1234567 1 eox.eos.b]’
正如我们预期的,在取消订单之后,查询订单表就会看到空表
cleos get table [exchange_account] eox.eos.b orders
{
“rows”: [],
“more”: false
}
撤回动作
“name”: “withdraw”,
“base”: “”,
“fields”: [
{“name”:”to”, “type”:”name”},
{“name”:”amount”, “type”:”asset”}
]
}
举例来说,假设一个用户有如下交易钱包余额
cleos get currency balance [exchange_account] [user_account]
20.00000000 EOS
5.00000000 EOX
如果该用户想要撤回现有EOS的一半,那么他需要发出如下命令:
cleos push action exchange_account withdraw ‘[user_account “10.00000000 EOS”]’
By querying the exchange balance after the withdraw, we can see that the withdraw completed as expected.
撤回之后我们查询交易余额,我们就可以看到撤回动作已经完成:
cleos get currency balance [exchange_account] [user_account]
10.00000000 EOS
5.00000000 EOX
小结
在我们每周的eosfinex博客的第二期,我们看到了eosfinex交易合约,以及我们怎么通过ABI直接应用合约。
In case you missed last weeks article — interacting with eosfinex using WebSockets — find it here:
如果您没有看过上期文章—通过WebSocket使用eosfinex—请点击:
eosfinex:基于EOS的链上交易WebSockets
我们马上就要发布eosfinex,现在我们想带大家看看这背后的机制……medium.com
在以下媒体上关注最新研发成果以及我们2019年3月的发布内容。
原文/Original:
At the heart of eosfinex lies the exchange contract. Designed to allow for the instantaneous and secure exchange of on-chain value, the eosfinex exchange contract acts as the very core of eosfinex.
In this article we focus on interacting directly with the exchange contract through the contract ABI.
Join our newly-created eosfinex Telegram channel for more information as we approach our launch.
The exchange contract supports fully on-chain limit order books, as well as matching and trade settlement. A user can interact with the exchange contract through a WebSocket gateway as described in the last installment of our weekly blog series, or directly with the contract ABI through a public facing EOS node that is running the standard HTTP plugin.eosfinex: WebSockets for EOS-based on-chain exchange
With the launch of eosfinex right around the corner, we’re pleased to give a sneak peek into the mechanics powering the…medium.com
The following examples use cleos — the default EOS command line tool — but the examples are easily extendable to other clients and libraries.
To get a feel for the exchange contract, we can start off by querying its ABI through a public node.
cleos -u http://[public_eosfinex_node] get abi [exchange_account]
…
“actions”: [{
“name”: “place”,
“type”: “place”,
“ricardian_contract”: “”
},{
“name”: “cancel”,
“type”: “cancel”,
“ricardian_contract”: “”
},{
“name”: “withdraw”,
“type”: “withdraw”,
“ricardian_contract”: “”
}, …]
…
“tables”: [{
“name”: “orders”,
“index_type”: “i64”,
“key_names”: [
“id”,
“price”
],
“key_types”: [
“uint64”,
“uint64”
],
“type”: “order”
},{
“name”: “accounts”,
“index_type”: “i64”,
“key_names”: [
“currency”
],
“key_types”: [
“uint64”
],
“type”: “account”
}
]
…
Above is an excerpt from the response, and highlights the essential exchange contract actions and tables.
We are interested in three actions: place, cancel and withdraw and two tables: orders and accounts. Once we understand these, we will be ready to begin trading. So let’s take a closer look at each through some examples.
For brevity, the following examples exclude the URL to the public endpoint and continue to use place holders for account names. These examples also assume the user has an unlocked wallet containing the necessary private keys.
Accounts Table
The accounts table stores a user’s available balance for a particular currency on the exchange. Before a user can trade, the user must first transfer funds onto the exchange.
cleos transfer [user_account] [exchange_account] “20.00000000 EOS” “Transfer some EOS onto the exchange”
cleos transfer [user_account] [exchange_account] “5.00000000 EOX” “Transfer some EOX onto the exchange”
Now that the funds have been transferred, the user can query their exchange account balance(s). Simply query the account balance on the exchange in the same way as you would any standard token contract.
cleos get currency balance [exchange_account] [user_account]
20.00000000 EOS
5.00000000 EOX
With some funds on the exchange, the user is now ready to send orders.
Place Action
Orders are sent to the exchange using the contract’s place action. Below are the details of the place action as defined in the ABI.
{
“name”: “place”,
“base”: “”,
“fields”: [
{“name”:”account”, “type”:”name”},
{“name”:”clId”, “type”:”uint64"},
{“name”:”scope”, “type”:”name”},
{“name”:”price”, “type”:”uint64"},
{“name”:”qty”, “type”:”uint64"},
{“name”:”flags”, “type”:”uint8"}
]
}
Let’s take a closer look at each of these fields.
Account: This is the account that is placing the order. The transaction must be signed using the private key for this account, and the user must have sufficient funds available within their exchange wallet.
Clid: This is the client order id, a unique id that the client assigns to each order request. This id allows the user to identify the order after the exchange contract process it.
Scope: Order scope is the amalgamation of the trading pair and order side. Scope follows the pattern: X.Y.Z. All values are lower case and X is the trading pair base currency, Y is the trading pair quote currency, and Z is the order side (either ‘b’ for bid or ‘a’ for ask). For example, setting scope to eox.eos.b would place a buy order for the eox.eos trading pair.
Price: This is an integer representation of the limit price for the order. eosfinex orders support 4 digits of price precision to the right of the decimal point. The integer representation is obtained by simply multiplying the floating point price by 10000. For example, the integer representation of the limit price 4.1250 is 41250 (4.1250 * 10000).
Qty: This is an integer representation of the order size. Like prices, eosfinex orders support 4 digits of size precision to the right of the decimal point. To convert from decimal to integer representation, again simply multiply by 10000. For example, the integer representation of the order size 100.05 is 1000500 (100.05 * 10000).
Flags: The flags field is used to specify order options. Each bit in the 8-bit field represents a different option and can be enabled by setting that bit to true. This allows enabling multiple options on the same order.
Here is a list of each option and its corresponding bit:
00000001 Post Only: The order will receive a price reflecting the maker rebate.
00000010 Immediate or Cancel: Any size that does not fill immediately will be canceled.
00000100 Market: Ignore limit price and trade at the best available price.
00001000 Self Trade Prevention: Do not trade with an order having the same account.
01000000 Release on Trade: Transfer new funds out of the exchange after a trade.
10000000 Sweep Collateral: Transfer collateral balance out of exchange when canceled.
For example, if flags = 11000010, this will be an Immediate or Cancelorder that will transfer the full collateral balance, as well as any funds acquired due to a trade, out of the exchange upon order completion.
Let’s attempt to make this more clear through an example. We will assume the user has the following exchange balances.
cleos get currency balance [exchange_account] [user_account]
20.00000000 EOS
5.00000000 EOX
Let’s also assume that the user wants to buy 3.0000 EOX using EOS, and that the user wants to pay no more than 1.5 EOS for each EOX. In that case, the user would send the following command.
cleos push action exchange_account place ‘[user_account 1 eox.eos.b 15000 30000 0]’
Let’s assume that the order did not fill after it was placed, and it is resting in the order book waiting to be filled. If we query the user’s exchange wallet balances we see that some EOS has been reserved as collateral to support the order that was just placed.
cleos get currency balance [exchange_account] [user_account]
15.50000000 EOS
5.00000000 EOX
Next, we can query the orders table to see the order we just placed.
Orders Table
This table stores the limit order book for each trading pair. Any portion of a limit order that does not fill will be placed in the limit order book. The limit order book can be queried by using the following command.
cleos get table [exchange_account] [order_scope] orders
Above, order_scope is identical to the scope used to place the order. For example, let’s assume a user places the following eox.eos buy order.
cleos push action exchange_account place ‘[user_account 1 eox.eos.b 15000 30000 0]’
If the order does not fill, then it will be placed into the eox.eos buy limit order book, and we can query the limit order book like this.
cleos get table [exchange_account] eox.eos.b orders
{
“rows”: [{
“id”: “1234567”,
“account”: “user_account”,
“clId”: 1,
“price”: 15000,
“qty”: 30000,
“reserved”: 0,
“flags”: 0
}],
“more”: false
}
All the fields of the stored limit order are exactly as we would expect them to be.
The only field in the stored order structure that we do not recognize is the ‘id’ field. This field is assigned by the exchange. Notice that both price and qty are stored as integers, in the same way the order was placed. The order will remain in the order book until someone trades with it or it is canceled.
Cancel Action
The cancel action is used to cancel an order in the order book. The cancel action has the following ABI definition.
{
“name”: “cancel”,
“base”: “”,
“fields”: [
{“name”:”account”, “type”:”name”},
{“name”:”id”, “type”:”uint64"},
{“name”:”clId”, “type”:”uint64"},
{“name”:”scope”, “type”:”name”}
]
}
These fields are a subset of the fields in the place order action with the addition of the exchange assigned ‘id’ field. Assuming our eox.eos buy order with ‘id’ 1234567 was resting in the order book, we can cancel that order using the following command.
cleos push action [exchange_account] cancel ‘[user_account 1234567 1 eox.eos.b]’
As expected, querying the orders table after canceling the order leaves us with an empty orders table.
cleos get table [exchange_account] eox.eos.b orders
{
“rows”: [],
“more”: false
}
Withdraw Action
“name”: “withdraw”,
“base”: “”,
“fields”: [
{“name”:”to”, “type”:”name”},
{“name”:”amount”, “type”:”asset”}
]
}
As an example, let’s assume a user has the following exchange wallet balances.
cleos get currency balance [exchange_account] [user_account]
20.00000000 EOS
5.00000000 EOX
If the user wants to withdraw half of the available EOS, then he/she would issue the following command.
cleos push action exchange_account withdraw ‘[user_account “10.00000000 EOS”]’
By querying the exchange balance after the withdraw, we can see that the withdraw completed as expected.
cleos get currency balance [exchange_account] [user_account]
10.00000000 EOS
5.00000000 EOX
Summary
In the second installment of our weekly eosfinex blog series we looked at the eosfinex exchange contract, as well as how one can interact with the contract directly via the ABI.
In case you missed last weeks article — interacting with eosfinex using WebSockets — find it here:eosfinex: WebSockets for a decentralised, on-chain exchange
With the launch of eosfinex right around the corner, we’re pleased to give a sneak peek into the mechanics powering the…medium.com
Stay up to date with developments below as we approach our March 2019 launch.
原文链接/Original URL: