/// <summary> /// 存储求购信息 /// </summary> /// <param name="fullHash"></param> /// <param name="map"></param> /// <returns></returns> public static bool PutOfferToBuyInfo(byte[] offerid, OfferToBuyInfo map) { StorageMap offerToBuyInfoMap = Storage.CurrentContext.CreateMap("offerToBuyInfoMap"); offerToBuyInfoMap.Put(offerid, map.Serialize()); return(true); }
/// <summary> /// 撤销上架的求购 /// </summary> /// <param name="buyer"></param> /// <param name="fullHash"></param> /// <param name="assetHash"></param> /// <returns></returns> public static bool DiscontinueOfferToBuy(byte[] offerid) { //获取求购信息 OfferToBuyInfo offerToBuyInfo = GetOfferToBuyInfo(offerid); if (offerToBuyInfo.fullHash.Length == 0)//没求购过别浪费时间了 { throw new InvalidOperationException("error"); } var buyer = offerToBuyInfo.buyer; var assetHash = offerToBuyInfo.assetHash; var fullHash = offerToBuyInfo.fullHash; //验证权限 if (!Runtime.CheckWitness(buyer) && !checkSpuerAdmin()) { throw new InvalidOperationException("error"); } //把钱退给求购者 var price = offerToBuyInfo.price; StorageMap balanceMap = Storage.CurrentContext.CreateMap("balanceMap"); //var balanceOfContract = balanceMap.Get(ExecutionEngine.ExecutingScriptHash.Concat(assetHash)).AsBigInteger();//合约 var balanceOfBuyer = balanceMap.Get(buyer.Concat(assetHash)).AsBigInteger(); //求购者 //玩家加钱 balanceOfBuyer = balanceOfBuyer + price; balanceMap.Put(buyer.Concat(assetHash), balanceOfBuyer); onDexTransfer(new byte[] { }, buyer, assetHash, price); //归还抵押金 var mortgageAssetHash = getSysSetting("mortgageAssetHash"); var mortgagePayments = offerToBuyInfo.mortgagePayments; var nncBalanceOfBuyer = balanceMap.Get(buyer.Concat(mortgageAssetHash)).AsBigInteger(); //求购者 nncBalanceOfBuyer = nncBalanceOfBuyer + mortgagePayments; balanceMap.Put(buyer.Concat(mortgageAssetHash), nncBalanceOfBuyer); onDexTransfer(new byte[] { }, buyer, mortgageAssetHash, mortgagePayments); onOfferToBuyDiscontinued(offerToBuyInfo);//通知 return(DeleteOfferToBuyInfo(offerid)); }
/// <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); }
/// <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); }