Commit ef710316 authored by harrylee's avatar harrylee Committed by vipwzw

add exchange dapp

parent f3fe57bb
all:
chmod +x ./build.sh
./build.sh $(OUT) $(FLAG)
#!/bin/sh
# 官方ci集成脚本
strpwd=$(pwd)
strcmd=${strpwd##*dapp/}
strapp=${strcmd%/cmd*}
OUT_DIR="${1}/$strapp"
#FLAG=$2
mkdir -p "${OUT_DIR}"
cp ./build/* "${OUT_DIR}"
/*Package commands implement dapp client commands*/
package commands
import (
"github.com/spf13/cobra"
)
/*
* 实现合约对应客户端
*/
// Cmd exchange client command
func Cmd() *cobra.Command {
cmd := &cobra.Command{
Use: "exchange",
Short: "exchange command",
Args: cobra.MinimumNArgs(1),
}
cmd.AddCommand(
//add sub command
)
return cmd
}
package executor
import (
log "github.com/33cn/chain33/common/log/log15"
drivers "github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
exchangetypes "github.com/33cn/plugin/plugin/dapp/exchange/types"
)
/*
* 执行器相关定义
* 重载基类相关接口
*/
var (
//日志
elog = log.New("module", "exchange.executor")
)
var driverName = exchangetypes.ExchangeX
// Init register dapp
func Init(name string, cfg *types.Chain33Config, sub []byte) {
drivers.Register(cfg, GetName(), newExchange, cfg.GetDappFork(driverName, "Enable"))
InitExecType()
}
// InitExecType Init Exec Type
func InitExecType() {
ety := types.LoadExecutorType(driverName)
ety.InitFuncList(types.ListMethod(&exchange{}))
}
type exchange struct {
drivers.DriverBase
}
func newExchange() drivers.Driver {
t := &exchange{}
t.SetChild(t)
t.SetExecutorType(types.LoadExecutorType(driverName))
return t
}
// GetName get driver name
func GetName() string {
return newExchange().GetName()
}
func (e *exchange) GetDriverName() string {
return driverName
}
// CheckTx 实现自定义检验交易接口,供框架调用
func (e *exchange) CheckTx(tx *types.Transaction, index int) error {
//发送交易的时候就检查payload,做严格的参数检查
var exchange exchangetypes.ExchangeAction
types.Decode(tx.GetPayload(), &exchange)
if exchange.Ty == exchangetypes.TyLimitOrderAction {
limitOrder := exchange.GetLimitOrder()
left := limitOrder.GetLeftAsset()
right := limitOrder.GetRightAsset()
price := Truncate(limitOrder.GetPrice())
amount := limitOrder.GetAmount()
op := limitOrder.GetOp()
if !CheckExchangeAsset(left, right) {
return exchangetypes.ErrAsset
}
if !CheckPrice(price) {
return exchangetypes.ErrAssetPrice
}
if !types.CheckAmount(amount) {
return exchangetypes.ErrAssetAmount
}
if !CheckOp(op) {
return exchangetypes.ErrAssetOp
}
}
return nil
}
// GetPayloadValue get payload value
func (e *exchange) GetPayloadValue() types.Message {
return &exchangetypes.ExchangeAction{}
}
package executor
import (
"testing"
)
func TestTruncate(t *testing.T) {
a:=float32(1.00000212000000000001)
b:=float32(0.34567)
c:=float32(1234)
t.Log(Truncate(a))
t.Log(Truncate(b))
t.Log(Truncate(c))
}
\ No newline at end of file
This diff is collapsed.
package executor
import (
"github.com/33cn/chain33/types"
exchangetypes "github.com/33cn/plugin/plugin/dapp/exchange/types"
)
/*
* 实现交易的链上执行接口
* 关键数据上链(statedb)并生成交易回执(log)
*/
func (e *exchange) Exec_LimitOrder(payload *exchangetypes.LimitOrder, tx *types.Transaction, index int) (*types.Receipt, error) {
var receipt *types.Receipt
//implement code
return receipt, nil
}
func (e *exchange) Exec_MarketOrder(payload *exchangetypes.MarketOrder, tx *types.Transaction, index int) (*types.Receipt, error) {
var receipt *types.Receipt
//implement code
return receipt, nil
}
func (e *exchange) Exec_RevokeOrder(payload *exchangetypes.RevokeOrder, tx *types.Transaction, index int) (*types.Receipt, error) {
var receipt *types.Receipt
//implement code
return receipt, nil
}
package executor
import (
"github.com/33cn/chain33/types"
)
/*
* 实现区块回退时本地执行的数据清除
*/
// ExecDelLocal 回退自动删除,重写基类
func (e *exchange) ExecDelLocal(tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) {
kvs, err := e.DelRollbackKV(tx, tx.Execer)
if err != nil {
return nil, err
}
dbSet := &types.LocalDBSet{}
dbSet.KV = append(dbSet.KV, kvs...)
return dbSet, nil
}
package executor
import (
"github.com/33cn/chain33/types"
exchangetypes "github.com/33cn/plugin/plugin/dapp/exchange/types"
)
/*
* 实现交易相关数据本地执行,数据不上链
* 非关键数据,本地存储(localDB), 用于辅助查询,效率高
*/
func (e *exchange) ExecLocal_LimitOrder(payload *exchangetypes.LimitOrder, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
dbSet := &types.LocalDBSet{}
if receiptData.Ty == types.ExecOk {
for _, log := range receiptData.Logs {
switch log.Ty {
case exchangetypes.TyLimitOrderLog:
receipt := &exchangetypes.ReceiptExchange{}
if err := types.Decode(log.Log, receipt); err != nil {
return nil, err
}
kv := e.updateIndex(receipt)
dbSet.KV = append(dbSet.KV, kv...)
}
}
}
return e.addAutoRollBack(tx, dbSet.KV), nil
}
func (e *exchange) ExecLocal_MarketOrder(payload *exchangetypes.MarketOrder, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
dbSet := &types.LocalDBSet{}
//implement code
return e.addAutoRollBack(tx, dbSet.KV), nil
}
func (e *exchange) ExecLocal_RevokeOrder(payload *exchangetypes.RevokeOrder, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
dbSet := &types.LocalDBSet{}
//implement code
return e.addAutoRollBack(tx, dbSet.KV), nil
}
//设置自动回滚
func (e *exchange) addAutoRollBack(tx *types.Transaction, kv []*types.KeyValue) *types.LocalDBSet {
dbSet := &types.LocalDBSet{}
dbSet.KV = e.AddRollbackKV(tx, tx.Execer, kv)
return dbSet
}
func (e *exchange) updateIndex(receipt *exchangetypes.ReceiptExchange) (kvs []*types.KeyValue) {
switch receipt.Order.Status {
case exchangetypes.Ordered:
left := receipt.GetOrder().GetLimitOrder().GetLeftAsset()
right := receipt.GetOrder().GetLimitOrder().GetRightAsset()
op := receipt.GetOrder().GetLimitOrder().GetOp()
price := receipt.GetOrder().GetLimitOrder().GetPrice()
oderID := receipt.GetOrder().OrderID
index := receipt.GetIndex()
addr := receipt.GetOrder().Addr
var markDepth exchangetypes.MarketDepth
err := findObject(e.GetLocalDB(), calcMarketDepthKey(left, right, op, price), &markDepth)
if err == types.ErrNotFound {
markDepth.Price = price
markDepth.LeftAsset = left
markDepth.RightAsset = right
markDepth.Op = op
markDepth.Amount = receipt.Order.Balance
}
markDepth.Amount = markDepth.Amount + receipt.Order.Balance
//marketDepth
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthKey(left, right, op, price), Value: types.Encode(&markDepth)})
//orderID
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthOrderKey(left, right, op, price, receipt.Index), Value: types.Encode(&exchangetypes.OrderID{ID: oderID, Index: index})})
//addr orderID
kvs = append(kvs, &types.KeyValue{Key: calcUserOrderIDKey(exchangetypes.Ordered, addr, index), Value: types.Encode(&exchangetypes.OrderID{ID: oderID, Index: index})})
if len(receipt.MatchOrders) > 0 {
//撮合交易更新
var balance int64
for _, matchOrder := range receipt.MatchOrders {
if matchOrder.Status == exchangetypes.Completed {
// 删除原有状态orderID
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthOrderKey(left, right, matchOrder.GetLimitOrder().Op, price, matchOrder.Index), Value: nil})
//删除原有状态orderID
kvs = append(kvs, &types.KeyValue{Key: calcUserOrderIDKey(exchangetypes.Ordered, matchOrder.Addr, matchOrder.Index), Value: nil})
//更新状态为已完成,索引index,改为当前的index
kvs = append(kvs, &types.KeyValue{Key: calcUserOrderIDKey(exchangetypes.Completed, matchOrder.Addr, index), Value: types.Encode(&exchangetypes.OrderID{ID: matchOrder.OrderID, Index: index})})
//calcCompletedOrderKey
kvs = append(kvs, &types.KeyValue{Key: calcCompletedOrderKey(left, right, index), Value: types.Encode(&exchangetypes.OrderID{ID: matchOrder.OrderID, Index: index})})
}
if matchOrder.Status == exchangetypes.Ordered {
//只需统一更改市场深度状态,其他不需要处理
balance = balance + matchOrder.Balance
}
}
//更改市场深度
var matchDepth exchangetypes.MarketDepth
err = findObject(e.GetLocalDB(), calcMarketDepthKey(left, right, OpSwap(op), price), &matchDepth)
if err == types.ErrNotFound {
matchDepth.Price = price
matchDepth.LeftAsset = left
matchDepth.RightAsset = right
matchDepth.Op = OpSwap(op)
matchDepth.Amount = balance
}
matchDepth.Amount = matchDepth.Amount - receipt.Order.Executed
//marketDepth
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthKey(left, right, OpSwap(op), price), Value: types.Encode(&matchDepth)})
}
return
case exchangetypes.Completed:
left := receipt.GetOrder().GetLimitOrder().GetLeftAsset()
right := receipt.GetOrder().GetLimitOrder().GetRightAsset()
op := receipt.GetOrder().GetLimitOrder().GetOp()
price := receipt.GetOrder().GetLimitOrder().GetPrice()
oderID := receipt.GetOrder().OrderID
index := receipt.GetIndex()
addr := receipt.GetOrder().Addr
//user orderID
kvs = append(kvs, &types.KeyValue{Key: calcUserOrderIDKey(exchangetypes.Completed, addr, index), Value: types.Encode(&exchangetypes.OrderID{ID: oderID, Index: index})})
if len(receipt.MatchOrders) > 0 {
//撮合交易更新
var balance int64
for _, matchOrder := range receipt.MatchOrders {
if matchOrder.Status == exchangetypes.Completed {
// 删除原有状态orderID
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthOrderKey(left, right, matchOrder.GetLimitOrder().Op, price, matchOrder.Index), Value: nil})
//删除原有状态orderID
kvs = append(kvs, &types.KeyValue{Key: calcUserOrderIDKey(exchangetypes.Ordered, matchOrder.Addr, matchOrder.Index), Value: nil})
//更新状态为已完成,更新索引
kvs = append(kvs, &types.KeyValue{Key: calcUserOrderIDKey(exchangetypes.Completed, matchOrder.Addr, index), Value: types.Encode(&exchangetypes.OrderID{ID: matchOrder.OrderID, Index: index})})
//calcCompletedOrderKey
kvs = append(kvs, &types.KeyValue{Key: calcCompletedOrderKey(left, right, index), Value: types.Encode(&exchangetypes.OrderID{ID: matchOrder.OrderID, Index: index})})
}
if matchOrder.Status == exchangetypes.Ordered {
//只需统一更改市场深度状态,其他不需要处理
balance = balance + matchOrder.Balance
}
}
//更改match市场深度
var matchDepth exchangetypes.MarketDepth
err := findObject(e.GetLocalDB(), calcMarketDepthKey(left, right, OpSwap(op), price), &matchDepth)
if err == types.ErrNotFound {
matchDepth.Price = price
matchDepth.LeftAsset = left
matchDepth.RightAsset = right
matchDepth.Op = OpSwap(op)
matchDepth.Amount = balance
}
matchDepth.Amount = matchDepth.Amount - receipt.Order.Executed
//marketDepth
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthKey(left, right, OpSwap(op), price), Value: types.Encode(&matchDepth)})
}
return
case exchangetypes.Revoked:
//只有状态时ordered状态的订单才能被撤回
left := receipt.GetOrder().GetLimitOrder().GetLeftAsset()
right := receipt.GetOrder().GetLimitOrder().GetRightAsset()
op := receipt.GetOrder().GetLimitOrder().GetOp()
price := receipt.GetOrder().GetLimitOrder().GetPrice()
oderID := receipt.GetOrder().OrderID
index := receipt.GetIndex()
addr := receipt.GetOrder().Addr
var marketDepth exchangetypes.MarketDepth
err := findObject(e.GetLocalDB(), calcMarketDepthKey(left, right, op, price), &marketDepth)
if err == nil {
//marketDepth
marketDepth.Amount = marketDepth.Amount - receipt.GetOrder().Balance
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthKey(left, right, op, price), Value: types.Encode(&marketDepth)})
}
// 删除原有状态orderID
kvs = append(kvs, &types.KeyValue{Key: calcMarketDepthOrderKey(left, right, op, price, receipt.GetOrder().Index), Value: nil})
//删除原有状态orderID
kvs = append(kvs, &types.KeyValue{Key: calcUserOrderIDKey(exchangetypes.Ordered, addr, receipt.GetOrder().Index), Value: nil})
//添加撤销的订单
kvs = append(kvs, &types.KeyValue{Key: calcUserOrderIDKey(exchangetypes.Revoked, addr, index), Value: types.Encode(&exchangetypes.OrderID{ID: oderID, Index: index})})
}
return
}
func OpSwap(op int32) int32 {
if op == exchangetypes.OpBuy {
return exchangetypes.OpSell
} else {
return exchangetypes.OpBuy
}
}
package executor
import (
"fmt"
"github.com/33cn/plugin/plugin/dapp/exchange/types"
)
/*
* 用户合约存取kv数据时,key值前缀需要满足一定规范
* 即key = keyPrefix + userKey
* 需要字段前缀查询时,使用’-‘作为分割符号
*/
var (
//KeyPrefixStateDB state db key必须前缀
KeyPrefixStateDB = "mavl-exchange-"
//KeyPrefixLocalDB local db的key必须前缀
KeyPrefixLocalDB = "LODB-exchange-"
)
//状态数据库中存储具体挂单信息
func calcOrderKey(orderID string) []byte {
key := fmt.Sprintf("%s"+"orderID:%s", KeyPrefixStateDB, orderID)
return []byte(key)
}
func calcMarketDepthPrefix(left, right *types.Asset, op int32) []byte {
key := fmt.Sprintf("%s"+"depth-%s-%s-%d:", KeyPrefixLocalDB, left.GetSymbol(), right.GetSymbol(), op)
return []byte(key)
}
//市场深度
func calcMarketDepthKey(left, right *types.Asset, op int32, price float32) []byte {
// 设置精度为1e8
key := fmt.Sprintf("%s"+"depth-%s-%s-%d:%016d", KeyPrefixLocalDB, left.GetSymbol(), right.GetSymbol(), op, int64(Truncate(price)*float32(1e8)))
return []byte(key)
}
func calcMarketDepthOrderPrefix(left, right *types.Asset, op int32, price float32) []byte {
// 设置精度为1e8
key := fmt.Sprintf("%s"+"order-%s-%s-%d:%016d", KeyPrefixLocalDB, left.GetSymbol(), right.GetSymbol(), op, int64(Truncate(price)*float32(1e8)))
return []byte(key)
}
// localdb中存储市场挂单ID
func calcMarketDepthOrderKey(left, right *types.Asset, op int32, price float32, index int64) []byte {
// 设置精度为1e8
key := fmt.Sprintf("%s"+"order-%s-%s-%d:%016d:%018d", KeyPrefixLocalDB, left.GetSymbol(), right.GetSymbol(), op, int64(Truncate(price)*float32(1e8)), index)
return []byte(key)
}
//最新已经成交的订单,这里状态固定都是完成状态,这个主要给外部使用,可以查询最新得成交信息
func calcCompletedOrderKey(left, right *types.Asset, index int64) []byte {
// 设置精度为1e8
key := fmt.Sprintf("%s"+"completed-%s-%s-%d:%018d", KeyPrefixLocalDB, left.GetSymbol(), right.GetSymbol(), types.Completed, index)
return []byte(key)
}
func calcCompletedOrderPrefix(left, right *types.Asset) []byte {
// 设置精度为1e8
key := fmt.Sprintf("%s"+"completed-%s-%s-%d:", KeyPrefixLocalDB, left.GetSymbol(), right.GetSymbol(), types.Completed)
return []byte(key)
}
//根据地址和订单状态,去查询订单列表,包含所有交易对
func calcUserOrderIDPrefix(status int32, addr string) []byte {
key := fmt.Sprintf("%s"+"addr:%s:%d:", KeyPrefixLocalDB, addr, status)
return []byte(key)
}
func calcUserOrderIDKey(status int32, addr string, index int64) []byte {
key := fmt.Sprintf("%s"+"addr:%s:%d:%018d", KeyPrefixLocalDB, addr, status, index)
return []byte(key)
}
package executor
import (
"github.com/33cn/chain33/types"
et "github.com/33cn/plugin/plugin/dapp/exchange/types"
)
//查询市场深度
func (s *exchange) Query_QueryMarketDepth(in *et.QueryMarketDepth) (types.Message, error) {
if !CheckCount(in.Count) {
return nil, et.ErrCount
}
if in.Count == 0 {
in.Count = 10
}
if !CheckExchangeAsset(in.LeftAsset, in.RightAsset) {
return nil, et.ErrAsset
}
if !CheckPrice(in.Price) {
return nil, et.ErrAssetPrice
}
if !CheckOp(in.Op) {
return nil, et.ErrAssetOp
}
return QueryMarketDepth(s.GetLocalDB(), in.LeftAsset, in.RightAsset, in.Op, in.Price, in.Count)
}
//查询已经完成得订单
func (s *exchange) Query_QueryCompletedOrderList(in *et.QueryCompletedOrderList) (types.Message, error) {
if !CheckExchangeAsset(in.LeftAsset, in.RightAsset) {
return nil, et.ErrAsset
}
if in.Count > 20 {
return nil, et.ErrCount
}
if !CheckDirection(in.Direction) {
return nil, et.ErrDirection
}
return QueryCompletedOrderList(s.GetLocalDB(), s.GetStateDB(), in.LeftAsset, in.RightAsset, in.Index, in.Count, in.Direction)
}
//根据orderID查询订单信息
func (s *exchange) Query_QueryOrder(in *et.QueryOrder) (types.Message, error) {
if in.OrderID == "" {
return nil, et.ErrOrderID
}
return findOrderByOrderID(s.GetStateDB(), in.OrderID)
}
//根据订单状态,查询订单信息(这里面包含所有交易对)
func (s *exchange) Query_QueryOrderList(in *et.QueryOrderList) (types.Message, error) {
if !CheckStatus(in.Status) {
return nil, et.ErrStatus
}
if !CheckCount(in.Count) {
return nil, et.ErrCount
}
if !CheckDirection(in.Direction) {
return nil, et.ErrDirection
}
if in.Address == "" {
return nil, et.ErrAddr
}
return QueryOrderList(s.GetLocalDB(), s.GetStateDB(), in.Address, in.Status, in.Count, in.Direction, in.Index)
}
package types
import (
"github.com/33cn/chain33/pluginmgr"
"github.com/33cn/plugin/plugin/dapp/exchange/commands"
"github.com/33cn/plugin/plugin/dapp/exchange/executor"
"github.com/33cn/plugin/plugin/dapp/exchange/rpc"
exchangetypes "github.com/33cn/plugin/plugin/dapp/exchange/types"
)
/*
* 初始化dapp相关的组件
*/
func init() {
pluginmgr.Register(&pluginmgr.PluginBase{
Name: exchangetypes.ExchangeX,
ExecName: executor.GetName(),
Exec: executor.Init,
Cmd: commands.Cmd,
RPC: rpc.Init,
})
}
all:
./create_protobuf.sh
#!/bin/sh
# proto生成命令,将pb.go文件生成到types/目录下, chain33_path支持引用chain33框架的proto文件
chain33_path=$(go list -f '{{.Dir}}' "github.com/33cn/chain33")
protoc --go_out=plugins=grpc:../types ./*.proto --proto_path=. --proto_path="${chain33_path}/types/proto/"
syntax = "proto3";
package types;
message Exchange {
}
message ExchangeAction {
oneof value {
LimitOrder limitOrder = 1;
// MarketOrder marketOrder = 2;
RevokeOrder revokeOrder = 3;
}
int32 ty = 6;
}
//限价订单
message LimitOrder {
//交易对
Asset leftAsset = 1;
//交易对
Asset rightAsset = 2;
//价格
float price = 3;
//总量
int64 amount = 4;
//操作, 1为买,2为卖
int32 op = 5;
}
//市价委托
message MarketOrder {
//资产1
Asset leftAsset = 1;
//资产2
Asset rightAsset = 2;
//总量
int64 amount = 3;
//操作, 1为买,2为卖
int32 op = 4;
}
//撤回订单
message RevokeOrder {
//订单号
string orderID = 1;
}
//资产类型
message Asset {
string execer = 1;
string symbol = 2;
}
//订单信息
message Order {
string orderID = 1;
oneof value {
LimitOrder limitOrder = 2;
MarketOrder marketOrder = 3;
}
//挂单类型
int32 ty = 4;
//已经成交的数量
int64 executed = 5;
//余额
int64 balance = 6;
//状态,0 挂单中ordered, 1 完成completed, 2撤回 revoked
int32 status = 7;
//用户地址
string addr = 8;
//更新时间
int64 updateTime = 9;
//索引
int64 index = 10;
}
//挂单价
message OrderPrice {
float price = 1;
int64 index = 2;
}
//单号
message OrderID {
string ID = 1;
int64 index = 2;
}
//查询接口
message QueryMarketDepth {
//资产1
Asset leftAsset = 1;
//资产2
Asset rightAsset = 2;
//操作, 1为买,2为卖
int32 op = 3;
// 这里用价格作为索引值
float price = 4;
//单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条
int32 count = 5;
}
//市场深度
message MarketDepth {
//资产1
Asset leftAsset = 1;
//资产2
Asset rightAsset = 2;
//价格
float price = 3;
//总量
int64 amount = 4;
//操作, 1为买,2为卖
int32 op = 5;
}
//查询接口返回的市场深度列表
message MarketDepthList {
repeated MarketDepth list = 1;
}
//查询最新得成交信息,外部接口
message QueryCompletedOrderList {
//资产1
Asset leftAsset = 1;
//资产2
Asset rightAsset = 2;
// 索引值
int64 index = 3;
//单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条
int32 count = 4;
// 0降序,1升序,默认降序
int32 direction = 5;
}
//根据orderID去查询订单信息
message QueryOrder {
string orderID = 1;
}
//根据地址,状态查询用户自己的挂单信息
message QueryOrderList {
//挂单状态必填(默认是0,只查询ordered挂单中的)
int32 status = 1;
//用户地址信息,必填
string address = 2;
// 索引值
int64 index = 3;
//单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条
int32 count = 4;
// 0降序,1升序,默认降序
int32 direction = 5;
}
//订单列表
message OrderList {
repeated Order list = 1;
}
//exchange执行票据日志
message ReceiptExchange {
Order order = 1;
repeated Order matchOrders = 2;
int64 index = 3;
}
service exchange {
}
package rpc
/*
* 实现json rpc和grpc service接口
* json rpc用Jrpc结构作为接收实例
* grpc使用channelClient结构作为接收实例
*/
package rpc
import (
rpctypes "github.com/33cn/chain33/rpc/types"
exchangetypes "github.com/33cn/plugin/plugin/dapp/exchange/types"
)
/*
* rpc相关结构定义和初始化
*/
// 实现grpc的service接口
type channelClient struct {
rpctypes.ChannelClient
}
// Jrpc 实现json rpc调用实例
type Jrpc struct {
cli *channelClient
}
// Grpc grpc
type Grpc struct {
*channelClient
}
// Init init rpc
func Init(name string, s rpctypes.RPCServer) {
cli := &channelClient{}
grpc := &Grpc{channelClient: cli}
cli.Init(name, s, &Jrpc{cli: cli}, grpc)
//存在grpc service时注册grpc server,需要生成对应的pb.go文件
exchangetypes.RegisterExchangeServer(s.GRPC(), grpc)
}
package types
import "fmt"
// some errors definition
var (
ErrAssetAmount = fmt.Errorf("%s", "The asset amount is not valid!")
ErrAssetPrice = fmt.Errorf("%s", "The asset price is not valid!")
ErrAssetOp = fmt.Errorf("%s", "The asset op is not define!")
ErrAssetBalance = fmt.Errorf("%s", "Insufficient balance!")
ErrOrderSatus = fmt.Errorf("%s", "The order status is reovked or completed!")
ErrAddr = fmt.Errorf("%s", "Wrong Addr!")
ErrAsset = fmt.Errorf("%s", "The asset's execer or symbol can't be nil,The same assets cannot be exchanged!")
ErrCount = fmt.Errorf("%s", "The param count can't large 20")
ErrDirection = fmt.Errorf("%s", "The direction only 0 or 1!")
ErrStatus = fmt.Errorf("%s", "The status only in 0 , 1, 2!")
ErrOrderID = fmt.Errorf("%s", "Wrong OrderID!")
)
package types
import (
log "github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/types"
)
/*
* 交易相关类型定义
* 交易action通常有对应的log结构,用于交易回执日志记录
* 每一种action和log需要用id数值和name名称加以区分
*/
// action类型id和name,这些常量可以自定义修改
const (
TyUnknowAction = iota + 200
TyLimitOrderAction
TyMarketOrderAction
TyRevokeOrderAction
NameLimitOrderAction = "LimitOrder"
NameMarketOrderAction = "MarketOrder"
NameRevokeOrderAction = "RevokeOrder"
FuncNameQueryMarketDepth = "QueryMarketDepth"
FuncNameQueryCompletedOrderList = "QueryCompletedOrderList"
FuncNameQueryOrder = "QueryOrder"
FuncNameQueryOrderList = "QueryOrderList"
)
// log类型id值
const (
TyUnknownLog = iota + 200
TyLimitOrderLog
TyMarketOrderLog
TyRevokeOrderLog
)
// OP
const (
OpBuy = iota + 1
OpSell
)
//order status
const (
Ordered = iota
Completed
Revoked
)
//const
const (
ListDESC = int32(0)
ListASC = int32(1)
ListSeek = int32(2)
)
//单次list还回条数
const (
Count = int32(5)
MaxCount = int32(20)
)
var (
//ExchangeX 执行器名称定义
ExchangeX = "exchange"
//定义actionMap
actionMap = map[string]int32{
NameLimitOrderAction: TyLimitOrderAction,
NameMarketOrderAction: TyMarketOrderAction,
NameRevokeOrderAction: TyRevokeOrderAction,
}
//定义log的id和具体log类型及名称,填入具体自定义log类型
logMap = map[int64]*types.LogInfo{
//LogID: {Ty: reflect.TypeOf(LogStruct), Name: LogName},
}
tlog = log.New("module", "exchange.types")
)
// init defines a register function
func init() {
types.AllowUserExec = append(types.AllowUserExec, []byte(ExchangeX))
//注册合约启用高度
types.RegFork(ExchangeX, InitFork)
types.RegExec(ExchangeX, InitExecutor)
}
// InitFork defines register fork
func InitFork(cfg *types.Chain33Config) {
cfg.RegisterDappFork(ExchangeX, "Enable", 0)
}
// InitExecutor defines register executor
func InitExecutor(cfg *types.Chain33Config) {
types.RegistorExecutor(ExchangeX, NewType(cfg))
}
type exchangeType struct {
types.ExecTypeBase
}
func NewType(cfg *types.Chain33Config) *exchangeType {
c := &exchangeType{}
c.SetChild(c)
c.SetConfig(cfg)
return c
}
// GetPayload 获取合约action结构
func (e *exchangeType) GetPayload() types.Message {
return &ExchangeAction{}
}
// GeTypeMap 获取合约action的id和name信息
func (e *exchangeType) GetTypeMap() map[string]int32 {
return actionMap
}
// GetLogMap 获取合约log相关信息
func (e *exchangeType) GetLogMap() map[int64]*types.LogInfo {
return logMap
}
This diff is collapsed.
......@@ -7,6 +7,7 @@ import (
_ "github.com/33cn/plugin/plugin/dapp/dposvote" //auto gen
_ "github.com/33cn/plugin/plugin/dapp/echo" //auto gen
_ "github.com/33cn/plugin/plugin/dapp/evm" //auto gen
_ "github.com/33cn/plugin/plugin/dapp/exchange" //auto gen
_ "github.com/33cn/plugin/plugin/dapp/game" //auto gen
_ "github.com/33cn/plugin/plugin/dapp/guess" //auto gen
_ "github.com/33cn/plugin/plugin/dapp/hashlock" //auto gen
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment