Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
plugin
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
link33
plugin
Commits
3f71a8a5
Unverified
Commit
3f71a8a5
authored
Jan 24, 2019
by
vipwzw
Committed by
GitHub
Jan 24, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #260 from linj-disanbo/trade-localdb
Trade localdb
parents
556879c1
8c429796
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
1188 additions
and
113 deletions
+1188
-113
table.go
plugin/dapp/guess/types/table.go
+2
-2
trade.go
plugin/dapp/trade/commands/trade.go
+127
-0
exec_del_local.go
plugin/dapp/trade/executor/exec_del_local.go
+41
-13
exec_local.go
plugin/dapp/trade/executor/exec_local.go
+35
-6
exec_test.go
plugin/dapp/trade/executor/exec_test.go
+53
-0
local_order.go
plugin/dapp/trade/executor/local_order.go
+454
-0
local_order_test.go
plugin/dapp/trade/executor/local_order_test.go
+66
-0
query.go
plugin/dapp/trade/executor/query.go
+80
-1
trade.go
plugin/dapp/trade/executor/trade.go
+47
-12
trade.proto
plugin/dapp/trade/proto/trade.proto
+21
-0
const.go
plugin/dapp/trade/types/const.go
+3
-0
trade.pb.go
plugin/dapp/trade/types/trade.pb.go
+259
-79
No files found.
plugin/dapp/guess/types/table.go
View file @
3f71a8a5
...
@@ -16,7 +16,7 @@ index: addr,status,addr_status,admin,admin_status,category_status
...
@@ -16,7 +16,7 @@ index: addr,status,addr_status,admin,admin_status,category_status
*/
*/
var
opt_guess_user
=
&
table
.
Option
{
var
opt_guess_user
=
&
table
.
Option
{
Prefix
:
"LODB
_
guess"
,
Prefix
:
"LODB
-
guess"
,
Name
:
"user"
,
Name
:
"user"
,
Primary
:
"index"
,
Primary
:
"index"
,
Index
:
[]
string
{
"addr"
,
"startindex"
},
Index
:
[]
string
{
"addr"
,
"startindex"
},
...
@@ -70,7 +70,7 @@ func (tx *GuessUserRow) Get(key string) ([]byte, error) {
...
@@ -70,7 +70,7 @@ func (tx *GuessUserRow) Get(key string) ([]byte, error) {
}
}
var
opt_guess_game
=
&
table
.
Option
{
var
opt_guess_game
=
&
table
.
Option
{
Prefix
:
"LODB
_
guess"
,
Prefix
:
"LODB
-
guess"
,
Name
:
"game"
,
Name
:
"game"
,
Primary
:
"startindex"
,
Primary
:
"startindex"
,
Index
:
[]
string
{
"gameid"
,
"status"
,
"admin"
,
"admin_status"
,
"category_status"
},
Index
:
[]
string
{
"gameid"
,
"status"
,
"admin"
,
"admin_status"
,
"category_status"
},
...
...
plugin/dapp/trade/commands/trade.go
View file @
3f71a8a5
...
@@ -30,6 +30,10 @@ func TradeCmd() *cobra.Command {
...
@@ -30,6 +30,10 @@ func TradeCmd() *cobra.Command {
CreateRawTradeBuyTxCmd
(),
CreateRawTradeBuyTxCmd
(),
CreateRawTradeRevokeTxCmd
(),
CreateRawTradeRevokeTxCmd
(),
CreateRawBuyLimitTxCmd
(),
CreateRawSellMarketTxCmd
(),
CreateRawBuyRevokeTxCmd
(),
ShowOnesSellOrdersCmd
(),
ShowOnesSellOrdersCmd
(),
ShowOnesSellOrdersStatusCmd
(),
ShowOnesSellOrdersStatusCmd
(),
ShowTokenSellOrdersStatusCmd
(),
ShowTokenSellOrdersStatusCmd
(),
...
@@ -555,3 +559,126 @@ func tokenSellRevoke(cmd *cobra.Command, args []string) {
...
@@ -555,3 +559,126 @@ func tokenSellRevoke(cmd *cobra.Command, args []string) {
ctx
:=
jsonrpc
.
NewRPCCtx
(
rpcLaddr
,
"trade.CreateRawTradeRevokeTx"
,
params
,
nil
)
ctx
:=
jsonrpc
.
NewRPCCtx
(
rpcLaddr
,
"trade.CreateRawTradeRevokeTx"
,
params
,
nil
)
ctx
.
RunWithoutMarshal
()
ctx
.
RunWithoutMarshal
()
}
}
// BuyLimit SellMarket BuyRevoke transactions
// CreateRawBuyLimitTxCmd : create raw buy limit token transaction
func
CreateRawBuyLimitTxCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"buy_limit"
,
Short
:
"Create a buy limit transaction"
,
Run
:
tokenBuyLimit
,
}
addTokenBuyLimitFlags
(
cmd
)
return
cmd
}
func
addTokenBuyLimitFlags
(
cmd
*
cobra
.
Command
)
{
cmd
.
Flags
()
.
StringP
(
"symbol"
,
"s"
,
""
,
"token symbol"
)
cmd
.
MarkFlagRequired
(
"symbol"
)
cmd
.
Flags
()
.
Int64P
(
"min"
,
"m"
,
0
,
"min boardlot"
)
cmd
.
MarkFlagRequired
(
"min"
)
cmd
.
Flags
()
.
Float64P
(
"price"
,
"p"
,
0
,
"price per boardlot"
)
cmd
.
MarkFlagRequired
(
"price"
)
cmd
.
Flags
()
.
Float64P
(
"fee"
,
"f"
,
0
,
"transaction fee"
)
cmd
.
Flags
()
.
Float64P
(
"total"
,
"t"
,
0
,
"total tokens to buy"
)
cmd
.
MarkFlagRequired
(
"total"
)
}
func
tokenBuyLimit
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
rpcLaddr
,
_
:=
cmd
.
Flags
()
.
GetString
(
"rpc_laddr"
)
symbol
,
_
:=
cmd
.
Flags
()
.
GetString
(
"symbol"
)
min
,
_
:=
cmd
.
Flags
()
.
GetInt64
(
"min"
)
price
,
_
:=
cmd
.
Flags
()
.
GetFloat64
(
"price"
)
fee
,
_
:=
cmd
.
Flags
()
.
GetFloat64
(
"fee"
)
total
,
_
:=
cmd
.
Flags
()
.
GetFloat64
(
"total"
)
priceInt64
:=
int64
(
price
*
1e4
)
feeInt64
:=
int64
(
fee
*
1e4
)
totalInt64
:=
int64
(
total
*
1e8
/
1e6
)
params
:=
&
pty
.
TradeBuyLimitTx
{
TokenSymbol
:
symbol
,
AmountPerBoardlot
:
1e6
,
MinBoardlot
:
min
,
PricePerBoardlot
:
priceInt64
*
1e4
,
TotalBoardlot
:
totalInt64
,
Fee
:
feeInt64
*
1e4
,
AssetExec
:
"token"
,
}
ctx
:=
jsonrpc
.
NewRPCCtx
(
rpcLaddr
,
"trade.CreateRawTradeBuyLimitTx"
,
params
,
nil
)
ctx
.
RunWithoutMarshal
()
}
// CreateRawSellMarketTxCmd : create raw sell market token transaction
func
CreateRawSellMarketTxCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"sell_market"
,
Short
:
"Create a sell market transaction"
,
Run
:
sellMarket
,
}
addSellMarketFlags
(
cmd
)
return
cmd
}
func
addSellMarketFlags
(
cmd
*
cobra
.
Command
)
{
cmd
.
Flags
()
.
StringP
(
"buy_id"
,
"b"
,
""
,
"buy id"
)
cmd
.
MarkFlagRequired
(
"buy_id"
)
cmd
.
Flags
()
.
Int64P
(
"count"
,
"c"
,
0
,
"count of selling (boardlot)"
)
cmd
.
MarkFlagRequired
(
"count"
)
cmd
.
Flags
()
.
Float64P
(
"fee"
,
"f"
,
0
,
"transaction fee"
)
}
func
sellMarket
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
rpcLaddr
,
_
:=
cmd
.
Flags
()
.
GetString
(
"rpc_laddr"
)
buyID
,
_
:=
cmd
.
Flags
()
.
GetString
(
"buy_id"
)
fee
,
_
:=
cmd
.
Flags
()
.
GetFloat64
(
"fee"
)
count
,
_
:=
cmd
.
Flags
()
.
GetInt64
(
"count"
)
feeInt64
:=
int64
(
fee
*
1e4
)
params
:=
&
pty
.
TradeSellMarketTx
{
BuyID
:
buyID
,
BoardlotCnt
:
count
,
Fee
:
feeInt64
*
1e4
,
}
ctx
:=
jsonrpc
.
NewRPCCtx
(
rpcLaddr
,
"trade.CreateRawTradeSellMarketTx"
,
params
,
nil
)
ctx
.
RunWithoutMarshal
()
}
// CreateRawBuyRevokeTxCmd : create raw buy revoke transaction
func
CreateRawBuyRevokeTxCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"revoke_buy"
,
Short
:
"Create a revoke buy limit transaction"
,
Run
:
buyRevoke
,
}
addBuyRevokeFlags
(
cmd
)
return
cmd
}
func
addBuyRevokeFlags
(
cmd
*
cobra
.
Command
)
{
cmd
.
Flags
()
.
StringP
(
"buy_id"
,
"b"
,
""
,
"buy id"
)
cmd
.
MarkFlagRequired
(
"buy_id"
)
cmd
.
Flags
()
.
Float64P
(
"fee"
,
"f"
,
0
,
"transaction fee"
)
}
func
buyRevoke
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
rpcLaddr
,
_
:=
cmd
.
Flags
()
.
GetString
(
"rpc_laddr"
)
buyID
,
_
:=
cmd
.
Flags
()
.
GetString
(
"buy_id"
)
fee
,
_
:=
cmd
.
Flags
()
.
GetFloat64
(
"fee"
)
feeInt64
:=
int64
(
fee
*
1e4
)
params
:=
&
pty
.
TradeRevokeBuyTx
{
BuyID
:
buyID
,
Fee
:
feeInt64
*
1e4
,
}
ctx
:=
jsonrpc
.
NewRPCCtx
(
rpcLaddr
,
"trade.CreateRawTradeRevokeBuyTx"
,
params
,
nil
)
ctx
.
RunWithoutMarshal
()
}
plugin/dapp/trade/executor/exec_del_local.go
View file @
3f71a8a5
...
@@ -5,46 +5,57 @@
...
@@ -5,46 +5,57 @@
package
executor
package
executor
import
(
import
(
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/types"
pty
"github.com/33cn/plugin/plugin/dapp/trade/types"
pty
"github.com/33cn/plugin/plugin/dapp/trade/types"
)
)
func
(
t
*
trade
)
ExecDelLocal_SellLimit
(
sell
*
pty
.
TradeForSell
,
tx
*
types
.
Transaction
,
receipt
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
func
(
t
*
trade
)
ExecDelLocal_SellLimit
(
sell
*
pty
.
TradeForSell
,
tx
*
types
.
Transaction
,
receipt
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
return
t
.
localDelLog
(
tx
,
receipt
,
index
)
return
t
.
localDelLog
(
tx
,
receipt
,
index
,
0
)
}
}
func
(
t
*
trade
)
ExecDelLocal_BuyMarket
(
buy
*
pty
.
TradeForBuy
,
tx
*
types
.
Transaction
,
receipt
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
func
(
t
*
trade
)
ExecDelLocal_BuyMarket
(
buy
*
pty
.
TradeForBuy
,
tx
*
types
.
Transaction
,
receipt
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
return
t
.
localDelLog
(
tx
,
receipt
,
index
)
return
t
.
localDelLog
(
tx
,
receipt
,
index
,
buy
.
BoardlotCnt
)
}
}
func
(
t
*
trade
)
ExecDelLocal_RevokeSell
(
revoke
*
pty
.
TradeForRevokeSell
,
tx
*
types
.
Transaction
,
receipt
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
func
(
t
*
trade
)
ExecDelLocal_RevokeSell
(
revoke
*
pty
.
TradeForRevokeSell
,
tx
*
types
.
Transaction
,
receipt
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
return
t
.
localDelLog
(
tx
,
receipt
,
index
)
return
t
.
localDelLog
(
tx
,
receipt
,
index
,
0
)
}
}
func
(
t
*
trade
)
ExecDelLocal_BuyLimit
(
buy
*
pty
.
TradeForBuyLimit
,
tx
*
types
.
Transaction
,
receipt
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
func
(
t
*
trade
)
ExecDelLocal_BuyLimit
(
buy
*
pty
.
TradeForBuyLimit
,
tx
*
types
.
Transaction
,
receipt
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
return
t
.
localDelLog
(
tx
,
receipt
,
index
)
return
t
.
localDelLog
(
tx
,
receipt
,
index
,
0
)
}
}
func
(
t
*
trade
)
ExecDelLocal_SellMarket
(
sell
*
pty
.
TradeForSellMarket
,
tx
*
types
.
Transaction
,
receipt
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
func
(
t
*
trade
)
ExecDelLocal_SellMarket
(
sell
*
pty
.
TradeForSellMarket
,
tx
*
types
.
Transaction
,
receipt
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
return
t
.
localDelLog
(
tx
,
receipt
,
index
)
return
t
.
localDelLog
(
tx
,
receipt
,
index
,
sell
.
BoardlotCnt
)
}
}
func
(
t
*
trade
)
ExecDelLocal_RevokeBuy
(
revoke
*
pty
.
TradeForRevokeBuy
,
tx
*
types
.
Transaction
,
receipt
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
func
(
t
*
trade
)
ExecDelLocal_RevokeBuy
(
revoke
*
pty
.
TradeForRevokeBuy
,
tx
*
types
.
Transaction
,
receipt
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
return
t
.
localDelLog
(
tx
,
receipt
,
index
)
return
t
.
localDelLog
(
tx
,
receipt
,
index
,
0
)
}
}
func
(
t
*
trade
)
localDelLog
(
tx
*
types
.
Transaction
,
receipt
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
func
(
t
*
trade
)
localDelLog
(
tx
*
types
.
Transaction
,
receipt
*
types
.
ReceiptData
,
index
int
,
tradedBoardlot
int64
)
(
*
types
.
LocalDBSet
,
error
)
{
var
set
types
.
LocalDBSet
var
set
types
.
LocalDBSet
table
:=
NewOrderTable
(
t
.
GetLocalDB
())
txIndex
:=
dapp
.
HeightIndexStr
(
t
.
GetHeight
(),
int64
(
index
))
for
i
:=
0
;
i
<
len
(
receipt
.
Logs
);
i
++
{
for
i
:=
0
;
i
<
len
(
receipt
.
Logs
);
i
++
{
item
:=
receipt
.
Logs
[
i
]
item
:=
receipt
.
Logs
[
i
]
if
item
.
Ty
==
pty
.
TyLogTradeSellLimit
||
item
.
Ty
==
pty
.
TyLogTradeSellRevoke
{
if
item
.
Ty
==
pty
.
TyLogTradeSellLimit
{
var
receipt
pty
.
ReceiptTradeSellLimit
var
receipt
pty
.
ReceiptTradeSellLimit
err
:=
types
.
Decode
(
item
.
Log
,
&
receipt
)
err
:=
types
.
Decode
(
item
.
Log
,
&
receipt
)
if
err
!=
nil
{
if
err
!=
nil
{
panic
(
err
)
//数据错误了,已经被修改了
panic
(
err
)
//数据错误了,已经被修改了
}
}
kv
:=
t
.
deleteSell
([]
byte
(
receipt
.
Base
.
SellID
),
item
.
Ty
)
kv
:=
t
.
deleteSell
(
receipt
.
Base
,
item
.
Ty
,
tx
,
txIndex
,
table
,
tradedBoardlot
)
set
.
KV
=
append
(
set
.
KV
,
kv
...
)
}
else
if
item
.
Ty
==
pty
.
TyLogTradeSellRevoke
{
var
receipt
pty
.
ReceiptTradeSellRevoke
err
:=
types
.
Decode
(
item
.
Log
,
&
receipt
)
if
err
!=
nil
{
panic
(
err
)
//数据错误了,已经被修改了
}
kv
:=
t
.
deleteSell
(
receipt
.
Base
,
item
.
Ty
,
tx
,
txIndex
,
table
,
tradedBoardlot
)
set
.
KV
=
append
(
set
.
KV
,
kv
...
)
set
.
KV
=
append
(
set
.
KV
,
kv
...
)
}
else
if
item
.
Ty
==
pty
.
TyLogTradeBuyMarket
{
}
else
if
item
.
Ty
==
pty
.
TyLogTradeBuyMarket
{
var
receipt
pty
.
ReceiptTradeBuyMarket
var
receipt
pty
.
ReceiptTradeBuyMarket
...
@@ -52,15 +63,23 @@ func (t *trade) localDelLog(tx *types.Transaction, receipt *types.ReceiptData, i
...
@@ -52,15 +63,23 @@ func (t *trade) localDelLog(tx *types.Transaction, receipt *types.ReceiptData, i
if
err
!=
nil
{
if
err
!=
nil
{
panic
(
err
)
//数据错误了,已经被修改了
panic
(
err
)
//数据错误了,已经被修改了
}
}
kv
:=
t
.
deleteBuy
(
receipt
.
Base
)
kv
:=
t
.
deleteBuy
(
receipt
.
Base
,
txIndex
,
table
)
set
.
KV
=
append
(
set
.
KV
,
kv
...
)
}
else
if
item
.
Ty
==
pty
.
TyLogTradeBuyRevoke
{
var
receipt
pty
.
ReceiptTradeBuyRevoke
err
:=
types
.
Decode
(
item
.
Log
,
&
receipt
)
if
err
!=
nil
{
panic
(
err
)
//数据错误了,已经被修改了
}
kv
:=
t
.
deleteBuyLimit
(
receipt
.
Base
,
item
.
Ty
,
tx
,
txIndex
,
table
,
tradedBoardlot
)
set
.
KV
=
append
(
set
.
KV
,
kv
...
)
set
.
KV
=
append
(
set
.
KV
,
kv
...
)
}
else
if
item
.
Ty
==
pty
.
TyLogTradeBuy
Revoke
||
item
.
Ty
==
pty
.
TyLogTradeBuy
Limit
{
}
else
if
item
.
Ty
==
pty
.
TyLogTradeBuyLimit
{
var
receipt
pty
.
ReceiptTradeBuyLimit
var
receipt
pty
.
ReceiptTradeBuyLimit
err
:=
types
.
Decode
(
item
.
Log
,
&
receipt
)
err
:=
types
.
Decode
(
item
.
Log
,
&
receipt
)
if
err
!=
nil
{
if
err
!=
nil
{
panic
(
err
)
//数据错误了,已经被修改了
panic
(
err
)
//数据错误了,已经被修改了
}
}
kv
:=
t
.
deleteBuyLimit
(
[]
byte
(
receipt
.
Base
.
BuyID
),
item
.
Ty
)
kv
:=
t
.
deleteBuyLimit
(
receipt
.
Base
,
item
.
Ty
,
tx
,
txIndex
,
table
,
tradedBoardlot
)
set
.
KV
=
append
(
set
.
KV
,
kv
...
)
set
.
KV
=
append
(
set
.
KV
,
kv
...
)
}
else
if
item
.
Ty
==
pty
.
TyLogTradeSellMarket
{
}
else
if
item
.
Ty
==
pty
.
TyLogTradeSellMarket
{
var
receipt
pty
.
ReceiptSellMarket
var
receipt
pty
.
ReceiptSellMarket
...
@@ -68,10 +87,19 @@ func (t *trade) localDelLog(tx *types.Transaction, receipt *types.ReceiptData, i
...
@@ -68,10 +87,19 @@ func (t *trade) localDelLog(tx *types.Transaction, receipt *types.ReceiptData, i
if
err
!=
nil
{
if
err
!=
nil
{
panic
(
err
)
//数据错误了,已经被修改了
panic
(
err
)
//数据错误了,已经被修改了
}
}
kv
:=
t
.
deleteSellMarket
(
receipt
.
Base
)
kv
:=
t
.
deleteSellMarket
(
receipt
.
Base
,
txIndex
,
table
)
set
.
KV
=
append
(
set
.
KV
,
kv
...
)
set
.
KV
=
append
(
set
.
KV
,
kv
...
)
}
}
}
}
newKvs
,
err
:=
table
.
Save
()
if
err
!=
nil
{
tradelog
.
Error
(
"trade table.Save failed"
,
"error"
,
err
)
return
nil
,
err
}
set
.
KV
=
append
(
set
.
KV
,
newKvs
...
)
for
_
,
kv
:=
range
set
.
KV
{
t
.
GetLocalDB
()
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
return
&
set
,
nil
return
&
set
,
nil
}
}
plugin/dapp/trade/executor/exec_local.go
View file @
3f71a8a5
...
@@ -5,6 +5,7 @@
...
@@ -5,6 +5,7 @@
package
executor
package
executor
import
(
import
(
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/types"
pty
"github.com/33cn/plugin/plugin/dapp/trade/types"
pty
"github.com/33cn/plugin/plugin/dapp/trade/types"
)
)
...
@@ -35,16 +36,26 @@ func (t *trade) ExecLocal_RevokeBuy(revoke *pty.TradeForRevokeBuy, tx *types.Tra
...
@@ -35,16 +36,26 @@ func (t *trade) ExecLocal_RevokeBuy(revoke *pty.TradeForRevokeBuy, tx *types.Tra
func
(
t
*
trade
)
localAddLog
(
tx
*
types
.
Transaction
,
receipt
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
func
(
t
*
trade
)
localAddLog
(
tx
*
types
.
Transaction
,
receipt
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
var
set
types
.
LocalDBSet
var
set
types
.
LocalDBSet
table
:=
NewOrderTable
(
t
.
GetLocalDB
())
txIndex
:=
dapp
.
HeightIndexStr
(
t
.
GetHeight
(),
int64
(
index
))
for
i
:=
0
;
i
<
len
(
receipt
.
Logs
);
i
++
{
for
i
:=
0
;
i
<
len
(
receipt
.
Logs
);
i
++
{
item
:=
receipt
.
Logs
[
i
]
item
:=
receipt
.
Logs
[
i
]
if
item
.
Ty
==
pty
.
TyLogTradeSellLimit
||
item
.
Ty
==
pty
.
TyLogTradeSellRevoke
{
if
item
.
Ty
==
pty
.
TyLogTradeSellLimit
{
var
receipt
pty
.
ReceiptTradeSellLimit
var
receipt
pty
.
ReceiptTradeSellLimit
err
:=
types
.
Decode
(
item
.
Log
,
&
receipt
)
err
:=
types
.
Decode
(
item
.
Log
,
&
receipt
)
if
err
!=
nil
{
if
err
!=
nil
{
panic
(
err
)
//数据错误了,已经被修改了
panic
(
err
)
//数据错误了,已经被修改了
}
}
kv
:=
t
.
saveSell
([]
byte
(
receipt
.
Base
.
SellID
),
item
.
Ty
)
kv
:=
t
.
saveSell
(
receipt
.
Base
,
item
.
Ty
,
tx
,
txIndex
,
table
)
set
.
KV
=
append
(
set
.
KV
,
kv
...
)
}
else
if
item
.
Ty
==
pty
.
TyLogTradeSellRevoke
{
var
receipt
pty
.
ReceiptTradeSellRevoke
err
:=
types
.
Decode
(
item
.
Log
,
&
receipt
)
if
err
!=
nil
{
panic
(
err
)
//数据错误了,已经被修改了
}
kv
:=
t
.
saveSell
(
receipt
.
Base
,
item
.
Ty
,
tx
,
txIndex
,
table
)
set
.
KV
=
append
(
set
.
KV
,
kv
...
)
set
.
KV
=
append
(
set
.
KV
,
kv
...
)
}
else
if
item
.
Ty
==
pty
.
TyLogTradeBuyMarket
{
}
else
if
item
.
Ty
==
pty
.
TyLogTradeBuyMarket
{
var
receipt
pty
.
ReceiptTradeBuyMarket
var
receipt
pty
.
ReceiptTradeBuyMarket
...
@@ -52,16 +63,25 @@ func (t *trade) localAddLog(tx *types.Transaction, receipt *types.ReceiptData, i
...
@@ -52,16 +63,25 @@ func (t *trade) localAddLog(tx *types.Transaction, receipt *types.ReceiptData, i
if
err
!=
nil
{
if
err
!=
nil
{
panic
(
err
)
//数据错误了,已经被修改了
panic
(
err
)
//数据错误了,已经被修改了
}
}
kv
:=
t
.
saveBuy
(
receipt
.
Base
)
kv
:=
t
.
saveBuy
(
receipt
.
Base
,
tx
,
txIndex
,
table
)
set
.
KV
=
append
(
set
.
KV
,
kv
...
)
set
.
KV
=
append
(
set
.
KV
,
kv
...
)
}
else
if
item
.
Ty
==
pty
.
TyLogTradeBuyRevoke
||
item
.
Ty
==
pty
.
TyLogTradeBuyLimit
{
}
else
if
item
.
Ty
==
pty
.
TyLogTradeBuyRevoke
{
var
receipt
pty
.
ReceiptTradeBuyRevoke
err
:=
types
.
Decode
(
item
.
Log
,
&
receipt
)
if
err
!=
nil
{
panic
(
err
)
//数据错误了,已经被修改了
}
kv
:=
t
.
saveBuyLimit
(
receipt
.
Base
,
item
.
Ty
,
tx
,
txIndex
,
table
)
set
.
KV
=
append
(
set
.
KV
,
kv
...
)
}
else
if
item
.
Ty
==
pty
.
TyLogTradeBuyLimit
{
var
receipt
pty
.
ReceiptTradeBuyLimit
var
receipt
pty
.
ReceiptTradeBuyLimit
err
:=
types
.
Decode
(
item
.
Log
,
&
receipt
)
err
:=
types
.
Decode
(
item
.
Log
,
&
receipt
)
if
err
!=
nil
{
if
err
!=
nil
{
panic
(
err
)
//数据错误了,已经被修改了
panic
(
err
)
//数据错误了,已经被修改了
}
}
kv
:=
t
.
saveBuyLimit
(
[]
byte
(
receipt
.
Base
.
BuyID
),
item
.
Ty
)
kv
:=
t
.
saveBuyLimit
(
receipt
.
Base
,
item
.
Ty
,
tx
,
txIndex
,
table
)
set
.
KV
=
append
(
set
.
KV
,
kv
...
)
set
.
KV
=
append
(
set
.
KV
,
kv
...
)
}
else
if
item
.
Ty
==
pty
.
TyLogTradeSellMarket
{
}
else
if
item
.
Ty
==
pty
.
TyLogTradeSellMarket
{
var
receipt
pty
.
ReceiptSellMarket
var
receipt
pty
.
ReceiptSellMarket
...
@@ -69,11 +89,20 @@ func (t *trade) localAddLog(tx *types.Transaction, receipt *types.ReceiptData, i
...
@@ -69,11 +89,20 @@ func (t *trade) localAddLog(tx *types.Transaction, receipt *types.ReceiptData, i
if
err
!=
nil
{
if
err
!=
nil
{
panic
(
err
)
//数据错误了,已经被修改了
panic
(
err
)
//数据错误了,已经被修改了
}
}
kv
:=
t
.
saveSellMarket
(
receipt
.
Base
)
kv
:=
t
.
saveSellMarket
(
receipt
.
Base
,
tx
,
txIndex
,
table
)
//tradelog.Info("saveSellMarket", "kv", kv)
//tradelog.Info("saveSellMarket", "kv", kv)
set
.
KV
=
append
(
set
.
KV
,
kv
...
)
set
.
KV
=
append
(
set
.
KV
,
kv
...
)
}
}
}
}
newKvs
,
err
:=
table
.
Save
()
if
err
!=
nil
{
tradelog
.
Error
(
"trade table.Save failed"
,
"error"
,
err
)
return
nil
,
err
}
set
.
KV
=
append
(
set
.
KV
,
newKvs
...
)
for
_
,
kv
:=
range
set
.
KV
{
t
.
GetLocalDB
()
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
return
&
set
,
nil
return
&
set
,
nil
}
}
plugin/dapp/trade/executor/exec_test.go
View file @
3f71a8a5
...
@@ -13,6 +13,7 @@ import (
...
@@ -13,6 +13,7 @@ import (
"github.com/33cn/chain33/common/crypto"
"github.com/33cn/chain33/common/crypto"
dbm
"github.com/33cn/chain33/common/db"
dbm
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
pty
"github.com/33cn/plugin/plugin/dapp/trade/types"
pty
"github.com/33cn/plugin/plugin/dapp/trade/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/assert"
)
)
...
@@ -83,9 +84,12 @@ func TestTrade_Exec_SellLimit(t *testing.T) {
...
@@ -83,9 +84,12 @@ func TestTrade_Exec_SellLimit(t *testing.T) {
accA
,
_
:=
account
.
NewAccountDB
(
AssetExecToken
,
Symbol
,
stateDB
)
accA
,
_
:=
account
.
NewAccountDB
(
AssetExecToken
,
Symbol
,
stateDB
)
accA
.
SaveExecAccount
(
address
.
ExecAddress
(
"trade"
),
&
accountA
)
accA
.
SaveExecAccount
(
address
.
ExecAddress
(
"trade"
),
&
accountA
)
_
,
ldb
,
kvdb
:=
util
.
CreateTestDB
()
driver
:=
newTrade
()
driver
:=
newTrade
()
driver
.
SetEnv
(
env
.
blockHeight
,
env
.
blockTime
,
env
.
difficulty
)
driver
.
SetEnv
(
env
.
blockHeight
,
env
.
blockTime
,
env
.
difficulty
)
driver
.
SetStateDB
(
stateDB
)
driver
.
SetStateDB
(
stateDB
)
driver
.
SetLocalDB
(
kvdb
)
sell
:=
&
pty
.
TradeSellTx
{
sell
:=
&
pty
.
TradeSellTx
{
TokenSymbol
:
Symbol
,
TokenSymbol
:
Symbol
,
...
@@ -124,6 +128,15 @@ func TestTrade_Exec_SellLimit(t *testing.T) {
...
@@ -124,6 +128,15 @@ func TestTrade_Exec_SellLimit(t *testing.T) {
assert
.
Equal
(
t
,
int64
(
0
),
sellOrder
.
SoldBoardlot
)
assert
.
Equal
(
t
,
int64
(
0
),
sellOrder
.
SoldBoardlot
)
assert
.
Equal
(
t
,
string
(
Nodes
[
0
]),
sellOrder
.
Address
)
assert
.
Equal
(
t
,
string
(
Nodes
[
0
]),
sellOrder
.
Address
)
receiptDataSell
:=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
,
}
_
,
err
=
driver
.
ExecLocal
(
tx
,
receiptDataSell
,
env
.
index
)
assert
.
Nil
(
t
,
err
)
kvdb
.
Commit
()
// test buy market
buy
:=
&
pty
.
TradeBuyTx
{
buy
:=
&
pty
.
TradeBuyTx
{
SellID
:
sellOrder
.
SellID
,
SellID
:
sellOrder
.
SellID
,
BoardlotCnt
:
buyArgs
.
total
,
BoardlotCnt
:
buyArgs
.
total
,
...
@@ -157,6 +170,27 @@ func TestTrade_Exec_SellLimit(t *testing.T) {
...
@@ -157,6 +170,27 @@ func TestTrade_Exec_SellLimit(t *testing.T) {
assert
.
Nil
(
t
,
err
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
expect
.
total
,
sellOrder
.
TotalBoardlot
-
sellOrder
.
SoldBoardlot
)
assert
.
Equal
(
t
,
expect
.
total
,
sellOrder
.
TotalBoardlot
-
sellOrder
.
SoldBoardlot
)
receiptDataBuy
:=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
,
}
_
,
err
=
driver
.
ExecLocal
(
tx
,
receiptDataBuy
,
env
.
index
)
assert
.
Nil
(
t
,
err
)
req
:=
&
pty
.
ReqAddrAssets
{
Addr
:
string
(
Nodes
[
0
]),
Status
:
pty
.
TradeOrderStatusOnSale
,
Token
:
nil
,
Direction
:
1
,
Count
:
10
,
FromKey
:
""
,
}
resp
,
err
:=
driver
.
Query
(
"GetOnesOrderWithStatus"
,
types
.
Encode
(
req
))
assert
.
Nil
(
t
,
err
)
orders
,
ok
:=
resp
.
(
*
pty
.
ReplyTradeOrders
)
assert
.
True
(
t
,
ok
)
assert
.
Equal
(
t
,
1
,
len
(
orders
.
Orders
))
ldb
.
Close
()
}
}
func
TestTrade_Exec_BuyLimit
(
t
*
testing
.
T
)
{
func
TestTrade_Exec_BuyLimit
(
t
*
testing
.
T
)
{
...
@@ -185,6 +219,8 @@ func TestTrade_Exec_BuyLimit(t *testing.T) {
...
@@ -185,6 +219,8 @@ func TestTrade_Exec_BuyLimit(t *testing.T) {
}
}
stateDB
,
_
:=
dbm
.
NewGoMemDB
(
"1"
,
"2"
,
100
)
stateDB
,
_
:=
dbm
.
NewGoMemDB
(
"1"
,
"2"
,
100
)
_
,
ldb
,
kvdb
:=
util
.
CreateTestDB
()
accB
:=
account
.
NewCoinsAccount
()
accB
:=
account
.
NewCoinsAccount
()
accB
.
SetDB
(
stateDB
)
accB
.
SetDB
(
stateDB
)
accB
.
SaveExecAccount
(
address
.
ExecAddress
(
"trade"
),
&
accountB
)
accB
.
SaveExecAccount
(
address
.
ExecAddress
(
"trade"
),
&
accountB
)
...
@@ -195,6 +231,7 @@ func TestTrade_Exec_BuyLimit(t *testing.T) {
...
@@ -195,6 +231,7 @@ func TestTrade_Exec_BuyLimit(t *testing.T) {
driver
:=
newTrade
()
driver
:=
newTrade
()
driver
.
SetEnv
(
env
.
blockHeight
,
env
.
blockTime
,
env
.
difficulty
)
driver
.
SetEnv
(
env
.
blockHeight
,
env
.
blockTime
,
env
.
difficulty
)
driver
.
SetStateDB
(
stateDB
)
driver
.
SetStateDB
(
stateDB
)
driver
.
SetLocalDB
(
kvdb
)
buy
:=
&
pty
.
TradeBuyLimitTx
{
buy
:=
&
pty
.
TradeBuyLimitTx
{
TokenSymbol
:
Symbol
,
TokenSymbol
:
Symbol
,
...
@@ -233,6 +270,13 @@ func TestTrade_Exec_BuyLimit(t *testing.T) {
...
@@ -233,6 +270,13 @@ func TestTrade_Exec_BuyLimit(t *testing.T) {
assert
.
Equal
(
t
,
int64
(
0
),
buyLimitOrder
.
BoughtBoardlot
)
assert
.
Equal
(
t
,
int64
(
0
),
buyLimitOrder
.
BoughtBoardlot
)
assert
.
Equal
(
t
,
string
(
Nodes
[
1
]),
buyLimitOrder
.
Address
)
assert
.
Equal
(
t
,
string
(
Nodes
[
1
]),
buyLimitOrder
.
Address
)
receiptDataBuy
:=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
,
}
_
,
err
=
driver
.
ExecLocal
(
tx
,
receiptDataBuy
,
env
.
index
)
assert
.
Nil
(
t
,
err
)
sell
:=
&
pty
.
TradeSellMarketTx
{
sell
:=
&
pty
.
TradeSellMarketTx
{
BuyID
:
buyLimitOrder
.
BuyID
,
BuyID
:
buyLimitOrder
.
BuyID
,
BoardlotCnt
:
sellArgs
.
total
,
BoardlotCnt
:
sellArgs
.
total
,
...
@@ -266,6 +310,15 @@ func TestTrade_Exec_BuyLimit(t *testing.T) {
...
@@ -266,6 +310,15 @@ func TestTrade_Exec_BuyLimit(t *testing.T) {
err
=
types
.
Decode
(
receipt
.
KV
[
4
]
.
Value
,
&
buyLimitOrder
)
err
=
types
.
Decode
(
receipt
.
KV
[
4
]
.
Value
,
&
buyLimitOrder
)
assert
.
Nil
(
t
,
err
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
expect
.
total
,
buyLimitOrder
.
TotalBoardlot
-
buyLimitOrder
.
BoughtBoardlot
)
assert
.
Equal
(
t
,
expect
.
total
,
buyLimitOrder
.
TotalBoardlot
-
buyLimitOrder
.
BoughtBoardlot
)
receiptDataSell
:=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
,
}
_
,
err
=
driver
.
ExecLocal
(
tx
,
receiptDataSell
,
env
.
index
)
assert
.
Nil
(
t
,
err
)
ldb
.
Close
()
}
}
func
signTx
(
tx
*
types
.
Transaction
,
hexPrivKey
string
)
(
*
types
.
Transaction
,
error
)
{
func
signTx
(
tx
*
types
.
Transaction
,
hexPrivKey
string
)
(
*
types
.
Transaction
,
error
)
{
...
...
plugin/dapp/trade/executor/local_order.go
0 → 100644
View file @
3f71a8a5
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
executor
import
(
"encoding/hex"
"fmt"
"strconv"
"github.com/33cn/chain33/common"
dbm
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/common/db/table"
"github.com/33cn/chain33/types"
pty
"github.com/33cn/plugin/plugin/dapp/trade/types"
)
/*
现有接口
1. 查询地址对应的买单 (无分页)
1.1 只指定地址 -> owner
1.2 同时指定地址和token -> owner_asset
1.3 显示一个用户成交的所有买单 -> owner
1.4 显示一个用户成交的指定一个或者多个token所有买单 -> owner_asset 不支持多个
2. 分状态查询地址的买单: 状态 地址 (无分页) -> owner_status
3. 显示一个token 指定数量的买单 GetTokenBuyOrderByStatus -> asset_inBuy_status
4. 显示指定token出售者的一个或多个token 或 不指定token 的卖单 (无分页) -> owner_asset/owner_asset_isSell 不支持多个
5. 显示指定状态下的某地址卖单 (无分页) -> owner_isSell_status
6. 显示一个token 指定数量的卖单 -> asset_isSell
7. 根据状态分页列出某地址的订单(包括买单卖单) owner_status
*/
var
opt_order_table
=
&
table
.
Option
{
Prefix
:
"LODB-trade"
,
Name
:
"order"
,
Primary
:
"txIndex"
,
// asset = asset_exec+asset_symbol
//
// status: 设计为可以同时查询几种的并集 , 存储为前缀, 需要提前设计需要合并的, 用前缀表示
// 进行中, 撤销, 部分成交 , 全部成交, 完成状态统一前缀. 数字和原来不一样
// 00 10 11 12 1*
// 排序过滤条件: 可以组合,status&isSell 和前缀冲突
Index
:
[]
string
{
"key"
,
// 内部查询用
"asset"
,
// 按资产统计订单
"asset_isSell_status"
,
// 接口 3
// "asset_status", 可能需求, 用于资产的交易历史
// "asset_isSell",
"owner"
,
// 接口 1.1, 1.3
"owner_asset"
,
// 接口 1.2, 1.4, 4, 7
"owner_asset_isSell"
,
// 接口 4
"owner_asset_status"
,
// 新需求, 在
"owner_isSell"
,
// 接口 6
// "owner_isSell_status", 可能需求, 界面分开显示订单
// "owner_isSell_statusPrefix", // 状态可以定制组合, 成交历史需求
"owner_status"
,
// 接口 2
"assset_isSell_isFinished"
,
// 用 isFinish, 进行订单是否完成的列表功能
"owner_asset_isFinished"
,
"owner_isFinished"
,
// "owner_statusPrefix", // 状态可以定制组合 , 成交历史需求
},
}
// OrderRow order row
type
OrderRow
struct
{
*
pty
.
LocalOrder
}
// NewOrderRow create row
func
NewOrderRow
()
*
OrderRow
{
return
&
OrderRow
{
LocalOrder
:
nil
}
}
// CreateRow create row
func
(
r
*
OrderRow
)
CreateRow
()
*
table
.
Row
{
return
&
table
.
Row
{
Data
:
&
pty
.
LocalOrder
{}}
}
// SetPayload set payload
func
(
r
*
OrderRow
)
SetPayload
(
data
types
.
Message
)
error
{
if
d
,
ok
:=
data
.
(
*
pty
.
LocalOrder
);
ok
{
r
.
LocalOrder
=
d
return
nil
}
return
types
.
ErrTypeAsset
}
// Get get index key
func
(
r
*
OrderRow
)
Get
(
key
string
)
([]
byte
,
error
)
{
switch
key
{
case
"txIndex"
:
return
[]
byte
(
r
.
TxIndex
),
nil
case
"key"
:
return
[]
byte
(
r
.
Key
),
nil
case
"asset"
:
return
[]
byte
(
r
.
asset
()),
nil
case
"asset_isSell_status"
:
return
[]
byte
(
fmt
.
Sprintf
(
"%s_%d_%s"
,
r
.
asset
(),
r
.
isSell
(),
r
.
status
())),
nil
case
"owner"
:
return
[]
byte
(
r
.
Owner
),
nil
case
"owner_asset"
:
return
[]
byte
(
fmt
.
Sprintf
(
"%s_%s"
,
r
.
Owner
,
r
.
asset
())),
nil
case
"owner_asset_isSell"
:
return
[]
byte
(
fmt
.
Sprintf
(
"%s_%s_%d"
,
r
.
Owner
,
r
.
asset
(),
r
.
isSell
())),
nil
case
"owner_asset_status"
:
return
[]
byte
(
fmt
.
Sprintf
(
"%s_%s_%s"
,
r
.
Owner
,
r
.
asset
(),
r
.
status
())),
nil
case
"owner_isSell"
:
return
[]
byte
(
fmt
.
Sprintf
(
"%s_%d"
,
r
.
Owner
,
r
.
isSell
())),
nil
//case "owner_isSell_statusPrefix":
// return []byte(fmt.Sprintf("%s_%d_%s", r.Owner, r.asset(), r.isSell())), nil
case
"owner_status"
:
return
[]
byte
(
fmt
.
Sprintf
(
"%s_%s"
,
r
.
Owner
,
r
.
status
())),
nil
//case "owner_statusPrefix":
// return []byte(fmt.Sprintf("%s_%d", r.Owner, r.isSell())), nil
case
"assset_isSell_isFinished"
:
return
[]
byte
(
fmt
.
Sprintf
(
"%s_%d_%d"
,
r
.
Owner
,
r
.
isSell
(),
r
.
isFinished
())),
nil
case
"owner_asset_isFinished"
:
return
[]
byte
(
fmt
.
Sprintf
(
"%s_%s_%d"
,
r
.
Owner
,
r
.
asset
(),
r
.
isFinished
())),
nil
case
"owner_isFinished"
:
return
[]
byte
(
fmt
.
Sprintf
(
"%s_%d"
,
r
.
Owner
,
r
.
isFinished
())),
nil
default
:
return
nil
,
types
.
ErrNotFound
}
}
func
(
r
*
OrderRow
)
asset
()
string
{
return
r
.
LocalOrder
.
AssetExec
+
"."
+
r
.
LocalOrder
.
AssetSymbol
}
func
(
r
*
OrderRow
)
isSell
()
int
{
if
r
.
IsSellOrder
{
return
1
}
return
0
}
func
(
r
*
OrderRow
)
isFinished
()
int
{
if
r
.
IsFinished
{
return
1
}
return
0
}
// status: 设计为可以同时查询几种的并集 , 存储为前缀, 需要提前设计需要合并的, 用前缀表示
// 进行中, 撤销, 部分成交 , 全部成交, 完成状态统一前缀. 数字和原来不一样
// 01 10 11 12 19 -> 1*
func
(
r
*
OrderRow
)
status
()
string
{
if
r
.
Status
==
pty
.
TradeOrderStatusOnBuy
||
r
.
Status
==
pty
.
TradeOrderStatusOnSale
{
return
"01"
// 试图用1 可以匹配所有完成的
}
else
if
r
.
Status
==
pty
.
TradeOrderStatusSoldOut
||
r
.
Status
==
pty
.
TradeOrderStatusBoughtOut
{
return
"12"
}
else
if
r
.
Status
==
pty
.
TradeOrderStatusRevoked
||
r
.
Status
==
pty
.
TradeOrderStatusBuyRevoked
{
return
"10"
}
else
if
r
.
Status
==
pty
.
TradeOrderStatusSellHalfRevoked
||
r
.
Status
==
pty
.
TradeOrderStatusBuyHalfRevoked
{
return
"11"
}
else
if
r
.
Status
==
pty
.
TradeOrderStatusGroupComplete
{
return
"1"
// 1* match complete
}
return
"XX"
}
// NewOrderTable create order table
func
NewOrderTable
(
kvdb
dbm
.
KV
)
*
table
.
Table
{
rowMeta
:=
NewOrderRow
()
rowMeta
.
SetPayload
(
&
pty
.
LocalOrder
{})
t
,
err
:=
table
.
NewTable
(
rowMeta
,
kvdb
,
opt_order_table
)
if
err
!=
nil
{
panic
(
err
)
}
return
t
}
func
(
t
*
trade
)
genSellLimit
(
tx
*
types
.
Transaction
,
sell
*
pty
.
ReceiptSellBase
,
sellorder
*
pty
.
SellOrder
,
txIndex
string
)
*
pty
.
LocalOrder
{
order
:=
&
pty
.
LocalOrder
{
AssetSymbol
:
sellorder
.
TokenSymbol
,
TxIndex
:
txIndex
,
Owner
:
sellorder
.
Address
,
AmountPerBoardlot
:
sellorder
.
AmountPerBoardlot
,
MinBoardlot
:
sellorder
.
MinBoardlot
,
PricePerBoardlot
:
sellorder
.
PricePerBoardlot
,
TotalBoardlot
:
sellorder
.
TotalBoardlot
,
TradedBoardlot
:
sellorder
.
SoldBoardlot
,
BuyID
:
""
,
Status
:
sellorder
.
Status
,
SellID
:
sell
.
SellID
,
TxHash
:
[]
string
{
common
.
ToHex
(
tx
.
Hash
())},
Height
:
sell
.
Height
,
Key
:
sell
.
SellID
,
BlockTime
:
t
.
GetBlockTime
(),
IsSellOrder
:
true
,
AssetExec
:
sellorder
.
AssetExec
,
IsFinished
:
false
,
}
return
order
}
func
(
t
*
trade
)
updateSellLimit
(
tx
*
types
.
Transaction
,
sell
*
pty
.
ReceiptSellBase
,
sellorder
*
pty
.
SellOrder
,
txIndex
string
,
ldb
*
table
.
Table
)
*
pty
.
LocalOrder
{
xs
,
err
:=
ldb
.
ListIndex
(
"key"
,
[]
byte
(
sell
.
SellID
),
nil
,
1
,
0
)
if
err
!=
nil
||
len
(
xs
)
!=
1
{
return
nil
}
order
,
ok
:=
xs
[
0
]
.
Data
.
(
*
pty
.
LocalOrder
)
tradelog
.
Debug
(
"Table dbg"
,
"sell-update"
,
order
,
"data"
,
xs
[
0
]
.
Data
)
if
!
ok
{
tradelog
.
Error
(
"Table failed"
,
"sell-update"
,
order
)
return
nil
}
status
:=
sellorder
.
Status
if
status
==
pty
.
TradeOrderStatusRevoked
&&
sell
.
SoldBoardlot
>
0
{
status
=
pty
.
TradeOrderStatusSellHalfRevoked
}
order
.
Status
=
status
order
.
TxHash
=
append
(
order
.
TxHash
,
common
.
ToHex
(
tx
.
Hash
()))
order
.
TradedBoardlot
=
sellorder
.
SoldBoardlot
order
.
IsFinished
=
(
status
!=
pty
.
TradeOrderStatusOnSale
)
tradelog
.
Debug
(
"Table"
,
"sell-update"
,
order
)
ldb
.
Replace
(
order
)
return
order
}
func
(
t
*
trade
)
rollBackSellLimit
(
tx
*
types
.
Transaction
,
sell
*
pty
.
ReceiptSellBase
,
sellorder
*
pty
.
SellOrder
,
txIndex
string
,
ldb
*
table
.
Table
,
tradedBoardlot
int64
)
*
pty
.
LocalOrder
{
xs
,
err
:=
ldb
.
ListIndex
(
"key"
,
[]
byte
(
sell
.
SellID
),
nil
,
1
,
0
)
if
err
!=
nil
||
len
(
xs
)
!=
1
{
return
nil
}
order
,
ok
:=
xs
[
0
]
.
Data
.
(
*
pty
.
LocalOrder
)
if
!
ok
{
return
nil
}
// 撤销订单回滚, 只需要修改状态
// 其他的操作需要还修改数量
order
.
Status
=
pty
.
TradeOrderStatusOnSale
order
.
TxHash
=
order
.
TxHash
[
:
len
(
order
.
TxHash
)
-
1
]
order
.
TradedBoardlot
=
order
.
TradedBoardlot
-
tradedBoardlot
order
.
IsFinished
=
(
order
.
Status
!=
pty
.
TradeOrderStatusOnSale
)
ldb
.
Replace
(
order
)
return
order
}
func
parseOrderAmountFloat
(
s
string
)
int64
{
x
,
err
:=
strconv
.
ParseFloat
(
s
,
64
)
if
err
!=
nil
{
tradelog
.
Error
(
"parseOrderAmountFloat"
,
"decode receipt"
,
err
)
return
0
}
return
int64
(
x
*
float64
(
types
.
TokenPrecision
))
}
func
parseOrderPriceFloat
(
s
string
)
int64
{
x
,
err
:=
strconv
.
ParseFloat
(
s
,
64
)
if
err
!=
nil
{
tradelog
.
Error
(
"parseOrderPriceFloat"
,
"decode receipt"
,
err
)
return
0
}
return
int64
(
x
*
float64
(
types
.
Coin
))
}
func
(
t
*
trade
)
genSellMarket
(
tx
*
types
.
Transaction
,
sell
*
pty
.
ReceiptSellBase
,
txIndex
string
)
*
pty
.
LocalOrder
{
order
:=
&
pty
.
LocalOrder
{
AssetSymbol
:
sell
.
TokenSymbol
,
TxIndex
:
txIndex
,
Owner
:
sell
.
Owner
,
AmountPerBoardlot
:
parseOrderAmountFloat
(
sell
.
AmountPerBoardlot
),
MinBoardlot
:
sell
.
MinBoardlot
,
PricePerBoardlot
:
parseOrderPriceFloat
(
sell
.
PricePerBoardlot
),
TotalBoardlot
:
sell
.
TotalBoardlot
,
TradedBoardlot
:
sell
.
SoldBoardlot
,
BuyID
:
sell
.
BuyID
,
Status
:
pty
.
TradeOrderStatusSoldOut
,
SellID
:
calcTokenSellID
(
hex
.
EncodeToString
(
tx
.
Hash
())),
TxHash
:
[]
string
{
common
.
ToHex
(
tx
.
Hash
())},
Height
:
sell
.
Height
,
Key
:
calcTokenSellID
(
hex
.
EncodeToString
(
tx
.
Hash
())),
BlockTime
:
t
.
GetBlockTime
(),
IsSellOrder
:
true
,
AssetExec
:
sell
.
AssetExec
,
IsFinished
:
true
,
}
return
order
}
func
(
t
*
trade
)
genBuyLimit
(
tx
*
types
.
Transaction
,
buy
*
pty
.
ReceiptBuyBase
,
txIndex
string
)
*
pty
.
LocalOrder
{
order
:=
&
pty
.
LocalOrder
{
AssetSymbol
:
buy
.
TokenSymbol
,
TxIndex
:
txIndex
,
Owner
:
buy
.
Owner
,
AmountPerBoardlot
:
parseOrderAmountFloat
(
buy
.
AmountPerBoardlot
),
MinBoardlot
:
buy
.
MinBoardlot
,
PricePerBoardlot
:
parseOrderPriceFloat
(
buy
.
PricePerBoardlot
),
TotalBoardlot
:
buy
.
TotalBoardlot
,
TradedBoardlot
:
buy
.
BoughtBoardlot
,
BuyID
:
buy
.
BuyID
,
Status
:
pty
.
TradeOrderStatusOnBuy
,
SellID
:
""
,
TxHash
:
[]
string
{
common
.
ToHex
(
tx
.
Hash
())},
Height
:
buy
.
Height
,
Key
:
buy
.
BuyID
,
BlockTime
:
t
.
GetBlockTime
(),
IsSellOrder
:
false
,
AssetExec
:
buy
.
AssetExec
,
IsFinished
:
false
,
}
return
order
}
func
(
t
*
trade
)
updateBuyLimit
(
tx
*
types
.
Transaction
,
buy
*
pty
.
ReceiptBuyBase
,
buyorder
*
pty
.
BuyLimitOrder
,
txIndex
string
,
ldb
*
table
.
Table
)
*
pty
.
LocalOrder
{
xs
,
err
:=
ldb
.
ListIndex
(
"key"
,
[]
byte
(
buy
.
BuyID
),
nil
,
1
,
0
)
if
err
!=
nil
||
len
(
xs
)
!=
1
{
return
nil
}
order
,
ok
:=
xs
[
0
]
.
Data
.
(
*
pty
.
LocalOrder
)
if
!
ok
{
return
nil
}
status
:=
buyorder
.
Status
if
status
==
pty
.
TradeOrderStatusBuyRevoked
&&
buy
.
BoughtBoardlot
>
0
{
status
=
pty
.
TradeOrderStatusBuyHalfRevoked
}
order
.
Status
=
status
order
.
TxHash
=
append
(
order
.
TxHash
,
common
.
ToHex
(
tx
.
Hash
()))
order
.
TradedBoardlot
=
buyorder
.
BoughtBoardlot
order
.
IsFinished
=
(
status
!=
pty
.
TradeOrderStatusOnBuy
)
ldb
.
Replace
(
order
)
return
order
}
func
(
t
*
trade
)
rollbackBuyLimit
(
tx
*
types
.
Transaction
,
buy
*
pty
.
ReceiptBuyBase
,
buyorder
*
pty
.
BuyLimitOrder
,
txIndex
string
,
ldb
*
table
.
Table
,
traded
int64
)
*
pty
.
LocalOrder
{
xs
,
err
:=
ldb
.
ListIndex
(
"key"
,
[]
byte
(
buy
.
BuyID
),
nil
,
1
,
0
)
if
err
!=
nil
||
len
(
xs
)
!=
1
{
return
nil
}
order
,
ok
:=
xs
[
0
]
.
Data
.
(
*
pty
.
LocalOrder
)
if
!
ok
{
return
nil
}
order
.
Status
=
pty
.
TradeOrderStatusOnBuy
order
.
TxHash
=
order
.
TxHash
[
:
len
(
order
.
TxHash
)
-
1
]
order
.
TradedBoardlot
=
order
.
TradedBoardlot
-
traded
order
.
IsFinished
=
false
ldb
.
Replace
(
order
)
return
order
}
func
(
t
*
trade
)
genBuyMarket
(
tx
*
types
.
Transaction
,
buy
*
pty
.
ReceiptBuyBase
,
txIndex
string
)
*
pty
.
LocalOrder
{
order
:=
&
pty
.
LocalOrder
{
AssetSymbol
:
buy
.
TokenSymbol
,
TxIndex
:
txIndex
,
Owner
:
buy
.
Owner
,
AmountPerBoardlot
:
parseOrderAmountFloat
(
buy
.
AmountPerBoardlot
),
MinBoardlot
:
buy
.
MinBoardlot
,
PricePerBoardlot
:
parseOrderPriceFloat
(
buy
.
PricePerBoardlot
),
TotalBoardlot
:
buy
.
TotalBoardlot
,
TradedBoardlot
:
buy
.
BoughtBoardlot
,
BuyID
:
calcTokenBuyID
(
hex
.
EncodeToString
(
tx
.
Hash
())),
Status
:
pty
.
TradeOrderStatusBoughtOut
,
SellID
:
buy
.
SellID
,
TxHash
:
[]
string
{
common
.
ToHex
(
tx
.
Hash
())},
Height
:
buy
.
Height
,
Key
:
calcTokenBuyID
(
hex
.
EncodeToString
(
tx
.
Hash
())),
BlockTime
:
t
.
GetBlockTime
(),
IsSellOrder
:
true
,
AssetExec
:
buy
.
AssetExec
,
IsFinished
:
true
,
}
return
order
}
func
list
(
db
dbm
.
KVDB
,
indexName
string
,
data
*
pty
.
LocalOrder
,
count
,
direction
int32
)
([]
*
table
.
Row
,
error
)
{
query
:=
NewOrderTable
(
db
)
.
GetQuery
(
db
)
var
primary
[]
byte
if
len
(
data
.
TxIndex
)
>
0
{
primary
=
[]
byte
(
data
.
TxIndex
)
}
cur
:=
&
OrderRow
{
LocalOrder
:
data
}
index
,
err
:=
cur
.
Get
(
indexName
)
if
err
!=
nil
{
tradelog
.
Error
(
"query List failed"
,
"key"
,
string
(
primary
),
"param"
,
data
,
"err"
,
err
)
return
nil
,
err
}
tradelog
.
Debug
(
"query List dbg"
,
"indexName"
,
indexName
,
"index"
,
string
(
index
),
"primary"
,
primary
,
"count"
,
count
,
"direction"
,
direction
)
rows
,
err
:=
query
.
ListIndex
(
indexName
,
index
,
primary
,
count
,
direction
)
if
err
!=
nil
{
tradelog
.
Error
(
"query List failed"
,
"key"
,
string
(
primary
),
"param"
,
data
,
"err"
,
err
)
return
nil
,
err
}
if
len
(
rows
)
==
0
{
return
nil
,
types
.
ErrNotFound
}
return
rows
,
nil
}
/*
按 资产 查询 :
按 资产 & 地址 查询
按 地址
排序和分类
1. 时间顺序 txindex
1. 分类, 不同的状态 & 不同的性质: 买/卖
交易 -> 订单 按订单来 (交易和订单是多对多的关系,不适合joinTable)
交易 T1 Create -> T2 part-take -> T3 Revoke
订单左为进行中, 右为完成,
订单 (C1) | () -> (C1m) | (C2) -> () | (C2, C1r)
查询交易 / 查询订单
C -> C/M -> C/D
\
\ ->R
状态 1, TradeOrderStatusOnSale, 在售
状态 2: TradeOrderStatusSoldOut,售完
状态 3: TradeOrderStatusRevoked, 卖单被撤回
状态 4: TradeOrderStatusExpired, 订单超时(目前不支持订单超时)
状态 5: TradeOrderStatusOnBuy, 求购
状态 6: TradeOrderStatusBoughtOut, 购买完成
状态 7: TradeOrderStatusBuyRevoked, 买单被撤回
*/
plugin/dapp/trade/executor/local_order_test.go
0 → 100644
View file @
3f71a8a5
package
executor
import
(
"testing"
"github.com/33cn/chain33/system/dapp"
pty
"github.com/33cn/plugin/plugin/dapp/trade/types"
//"github.com/33cn/chain33/common/db"
//"github.com/33cn/chain33/common/db/table"
"github.com/33cn/chain33/util"
"github.com/stretchr/testify/assert"
)
var
order1
=
&
pty
.
LocalOrder
{
AssetSymbol
:
"A"
,
Owner
:
"O1"
,
AmountPerBoardlot
:
1
,
MinBoardlot
:
1
,
PricePerBoardlot
:
1
,
TotalBoardlot
:
10
,
TradedBoardlot
:
0
,
BuyID
:
"B1"
,
Status
:
pty
.
TradeOrderStatusOnBuy
,
SellID
:
""
,
TxHash
:
nil
,
Height
:
1
,
Key
:
"B1"
,
BlockTime
:
1
,
IsSellOrder
:
false
,
AssetExec
:
"a"
,
TxIndex
:
dapp
.
HeightIndexStr
(
1
,
1
),
IsFinished
:
false
,
}
var
order2
=
&
pty
.
LocalOrder
{
AssetSymbol
:
"A"
,
Owner
:
"O1"
,
AmountPerBoardlot
:
1
,
MinBoardlot
:
1
,
PricePerBoardlot
:
1
,
TotalBoardlot
:
10
,
TradedBoardlot
:
0
,
BuyID
:
"B2"
,
Status
:
pty
.
TradeOrderStatusOnBuy
,
SellID
:
""
,
TxHash
:
nil
,
Height
:
2
,
Key
:
"B2"
,
BlockTime
:
2
,
IsSellOrder
:
false
,
AssetExec
:
"a"
,
TxIndex
:
dapp
.
HeightIndexStr
(
2
,
1
),
IsFinished
:
false
,
}
func
TestListAll
(
t
*
testing
.
T
)
{
dir
,
ldb
,
tdb
:=
util
.
CreateTestDB
()
t
.
Log
(
dir
,
ldb
,
tdb
)
odb
:=
NewOrderTable
(
tdb
)
odb
.
Add
(
order1
)
odb
.
Add
(
order2
)
kvs
,
err
:=
odb
.
Save
()
assert
.
Nil
(
t
,
err
)
t
.
Log
(
kvs
)
ldb
.
Close
()
}
plugin/dapp/trade/executor/query.go
View file @
3f71a8a5
...
@@ -60,6 +60,10 @@ func (t *trade) Query_GetOnesOrderWithStatus(req *pty.ReqAddrAssets) (types.Mess
...
@@ -60,6 +60,10 @@ func (t *trade) Query_GetOnesOrderWithStatus(req *pty.ReqAddrAssets) (types.Mess
return
t
.
GetOnesOrderWithStatus
(
req
)
return
t
.
GetOnesOrderWithStatus
(
req
)
}
}
func
(
t
*
trade
)
Query_GetOneOrder
(
req
*
pty
.
ReqAddrAssets
)
(
types
.
Message
,
error
)
{
return
t
.
GetOneOrder
(
req
)
}
func
(
t
*
trade
)
GetOnesSellOrder
(
addrTokens
*
pty
.
ReqAddrAssets
)
(
types
.
Message
,
error
)
{
func
(
t
*
trade
)
GetOnesSellOrder
(
addrTokens
*
pty
.
ReqAddrAssets
)
(
types
.
Message
,
error
)
{
var
keys
[][]
byte
var
keys
[][]
byte
if
0
==
len
(
addrTokens
.
Token
)
{
if
0
==
len
(
addrTokens
.
Token
)
{
...
@@ -641,7 +645,7 @@ func (t *trade) loadOrderFromKey(key []byte) *pty.ReplyTradeOrder {
...
@@ -641,7 +645,7 @@ func (t *trade) loadOrderFromKey(key []byte) *pty.ReplyTradeOrder {
return
txResult2OrderReply
(
txResult
)
return
txResult2OrderReply
(
txResult
)
}
}
func
(
t
*
trade
)
GetOnesOrderWithStatus
(
req
*
pty
.
ReqAddrAssets
)
(
types
.
Message
,
error
)
{
func
(
t
*
trade
)
GetOnesOrderWithStatus
V1
(
req
*
pty
.
ReqAddrAssets
)
(
types
.
Message
,
error
)
{
fromKey
:=
[]
byte
(
""
)
fromKey
:=
[]
byte
(
""
)
if
len
(
req
.
FromKey
)
!=
0
{
if
len
(
req
.
FromKey
)
!=
0
{
order
:=
t
.
loadOrderFromKey
([]
byte
(
req
.
FromKey
))
order
:=
t
.
loadOrderFromKey
([]
byte
(
req
.
FromKey
))
...
@@ -674,3 +678,78 @@ func (t *trade) GetOnesOrderWithStatus(req *pty.ReqAddrAssets) (types.Message, e
...
@@ -674,3 +678,78 @@ func (t *trade) GetOnesOrderWithStatus(req *pty.ReqAddrAssets) (types.Message, e
}
}
return
&
replys
,
nil
return
&
replys
,
nil
}
}
func
(
t
*
trade
)
GetOnesOrderWithStatus
(
req
*
pty
.
ReqAddrAssets
)
(
types
.
Message
,
error
)
{
orderStatus
,
orderType
:=
fromStatus
(
req
.
Status
)
if
orderStatus
==
orderStatusInvalid
||
orderType
==
orderTypeInvalid
{
return
nil
,
types
.
ErrInvalidParam
}
// 使用 owner isFinished 组合
var
order
pty
.
LocalOrder
if
orderStatus
==
orderStatusOn
{
order
.
IsFinished
=
false
}
else
{
order
.
IsFinished
=
true
}
order
.
Owner
=
req
.
Addr
if
len
(
req
.
FromKey
)
>
0
{
order
.
TxIndex
=
req
.
FromKey
}
rows
,
err
:=
list
(
t
.
GetLocalDB
(),
"owner_isFinished"
,
&
order
,
req
.
Count
,
req
.
Direction
)
if
err
!=
nil
{
tradelog
.
Error
(
"GetOnesOrderWithStatus"
,
"err"
,
err
)
return
nil
,
err
}
var
replys
pty
.
ReplyTradeOrders
for
_
,
row
:=
range
rows
{
o
,
ok
:=
row
.
Data
.
(
*
pty
.
LocalOrder
)
if
!
ok
{
tradelog
.
Error
(
"GetOnesOrderWithStatus"
,
"err"
,
"bad row type"
)
return
nil
,
types
.
ErrTypeAsset
}
reply
:=
fmtReply
(
o
)
replys
.
Orders
=
append
(
replys
.
Orders
,
reply
)
}
return
&
replys
,
nil
}
func
fmtReply
(
order
*
pty
.
LocalOrder
)
*
pty
.
ReplyTradeOrder
{
return
&
pty
.
ReplyTradeOrder
{
TokenSymbol
:
order
.
AssetSymbol
,
Owner
:
order
.
Owner
,
AmountPerBoardlot
:
order
.
AmountPerBoardlot
,
MinBoardlot
:
order
.
MinBoardlot
,
PricePerBoardlot
:
order
.
PricePerBoardlot
,
TotalBoardlot
:
order
.
TotalBoardlot
,
TradedBoardlot
:
order
.
TradedBoardlot
,
BuyID
:
order
.
BuyID
,
Status
:
order
.
Status
,
SellID
:
order
.
SellID
,
TxHash
:
order
.
TxHash
[
0
],
Height
:
order
.
Height
,
Key
:
order
.
TxIndex
,
BlockTime
:
order
.
BlockTime
,
IsSellOrder
:
order
.
IsSellOrder
,
AssetExec
:
order
.
AssetExec
,
}
}
func
(
t
*
trade
)
GetOneOrder
(
req
*
pty
.
ReqAddrAssets
)
(
types
.
Message
,
error
)
{
query
:=
NewOrderTable
(
t
.
GetLocalDB
())
tradelog
.
Debug
(
"query GetData dbg"
,
"primary"
,
req
.
FromKey
)
row
,
err
:=
query
.
GetData
([]
byte
(
req
.
FromKey
))
if
err
!=
nil
{
tradelog
.
Error
(
"query GetData failed"
,
"key"
,
req
.
FromKey
,
"err"
,
err
)
return
nil
,
err
}
o
,
ok
:=
row
.
Data
.
(
*
pty
.
LocalOrder
)
if
!
ok
{
tradelog
.
Error
(
"query GetData failed"
,
"err"
,
"bad row type"
)
return
nil
,
types
.
ErrTypeAsset
}
reply
:=
fmtReply
(
o
)
return
reply
,
nil
}
plugin/dapp/trade/executor/trade.go
View file @
3f71a8a5
...
@@ -19,6 +19,7 @@ trade执行器支持trade的创建和交易,
...
@@ -19,6 +19,7 @@ trade执行器支持trade的创建和交易,
import
(
import
(
log
"github.com/33cn/chain33/common/log/log15"
log
"github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/common/db/table"
drivers
"github.com/33cn/chain33/system/dapp"
drivers
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/types"
pty
"github.com/33cn/plugin/plugin/dapp/trade/types"
pty
"github.com/33cn/plugin/plugin/dapp/trade/types"
...
@@ -81,8 +82,16 @@ func genSaveSellKv(sellorder *pty.SellOrder) []*types.KeyValue {
...
@@ -81,8 +82,16 @@ func genSaveSellKv(sellorder *pty.SellOrder) []*types.KeyValue {
return
kv
return
kv
}
}
func
(
t
*
trade
)
saveSell
(
sellID
[]
byte
,
ty
int32
)
[]
*
types
.
KeyValue
{
func
(
t
*
trade
)
saveSell
(
base
*
pty
.
ReceiptSellBase
,
ty
int32
,
tx
*
types
.
Transaction
,
txIndex
string
,
ldb
*
table
.
Table
)
[]
*
types
.
KeyValue
{
sellorder
:=
t
.
getSellOrderFromDb
(
sellID
)
sellorder
:=
t
.
getSellOrderFromDb
([]
byte
(
base
.
SellID
))
if
ty
==
pty
.
TyLogTradeSellLimit
&&
sellorder
.
SoldBoardlot
==
0
{
newOrder
:=
t
.
genSellLimit
(
tx
,
base
,
sellorder
,
txIndex
)
tradelog
.
Info
(
"Table"
,
"sell-add"
,
newOrder
)
ldb
.
Add
(
newOrder
)
}
else
{
t
.
updateSellLimit
(
tx
,
base
,
sellorder
,
txIndex
,
ldb
)
}
return
genSaveSellKv
(
sellorder
)
return
genSaveSellKv
(
sellorder
)
}
}
...
@@ -106,20 +115,29 @@ func genDeleteSellKv(sellorder *pty.SellOrder) []*types.KeyValue {
...
@@ -106,20 +115,29 @@ func genDeleteSellKv(sellorder *pty.SellOrder) []*types.KeyValue {
return
kv
return
kv
}
}
func
(
t
*
trade
)
deleteSell
(
sellID
[]
byte
,
ty
int32
)
[]
*
types
.
KeyValue
{
func
(
t
*
trade
)
deleteSell
(
base
*
pty
.
ReceiptSellBase
,
ty
int32
,
tx
*
types
.
Transaction
,
txIndex
string
,
ldb
*
table
.
Table
,
tradedBoardlot
int64
)
[]
*
types
.
KeyValue
{
sellorder
:=
t
.
getSellOrderFromDb
(
sellID
)
sellorder
:=
t
.
getSellOrderFromDb
([]
byte
(
base
.
SellID
))
if
ty
==
pty
.
TyLogTradeSellLimit
&&
sellorder
.
SoldBoardlot
==
0
{
ldb
.
Del
([]
byte
(
txIndex
))
}
else
{
t
.
rollBackSellLimit
(
tx
,
base
,
sellorder
,
txIndex
,
ldb
,
tradedBoardlot
)
}
return
genDeleteSellKv
(
sellorder
)
return
genDeleteSellKv
(
sellorder
)
}
}
func
(
t
*
trade
)
saveBuy
(
receiptTradeBuy
*
pty
.
ReceiptBuyBase
)
[]
*
types
.
KeyValue
{
func
(
t
*
trade
)
saveBuy
(
receiptTradeBuy
*
pty
.
ReceiptBuyBase
,
tx
*
types
.
Transaction
,
txIndex
string
,
ldb
*
table
.
Table
)
[]
*
types
.
KeyValue
{
//tradelog.Info("save", "buy", receiptTradeBuy)
//tradelog.Info("save", "buy", receiptTradeBuy)
var
kv
[]
*
types
.
KeyValue
var
kv
[]
*
types
.
KeyValue
order
:=
t
.
genBuyMarket
(
tx
,
receiptTradeBuy
,
txIndex
)
tradelog
.
Debug
(
"trade BuyMarket save local"
,
"order"
,
order
)
ldb
.
Add
(
order
)
return
saveBuyMarketOrderKeyValue
(
kv
,
receiptTradeBuy
,
pty
.
TradeOrderStatusBoughtOut
,
t
.
GetHeight
())
return
saveBuyMarketOrderKeyValue
(
kv
,
receiptTradeBuy
,
pty
.
TradeOrderStatusBoughtOut
,
t
.
GetHeight
())
}
}
func
(
t
*
trade
)
deleteBuy
(
receiptTradeBuy
*
pty
.
ReceiptBuyBase
)
[]
*
types
.
KeyValue
{
func
(
t
*
trade
)
deleteBuy
(
receiptTradeBuy
*
pty
.
ReceiptBuyBase
,
txIndex
string
,
ldb
*
table
.
Table
)
[]
*
types
.
KeyValue
{
var
kv
[]
*
types
.
KeyValue
var
kv
[]
*
types
.
KeyValue
ldb
.
Del
([]
byte
(
txIndex
))
return
deleteBuyMarketOrderKeyValue
(
kv
,
receiptTradeBuy
,
pty
.
TradeOrderStatusBoughtOut
,
t
.
GetHeight
())
return
deleteBuyMarketOrderKeyValue
(
kv
,
receiptTradeBuy
,
pty
.
TradeOrderStatusBoughtOut
,
t
.
GetHeight
())
}
}
...
@@ -145,8 +163,17 @@ func genSaveBuyLimitKv(buyOrder *pty.BuyLimitOrder) []*types.KeyValue {
...
@@ -145,8 +163,17 @@ func genSaveBuyLimitKv(buyOrder *pty.BuyLimitOrder) []*types.KeyValue {
return
kv
return
kv
}
}
func
(
t
*
trade
)
saveBuyLimit
(
buyID
[]
byte
,
ty
int32
)
[]
*
types
.
KeyValue
{
func
(
t
*
trade
)
saveBuyLimit
(
buy
*
pty
.
ReceiptBuyBase
,
ty
int32
,
tx
*
types
.
Transaction
,
txIndex
string
,
ldb
*
table
.
Table
)
[]
*
types
.
KeyValue
{
buyOrder
:=
t
.
getBuyOrderFromDb
(
buyID
)
buyOrder
:=
t
.
getBuyOrderFromDb
([]
byte
(
buy
.
BuyID
))
tradelog
.
Debug
(
"Table"
,
"buy-add"
,
buyOrder
)
if
buyOrder
.
Status
==
pty
.
TradeOrderStatusOnBuy
&&
buy
.
BoughtBoardlot
==
0
{
order
:=
t
.
genBuyLimit
(
tx
,
buy
,
txIndex
)
tradelog
.
Info
(
"Table"
,
"buy-add"
,
order
)
ldb
.
Add
(
order
)
}
else
{
t
.
updateBuyLimit
(
tx
,
buy
,
buyOrder
,
txIndex
,
ldb
)
}
return
genSaveBuyLimitKv
(
buyOrder
)
return
genSaveBuyLimitKv
(
buyOrder
)
}
}
...
@@ -170,18 +197,26 @@ func genDeleteBuyLimitKv(buyOrder *pty.BuyLimitOrder) []*types.KeyValue {
...
@@ -170,18 +197,26 @@ func genDeleteBuyLimitKv(buyOrder *pty.BuyLimitOrder) []*types.KeyValue {
return
kv
return
kv
}
}
func
(
t
*
trade
)
deleteBuyLimit
(
buyID
[]
byte
,
ty
int32
)
[]
*
types
.
KeyValue
{
func
(
t
*
trade
)
deleteBuyLimit
(
buy
*
pty
.
ReceiptBuyBase
,
ty
int32
,
tx
*
types
.
Transaction
,
txIndex
string
,
ldb
*
table
.
Table
,
traded
int64
)
[]
*
types
.
KeyValue
{
buyOrder
:=
t
.
getBuyOrderFromDb
(
buyID
)
buyOrder
:=
t
.
getBuyOrderFromDb
([]
byte
(
buy
.
BuyID
))
if
ty
==
pty
.
TyLogTradeBuyLimit
&&
buy
.
BoughtBoardlot
==
0
{
ldb
.
Del
([]
byte
(
txIndex
))
}
else
{
t
.
rollbackBuyLimit
(
tx
,
buy
,
buyOrder
,
txIndex
,
ldb
,
traded
)
}
return
genDeleteBuyLimitKv
(
buyOrder
)
return
genDeleteBuyLimitKv
(
buyOrder
)
}
}
func
(
t
*
trade
)
saveSellMarket
(
receiptTradeBuy
*
pty
.
ReceiptSellBase
)
[]
*
types
.
KeyValue
{
func
(
t
*
trade
)
saveSellMarket
(
receiptTradeBuy
*
pty
.
ReceiptSellBase
,
tx
*
types
.
Transaction
,
txIndex
string
,
ldb
*
table
.
Table
)
[]
*
types
.
KeyValue
{
var
kv
[]
*
types
.
KeyValue
var
kv
[]
*
types
.
KeyValue
order
:=
t
.
genSellMarket
(
tx
,
receiptTradeBuy
,
txIndex
)
ldb
.
Add
(
order
)
return
saveSellMarketOrderKeyValue
(
kv
,
receiptTradeBuy
,
pty
.
TradeOrderStatusSoldOut
,
t
.
GetHeight
())
return
saveSellMarketOrderKeyValue
(
kv
,
receiptTradeBuy
,
pty
.
TradeOrderStatusSoldOut
,
t
.
GetHeight
())
}
}
func
(
t
*
trade
)
deleteSellMarket
(
receiptTradeBuy
*
pty
.
ReceiptSellBase
)
[]
*
types
.
KeyValue
{
func
(
t
*
trade
)
deleteSellMarket
(
receiptTradeBuy
*
pty
.
ReceiptSellBase
,
txIndex
string
,
ldb
*
table
.
Table
)
[]
*
types
.
KeyValue
{
var
kv
[]
*
types
.
KeyValue
var
kv
[]
*
types
.
KeyValue
ldb
.
Del
([]
byte
(
txIndex
))
return
deleteSellMarketOrderKeyValue
(
kv
,
receiptTradeBuy
,
pty
.
TradeOrderStatusSoldOut
,
t
.
GetHeight
())
return
deleteSellMarketOrderKeyValue
(
kv
,
receiptTradeBuy
,
pty
.
TradeOrderStatusSoldOut
,
t
.
GetHeight
())
}
}
...
...
plugin/dapp/trade/proto/trade.proto
View file @
3f71a8a5
...
@@ -284,6 +284,27 @@ message ReqBuyToken {
...
@@ -284,6 +284,27 @@ message ReqBuyToken {
string
buyer
=
2
;
string
buyer
=
2
;
}
}
message
LocalOrder
{
string
assetSymbol
=
1
;
string
owner
=
2
;
int64
amountPerBoardlot
=
3
;
int64
minBoardlot
=
4
;
int64
pricePerBoardlot
=
5
;
int64
totalBoardlot
=
6
;
int64
tradedBoardlot
=
7
;
string
buyID
=
8
;
int32
status
=
9
;
string
sellID
=
10
;
repeated
string
txHash
=
11
;
int64
height
=
12
;
string
key
=
13
;
int64
blockTime
=
14
;
bool
isSellOrder
=
15
;
string
assetExec
=
16
;
string
txIndex
=
17
;
bool
isFinished
=
18
;
}
service
trade
{
service
trade
{
rpc
CreateRawTradeSellTx
(
TradeForSell
)
returns
(
UnsignTx
)
{}
rpc
CreateRawTradeSellTx
(
TradeForSell
)
returns
(
UnsignTx
)
{}
rpc
CreateRawTradeBuyTx
(
TradeForBuy
)
returns
(
UnsignTx
)
{}
rpc
CreateRawTradeBuyTx
(
TradeForBuy
)
returns
(
UnsignTx
)
{}
...
...
plugin/dapp/trade/types/const.go
View file @
3f71a8a5
...
@@ -35,6 +35,9 @@ const (
...
@@ -35,6 +35,9 @@ const (
TradeOrderStatusOnBuy
TradeOrderStatusOnBuy
TradeOrderStatusBoughtOut
TradeOrderStatusBoughtOut
TradeOrderStatusBuyRevoked
TradeOrderStatusBuyRevoked
TradeOrderStatusSellHalfRevoked
TradeOrderStatusBuyHalfRevoked
TradeOrderStatusGroupComplete
)
)
//SellOrderStatus : sell order status map
//SellOrderStatus : sell order status map
...
...
plugin/dapp/trade/types/trade.pb.go
View file @
3f71a8a5
...
@@ -2410,6 +2410,181 @@ func (m *ReqBuyToken) GetBuyer() string {
...
@@ -2410,6 +2410,181 @@ func (m *ReqBuyToken) GetBuyer() string {
return
""
return
""
}
}
type
LocalOrder
struct
{
AssetSymbol
string
`protobuf:"bytes,1,opt,name=assetSymbol,proto3" json:"assetSymbol,omitempty"`
Owner
string
`protobuf:"bytes,2,opt,name=owner,proto3" json:"owner,omitempty"`
AmountPerBoardlot
int64
`protobuf:"varint,3,opt,name=amountPerBoardlot,proto3" json:"amountPerBoardlot,omitempty"`
MinBoardlot
int64
`protobuf:"varint,4,opt,name=minBoardlot,proto3" json:"minBoardlot,omitempty"`
PricePerBoardlot
int64
`protobuf:"varint,5,opt,name=pricePerBoardlot,proto3" json:"pricePerBoardlot,omitempty"`
TotalBoardlot
int64
`protobuf:"varint,6,opt,name=totalBoardlot,proto3" json:"totalBoardlot,omitempty"`
TradedBoardlot
int64
`protobuf:"varint,7,opt,name=tradedBoardlot,proto3" json:"tradedBoardlot,omitempty"`
BuyID
string
`protobuf:"bytes,8,opt,name=buyID,proto3" json:"buyID,omitempty"`
Status
int32
`protobuf:"varint,9,opt,name=status,proto3" json:"status,omitempty"`
SellID
string
`protobuf:"bytes,10,opt,name=sellID,proto3" json:"sellID,omitempty"`
TxHash
[]
string
`protobuf:"bytes,11,rep,name=txHash,proto3" json:"txHash,omitempty"`
Height
int64
`protobuf:"varint,12,opt,name=height,proto3" json:"height,omitempty"`
Key
string
`protobuf:"bytes,13,opt,name=key,proto3" json:"key,omitempty"`
BlockTime
int64
`protobuf:"varint,14,opt,name=blockTime,proto3" json:"blockTime,omitempty"`
IsSellOrder
bool
`protobuf:"varint,15,opt,name=isSellOrder,proto3" json:"isSellOrder,omitempty"`
AssetExec
string
`protobuf:"bytes,16,opt,name=assetExec,proto3" json:"assetExec,omitempty"`
TxIndex
string
`protobuf:"bytes,17,opt,name=txIndex,proto3" json:"txIndex,omitempty"`
IsFinished
bool
`protobuf:"varint,18,opt,name=isFinished,proto3" json:"isFinished,omitempty"`
XXX_NoUnkeyedLiteral
struct
{}
`json:"-"`
XXX_unrecognized
[]
byte
`json:"-"`
XXX_sizecache
int32
`json:"-"`
}
func
(
m
*
LocalOrder
)
Reset
()
{
*
m
=
LocalOrder
{}
}
func
(
m
*
LocalOrder
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
LocalOrder
)
ProtoMessage
()
{}
func
(
*
LocalOrder
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_ee944bd90e8a0312
,
[]
int
{
29
}
}
func
(
m
*
LocalOrder
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_LocalOrder
.
Unmarshal
(
m
,
b
)
}
func
(
m
*
LocalOrder
)
XXX_Marshal
(
b
[]
byte
,
deterministic
bool
)
([]
byte
,
error
)
{
return
xxx_messageInfo_LocalOrder
.
Marshal
(
b
,
m
,
deterministic
)
}
func
(
m
*
LocalOrder
)
XXX_Merge
(
src
proto
.
Message
)
{
xxx_messageInfo_LocalOrder
.
Merge
(
m
,
src
)
}
func
(
m
*
LocalOrder
)
XXX_Size
()
int
{
return
xxx_messageInfo_LocalOrder
.
Size
(
m
)
}
func
(
m
*
LocalOrder
)
XXX_DiscardUnknown
()
{
xxx_messageInfo_LocalOrder
.
DiscardUnknown
(
m
)
}
var
xxx_messageInfo_LocalOrder
proto
.
InternalMessageInfo
func
(
m
*
LocalOrder
)
GetAssetSymbol
()
string
{
if
m
!=
nil
{
return
m
.
AssetSymbol
}
return
""
}
func
(
m
*
LocalOrder
)
GetOwner
()
string
{
if
m
!=
nil
{
return
m
.
Owner
}
return
""
}
func
(
m
*
LocalOrder
)
GetAmountPerBoardlot
()
int64
{
if
m
!=
nil
{
return
m
.
AmountPerBoardlot
}
return
0
}
func
(
m
*
LocalOrder
)
GetMinBoardlot
()
int64
{
if
m
!=
nil
{
return
m
.
MinBoardlot
}
return
0
}
func
(
m
*
LocalOrder
)
GetPricePerBoardlot
()
int64
{
if
m
!=
nil
{
return
m
.
PricePerBoardlot
}
return
0
}
func
(
m
*
LocalOrder
)
GetTotalBoardlot
()
int64
{
if
m
!=
nil
{
return
m
.
TotalBoardlot
}
return
0
}
func
(
m
*
LocalOrder
)
GetTradedBoardlot
()
int64
{
if
m
!=
nil
{
return
m
.
TradedBoardlot
}
return
0
}
func
(
m
*
LocalOrder
)
GetBuyID
()
string
{
if
m
!=
nil
{
return
m
.
BuyID
}
return
""
}
func
(
m
*
LocalOrder
)
GetStatus
()
int32
{
if
m
!=
nil
{
return
m
.
Status
}
return
0
}
func
(
m
*
LocalOrder
)
GetSellID
()
string
{
if
m
!=
nil
{
return
m
.
SellID
}
return
""
}
func
(
m
*
LocalOrder
)
GetTxHash
()
[]
string
{
if
m
!=
nil
{
return
m
.
TxHash
}
return
nil
}
func
(
m
*
LocalOrder
)
GetHeight
()
int64
{
if
m
!=
nil
{
return
m
.
Height
}
return
0
}
func
(
m
*
LocalOrder
)
GetKey
()
string
{
if
m
!=
nil
{
return
m
.
Key
}
return
""
}
func
(
m
*
LocalOrder
)
GetBlockTime
()
int64
{
if
m
!=
nil
{
return
m
.
BlockTime
}
return
0
}
func
(
m
*
LocalOrder
)
GetIsSellOrder
()
bool
{
if
m
!=
nil
{
return
m
.
IsSellOrder
}
return
false
}
func
(
m
*
LocalOrder
)
GetAssetExec
()
string
{
if
m
!=
nil
{
return
m
.
AssetExec
}
return
""
}
func
(
m
*
LocalOrder
)
GetTxIndex
()
string
{
if
m
!=
nil
{
return
m
.
TxIndex
}
return
""
}
func
(
m
*
LocalOrder
)
GetIsFinished
()
bool
{
if
m
!=
nil
{
return
m
.
IsFinished
}
return
false
}
func
init
()
{
func
init
()
{
proto
.
RegisterType
((
*
Trade
)(
nil
),
"types.Trade"
)
proto
.
RegisterType
((
*
Trade
)(
nil
),
"types.Trade"
)
proto
.
RegisterType
((
*
TradeForSell
)(
nil
),
"types.TradeForSell"
)
proto
.
RegisterType
((
*
TradeForSell
)(
nil
),
"types.TradeForSell"
)
...
@@ -2440,90 +2615,95 @@ func init() {
...
@@ -2440,90 +2615,95 @@ func init() {
proto
.
RegisterType
((
*
ReqSellToken
)(
nil
),
"types.ReqSellToken"
)
proto
.
RegisterType
((
*
ReqSellToken
)(
nil
),
"types.ReqSellToken"
)
proto
.
RegisterType
((
*
ReqRevokeSell
)(
nil
),
"types.ReqRevokeSell"
)
proto
.
RegisterType
((
*
ReqRevokeSell
)(
nil
),
"types.ReqRevokeSell"
)
proto
.
RegisterType
((
*
ReqBuyToken
)(
nil
),
"types.ReqBuyToken"
)
proto
.
RegisterType
((
*
ReqBuyToken
)(
nil
),
"types.ReqBuyToken"
)
proto
.
RegisterType
((
*
LocalOrder
)(
nil
),
"types.LocalOrder"
)
}
}
func
init
()
{
proto
.
RegisterFile
(
"trade.proto"
,
fileDescriptor_ee944bd90e8a0312
)
}
func
init
()
{
proto
.
RegisterFile
(
"trade.proto"
,
fileDescriptor_ee944bd90e8a0312
)
}
var
fileDescriptor_ee944bd90e8a0312
=
[]
byte
{
var
fileDescriptor_ee944bd90e8a0312
=
[]
byte
{
// 1246 bytes of a gzipped FileDescriptorProto
// 1306 bytes of a gzipped FileDescriptorProto
0x1f
,
0x8b
,
0x08
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x02
,
0xff
,
0xe4
,
0x58
,
0x41
,
0x6f
,
0xdb
,
0x36
,
0x1f
,
0x8b
,
0x08
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x02
,
0xff
,
0xec
,
0x59
,
0x41
,
0x6f
,
0xe3
,
0x44
,
0x14
,
0x8e
,
0x2d
,
0xcb
,
0xb1
,
0x9e
,
0x63
,
0xc7
,
0x61
,
0xdd
,
0x4c
,
0x0d
,
0x76
,
0x30
,
0x84
,
0x62
,
0x14
,
0x6e
,
0xe2
,
0x38
,
0x8d
,
0x5f
,
0x9a
,
0x34
,
0x9d
,
0xcd
,
0x16
,
0x6f
,
0x85
,
0x50
,
0x64
,
0xad
,
0x4b
,
0x8b
,
0x22
,
0xc0
,
0x52
,
0x14
,
0x18
,
0xb0
,
0x61
,
0x43
,
0x9c
,
0xac
,
0x73
,
0xb7
,
0x16
,
0x1b
,
0xa0
,
0xbb
,
0x5a
,
0x55
,
0xa2
,
0xab
,
0x95
,
0x90
,
0x40
,
0xa0
,
0xa6
,
0xa5
,
0xa4
,
0xd0
,
0x15
,
0x68
,
0x18
,
0x0f
,
0xd8
,
0x55
,
0xb6
,
0xd8
,
0x44
,
0x88
,
0x6c
,
0x39
,
0x22
,
0xd5
,
0x58
,
0x7f
,
0x65
,
0x3b
,
0x1a
,
0x24
,
0xae
,
0x4e
,
0x3c
,
0xdb
,
0x5a
,
0x75
,
0xec
,
0xd4
,
0x1e
,
0x6f
,
0xe3
,
0xbf
,
0x02
,
0x07
,
0xec
,
0xb6
,
0xcb
,
0xae
,
0x03
,
0xf6
,
0x17
,
0x06
,
0xec
,
0xef
,
0xf4
,
0x52
,
0xec
,
0x52
,
0x90
,
0xa2
,
0x6e
,
0x5c
,
0x90
,
0x38
,
0x21
,
0xf1
,
0x17
,
0x90
,
0xf8
,
0x3b
,
0x7b
,
0x59
,
0x71
,
0x41
,
0x33
,
0x9e
,
0x25
,
0x4a
,
0x96
,
0x52
,
0x1b
,
0xe8
,
0x21
,
0x4d
,
0x6f
,
0xe6
,
0xe3
,
0xe3
,
0xc7
,
0xa7
,
0xef
,
0x7b
,
0xd8
,
0x63
,
0xc7
,
0xee
,
0x26
,
0xd2
,
0x1e
,
0xba
,
0x5d
,
0x6e
,
0x99
,
0x37
,
0x6f
,
0xbe
,
0x79
,
0xfe
,
0x8f
,
0x7c
,
0x26
,
0x34
,
0x59
,
0x60
,
0x3b
,
0xe4
,
0x60
,
0x16
,
0xf8
,
0xcc
,
0x47
,
0x3a
,
0x8b
,
0x66
,
0xbe
,
0xf7
,
0x66
,
0x9e
,
0x1d
,
0x68
,
0x52
,
0xdf
,
0xb4
,
0xc8
,
0xde
,
0xd4
,
0xf7
,
0xa8
,
0x87
,
0x54
,
0x84
,
0xee
,
0xed
,
0xb0
,
0xc0
,
0x9e
,
0x52
,
0x7b
,
0xcc
,
0x5c
,
0x7f
,
0x1a
,
0xcf
,
0x58
,
0xaf
,
0xab
,
0x1a
,
0x4d
,
0x49
,
0xb0
,
0xb3
,
0x45
,
0x7d
,
0xd3
,
0x0d
,
0xcc
,
0x31
,
0xb5
,
0x3d
,
0x37
,
0x9e
,
0x31
,
0xa0
,
0x0f
,
0xb9
,
0x27
,
0x7a
,
0x0c
,
0x06
,
0x25
,
0x9e
,
0xf7
,
0xdc
,
0x9d
,
0xb8
,
0xcc
,
0xac
,
0xf4
,
0x5e
,
0x55
,
0x41
,
0x1d
,
0x32
,
0x4f
,
0xf4
,
0x14
,
0xb4
,
0x80
,
0x38
,
0xce
,
0xa9
,
0x3d
,
0xb1
,
0xa9
,
0x2a
,
0xfb
,
0xcd
,
0xc3
,
0x3b
,
0x07
,
0x62
,
0xdd
,
0x81
,
0x70
,
0x78
,
0xea
,
0x07
,
0xa7
,
0xc4
,
0xf3
,
0x5e
,
0xe9
,
0x55
,
0x76
,
0x9b
,
0xfb
,
0xf7
,
0xf6
,
0xf8
,
0xba
,
0x3d
,
0xee
,
0x70
,
0xec
,
0xf9
,
0x67
,
0x06
,
0x1b
,
0x38
,
0xf5
,
0x43
,
0x87
,
0x60
,
0x8c
,
0xc2
,
0xe8
,
0x85
,
0x1d
,
0x5c
,
0x10
,
0x66
,
0x56
,
0xc4
,
0x71
,
0x06
,
0x6b
,
0x38
,
0xf5
,
0x43
,
0xfb
,
0xa0
,
0x8d
,
0xc2
,
0xe8
,
0xb9
,
0xe9
,
0x5f
,
0x12
,
0xc5
,
0x22
,
0x94
,
0x5b
,
0xd4
,
0x0f
,
0x23
,
0xbe
,
0x26
,
0x71
,
0x43
,
0x5f
,
0x01
,
0x04
,
0xe4
,
0x95
,
0xaa
,
0x57
,
0xf9
,
0x22
,
0x94
,
0x5b
,
0xd4
,
0x0f
,
0x23
,
0xb6
,
0x26
,
0x71
,
0x43
,
0x9f
,
0x03
,
0xf8
,
0x7f
,
0x41
,
0x38
,
0x9c
,
0xa9
,
0x89
,
0x45
,
0xf7
,
0x72
,
0x8b
,
0x70
,
0xe2
,
0x30
,
0xd8
,
0xc0
,
0x8a
,
0xe4
,
0xa5
,
0x77
,
0x49
,
0x18
,
0x9c
,
0xae
,
0xf0
,
0x45
,
0x0f
,
0x72
,
0x8b
,
0x70
,
0xe2
,
0x30
,
0x58
,
0x3b
,
0x7a
,
0x02
,
0x8d
,
0x51
,
0x18
,
0xc5
,
0x41
,
0xea
,
0x62
,
0xe9
,
0x27
,
0xcb
,
0xfb
,
0x89
,
0xe9
,
0xc3
,
0x92
,
0x3b
,
0x7a
,
0x06
,
0x8d
,
0x51
,
0x18
,
0xc5
,
0x41
,
0xaa
,
0x7c
,
0xe9
,
0x07
,
0x8b
,
0xfb
,
0xc1
,
0x06
,
0x4e
,
0x5c
,
0xf9
,
0x9e
,
0x3c
,
0x68
,
0x19
,
0x68
,
0xbd
,
0x70
,
0xcf
,
0xd3
,
0xc4
,
0x81
,
0xf1
,
0xe9
,
0xc1
,
0x1a
,
0x4e
,
0x5c
,
0xd9
,
0x9e
,
0x2c
,
0x68
,
0x11
,
0x68
,
0xbd
,
0x70
,
0xcf
,
0xb3
,
0xef
,
0x99
,
0xba
,
0xa3
,
0x2f
,
0xc1
,
0x88
,
0x23
,
0xe8
,
0x87
,
0x91
,
0xb9
,
0x29
,
0xd6
,
0x9a
,
0x85
,
0xc4
,
0x81
,
0xed
,
0x99
,
0xba
,
0xa3
,
0xcf
,
0x40
,
0x8b
,
0x23
,
0xe8
,
0x87
,
0x91
,
0xbe
,
0xce
,
0xd7
,
0xf1
,
0xca
,
0x4f
,
0x4d
,
0x9c
,
0x51
,
0x1b
,
0xaa
,
0x2c
,
0x32
,
0x6b
,
0xbd
,
0xca
,
0xbe
,
0x8e
,
0xab
,
0xea
,
0x85
,
0xf1
,
0x8a
,
0x47
,
0x4d
,
0x9c
,
0x51
,
0x1b
,
0xaa
,
0x34
,
0xd2
,
0x6b
,
0xbd
,
0xca
,
0xae
,
0x2c
,
0xea
,
0x6f
,
0x82
,
0xfe
,
0xca
,
0xf6
,
0x42
,
0x62
,
0xfd
,
0x5b
,
0x85
,
0x2d
,
0x75
,
0x5f
,
0xd4
,
0x8a
,
0xab
,
0x34
,
0xea
,
0xaf
,
0x83
,
0xfa
,
0xd2
,
0x74
,
0x42
,
0x62
,
0xfc
,
0x5d
,
0x85
,
0x0d
,
0x79
,
0x83
,
0x26
,
0xf3
,
0x2f
,
0xc8
,
0xf4
,
0x34
,
0x9a
,
0x8c
,
0x7c
,
0x4f
,
0xf0
,
0x6f
,
0x60
,
0xd5
,
0x84
,
0x5f
,
0xd4
,
0x83
,
0x26
,
0xf5
,
0x2e
,
0x89
,
0x7b
,
0x16
,
0x4d
,
0x46
,
0x9e
,
0xc3
,
0xf9
,
0xd7
,
0xb0
,
0x1e
,
0xc1
,
0x8e
,
0x3d
,
0xf1
,
0xc3
,
0x29
,
0xfb
,
0x99
,
0x04
,
0x7d
,
0xdf
,
0x0e
,
0x1c
,
0xcf
,
0x8f
,
0x6c
,
0x42
,
0x4f
,
0x60
,
0xcb
,
0x9c
,
0x78
,
0xa1
,
0x4b
,
0x7f
,
0x20
,
0x7e
,
0xdf
,
0x33
,
0x7d
,
0xcb
,
0x29
,
0xd7
,
0xf0
,
0xf2
,
0x04
,
0xc7
,
0x9b
,
0xb8
,
0xd3
,
0xc4
,
0x4f
,
0x13
,
0x7e
,
0xaa
,
0x09
,
0x3d
,
0xf1
,
0x62
,
0xca
,
0x15
,
0xbc
,
0x38
,
0xc1
,
0xf0
,
0x26
,
0xb6
,
0x9b
,
0xf8
,
0x29
,
0xdc
,
0x4f
,
0x36
,
0x84
,
0xce
,
0x2c
,
0x70
,
0xc7
,
0x44
,
0x85
,
0xab
,
0x09
,
0xb7
,
0x25
,
0x3b
,
0xba
,
0x0f
,
0x2d
,
0xe6
,
0xa1
,
0xc7
,
0xd0
,
0x99
,
0xfa
,
0xf6
,
0x98
,
0xc8
,
0x70
,
0x35
,
0xee
,
0xb6
,
0x60
,
0x47
,
0x0f
,
0xa1
,
0x33
,
0xdb
,
0x4b
,
0x1c
,
0x75
,
0xe1
,
0x98
,
0x35
,
0xa2
,
0x4f
,
0xc1
,
0xa0
,
0xcc
,
0x0e
,
0x18
,
0x73
,
0x45
,
0x3d
,
0x6a
,
0x3a
,
0x89
,
0xa3
,
0xca
,
0x1d
,
0xb3
,
0x46
,
0xf4
,
0x21
,
0x68
,
0x01
,
0x35
,
0x7d
,
0x27
,
0x44
,
0x70
,
0xac
,
0xe1
,
0xd4
,
0x80
,
0xf6
,
0xa0
,
0x41
,
0x99
,
0x3f
,
0x13
,
0x93
,
0x9b
,
0x62
,
0x4a
,
0xed
,
0x09
,
0xe1
,
0x1c
,
0x2b
,
0x38
,
0x35
,
0xa0
,
0x1d
,
0x68
,
0x04
,
0xd4
,
0x9b
,
0xf2
,
0xc9
,
0x32
,
0x19
,
0xf3
,
0x95
,
0xe3
,
0xc0
,
0xbf
,
0x72
,
0x5e
,
0x86
,
0x53
,
0xc7
,
0x6c
,
0xf4
,
0x2a
,
0xfb
,
0x75
,
0x3e
,
0x99
,
0x8c
,
0xd9
,
0xca
,
0xb1
,
0xef
,
0x5d
,
0x5b
,
0x2f
,
0x42
,
0xd7
,
0xd2
,
0x1b
,
0xbd
,
0x0d
,
0x9c
,
0x1a
,
0xf8
,
0xac
,
0x4d
,
0x29
,
0x61
,
0xdf
,
0xcd
,
0xc9
,
0xd8
,
0x34
,
0x04
,
0x33
,
0xa9
,
0xca
,
0x6e
,
0x03
,
0xa7
,
0x06
,
0x36
,
0x6b
,
0x06
,
0x01
,
0xa1
,
0x5f
,
0xcf
,
0xc8
,
0x58
,
0xd7
,
0x38
,
0xc1
,
0xfa
,
0x1e
,
0x9a
,
0x8a
,
0xf4
,
0x68
,
0x17
,
0xea
,
0x5c
,
0xba
,
0x67
,
0x27
,
0x92
,
0x43
,
0x39
,
0x33
,
0xa9
,
0xc1
,
0xf8
,
0x06
,
0x9a
,
0x92
,
0xf4
,
0x68
,
0x1b
,
0xea
,
0x4c
,
0xba
,
0x93
,
0x23
,
0xc1
,
0xe2
,
0x84
,
0x8c
,
0x64
,
0xa0
,
0xc7
,
0xd3
,
0x05
,
0x71
,
0xaa
,
0xc9
,
0x7a
,
0x04
,
0x68
,
0x39
,
0xfd
,
0xa1
,
0x18
,
0x31
,
0x42
,
0x46
,
0x22
,
0xd0
,
0x43
,
0x77
,
0x4e
,
0x9c
,
0x6c
,
0x32
,
0x9e
,
0x00
,
0x5a
,
0xca
,
0xf0
,
0xac
,
0xd7
,
0x15
,
0xe8
,
0xe4
,
0x53
,
0xee
,
0xb6
,
0xa8
,
0x98
,
0xb2
,
0x5d
,
0xcf
,
0xb3
,
0x4c
,
0xbf
,
0x32
,
0x3c
,
0xe3
,
0x55
,
0x05
,
0x3a
,
0xf9
,
0x94
,
0xbb
,
0x2b
,
0x2a
,
0xa6
,
0x6c
,
0xd7
,
0xfd
,
0x3c
,
0x25
,
0x29
,
0xad
,
0x17
,
0xd4
,
0x05
,
0x7d
,
0x14
,
0x46
,
0x09
,
0x47
,
0xf1
,
0x60
,
0x05
,
0xf3
,
0x6c
,
0x9f
,
0xa6
,
0x24
,
0xa5
,
0xf5
,
0x82
,
0xba
,
0xa0
,
0x8e
,
0xc2
,
0x28
,
0xe1
,
0x28
,
0x1e
,
0xca
,
0x1f
,
0xc0
,
0xce
,
0x52
,
0x05
,
0x15
,
0x83
,
0x59
,
0xff
,
0x69
,
0x60
,
0xf0
,
0x1d
,
0x7f
,
0x0a
,
0x2c
,
0x41
,
0xf9
,
0x23
,
0xd8
,
0x5a
,
0xa8
,
0xa0
,
0x62
,
0x30
,
0xe3
,
0x1f
,
0x05
,
0x34
,
0xb6
,
0xe3
,
0x1c
,
0x12
,
0xac
,
0x40
,
0xb4
,
0x09
,
0x9b
,
0xb6
,
0xe3
,
0x04
,
0x84
,
0x52
,
0xb1
,
0xb1
,
0x81
,
0x17
,
0xf7
,
0xbe
,
0x45
,
0xfc
,
0x25
,
0x88
,
0xd6
,
0x61
,
0xdd
,
0xb4
,
0x2c
,
0x9f
,
0x04
,
0x01
,
0xdf
,
0x58
,
0xc3
,
0x62
,
0x09
,
0xb4
,
0x15
,
0x25
,
0xa8
,
0xad
,
0x26
,
0x81
,
0xbe
,
0xaa
,
0x04
,
0xf5
,
0x22
,
0x09
,
0xc3
,
0xf3
,
0x61
,
0xb1
,
0x04
,
0xca
,
0x92
,
0x12
,
0xd4
,
0x96
,
0x93
,
0x40
,
0x5d
,
0x56
,
0x82
,
0x7a
,
0x2c
,
0xd8
,
0xa2
,
0xbe
,
0xe7
,
0x24
,
0x4e
,
0x71
,
0xb9
,
0x64
,
0x6c
,
0xd9
,
0x62
,
0x6b
,
0x5c
,
0x57
,
0x91
,
0x04
,
0x06
,
0x6c
,
0x04
,
0x9e
,
0x63
,
0x25
,
0x4e
,
0x71
,
0xb9
,
0x64
,
0x6c
,
0xd9
,
0x62
,
0x6b
,
0x6c
,
0xc6
,
0x75
,
0xc5
,
0x06
,
0xf9
,
0x62
,
0x4b
,
0xf3
,
0xbd
,
0x99
,
0xa9
,
0x1f
,
0x6e
,
0x67
,
0x36
,
0xdc
,
0x54
,
0x6c
,
0xda
,
0x4d
,
0xc5
,
0x06
,
0xf9
,
0x62
,
0x4b
,
0xf3
,
0xbd
,
0x99
,
0xa9
,
0x1f
,
0x66
,
0x0b
,
0xa9
,
0xb9
,
0x25
,
0x8e
,
0x33
,
0x39
,
0xe2
,
0xf6
,
0x73
,
0xe2
,
0x9e
,
0x9d
,
0x33
,
0xb3
,
0x25
,
0xa7
,
0x26
,
0x0d
,
0x03
,
0x7d
,
0x83
,
0x1f
,
0x67
,
0x62
,
0xc4
,
0xec
,
0x17
,
0xc4
,
0x3e
,
0xbf
,
0xa0
,
0xf6
,
0x91
,
0xa3
,
0x6c
,
0x1a
,
0xb5
,
0xf3
,
0x69
,
0xf4
,
0xa6
,
0x0a
,
0xad
,
0x45
,
0xd5
,
0x7c
,
0x0c
,
0x7a
,
0x8b
,
0xef
,
0x23
,
0x46
,
0xd9
,
0x34
,
0x6a
,
0xe7
,
0xd3
,
0xe8
,
0x75
,
0x15
,
0x5a
,
0xf3
,
0xaa
,
0x8a
,
0x7e
,
0x06
,
0xed
,
0x91
,
0x1f
,
0x9e
,
0x9d
,
0xb3
,
0x9c
,
0xa6
,
0x39
,
0x6b
,
0x9a
,
0xfb
,
0x0d
,
0x79
,
0x1f
,
0x14
,
0xfd
,
0x18
,
0xda
,
0x23
,
0x2f
,
0x3c
,
0xbf
,
0xa0
,
0x39
,
0x4d
,
0x73
,
0xd6
,
0x34
,
0xb5
,
0x90
,
0x52
,
0xee
,
0x8d
,
0x12
,
0xee
,
0xa1
,
0x9c
,
0xfb
,
0x66
,
0x9e
,
0xfb
,
0x3f
,
0x35
,
0x68
,
0xf7
,
0x1b
,
0x72
,
0x21
,
0xa5
,
0xdc
,
0x6b
,
0x25
,
0xdc
,
0x43
,
0x39
,
0xf7
,
0xcd
,
0x3c
,
0xf7
,
0xbf
,
0x63
,
0x32
,
0x26
,
0xee
,
0x8c
,
0xf5
,
0xc3
,
0xa8
,
0x6f
,
0x53
,
0xb2
,
0x02
,
0xf9
,
0x5d
,
0xd0
,
0xfd
,
0x29
,
0xd0
,
0xc6
,
0x64
,
0x4c
,
0xec
,
0x29
,
0xed
,
0x87
,
0x51
,
0xdf
,
0x0c
,
0xc8
,
0x12
,
0xe4
,
0x77
,
0xab
,
0x29
,
0x09
,
0x24
,
0xf5
,
0xf1
,
0xa0
,
0x9c
,
0x78
,
0xe3
,
0xfd
,
0x12
,
0x6f
,
0xdc
,
0x08
,
0xe2
,
0x41
,
0xf5
,
0xae
,
0x5d
,
0xe2
,
0x0b
,
0xea
,
0xe3
,
0x41
,
0x39
,
0xf1
,
0xda
,
0xdb
,
0x25
,
0x5e
,
0xbb
,
0x0d
,
0x95
,
0x78
,
0x59
,
0x24
,
0x90
,
0x2f
,
0x12
,
0x36
,
0x1f
,
0xd8
,
0xf4
,
0x7c
,
0x51
,
0x3c
,
0xf1
,
0x15
,
0xc4
,
0x6b
,
0x32
,
0xf1
,
0xa2
,
0x48
,
0x20
,
0x5f
,
0x24
,
0x74
,
0x36
,
0x30
,
0x83
,
0x8b
,
0x79
,
0x48
,
0x11
,
0x6a
,
0xab
,
0x5c
,
0xa8
,
0x56
,
0x5e
,
0xa8
,
0xff
,
0x35
,
0xd8
,
0x96
,
0x42
,
0xf1
,
0x93
,
0xf1
,
0xc4
,
0x23
,
0x49
,
0xa8
,
0x8d
,
0x72
,
0xa1
,
0x5a
,
0x79
,
0xa1
,
0xfe
,
0x55
,
0x60
,
0x53
,
0x08
,
0xef
,
0x96
,
0x2b
,
0x75
,
0xf3
,
0x0f
,
0xbd
,
0x54
,
0xff
,
0x24
,
0x5b
,
0x5a
,
0xb9
,
0x6c
,
0x91
,
0xea
,
0xc5
,
0x4e
,
0xbe
,
0x3b
,
0xae
,
0xd4
,
0xed
,
0x3f
,
0xf4
,
0x52
,
0xfd
,
0x93
,
0x6c
,
0x69
,
0xe5
,
0xb2
,
0xb7
,
0x4b
,
0xd4
,
0xdf
,
0x2e
,
0x57
,
0xbf
,
0x93
,
0x57
,
0xbf
,
0x0f
,
0x77
,
0xa5
,
0xf8
,
0xe2
,
0x8a
,
0x45
,
0xa8
,
0xdf
,
0x2e
,
0x51
,
0x7f
,
0xb3
,
0x5c
,
0xfd
,
0x4e
,
0x5e
,
0xfd
,
0x3e
,
0xdc
,
0x17
,
0xe2
,
0xec
,
0x27
,
0xfd
,
0xf3
,
0x03
,
0xa8
,
0x8d
,
0x6c
,
0x4a
,
0x64
,
0x8f
,
0x7e
,
0x57
,
0x76
,
0xa2
,
0xd9
,
0xf3
,
0x2b
,
0xb2
,
0x9f
,
0xf4
,
0xcf
,
0x8f
,
0xa0
,
0x36
,
0x32
,
0x03
,
0x22
,
0x7a
,
0xf4
,
0xfb
,
0xa2
,
0x8a
,
0xc6
,
0xc2
,
0xc5
,
0x3a
,
0x82
,
0x6e
,
0x0e
,
0x23
,
0xee
,
0x53
,
0xd6
,
0x80
,
0x58
,
0x0e
,
0x23
,
0x13
,
0xcd
,
0x56
,
0x34
,
0xe6
,
0x2e
,
0xc6
,
0x01
,
0x74
,
0x73
,
0x18
,
0x71
,
0x9f
,
0xb2
,
0x02
,
0xc4
,
0xbe
,
0xa9
,
0xd7
,
0xc1
,
0x38
,
0xce
,
0x62
,
0x9c
,
0x26
,
0x7f
,
0x1f
,
0x1e
,
0x66
,
0x30
,
0x76
,
0xb3
,
0x62
,
0x18
,
0xf1
,
0x4d
,
0xbd
,
0x0a
,
0xc6
,
0x61
,
0x16
,
0xe3
,
0x2c
,
0x79
,
0x7d
,
0x78
,
0x9c
,
0xc1
,
0x18
,
0x8b
,
0x9c
,
0x97
,
0x20
,
0xdf
,
0xc2
,
0x8e
,
0x32
,
0x21
,
0xb9
,
0x58
,
0x07
,
0xe0
,
0x04
,
0x76
,
0xd8
,
0xce
,
0x62
,
0xcc
,
0x73
,
0x5e
,
0x80
,
0x7c
,
0x05
,
0x5b
,
0xd2
,
0x84
,
0xe0
,
0x62
,
0x15
,
0x80
,
0xf3
,
0x51
,
0xc8
,
0x4f
,
0x59
,
0x07
,
0xe5
,
0x8f
,
0x0a
,
0xb4
,
0x30
,
0xb9
,
0x3c
,
0x72
,
0x9c
,
0xe0
,
0x23
,
0xd8
,
0xce
,
0x47
,
0x21
,
0x1e
,
0x65
,
0x15
,
0x94
,
0x5f
,
0x2b
,
0xd0
,
0xc2
,
0xe4
,
0xea
,
0xc0
,
0x88
,
0x6b
,
0x45
,
0x11
,
0x82
,
0x1a
,
0xbf
,
0x88
,
0x64
,
0x2d
,
0x8a
,
0xdf
,
0x4a
,
0xe2
,
0x54
,
0x33
,
0xb2
,
0xfc
,
0x03
,
0xa6
,
0x55
,
0x80
,
0x10
,
0xd4
,
0xd8
,
0x45
,
0x24
,
0x6a
,
0x91
,
0xff
,
0x96
,
0x12
,
0x27
,
0x76
,
0x17
,
0x74
,
0x51
,
0xab
,
0xa6
,
0xd6
,
0xd3
,
0x78
,
0xe2
,
0x88
,
0x01
,
0x4f
,
0x04
,
0xc7
,
0xa7
,
0x9a
,
0x39
,
0xb1
,
0xbb
,
0xa0
,
0xf2
,
0x5a
,
0xd5
,
0x95
,
0x9e
,
0xc2
,
0x12
,
0x87
,
0x0f
,
0x58
,
0x0d
,
0x88
,
0xf8
,
0x5f
,
0x26
,
0xff
,
0x2d
,
0xa4
,
0x06
,
0xbe
,
0x66
,
0xcc
,
0x0b
,
0x54
,
0xd4
,
0x97
,
0x22
,
0x58
,
0xb6
,
0x4f
,
0xf8
,
0x7b
,
0x99
,
0x78
,
0x5b
,
0x48
,
0x0d
,
0x6c
,
0xcd
,
0x98
,
0x15
,
0x28
,
0x8e
,
0xe3
,
0x01
,
0xbf
,
0x0d
,
0x5f
,
0x06
,
0xfe
,
0xe4
,
0x47
,
0x12
,
0xc9
,
0x26
,
0x6d
,
0x31
,
0xb4
,
0xaf
,
0x2f
,
0x15
,
0xc7
,
0x03
,
0x76
,
0x1b
,
0xbe
,
0xf0
,
0xbd
,
0xc9
,
0x77
,
0x24
,
0x12
,
0x4d
,
0xda
,
0x7e
,
0xaf
,
0x70
,
0xa6
,
0x2e
,
0x87
,
0xe2
,
0x4c
,
0x58
,
0xaf
,
0x63
,
0x5a
,
0x20
,
0x56
,
0x33
,
0x88
,
0x7c
,
0x68
,
0xfc
,
0x52
,
0x61
,
0x4c
,
0x5d
,
0x0d
,
0xf9
,
0x99
,
0xb0
,
0x5a
,
0xc7
,
0x34
,
0x47
,
0xac
,
0x69
,
0x04
,
0x9a
,
0x1a
,
0xc1
,
0xf5
,
0x51
,
0xa7
,
0x0c
,
0xe8
,
0x2a
,
0x03
,
0xd6
,
0x6f
,
0x15
,
0xe8
,
0x66
,
0x10
,
0xd3
,
0x08
,
0x14
,
0x39
,
0x82
,
0x9b
,
0xa3
,
0x4e
,
0x19
,
0x50
,
0x65
,
0x06
,
0x8c
,
0x9f
,
0x2c
,
0xa2
,
0xeb
,
0x87
,
0xd1
,
0xcd
,
0x0a
,
0xee
,
0x1f
,
0x8d
,
0x8b
,
0x3b
,
0xf3
,
0xa2
,
0x35
,
0x22
,
0x2b
,
0xd0
,
0x99
,
0x47
,
0xd7
,
0x0f
,
0xa3
,
0xdb
,
0x15
,
0xdc
,
0x5f
,
0x0a
,
0x13
,
0x77
,
0xea
,
0x44
,
0x5b
,
0xf3
,
0xbc
,
0xbd
,
0xfd
,
0x2d
,
0xc9
,
0x7b
,
0xb9
,
0x19
,
0x3b
,
0xa0
,
0x5d
,
0x90
,
0x48
,
0x9e
,
0x2b
,
0x44
,
0xb6
,
0xe2
,
0x79
,
0x7b
,
0xf7
,
0x5b
,
0x92
,
0xb7
,
0x72
,
0x33
,
0x76
,
0x40
,
0xb9
,
0x24
,
0xaf
,
0xfc
,
0xe7
,
0x3b
,
0x1a
,
0xca
,
0xbf
,
0x45
,
0x53
,
0x33
,
0xf3
,
0xa2
,
0x75
,
0x32
,
0xfe
,
0x43
,
0x91
,
0x38
,
0x5f
,
0xd9
,
0xcf
,
0x37
,
0x34
,
0x94
,
0x7f
,
0xf2
,
0xa6
,
0x66
,
0xea
,
0x44
,
0xab
,
0x64
,
0x95
,
0x6e
,
0x95
,
0xab
,
0xf2
,
0xc3
,
0x90
,
0x6d
,
0xc0
,
0x3b
,
0x1c
,
0x55
,
0x35
,
0x8a
,
0x9e
,
0xc4
,
0xfc
,
0xbb
,
0x2a
,
0xdd
,
0x32
,
0x57
,
0xe5
,
0xbb
,
0x21
,
0xdb
,
0x80
,
0x75
,
0x38
,
0xb2
,
0x6a
,
0x01
,
0x4f
,
0x35
,
0xf1
,
0xc8
,
0xac
,
0xf4
,
0xb4
,
0xcc
,
0xed
,
0xa2
,
0xfa
,
0x62
,
0xc5
,
0xd1
,
0x3a
,
0x91
,
0x7a
,
0x16
,
0x7f
,
0xaa
,
0x89
,
0x47
,
0x7a
,
0xa5
,
0xa7
,
0x64
,
0x6e
,
0x17
,
0xd9
,
0x17
,
0x4b
,
0x8e
,
0xfa
,
0x2f
,
0x2a
,
0x97
,
0xca
,
0xb7
,
0xa9
,
0x0c
,
0x4e
,
0x57
,
0xc5
,
0x59
,
0x78
,
0xe2
,
0xd4
,
0xcd
,
0xc6
,
0x91
,
0xd0
,
0x7f
,
0x5e
,
0xb9
,
0x81
,
0xf8
,
0x36
,
0x95
,
0xc1
,
0xe9
,
0xca
,
0x38
,
0x73
,
0x4f
,
0x7a
,
0xa3
,
0xc9
,
0x80
,
0xc4
,
0x15
,
0xf1
,
0x11
,
0x1c
,
0x01
,
0xe2
,
0x95
,
0x30
,
0x9f
,
0x49
,
0x39
,
0x9c
,
0xba
,
0x19
,
0xaf
,
0x15
,
0x11
,
0x10
,
0xbf
,
0x22
,
0xde
,
0x83
,
0x23
,
0x80
,
0x7f
,
0x25
,
0xcc
,
0xeb
,
0x4d
,
0xca
,
0xa5
,
0x91
,
0xe7
,
0x8f
,
0x2f
,
0x86
,
0xbc
,
0xc3
,
0x6b
,
0xc7
,
0xed
,
0x5f
,
0x62
,
0x67
,
0x52
,
0xce
,
0x7a
,
0x9b
,
0x72
,
0x69
,
0xe4
,
0x78
,
0xe3
,
0xcb
,
0x21
,
0xeb
,
0xf0
,
0xda
,
0x71
,
0xe0
,
0x0c
,
0xba
,
0x34
,
0x49
,
0x0e
,
0xd1
,
0x6b
,
0x35
,
0xb0
,
0x6a
,
0x7a
,
0x67
,
0xc3
,
0xd5
,
0xc9
,
0xfb
,
0x97
,
0x18
,
0x18
,
0x83
,
0x76
,
0x90
,
0x24
,
0x07
,
0xef
,
0xb5
,
0x1a
,
0x58
,
0x36
,
0xbd
,
0xb1
,
0x49
,
0x4f
,
0xd1
,
0x01
,
0xd4
,
0x7d
,
0x35
,
0x81
,
0x76
,
0xd5
,
0x04
,
0x4a
,
0x1d
,
0xb1
,
0xf4
,
0xb2
,
0xe1
,
0xea
,
0xe4
,
0xa4
,
0x0f
,
0xd0
,
0x1e
,
0xd4
,
0x3d
,
0x39
,
0x81
,
0xb6
,
0xe5
,
0x04
,
0x4a
,
0x1d
,
0x5e
,
0xc0
,
0x16
,
0x26
,
0x97
,
0x7c
,
0x47
,
0x71
,
0xc1
,
0xa1
,
0xcf
,
0xa1
,
0xc6
,
0xbf
,
0xfe
,
0x9a
,
0xb1
,
0xf0
,
0x32
,
0x9e
,
0xc3
,
0x06
,
0x26
,
0x57
,
0x6c
,
0x47
,
0x7e
,
0xc1
,
0xa1
,
0x4f
,
0xa0
,
0xc6
,
0xf7
,
0x54
,
0x2c
,
0x1c
,
0x8a
,
0x53
,
0xc8
,
0xfa
,
0x55
,
0xf4
,
0x1a
,
0xca
,
0x6b
,
0xd4
,
0x17
,
0x50
,
0x9e
,
0xfe
,
0x86
,
0xef
,
0xa9
,
0x98
,
0x3b
,
0x14
,
0xa7
,
0x90
,
0xf1
,
0x13
,
0xef
,
0x35
,
0xa4
,
0xaf
,
0x8f
,
0x5f
,
0x17
,
0x25
,
0x62
,
0xf9
,
0xbb
,
0x29
,
0x96
,
0x8e
,
0x25
,
0xc8
,
0xcf
,
0xa0
,
0x89
,
0xc9
,
0x51
,
0x9f
,
0x42
,
0x3d
,
0xfe
,
0xba
,
0x28
,
0x10
,
0xcb
,
0xbf
,
0x9b
,
0x62
,
0xe1
,
0x58
,
0x82
,
0x7c
,
0x65
,
0x3f
,
0x8c
,
0xe2
,
0x38
,
0xef
,
0x83
,
0x36
,
0x0a
,
0x23
,
0x09
,
0x5a
,
0xf0
,
0x82
,
0x8b
,
0xf9
,
0x02
,
0x4d
,
0x4c
,
0xae
,
0xfa
,
0x61
,
0x14
,
0xc7
,
0xf9
,
0x10
,
0x94
,
0x51
,
0x18
,
0x09
,
0xd0
,
0x82
,
0xb4
,
0xcc
,
0x83
,
0x14
,
0x4a
,
0x0c
,
0x0e
,
0xff
,
0xd2
,
0x40
,
0x17
,
0x09
,
0x83
,
0xbe
,
0x81
,
0xee
,
0x2f
,
0xb8
,
0x98
,
0x4d
,
0x8b
,
0x3c
,
0x48
,
0xa1
,
0xf8
,
0xc0
,
0xf8
,
0xa3
,
0x06
,
0x70
,
0xea
,
0x8d
,
0x71
,
0x40
,
0x6c
,
0x46
,
0xb0
,
0x7d
,
0x95
,
0xf4
,
0x58
,
0xc3
,
0x39
,
0x2a
,
0xfa
,
0xee
,
0xbd
,
0x6d
,
0xcd
,
0xf4
,
0xd8
,
0xe5
,
0x9c
,
0x66
,
0xcb
,
0x45
,
0x32
,
0xfd
,
0x5f
,
0x2e
,
0x2b
,
0x97
,
0x8b
,
0x72
,
0x69
,
0xfc
,
0x65
,
0x4a
,
0xdd
,
0xb3
,
0xe9
,
0x70
,
0x6e
,
0x6d
,
0xa0
,
0xaf
,
0xe1
,
0x4e
,
0x76
,
0x3d
,
0xfb
,
0xca
,
0x85
,
0x75
,
0x64
,
0x74
,
0x76
,
0xe2
,
0x5a
,
0x64
,
0xa6
,
0x6f
,
0xc5
,
0x1d
,
0x99
,
0x18
,
0x8f
,
0x6f
,
0x8e
,
0x0a
,
0xe2
,
0x29
,
0x5a
,
0xfd
,
0x14
,
0x76
,
0xb3
,
0xab
,
0x63
,
0x32
,
0x86
,
0x73
,
0xa2
,
0x8f
,
0x00
,
0xec
,
0xe0
,
0xd8
,
0x76
,
0xed
,
0xe0
,
0x82
,
0x58
,
0x3a
,
0xe2
,
0xc0
,
0x92
,
0x65
,
0x54
,
0xce
,
0x52
,
0x31
,
0x8e
,
0xb9
,
0x14
,
0x85
,
0x68
,
0x57
,
0x87
,
0x73
,
0x54
,
0xf6
,
0xd8
,
0x5c
,
0xff
,
0x77
,
0x05
,
0x54
,
0x4e
,
0x19
,
0xfa
,
0x12
,
0xba
,
0x87
,
0x3e
,
0x31
,
0x29
,
0xc1
,
0xe6
,
0x75
,
0x84
,
0xf3
,
0x03
,
0xec
,
0x2d
,
0xb3
,
0x11
,
0xf7
,
0xad
,
0x05
,
0x31
,
0xa5
,
0x93
,
0x45
,
0x58
,
0x03
,
0xd2
,
0x94
,
0x0f
,
0x67
,
0xa8
,
0xa8
,
0x50
,
0x76
,
0x36
,
0x85
,
0xf1
,
0x47
,
0x37
,
0xb0
,
0xcf
,
0xdd
,
0xb8
,
0x57
,
0xf4
,
0x6d
,
0x31
,
0x3f
,
0xa5
,
0x8f
,
0xd1
,
0x05
,
0x48
,
0xa3
,
0xba
,
0x78
,
0xf7
,
0x7f
,
0xe1
,
0xcc
,
0x58
,
0x43
,
0x5f
,
0xc0
,
0xbd
,
0xec
,
0x7a
,
0x96
,
0xd0
,
0x33
,
0x54
,
0x90
,
0xc0
,
0x45
,
0xfc
,
0x36
,
0x00
,
0x00
,
0xff
,
0xff
,
0x84
,
0x9a
,
0xb6
,
0x92
,
0x20
,
0x18
,
0x00
,
0x00
,
0xab
,
0x8f
,
0x61
,
0x3b
,
0xbb
,
0x3a
,
0xae
,
0x9e
,
0xe1
,
0x0c
,
0x95
,
0x97
,
0x55
,
0x31
,
0x8e
,
0xbe
,
0x10
,
0x05
,
0x7f
,
0xbf
,
0x19
,
0xce
,
0x50
,
0xd9
,
0xbf
,
0x13
,
0x45
,
0x38
,
0xdf
,
0xc2
,
0xce
,
0x22
,
0x1b
,
0xf1
,
0x8b
,
0x4e
,
0x41
,
0x4c
,
0xe9
,
0x64
,
0x11
,
0xd6
,
0x00
,
0x1e
,
0x14
,
0x3d
,
0x5b
,
0xcc
,
0x4f
,
0xe9
,
0xbf
,
0x17
,
0x05
,
0x48
,
0xa3
,
0x3a
,
0xff
,
0xa3
,
0xe8
,
0xe9
,
0x7f
,
0x01
,
0x00
,
0x00
,
0xff
,
0xff
,
0xe7
,
0xe7
,
0x49
,
0x74
,
0x51
,
0x1a
,
0x00
,
0x00
,
}
}
// Reference imports to suppress errors if they are not otherwise used.
// Reference imports to suppress errors if they are not otherwise used.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment