Exemple #1
0
        public static object setAssetSetting(byte[] assetHash, BigInteger enable, BigInteger valueMin, BigInteger valueUnit, BigInteger handlingFeeRate, string transferMethod)
        {
            //只有管理员地址可以操作此方法
            if (!checkSpuerAdmin())
            {
                throw new InvalidOperationException("error");
            }

            if (valueMin < 0 || valueUnit < 0 || handlingFeeRate < 0)
            {
                throw new InvalidOperationException("error");
            }
            if (enable != 0 && enable != 1)
            {
                throw new InvalidOperationException("error");
            }

            assetSetting assetSetting = new assetSetting();

            assetSetting.enable            = enable;
            assetSetting.valueMin          = valueMin;
            assetSetting.valueUnit         = valueUnit;
            assetSetting.handlingFeeRate   = handlingFeeRate;
            assetSetting.appTransferMethod = transferMethod;

            StorageMap assetSettingMap = Storage.CurrentContext.CreateMap("assetSettingMap");

            assetSettingMap.Put(assetHash, assetSetting.Serialize());

            //通知资产设置事件
            onSetAssetSetting(assetHash, assetSetting);

            return(true);
        }
Exemple #2
0
        private static bool NEP5transfer(byte[] from, byte[] to, byte[] assetHash, BigInteger amount)
        {
            StorageMap   balanceMap   = Storage.CurrentContext.CreateMap("balanceMap");
            assetSetting assetSetting = getAssetSetting(assetHash);

            //多判断总比少判断好
            if (amount <= 0)
            {
                throw new InvalidOperationException("error");
            }
            if (from.Length != 20 || to.Length != 20)
            {
                throw new InvalidOperationException("error");
            }

            //构造入参
            object[] transInput = new object[3];
            transInput[0] = from;
            transInput[1] = to;
            transInput[2] = amount;

            //动态调用执行转账
            deleDyncall dyncall = (deleDyncall)assetHash.ToDelegate();
            bool        result  = (bool)dyncall(assetSetting.appTransferMethod, transInput);

            return(result);
        }
Exemple #3
0
        public static assetSetting getAssetSetting(byte[] assetHash)
        {
            StorageMap assetSettingMap = Storage.CurrentContext.CreateMap("assetSettingMap");

            byte[]       data         = assetSettingMap.Get(assetHash);
            assetSetting assetSetting = new assetSetting();

            assetSetting.enable = 0;
            if (data.Length > 0)
            {
                assetSetting = data.Deserialize() as assetSetting;
            }

            return(assetSetting);
        }
Exemple #4
0
        public static bool GetMoneyBack(byte[] who, byte[] assetHash, BigInteger amount)
        {
            StorageMap   balanceMap   = Storage.CurrentContext.CreateMap("balanceMap");
            assetSetting assetSetting = getAssetSetting(assetHash);

            if (!Runtime.CheckWitness(who) && !checkSpuerAdmin())
            {
                throw new InvalidOperationException("error");
            }
            //多判断总比少判断好
            if (amount <= 0)
            {
                throw new InvalidOperationException("error");
            }
            if (who.Length != 20)
            {
                throw new InvalidOperationException("error");
            }

            var balance = balanceMap.Get(who.Concat(assetHash)).AsBigInteger();

            if (balance < amount)
            {
                throw new InvalidOperationException("error");
            }

            //NEP5转出
            bool result = NEP5transfer(ExecutionEngine.ExecutingScriptHash, who, assetHash, amount);

            if (result)
            {
                if (balance == amount)
                {
                    balanceMap.Delete(who.Concat(assetHash));
                }
                else
                {
                    balance -= amount;
                    balanceMap.Put(who.Concat(assetHash), balance);
                }

                onGetMoneyBack(who, assetHash, amount);
                return(true);
            }

            throw new InvalidOperationException("error");
        }
Exemple #5
0
        /// <summary>
        /// 拍卖某个域名
        /// </summary>
        /// <param name="domainArray"></param>
        /// <param name="startPrice"></param>
        /// <param name="endPrice"></param>
        /// <param name="ratio"></param>
        /// <returns></returns>
        public static bool Auction(string[] domainArray, byte[] assetHash, BigInteger startPrice, BigInteger endPrice, BigInteger salePrice, BigInteger mortgagePayments)
        {
            //不允许的资产不能定价
            assetSetting assetSetting = getAssetSetting(assetHash);

            if (assetSetting.enable != 1)
            {
                throw new InvalidOperationException("error");
            }

            //价格必须大于0
            if (startPrice <= 0 || endPrice <= 0 || endPrice > startPrice)
            {
                throw new InvalidOperationException("error");
            }

            //合约限制最小价格为0.1,并且小数点后面不能超过一位(按照精度2换算),NNC为10
            if (startPrice < assetSetting.valueMin || startPrice % assetSetting.valueUnit > 0 || endPrice < assetSetting.valueMin || endPrice % assetSetting.valueUnit > 0)
            {
                throw new InvalidOperationException("error");
            }
            //限制每次降价的精度
            if ((salePrice < assetSetting.valueMin || salePrice % assetSetting.valueUnit > 0) && salePrice != 0)
            {
                throw new InvalidOperationException("error");
            }

            //验证押金
            BigInteger minMortgagePayments = getSysSetting("minMortgagePayments").AsBigInteger();

            if (mortgagePayments < minMortgagePayments)
            {
                throw new InvalidOperationException("error");
            }

            byte[] fullHash = NameHashArray(domainArray);
            //先获取这个域名的信息
            OwnerInfo ownerInfo = GetOwnerInfo(fullHash);
            var       auctioner = ownerInfo.owner;

            //域名没有初始化不能上架
            if (ownerInfo.owner.Length == 0)
            {
                throw new InvalidOperationException("error");
            }
            //域名已经到期了不能上架
            if (!verifyExpires(ownerInfo.TTL))
            {
                throw new InvalidOperationException("error");
            }
            //验证权限
            if (!Runtime.CheckWitness(auctioner))
            {
                throw new InvalidOperationException("error");
            }

            //将域名抵押给本合约(域名所有权:卖家=>DEX合约)
            //本合约的scripthash
            byte[]      scriptHash = ExecutionEngine.ExecutingScriptHash;
            deleDyncall centerCall = (deleDyncall)getSysSetting("domainCenterHash").ToDelegate();
            var         result     = (byte[])centerCall("owner_SetOwner", new object[3] {
                auctioner, fullHash, scriptHash
            });

            if (result.AsBigInteger() != 1)
            {
                throw new InvalidOperationException("error");
            }

            //扣除押金
            var        mortgageAssetHash = getSysSetting("mortgageAssetHash");
            StorageMap balanceMap        = Storage.CurrentContext.CreateMap("balanceMap");
            var        balanceOfBuyer    = balanceMap.Get(auctioner.Concat(mortgageAssetHash)).AsBigInteger();

            balanceOfBuyer = balanceOfBuyer - mortgagePayments;
            if (balanceOfBuyer > 0)
            {
                balanceMap.Put(auctioner.Concat(mortgageAssetHash), balanceOfBuyer);
            }
            else if (balanceOfBuyer == 0)
            {
                balanceMap.Delete(auctioner.Concat(mortgageAssetHash));
            }
            else
            {
                throw new Exception("no money");
            }
            onDexTransfer(auctioner, new byte[] { }, mortgageAssetHash, mortgagePayments);
            //获取开始拍卖的时间戳
            var timeStamp = Blockchain.GetHeader(Blockchain.GetHeight()).Timestamp;
            //获取交易id
            var auctionid = (ExecutionEngine.ScriptContainer as Transaction).Hash;
            //记录拍卖的信息
            AuctionInfo auctionInfo = new AuctionInfo()
            {
                auctionid        = auctionid,
                fullDomain       = getFullStrForArray(domainArray),
                fullHash         = fullHash,
                auctioner        = auctioner,
                startPrice       = startPrice,
                endPrice         = endPrice,
                salePrice        = salePrice,
                startTimeStamp   = timeStamp,
                assetHash        = assetHash,
                mortgagePayments = mortgagePayments,
            };
            StorageMap auctionInfoMap = Storage.CurrentContext.CreateMap("auctionInfoMap");

            //如果已经存在这个id报错
            if (auctionInfoMap.Get(auctionid).Length != 0)
            {
                throw new Exception("error");
            }
            auctionInfoMap.Put(auctionid, auctionInfo.Serialize());
            //记录当前这个域名正在拍卖的场次是什么
            StorageMap auctionInfoCurrentMap = Storage.CurrentContext.CreateMap("auctionInfoCurrentMap");

            auctionInfoCurrentMap.Put(fullHash, auctionid);
            onAuction(auctionInfo);
            return(true);
        }
Exemple #6
0
        /// <summary>
        /// 出售
        /// </summary>
        /// <param name="buyer">求购者</param>
        /// <param name="fullHash"></param>
        /// <param name="assetHash"></param>
        /// <returns></returns>
        public static bool Sell(byte[] offerid)
        {
            //获取求购信息
            OfferToBuyInfo offerToBuyInfo = GetOfferToBuyInfo(offerid);

            if (offerToBuyInfo.fullHash.Length == 0)//没求购过别浪费时间了
            {
                throw new InvalidOperationException("error");
            }
            var fullHash  = offerToBuyInfo.fullHash;
            var buyer     = offerToBuyInfo.buyer;
            var assetHash = offerToBuyInfo.assetHash;
            //先获取这个域名的信息
            OwnerInfo ownerInfo = GetOwnerInfo(fullHash);

            if (ownerInfo.owner.Length == 0 || !verifyExpires(ownerInfo.TTL))//验证域名是否有效
            {
                throw new InvalidOperationException("error");
            }
            //验证权限
            var seller = ownerInfo.owner;

            if (!Runtime.CheckWitness(seller))
            {
                throw new InvalidOperationException("error");
            }
            //进行域名的转让操作(域名所有权:卖家=>买家)
            deleDyncall centerCall = (deleDyncall)getSysSetting("domainCenterHash").ToDelegate();

            var result = (byte[])centerCall("owner_SetOwner", new object[3] {
                seller, fullHash, buyer
            });

            if (result.AsBigInteger() != 1) //如果域名所有权转移失败,返回失败
            {
                throw new InvalidOperationException("error");
            }

            //把钱转给卖家
            assetSetting assetSetting    = getAssetSetting(assetHash);
            BigInteger   handlingFee     = offerToBuyInfo.price * assetSetting.handlingFeeRate / fixedNumber; //handlingFeeRate是事先乘10000存储的
            StorageMap   balanceMap      = Storage.CurrentContext.CreateMap("balanceMap");
            var          balanceOfSeller = balanceMap.Get(seller.Concat(assetHash)).AsBigInteger();           //卖家

            balanceOfSeller = balanceOfSeller + offerToBuyInfo.price - handlingFee;
            //给卖方增加钱(扣除手续费)
            balanceMap.Put(seller.Concat(assetHash), balanceOfSeller);
            onDexTransfer(new byte[] { }, seller, assetHash, offerToBuyInfo.price - handlingFee);

            //转移手续费
            //发送手续费到分红池
            if (handlingFee > 0)
            {
                if (!NEP5transfer(ExecutionEngine.ExecutingScriptHash, getSysSetting("dividingPoolAddr"), assetHash, handlingFee))
                {
                    throw new Exception("NEP5transfer is wrong");
                }
            }

            //把押金还给买家
            var mortgageAssetHash = getSysSetting("mortgageAssetHash");
            var nncBalanceOfOffer = balanceMap.Get(buyer.Concat(mortgageAssetHash)).AsBigInteger();

            nncBalanceOfOffer += offerToBuyInfo.mortgagePayments;
            balanceMap.Put(buyer.Concat(mortgageAssetHash), nncBalanceOfOffer);
            onDexTransfer(new byte[] { }, buyer, mortgageAssetHash, offerToBuyInfo.mortgagePayments);
            //删除此条求购信息
            DeleteOfferToBuyInfo(offerid);
            //通知
            onSell(seller, offerToBuyInfo);
            return(true);
        }
Exemple #7
0
        /// <summary>
        /// 求购
        /// </summary>
        /// <param name="fullhash"></param>
        /// <param name="price"></param>
        /// <returns></returns>
        public static bool OfferToBuy(byte[] buyer, string[] domainArray, byte[] assetHash, BigInteger price, BigInteger MortgagePayments)
        {
            if (!Runtime.CheckWitness(buyer))
            {
                throw new InvalidOperationException("error");
            }
            if (price <= 0)
            {
                throw new InvalidOperationException("error");
            }

            //不允许的资产不能定价
            assetSetting assetSetting = getAssetSetting(assetHash);

            if (assetSetting.enable != 1)
            {
                throw new InvalidOperationException("error");
            }
            //价格必须大于0
            if (price <= 0)
            {
                throw new InvalidOperationException("error");
            }
            //支付的抵押金数额必须大于
            BigInteger minMortgagePayments = getSysSetting("minMortgagePayments").AsBigInteger();

            if (MortgagePayments < minMortgagePayments)
            {
                throw new InvalidOperationException("error");
            }

            //合约限制最小价格为0.1,并且小数点后面不能超过一位(按照精度2换算),NNC为10
            if (price < assetSetting.valueMin || price % assetSetting.valueUnit > 0)
            {
                throw new InvalidOperationException("error");
            }
            //获取域名的fullhash
            byte[] fullHash = NameHashArray(domainArray);
            //获取这个交易的txid
            byte[] offerid = (ExecutionEngine.ScriptContainer as Transaction).Hash;
            //获取求购信息
            OfferToBuyInfo offerToBuyInfo = GetOfferToBuyInfo(offerid);

            if (offerToBuyInfo.fullHash.Length != 0)//已经有了这个资产的求购信息  同资产只能有一个求购
            {
                throw new InvalidOperationException("error");
            }
            //先获取这个域名的信息
            OwnerInfo ownerInfo = GetOwnerInfo(fullHash);

            //域名没有初始化或者已经到期了不能求购    ???????先写着  再想想有没有必要限制
            if (ownerInfo.owner.Length == 0 || !verifyExpires(ownerInfo.TTL))
            {
                throw new InvalidOperationException("error");
            }
            //不能求购属于自己的合约
            if (buyer == ownerInfo.owner)
            {
                throw new InvalidOperationException("error");
            }
            //看看有没有这么多钱
            StorageMap balanceMap     = Storage.CurrentContext.CreateMap("balanceMap");
            var        balanceOfBuyer = balanceMap.Get(buyer.Concat(assetHash)).AsBigInteger();

            balanceOfBuyer = balanceOfBuyer - price;
            //扣钱
            if (balanceOfBuyer > 0)
            {
                balanceMap.Put(buyer.Concat(assetHash), balanceOfBuyer);
            }
            else if (balanceOfBuyer == 0)
            {
                balanceMap.Delete(buyer.Concat(assetHash));
            }
            else
            {
                throw new InvalidOperationException("error");
            }
            onDexTransfer(buyer, new byte[] { }, assetHash, price);

            //扣除抵押金
            var mortgageAssetHash = getSysSetting("mortgageAssetHash");
            var nncBalanceOfBuyer = balanceMap.Get(buyer.Concat(mortgageAssetHash)).AsBigInteger();

            //var nncBalanceOfContract = balanceMap.Get(ExecutionEngine.ExecutingScriptHash.Concat(nncHash)).AsBigInteger();
            nncBalanceOfBuyer = nncBalanceOfBuyer - MortgagePayments;
            if (nncBalanceOfBuyer > 0)
            {
                balanceMap.Put(buyer.Concat(mortgageAssetHash), nncBalanceOfBuyer);
            }
            else if (nncBalanceOfBuyer == 0)
            {
                balanceMap.Delete(buyer.Concat(mortgageAssetHash));
            }
            else
            {
                throw new InvalidOperationException("error");
            }
            onDexTransfer(buyer, new byte[] { }, mortgageAssetHash, MortgagePayments);

            //更新这个域名的求购信息
            offerToBuyInfo = new OfferToBuyInfo {
                offerid = offerid, fullHash = fullHash, buyer = buyer, assetHash = assetHash, price = price, fullDomain = getFullStrForArray(domainArray), mortgagePayments = MortgagePayments
            };
            PutOfferToBuyInfo(offerid, offerToBuyInfo);
            onOfferToBuy(offerToBuyInfo);
            return(true);
        }
Exemple #8
0
        /// <summary>
        /// 竞拍
        /// </summary>
        /// <param name="fullHash"></param>
        /// <param name="price">价格,价格合约内计算,但是要求传入是以防前端计算错误误导用户</param>
        /// <returns></returns>
        public static bool Bet(byte[] buyer, byte[] auctionid, byte[] assetHash, BigInteger price)
        {
            if (!Runtime.CheckWitness(buyer))
            {
                throw new InvalidOperationException("error");
            }
            //获取域名的拍卖情况
            AuctionInfo auctionInfo = GetAuctionInfo(auctionid);

            //自己不能竞拍自己上架的域名
            if (buyer == auctionInfo.auctioner)
            {
                throw new InvalidOperationException("error");
            }
            if (auctionInfo.fullDomain == "")
            {
                throw new InvalidOperationException("error");
            }
            //验证资产种类
            if (auctionInfo.assetHash != assetHash)
            {
                throw new InvalidOperationException("error");
            }
            //获取当前的时间戳
            var currentTimeStamp = Blockchain.GetHeader(Blockchain.GetHeight()).Timestamp;
            //距离开始拍卖已经过了多久
            var timeStamp = currentTimeStamp - auctionInfo.startTimeStamp;

            //获取降价的间隔
            var interval = getSysSetting("interval").AsBigInteger();

            //X小时一轮 开拍为0阶段  X小时后为1阶段 X*2小时后为2阶段    X*60*60
            var phase = timeStamp / interval;
            //计算当前的价格
            var currentPrice = auctionInfo.startPrice - auctionInfo.salePrice * phase;

            if (currentPrice < auctionInfo.endPrice)
            {
                currentPrice = auctionInfo.endPrice;
            }
            //对比下用户从前端获取到的价格
            if (price != currentPrice)
            {
                throw new InvalidOperationException("error");
            }
            //检查用户钱够不够
            StorageMap balanceMap     = Storage.CurrentContext.CreateMap("balanceMap");
            var        balanceOfBuyer = balanceMap.Get(buyer.Concat(assetHash)).AsBigInteger();//买家

            if (balanceOfBuyer < price)
            {
                throw new InvalidOperationException("error");
            }

            //合约将域名转让给买家
            byte[]      scriptHash = ExecutionEngine.ExecutingScriptHash;
            deleDyncall centerCall = (deleDyncall)getSysSetting("domainCenterHash").ToDelegate();
            var         result     = (byte[])centerCall("owner_SetOwner", new object[3] {
                scriptHash, auctionInfo.fullHash, buyer
            });

            if (result.AsBigInteger() != 1)
            {
                throw new InvalidOperationException("error");
            }

            //购买者扣钱
            balanceOfBuyer = balanceOfBuyer - price;
            if (balanceOfBuyer == 0)
            {
                balanceMap.Delete(buyer.Concat(assetHash));
            }
            else
            {
                balanceMap.Put(buyer.Concat(assetHash), balanceOfBuyer);
            }
            onDexTransfer(buyer, new byte[] { }, assetHash, price);

            //转钱给拍卖者
            //计算手续费
            assetSetting assetSetting = getAssetSetting(assetHash);
            BigInteger   handlingFee  = price * assetSetting.handlingFeeRate / fixedNumber;//handlingFeeRate是事先乘10000存储的
            //给卖方增加钱(扣除手续费)
            var auctioner          = auctionInfo.auctioner;
            var balanceOfAuctioner = balanceMap.Get(auctioner.Concat(assetHash)).AsBigInteger();

            balanceMap.Put(auctioner.Concat(assetHash), balanceOfAuctioner + price - handlingFee);
            onDexTransfer(new byte[] { }, auctioner, assetHash, price - handlingFee);
            //归还卖方的抵押金
            var mortgageAssetHash     = getSysSetting("mortgageAssetHash");
            var nncBalanceOfAuctioner = balanceMap.Get(auctioner.Concat(mortgageAssetHash)).AsBigInteger();

            balanceMap.Put(auctioner.Concat(mortgageAssetHash), nncBalanceOfAuctioner + auctionInfo.mortgagePayments);
            onDexTransfer(new byte[] { }, auctioner, mortgageAssetHash, auctionInfo.mortgagePayments);

            if (handlingFee > 0)
            {
                if (!NEP5transfer(ExecutionEngine.ExecutingScriptHash, getSysSetting("dividingPoolAddr"), assetHash, handlingFee))
                {
                    throw new Exception("NEP5transfer is wrong");
                }
            }


            //删除拍卖信息
            StorageMap auctionInfoMap = Storage.CurrentContext.CreateMap("auctionInfoMap");

            auctionInfoMap.Delete(auctionid);
            onBet(auctionInfo, buyer, price);
            return(true);
        }