程序员的自我救赎---12.2.2: 虚拟币交易平台(区块链) 中 【开发交易所】 12.2.1: 虚拟币交易平台(区块链) 上【发行区块链代币】 【发行区块链代币】

《前言》html

(一) Winner2.0 框架基础分析前端

(二)PLSQL报表系统数据库

(三)SSO单点登陆前端框架

(四) 短信中心与消息中心框架

(五)钱包系统数据库设计

(六)GPU支付中心ide

(七)权限系统post

(八)监控系统区块链

(九)会员中心网站

(十) APP版本控制系统

(十一)Winner前端框架与RPC接口规范讲解

(十二)上层应用案例

(十三)总结

 

 

虚拟币交易平台(区块链) 中 【开发交易所】

 

对于,若是没有看上一篇文章的,建议先看一下上一篇文章了解如何发行一个区块链代币: 12.2.1: 虚拟币交易平台(区块链) 上【发行区块链代币】

 

首先咱们要知道一个概念,虽然区块链是去中心化的,可是交易所倒是中心化的。这也是为何区块链技术被吹捧的那么厉害,却仍是又发生那么多比特币、莱特币被盗事件。

在咱们国家,去年(2017年)9月4号以前是没有明确的法律法规说不容许作ICO,也没有明确指出不容许作区块链代币交易所。 直到去年9月4号七部委联合发文,比特币、莱特币等虚拟币也应声降价,以后国内全部交易所基本都关了。

 

这里我引用一下百度上的解释:

 

公告指出,代币发行融资中使用的代币或“虚拟货币”不禁货币当局发行,不具备法偿性与强制性等货币属性,不具备与货币等同的法律地位,不能也不该做为货币在市场上流通使用。

公告中代表:任何组织和我的不得非法从事代币发行融资活动,各金融机构和非银行支付机构不得开展与代币发行融资交易相关的业务。

 

 

咱们要知道,比特币、莱特币各类代币并不等于区块链,因此各国在法律法规对于比特币和区块是两种态度,一方面打压比特币、莱特币这种代币,一方面又支持区块链技术的发展。

 

这里我也呼吁一下,但愿你们不要去从事ICO非法融资,这种钱说不定有命赚,没命花。

 

===================================================华丽的分割线=======================================

 

回到正题,咱们知道区块链,是经过记帐来确认交易,而记帐是记载在区块上。拿比特币来讲每10分钟才出一个区块6个区块才确认一笔交易,这个过程是很是慢的。

因此虽然叫"比特币" 它却没有像咱们平时网银转帐那样的及时性。 这就衍生出了交易所,而交易所是中心化的,也就是服务端的数据库操做。

 

(如今有人研究去中心化的交易所,可是目前尚未很好解决各类区块链之间转帐,因此去中心化的交易所目前尚未落地)

 

说道这里就好作,网站这种东西,咱们平时真的是作太多了。说作网站,确定先从数据库提及,由于咱们的项目基于Winner2.0 框架,因此这里咱们会省去不少环节,好比用户,权限等。不清楚的就看我前面的博客吧。

 

 

 

 

 

 

 

 

 

 ==========================================华丽的分割线==============================================================

 

最重要的就以上五张表了,咱们来简单分析一下这五张表, 咱们先看看前端的UI界面图:

 

 

 

 

 这样就一目了然知道各个表是干什么用的:

 

 

数字货币表:存储当前平台能够交易的数字代币,就是左上角的“比特币”,“莱特币”

货币动态表:保存该数字代币的价格浮动信息,好比比特币的今日最高价,价格走势图。

委托交易表:简单来讲就是咱们的挂单信息表,像“个人挂单”,还有右侧的委托信息,都在张表。

撮合信息表:撮合简单来讲就是好比有人出10块卖,有人出100块买,自己价格是不对应的,可是咱们认定出100块的人更愿意出10块买,因此咱们促成他们交易。

                     最终他们会在撮合机制下,以10块的价格达成交易。 而撮合信息表本质来讲就是“成交信息表”,好比左侧的成交记录。

 

 

 

==========================================================华丽的分割线================================================

 

因为上一篇文章 【发行区块链代币】 这篇文章不少人说我实在写的太长了。

 

因此今天这一篇咱们直接简单粗暴一点。看完了数据库核心的四张表,我来看看核心的代码。

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Winner.Balance.Facade;
using Winner.Balance.GlobalCurrency;
using Winner.DCTS.DataAccess;
using Winner.DCTS.Entities;
using Winner.DCTS.Entities.enums;
using Winner.Framework.Core.Facade;
using Winner.Framework.Utils;

namespace Winner.DCTS.Facade
{
    public class MatchTransfer : FacadeBase
    {
        private eBankTransaction EBankTransaction { get; set; }
        private Tdct_Match daMatch { get; set; }

        public bool DoTransfer(Tdct_Match match)
        {
            daMatch = match;
            
            //开启事务
            BeginTransaction();

            //关联事务
            EBankTransaction = Transfer.GeteBankTransaction(); 

            //出售者把币转到购买者
            if (!SellToBuy())
            {
                Rollback(); //回滚事务

                UpdateFail(this.PromptInfo.MessageStack); 
                return false;
            }
            //购买者把钱转到出售者 + 手续费
            if (!BuyToSell())
            {
                Rollback();
                UpdateFail(this.PromptInfo.MessageStack);
                return false;
            }
            daMatch.TransferId = this.EBankTransaction;

            //撮合成功时修改撮合信息表状态
            if (!UpdateSuccess())
            {
                Rollback();
                return false;
            }

            //解除代币以及人名币锁定
            if (!UnFreeze())
            {
                Rollback();
                return false;
            }

           //同步代币动态交易信息
            if (!SyncDynamice())
            {
                Rollback();
                return false;
            }
            Commit();
            return true;
        }

        //出售者把币转到购买者
        private bool SellToBuy()
        {
            BeginTransaction();
            Currency currency = new Currency(CurrencyType.RMB, daMatch.BuyCount);
            UserPurse sellPurse = UserPurseProvider.Get(daMatch.SellUserId, daMatch.SellCurrency);
            UserPurse buyPurse = UserPurseProvider.Get(daMatch.BuyUserId, daMatch.SellCurrency);
            Transfer transfer = new Transfer(EBankTransaction);
            transfer.ReferenceTransactionFrom(this.Transaction);
            //若是买和卖都是同一我的则须要用转到系统用户再转入
            if (daMatch.SellUserId == daMatch.BuyUserId)
            {
                //系统用户钱包
                UserPurse transitPurse = UserPurseProvider.Get(AppConfig.TransitUserId, daMatch.SellCurrency);
                if (!transfer.DoTransferAndUnFreeze(sellPurse, transitPurse, currency, (int)TransferReson.出售者转入购买者, "出售货币中转出帐", daMatch.SellFreezeId, "购买货币中转入帐"))
                {
                    Rollback();
                    Alert("出售者转中转钱包失败!", transfer.PromptInfo);
                    return false;
                }
                if (!transfer.DoTransfer(transitPurse, buyPurse, currency, (int)TransferReson.出售者转入购买者, "出售货币中转出帐", "购买货币中转入帐"))
                {
                    Rollback();
                    Alert("中转者转购买者失败!", transfer.PromptInfo);
                    return false;
                }
            }
            else
            {
                if (!transfer.DoTransferAndUnFreeze(sellPurse, buyPurse, currency, (int)TransferReson.出售者转入购买者, "出售货币出帐", daMatch.SellFreezeId, "购买货币入帐"))
                {
                    Rollback();
                    Alert("出售者转购买者失败!", transfer.PromptInfo);
                    return false;
                }
            }
            Commit();
            return true;
        }


        //购买者把钱转到出售者 + 手续费
        private bool BuyToSell()
        {
            BeginTransaction();
            Currency currency = new Currency(CurrencyType.RMB, daMatch.Amount);
            UserPurse buyPurse = UserPurseProvider.Get(daMatch.BuyUserId, daMatch.BuyCurrency);
            UserPurse sellPurse = UserPurseProvider.Get(daMatch.SellUserId, daMatch.BuyCurrency);
            //收取手续费

            Transfer transfer = new Transfer(EBankTransaction);
            transfer.ReferenceTransactionFrom(this.Transaction);
            //若是买和卖都是同一我的则须要用转到系统用户再转入
            if (daMatch.BuyUserId == daMatch.SellUserId)
            {
                UserPurse transitPurse = UserPurseProvider.Get(AppConfig.TransitUserId, daMatch.BuyCurrency);
                if (!transfer.DoTransferAndUnFreeze(buyPurse, transitPurse, currency, (int)TransferReson.购买者转入出售者, "购买货币中转付款", daMatch.BuyFreezeId, "出售货币中转入帐"))
                {
                    Rollback();
                    Alert("购买者转中转者失败!", transfer.PromptInfo);
                    return false;
                }
                if (!transfer.DoTransfer(transitPurse, sellPurse, currency, (int)TransferReson.购买者转入出售者, "购买货币中转付款", "出售货币中转入帐"))
                {
                    Rollback();
                    Alert("中转者转出售者失败!", transfer.PromptInfo);
                    return false;
                }
            }
            else
            {
                if (!transfer.DoTransferAndUnFreeze(buyPurse, sellPurse, currency, (int)TransferReson.购买者转入出售者, "购买货币付款", daMatch.BuyFreezeId, "出售货币入帐"))
                {
                    Rollback();
                    Alert("购买者转出售者失败!", transfer.PromptInfo);
                    return false;
                }
            }

            if (daMatch.Fee <= 0)
            {
                Commit();
                return true;
            }
            UserPurse feePurse = UserPurseProvider.Get(AppConfig.SystemUserId, daMatch.BuyCurrency);
            Currency feeCurrency = new Currency(feePurse.CurrencyType, daMatch.Fee);
            if (!transfer.DoTransfer(sellPurse, feePurse, feeCurrency, (int)TransferReson.收取出售者手续费, "收取出售者手续费"))
            {
                Rollback();
                Alert("收取出售者手续费失败!", transfer.PromptInfo);
                return false;
            }
            Commit();
            return true;
        }

        //修改撮合成功信息
        private bool UpdateSuccess()
        {
            daMatch.ReferenceTransactionFrom(this.Transaction);
            if (!daMatch.UpdateTransferSuccess(daMatch.MatchId, daMatch.TransferId.Value))
            {
                Alert("修改撮合历史成功时发现失败", daMatch.PromptInfo);
                return false;
            }
            return true;
        }


        //修改撮合失败信息
        private bool UpdateFail(string remarks)
        {
            Tdct_Match match = new Tdct_Match();
            if (!daMatch.UpdateTransferFail(daMatch.MatchId, remarks))
            {
                Alert("修改撮合历史成功时发现失败", daMatch.PromptInfo);
                return false;
            }
            return true;
        }


        //解除挂单的代币锁定
        public bool UnFreeze()
        {
            Tdct_EntrustCollection daEntrustColl = new Tdct_EntrustCollection();
            daEntrustColl.ReferenceTransactionFrom(this.Transaction);
            daEntrustColl.ListWaitRevokeRedundant(daMatch.SellEntrust, daMatch.BuyEntrust);
            Log.Info("解冻冗余[{0}笔]:", daEntrustColl.Count);
            if (daEntrustColl.Count <= 0)
            {
                return true;
            }
            foreach (Tdct_Entrust item in daEntrustColl)
            {
                Log.Info("[{0}]解冻就绪", item.Id);
                decimal amount = item.EAmount - item.TAmount;
                Currency currency = new Currency(CurrencyType.RMB, amount);
                Log.Info("[{0}]委托剩余解冻{1}金额", item.Id, amount);
                UserPurse userPurse = UserPurseProvider.Get(item.UserId, item.TCurrency);
                userPurse.ReferenceTransactionFrom(this.Transaction);
                if (!userPurse.UnFreeze(item.FreezeId, currency))
                {
                    Alert(userPurse.PromptInfo);
                    Log.Info("[{0}]解冻失败:{1}", item.Id, userPurse.PromptInfo.MessageStack);
                    return false;
                }
                Log.Info("[{0}]解冻成功", item.Id);
            }
            return true;
        }


        //同步代币动态信息
        private bool SyncDynamice()
        {
            Tdct_Daily_Dynamics daDynamice = new Tdct_Daily_Dynamics();
            daDynamice.ReferenceTransactionFrom(this.Transaction);
            if (daDynamice.SelectByDate(daMatch.SellCurrency, daMatch.BuyCurrency))
            {
                if (!daDynamice.UpdateNewSycn(daDynamice.Id, daMatch.Price, daMatch.BuyCount))
                {
                    Alert("同步每日动态失败");
                    return false;
                }
                return true;
            }
            daDynamice.BuyCurrencyId = daMatch.BuyCurrency;
            daDynamice.SellCurrencyId = daMatch.SellCurrency;
            daDynamice.LastTime = DateTime.Now;
            daDynamice.MaxPrice = daMatch.Price;
            daDynamice.MinPrice = daMatch.Price;
            daDynamice.NewPrice = daMatch.Price;
            daDynamice.StartPrice = daMatch.Price;
            daDynamice.TCount = daMatch.BuyCount;
            if (!daDynamice.Insert())
            {
                Alert("保存每日动态数据失败!", daDynamice.PromptInfo);
                return false;
            }
            return true;
        }
    }
}

 



上面的代码我基本上都加了注释,基本上能理解撮合交易的概念,配合我提供的这段代码以及数据库设计,就对于开发代币交易所的基本没有问题。

前端有个价格是实时动态的,若是技术水平还的话能够作个实时推送,若是以为麻烦就作个定时器3秒轮训一次也能够。

 

======================================================华丽的分割线=======================================================

 

再多说几句,区块链之因此那么火热是在于它的技术性特,好比"去中心化"  能够帮助人们解除中心存储的信任问题,“UXTO”机制能够保证每一笔钱都能查的清清楚楚,“不可修改” 的特性能够保证数据的惟一性和一致性。

自己比特币,只是在咱们每一个为何要去同步区块?同步区块以及挖矿(记帐)我有什么好处?这时就给予了比特币的奖励!俗气一点说,比特币就是这个用途,固然咱们能够高尚去说他解决了 “货币超发”,“通货膨胀”,“中心化不可信任”等问题。

 

如今国家基本上是不让作交易所了,因此去年末全部交易所也纷纷清退,关停了。这也让咱们更清晰的去看待“区块链”技术,而不是只有“炒币”。

 

不能否认的是,确定还有不少币的交易所在见不得光的运做着,我以为就是早期在比特币和ICO来临的时候,没有圈到钱,而且有着一种“不甘心”的心态在执着。

若是只是去发一个没有技术含量的“空气币” 而后借着区块链的名头“割韭菜”,这其实就涉嫌"非法吸取公众存款"的罪名。钱不会凭空产生,也不会凭空消失,有人赚钱就注定有人在亏钱。

 

“空气币”自己不具有任何价值,只有将区块链技术应用到生活,区块链对应的代币才有价值。

 

就写到这吧,下一篇文章我将会回到“以太坊”的区块链技术,讲解如何将“.net” 技术以及C# 这们技术语言与“以太坊”区块链相结合。(C# 在移动互联网时代没落,但愿在区块链的风口上能再次崛起!)

 

若是你以为这篇文章对你有帮助,请捐助:

 

                                                                                                               

 

 

有兴趣一块儿探讨Winner2.0框架的能够加咱们QQ群:261083244。或者扫描左侧二维码加群。

相关文章
相关标签/搜索