public static bool wantBuy(byte[] hash, string domainname) { var domaininfo = getOwnerInfo(hash); //先看这个域名归我管不 if (domaininfo.register.AsBigInteger() != ExecutionEngine.ExecutingScriptHash.AsBigInteger()) { return(false); } //再看看域名能不能拍卖 var fullhash = nameHashSub(hash, domainname); var inuse = getDomainUseState(fullhash); if (inuse == DomainUseState.InUse) { return(false); } //再看看有没有在拍卖 var selling = getSellingStateByFullhash(fullhash); if (selling.startBlockSelling > 0) //已经在拍卖中了 { if (testEnd(selling) == false) //拍卖未结束不准 { return(false); } if (selling.maxBuyer.Length > 0)//未流拍的拍卖,一年内不得再拍 { var nowtime = Blockchain.GetHeader(Blockchain.GetHeight()).Timestamp; var starttime = Blockchain.GetHeader((uint)selling.startBlockSelling).Timestamp; if ((nowtime - starttime) < secondyear) { return(false); } } } SellingState sell = new SellingState(); sell.parenthash = hash; sell.domain = domainname; sell.domainTTL = domaininfo.TTL; sell.startBlockSelling = Blockchain.GetHeight();//开始拍卖了 //sell.startBlockRan = 0;//随机块现在还不能确定 sell.endBlock = 0; sell.maxPrice = 0; sell.maxBuyer = new byte[0]; sell.lastBlock = 0; var txid = (ExecutionEngine.ScriptContainer as Transaction).Hash; sell.id = txid; saveSellingState(sell); onSellingState(sell); return(true); }
public static SellingState getSellingStateByTXID(byte[] txid) { var data = Storage.Get(Storage.CurrentContext, new byte[] { 0x02 }.Concat(txid)); SellingState state = new SellingState(); state.id = txid; int seek = 0; int len = 0; len = (int)data.Range(seek, 2).AsBigInteger(); seek += 2; state.parenthash = data.Range(seek, len); seek += len; len = (int)data.Range(seek, 2).AsBigInteger(); seek += 2; state.domain = data.Range(seek, len).AsString(); seek += len; len = (int)data.Range(seek, 2).AsBigInteger(); seek += 2; state.domainTTL = data.Range(seek, len).AsBigInteger(); seek += len; len = (int)data.Range(seek, 2).AsBigInteger(); seek += 2; state.startBlockSelling = data.Range(seek, len).AsBigInteger(); seek += len; //len = (int)data.Range(seek, 2).AsBigInteger(); //seek += 2; //state.startBlockRan = data.Range(seek, len).AsBigInteger(); //seek += len; len = (int)data.Range(seek, 2).AsBigInteger(); seek += 2; state.endBlock = data.Range(seek, len).AsBigInteger(); seek += len; len = (int)data.Range(seek, 2).AsBigInteger(); seek += 2; state.maxPrice = data.Range(seek, len).AsBigInteger(); seek += len; len = (int)data.Range(seek, 2).AsBigInteger(); seek += 2; state.maxBuyer = data.Range(seek, len); seek += len; len = (int)data.Range(seek, 2).AsBigInteger(); seek += 2; state.lastBlock = data.Range(seek, len).AsBigInteger(); seek += len; return(state); }
private static bool testEnd(SellingState selling) { if (selling.startBlockSelling == 0)//就没开始过 { return(false); } if (selling.endBlock > 0)//已经结束了 { return(false); } var nowtime = Blockchain.GetHeader(Blockchain.GetHeight()).Timestamp; var starttime = Blockchain.GetHeader((uint)selling.startBlockSelling).Timestamp; var step2time = starttime + secondday * 2; var steprantime = starttime + secondday * 3; var endtime = starttime + secondday * 5; if (nowtime < steprantime)//随机期都没到,肯定没结束 { return(false); } if (nowtime > endtime)//毫无悬念结束了 { selling.endBlock = Blockchain.GetHeight(); saveSellingState(selling); onSellingState(selling); return(true); } var lasttime = Blockchain.GetHeader((uint)selling.lastBlock).Timestamp; if (lasttime < step2time)//阶段2没出过价 { selling.endBlock = Blockchain.GetHeight(); saveSellingState(selling); onSellingState(selling); return(true); } //随机期 var nowheader = Blockchain.GetHeader(Blockchain.GetHeight()); //得到当前块在整个随机期所处的位置 var persenttime = (nowheader.Timestamp - steprantime) * 1000 / (endtime - steprantime); //当处于10%位置的时候,只有10%的几率结束 if ((nowheader.ConsensusData % 1000) < persenttime) //随机数小于块位置 { selling.endBlock = nowheader.Index;; //突然死亡,无法出价了 saveSellingState(selling); onSellingState(selling); return(true); } //走到这里都没死,那就允许你出价,这里是随机期 return(false); }
private static void saveSellingState(SellingState state) { var fullhash = nameHashSub(state.parenthash, state.domain); byte[] _id = Storage.Get(Storage.CurrentContext, new byte[] { 0x01 }.Concat(fullhash)); if (_id.AsBigInteger() != state.id.AsBigInteger())//没存过ID { Storage.Put(Storage.CurrentContext, new byte[] { 0x01 }.Concat(fullhash), state.id); } var key = new byte[] { 0x02 }.Concat(state.id); var doublezero = new byte[] { 0, 0 }; var data = state.parenthash; var datalen = ((BigInteger)data.Length).AsByteArray().Concat(doublezero).Range(0, 2); var value = datalen.Concat(data); data = state.domain.AsByteArray(); datalen = ((BigInteger)data.Length).AsByteArray().Concat(doublezero).Range(0, 2); value = value.Concat(datalen).Concat(data); data = state.domainTTL.AsByteArray(); datalen = ((BigInteger)data.Length).AsByteArray().Concat(doublezero).Range(0, 2); value = value.Concat(datalen).Concat(data); data = state.startBlockSelling.AsByteArray(); datalen = ((BigInteger)data.Length).AsByteArray().Concat(doublezero).Range(0, 2); value = value.Concat(datalen).Concat(data); //data = state.startBlockRan.AsByteArray(); //datalen = ((BigInteger)data.Length).AsByteArray().Concat(doublezero).Range(0, 2); //value = value.Concat(datalen).Concat(data); data = state.endBlock.AsByteArray(); datalen = ((BigInteger)data.Length).AsByteArray().Concat(doublezero).Range(0, 2); value = value.Concat(datalen).Concat(data); data = state.maxPrice.AsByteArray(); datalen = ((BigInteger)data.Length).AsByteArray().Concat(doublezero).Range(0, 2); value = value.Concat(datalen).Concat(data); data = state.maxBuyer; datalen = ((BigInteger)data.Length).AsByteArray().Concat(doublezero).Range(0, 2); value = value.Concat(datalen).Concat(data); data = state.lastBlock.AsByteArray(); datalen = ((BigInteger)data.Length).AsByteArray().Concat(doublezero).Range(0, 2); value = value.Concat(datalen).Concat(data); onSellingState(state); Storage.Put(Storage.CurrentContext, key, value); }
public static SellingState getSellingStateByFullhash(byte[] fullhash) { //需要保存每一笔拍卖记录,因为过去拍卖者的资金都要锁定在这里 byte[] id = Storage.Get(Storage.CurrentContext, new byte[] { 0x01 }.Concat(fullhash)); if (id.Length == 0)//没在销售中 { SellingState _state = new SellingState(); _state.id = new byte[0]; _state.startBlockSelling = 0; return(_state); } return(getSellingStateByTXID(id)); }