// 修改飞机所属者 // 可用于购买飞机 // Failure 0x11 / 0x12 / 0x16 // Success 0x01 public static byte[] ChangeOwner(BigInteger tokenId, byte[] fromOwner, byte[] toOwner) { byte[] aircraftInfo = Storage.Get(Storage.CurrentContext, tokenId.AsByteArray()); if (aircraftInfo.Length == 0) { ChangeOwnerLog(tokenId, fromOwner, toOwner); return(new byte[] { 0x11 }); } Aircraft aircraft = (Aircraft)Helper.Deserialize(aircraftInfo); if (aircraft.owner != fromOwner) { ChangeOwnerLog(tokenId, fromOwner, toOwner); return(new byte[] { 0x12 }); } BigInteger currentTimestamp = Blockchain.GetHeader(Blockchain.GetHeight()).Timestamp; if (aircraft.auctionTime < currentTimestamp) { ChangeOwnerLog(tokenId, fromOwner, toOwner); return(new byte[] { 0x16 }); } // 执行所属转移 aircraft.owner = toOwner; aircraft.auctionTime = 1525104000; // 较早的时间戳,清除售卖中状态 byte[] aircraftData = Helper.Serialize(aircraft); Storage.Put(Storage.CurrentContext, tokenId.AsByteArray(), aircraftData); ChangeOwnerLog(tokenId, fromOwner, toOwner); return(new byte[] { 0x01 }); }
// 系统产出飞机,系统创建的飞机初始只属于系统账号 // 此处的prefix,不包含正式token中的最后三位标识数量 // Failure 0x14 / 0x15 // Success 0x01 private static byte[] InitAircraft(BigInteger tokenPrefix, byte[] ownerId) { BigInteger tokenId = _getNextTokenId(tokenPrefix); if (tokenId == -1) { // 没有库存了,不能创建该颜色类型飞机 BirthedLog(-1, ownerId); return(new byte[] { 0x14 }); } byte[] tokenIdKey = tokenId.AsByteArray(); var existingAircraft = Storage.Get(Storage.CurrentContext, tokenIdKey); if (existingAircraft.Length == 0) { Aircraft newAircraft = new Aircraft(); newAircraft.Id = tokenId; newAircraft.owner = ownerId; newAircraft.level = 1; newAircraft.auctionTime = 1525104000; // 较早的时间戳 newAircraft.price = 100; byte[] aircraftData = Helper.Serialize(newAircraft); Storage.Put(Storage.CurrentContext, tokenIdKey, aircraftData); BirthedLog(tokenId, ownerId); return(new byte[] { 0x01 }); } else { BirthedLog(-1, ownerId); return(new byte[] { 0x15 }); } }
public static byte[] InAuction(BigInteger tokenId, byte[] owner, int price) { byte[] aircraftInfo = Storage.Get(Storage.CurrentContext, tokenId.AsByteArray()); if (aircraftInfo.Length == 0) { InAuctionLog(tokenId, owner, price, -1); return(new byte[] { 0x11 }); } Aircraft aircraft = (Aircraft)Helper.Deserialize(aircraftInfo); if (aircraft.owner != owner) { InAuctionLog(tokenId, owner, price, -1); return(new byte[] { 0x12 }); } aircraft.price = price; // 当前时间增加三天,单位为秒 aircraft.auctionTime = Blockchain.GetHeader(Blockchain.GetHeight()).Timestamp + 3 * 24 * 60 * 60; byte[] aircraftData = Helper.Serialize(aircraft); Storage.Put(Storage.CurrentContext, tokenId.AsByteArray(), aircraftData); InAuctionLog(tokenId, owner, price, aircraft.auctionTime); return(new byte[] { 0x01 }); }
public static byte[] create(byte[] invoker, byte[][] owners, byte[] theOperator, byte[] nonce) { BasicMethods.assert(Runtime.CheckWitness(invoker), "CheckWitness failed"); BasicMethods.assert(BasicMethods._isLegalAddresses(owners), "owners addresses are not byte20"); BasicMethods.assert(BasicMethods._isLegalAddress(theOperator), "the operator is not byte20"); //TODO: no need to check the nonce byte[] length _whenNotPaused(); BasicMethods.assert(BasicMethods._isLegalAddress(theOperator), "New operator is address zero"); byte[] SelfContractHash = ExecutionEngine.ExecutingScriptHash; byte[] concatRes = SelfContractHash.Concat(invoker).Concat(nonce); byte[] walletId = SmartContract.Sha256(concatRes); BasicMethods.assert(getWallet(walletId).theOperator == null, "Occupied wallet id"); Wallet w = new Wallet(); BasicMethods.assert(BasicMethods._isLegalAddresses(owners), "owners contains illegal address"); w.owners = owners; w.theOperator = theOperator; BigInteger walletNum = Storage.Get(Storage.CurrentContext, WalletNum).AsBigInteger(); Storage.Put(Storage.CurrentContext, WalletNum, (walletNum + 1).AsByteArray()); Storage.Put(Storage.CurrentContext, WalletsPrefix.Concat(walletId), Helper.Serialize(w)); CreateWallet(walletId, owners, theOperator); return(walletId); }
public static bool setRWProperties(BigInteger tokenID, string rwProperties) { if (!isOpen() && !Runtime.CheckWitness(superAdmin)) { return(false); } StorageMap tokenMap = Storage.CurrentContext.CreateMap("token"); var data = tokenMap.Get(tokenID.AsByteArray()); if (data.Length > 0) { Token token = Helper.Deserialize(data) as Token; if (!Runtime.CheckWitness(token.owner) && !Runtime.CheckWitness(superAdmin)) { return(false); } token.rwProperties = rwProperties; tokenMap.Put(token.token_id.AsByteArray(), Helper.Serialize(token)); onNFTModify(tokenID, "rwProperties", rwProperties); return(true); } return(false); }
/** * 游戏币交换 */ public static bool transferABC(byte[] from, byte[] to, BigInteger tokenId, BigInteger pabc, BigInteger value) { bool bol = false; if (from.Length == 20 && to.Length == 20 && pabc > 0 && value > 0) { UserInfo fromUser = getUserInfo(from); UserInfo toUser = getUserInfo(to); if (fromUser.balance >= pabc && toUser.gold >= value) { fromUser.balance -= pabc; fromUser.gold += value; toUser.balance += pabc; toUser.gold -= value; byte[] keyfrom = new byte[] { 0x11 }.Concat(from); byte[] keyto = new byte[] { 0x11 }.Concat(to); Storage.Put(Storage.CurrentContext, keyfrom, Helper.Serialize(fromUser)); Storage.Put(Storage.CurrentContext, keyto, Helper.Serialize(toUser)); bol = true; } if (bol == true) { TransferABCed(1, from, to, tokenId, pabc, value); } else { TransferABCed(0, from, to, tokenId, pabc, value); } } return(bol); }
public static bool initToken(byte[] addr) { if (addr.Length != 20) { throw new InvalidOperationException("The parameter addr SHOULD be 20-byte addresses."); } //check SAR if (!checkState(SAR_STATE)) { throw new InvalidOperationException("The sar state MUST be pause."); } var key = getSARKey(addr); byte[] sar = Storage.Get(Storage.CurrentContext, key); if (sar.Length == 0) { throw new InvalidOperationException("The sar must not be null."); } SARInfo info = (SARInfo)Helper.Deserialize(sar); Storage.Put(Storage.CurrentContext, key, Helper.Serialize(info)); var txid = ((Transaction)ExecutionEngine.ScriptContainer).Hash; Operated(info.name.AsByteArray(), addr, info.txid, txid, (int)ConfigTranType.TRANSACTION_TYPE_INIT, 0); Nep55Operated(info.name.AsByteArray(), addr, info.txid, info.anchor.AsByteArray(), info.symbol.AsByteArray(), info.decimals); return(true); }
public static BigInteger GenerateAlien(string alienName, byte[] owner) { if (owner.Length != 20 && owner.Length != 33) { throw new InvalidOperationException("The parameter owner should be a 20-byte address or a 33-byte public key"); } // Check if the owner is the same as one who invoked contract if (!Runtime.CheckWitness(owner)) { return(false); } uint xna = FindXna(RandomNumber()); Alien someAlien = new Alien { Xna = xna, AlienName = alienName, Id = updateCounter(), Owner = owner }; // add the object to storage StorageMap alienMap = Storage.CurrentContext.CreateMap(nameof(alienMap)); alienMap.Put(someAlien.Id.ToByteArray(), Helper.Serialize(someAlien)); OnAlienGenerated(someAlien.Id); // save the id to the specified account Storage.Put(owner, someAlien.Id); return(someAlien.Id); }
public static void SaveGame(Game game) { var key = KeysFactory.GameId(game.Id); var serialized = Helper.Serialize(game); Storage.Put(Storage.CurrentContext, key, serialized); }
public static bool transferFrom(byte[] addrTo, BigInteger tokenID) { if (addrTo.Length != 20) { return(false); } StorageMap tokenMap = Storage.CurrentContext.CreateMap("token"); var data = tokenMap.Get(tokenID.AsByteArray()); if (data.Length > 0) { Token token = Helper.Deserialize(data) as Token; if (!Runtime.CheckWitness(token.approved) && !Runtime.CheckWitness(superAdmin)) { return(false); } var addrFrom = token.owner; token.owner = addrTo; tokenMap.Put(tokenID.AsByteArray(), Helper.Serialize(token)); addrNFTlistRemove(addrFrom, tokenID); addrNFTlistAdd(addrTo, tokenID); onTransfer(addrFrom, addrTo, 1); onNFTTransfer(addrFrom, addrTo, tokenID); return(true); } return(false); }
public static bool IssueBond(string bondName, uint parValue, uint purchaseEndTime, uint interval, uint round, uint couponRate, ulong totalCap, byte[] Account) { if (!Runtime.CheckWitness(admin)) { return(false); } if (purchaseEndTime <= Runtime.Time) { return(false); } if (totalCap < minIssueCap || round < minRound || couponRate <= 0 || interval < minInterval) { return(false); } if (!validateAddress(Account)) { return(false); } BondItem bond = new BondItem(); bond.ParValue = parValue; bond.purchaseEndTime = purchaseEndTime; bond.CouponRate = couponRate; bond.Interval = interval; bond.TotalCap = totalCap; bond.remainCap = totalCap; bond.Round = round; bond.Maturity = purchaseEndTime + round * interval; byte[] b = Helper.Serialize(bond); Storage.Put(Storage.CurrentContext, bondPrefix.Concat(bondName.AsByteArray()), b); return(true); }
// 可以动态发行一个新的资产 private static bool Deploy(BigInteger anftid, BigInteger atype, BigInteger atotal_amount, BigInteger aprice) { if (!Runtime.CheckWitness(Owner)) { return(false); } StorageMap nftinfo = Storage.CurrentContext.CreateMap(nameof(nftinfo)); byte[] ni = nftinfo.Get(anftid.AsByteArray()); if (ni != null && ni.Length != 0) { return(false); } NftInfo info = new NftInfo { nftid = anftid, type = atype, total_amount = atotal_amount, price = aprice, total_supply = 0, canbuy = true }; nftinfo.Put(anftid.AsByteArray(), Helper.Serialize(info)); return(true); }
public static object addPauser(byte[] invoker, byte[] account) { BasicMethods.assert(Runtime.CheckWitness(invoker), "Checkwitness failed"); // make sure the invoker is one effective pauser Map <byte[], bool> pausers = new Map <byte[], bool>(); byte[] pauserBs = Storage.Get(Storage.CurrentContext, PauserKey); if (pauserBs.Length > 0) { pausers = Helper.Deserialize(pauserBs) as Map <byte[], bool>; } byte[] admin = BasicMethods.getAdmin(); if (!invoker.Equals(admin)) { BasicMethods.assert(pausers.HasKey(invoker), "invoker is not one pauser"); BasicMethods.assert(pausers[invoker], "invoker is an effective pauser"); } // update the pausers map pausers[account] = true; Storage.Put(Storage.CurrentContext, PauserKey, Helper.Serialize(pausers)); PauserAdded(account); return(true); }
//销毁货币 public static bool destoryByBu(string name, byte[] from, BigInteger value) { if (from.Length != 20) { return(false); } if (value <= 0) { return(false); } var key = new byte[] { 0x12 }.Concat(name.AsByteArray()); byte[] token = Storage.Get(Storage.CurrentContext, key); if (token.Length == 0) { return(false); } transfer(name, from, null, value); Tokenized t = Helper.Deserialize(token) as Tokenized; t.totalSupply = t.totalSupply - value; Storage.Put(Storage.CurrentContext, key, Helper.Serialize(t)); return(true); }
public static void Main() { // create struct instance Person p = new Person(); p.Name = "bob"; p.Age = 20; Runtime.Notify(p.Name); Runtime.Notify(p.Age); // serialize struct instance to byte[] byte[] b = Helper.Serialize(p); // deserialize byte[] to struct Person p2 = (Person)Helper.Deserialize(b); Runtime.Notify(p2.Name); Runtime.Notify(p2.Age); // create struct array Person[] array = new Person[] { new Person { Name = "tom", Age = 18 }, new Person { Name = "jack", Age = 20 } }; }
public static bool destoryByBu(string name, byte[] from, BigInteger value) { if (from.Length != 20) { return(false); } if (value <= 0) { return(false); } var key = getNameKey(name.AsByteArray()); byte[] token = Storage.Get(Storage.CurrentContext, key); if (token.Length == 0) { return(false); } if (!transfer(name, from, null, value)) { throw new InvalidOperationException("Operation is error."); } Tokenized t = Helper.Deserialize(token) as Tokenized; t.totalSupply = t.totalSupply - value; Storage.Put(Storage.CurrentContext, key, Helper.Serialize(t)); return(true); }
public static bool transfer(byte[] to, byte[] tokenid) { if (to.Length != 20) { throw new InvalidOperationException("The parameter owner should be a 20-byte address"); } Alien token = Query(tokenid); if (token == null) { throw new InvalidOperationException("Invalid Alien token id"); } // Check if the owner of the alien is the same as the caller of the contract if (!Runtime.CheckWitness(token.Owner)) { return(false); } // Transfer byte[] from = token.Owner; Storage.Put(from, balanceOf(from) - 1); Storage.Put(to, balanceOf(to) + 1); token.Owner = to; // Save the modified token StorageMap alienMap = Storage.CurrentContext.CreateMap(nameof(alienMap)); alienMap.Put(tokenid, Helper.Serialize(token)); // Raise event OnTransfer(token.Owner, to, tokenid); return(true); }
private static bool Announce(byte[] address) { if (Runtime.CheckWitness(Owner)) { return(false); } Runtime.Notify("0"); //Auction auction = (Auction)Storage.Get(Storage.CurrentContext, "auction").Deserialize(); Auction auction = (Auction)Helper.Deserialize(Storage.Get("auction")); Runtime.Notify("1"); uint now = Runtime.Time; Runtime.Notify("11"); uint test = auction.endOfBidding; Runtime.Notify("12"); if (now >= test) { return(false); } Runtime.Notify("2"); if (!auction.AnnounceBidder(address)) { return(false); } Runtime.Notify("3"); Transferred(null, address, 1000); Runtime.Notify("4"); //Storage.Put(Storage.CurrentContext, "auction", auction.Serialize()); Storage.Put("auction", Helper.Serialize(auction)); Runtime.Notify("5"); Storage.Put("totalSupply", BytesToBigInteger(Storage.Get("totalSupply")) + 1000); return(true); }
public static bool mintToken(byte[] owner, string properties, string URI, string rwProperties) { if (!isOpen() && !Runtime.CheckWitness(superAdmin)) { return(false); } if (!Runtime.CheckWitness(owner)) { return(false); } StorageMap sysStateMap = Storage.CurrentContext.CreateMap("sysState"); StorageMap tokenMap = Storage.CurrentContext.CreateMap("token"); BigInteger totalSupply = sysStateMap.Get("totalSupply").AsBigInteger(); Token newToken = new Token(); newToken.token_id = totalSupply + 1; newToken.owner = owner; newToken.approved = new byte[0]; newToken.properties = properties; newToken.uri = URI; newToken.rwProperties = rwProperties; sysStateMap.Put("totalSupply", newToken.token_id); tokenMap.Put(newToken.token_id.AsByteArray(), Helper.Serialize(newToken)); addrNFTlistAdd(owner, newToken.token_id); onMint(owner, 1); onNFTMint(owner, newToken.token_id, newToken); return(true); }
/// <summary> /// Store auction transaction records /// </summary> public static void _putAuctionRecord(byte[] tokenId, AuctionRecord info) { var key = "auction".AsByteArray().Concat(tokenId); byte[] bytes = Helper.Serialize(info); Storage.Put(Storage.CurrentContext, key, bytes); }
public static object TestMap() { StorageContext context = Storage.CurrentContext; Map <string, int> m = new Map <string, int>(); int value = 100; //m["hello"] = "world"; m["key"] = value; byte[] b = Helper.Serialize(m); Storage.Put(context, "tx", b); byte[] v = Storage.Get(context, "tx"); Map <string, int> b2 = (Map <string, int>)Helper.Deserialize(v); //&& b2["hello"] == "world" if (b2 != null && (int)b2["key"] == value) { Storage.Put(context, "result", "true"); return(b); } Storage.Put(context, "result", "false"); return(false); }
public static void SaveNftInfo(NFTInfo nftInfo) { var key = NftInfoKey(nftInfo.TokenId); byte[] nftInfoBytes = Helper.Serialize(nftInfo); Storage.Put(Context(), key, nftInfoBytes); }
public static bool ConfirmShipment(byte[] txid) { var info = GetSale(txid); if (info.State != SaleState.AwaitingShipment) { Error("sale state incorrect", new object[] { info.State }); return(false); } if (info.Buyer == null) { Error("buyer not specified"); return(false); } if (!Runtime.CheckWitness(info.Seller)) { Error("must be seller to confirm shipment", new object[] { info.Seller }); return(false); } info.State = SaleState.ShipmentConfirmed; StorageMap saleInfoMap = Storage.CurrentContext.CreateMap(SalesMapName); saleInfoMap.Put(info.Id, Helper.Serialize(info)); SaleStateUpdated(info.Id, null, info.State); return(true); }
private static void setTxInfo(byte[] from, byte[] to, BigInteger value) { TransferInfo info = new TransferInfo(); info.from = from; info.to = to; info.value = value; ////用一个老式实现法 // ////优化的拼包方法 // //var data = info.from; //var lendata = ((BigInteger)data.Length).AsByteArray().Concat(doublezero).Range(0, 2); ////lendata是数据长度得bytearray,因为bigint长度不固定,统一加两个零,然后只取前面两个字节 ////为什么要两个字节,因为bigint是含有符号位得,统一加个零安全,要不然长度129取一个字节就是负数了 //var txinfo = lendata.Concat(data); // //data = info.to; //lendata = ((BigInteger)data.Length).AsByteArray().Concat(doublezero).Range(0, 2); //txinfo = txinfo.Concat(lendata).Concat(data); // //data = value.AsByteArray(); //lendata = ((BigInteger)data.Length).AsByteArray().Concat(doublezero).Range(0, 2); //txinfo = txinfo.Concat(lendata).Concat(data); //新式实现方法只要一行 byte[] txinfo = Helper.Serialize(info); var txid = (ExecutionEngine.ScriptContainer as Transaction).Hash; var keytxid = new byte[] { 0x12 }.Concat(txid); Storage.Put(Storage.CurrentContext, keytxid, txinfo); }
//增发货币 public static bool increaseByBu(string name, byte[] to, BigInteger value) { if (to.Length != 20) { return(false); } if (value <= 0) { return(false); } var key = getNameKey(name.AsByteArray()); byte[] token = Storage.Get(Storage.CurrentContext, key); if (token.Length == 0) { return(false); } transfer(name, null, to, value); Tokenized t = Helper.Deserialize(token) as Tokenized; t.totalSupply = t.totalSupply + value; Storage.Put(Storage.CurrentContext, key, Helper.Serialize(t)); return(true); }
/** * 存储拍卖成交记录 */ private static void _putAuctionRecord(byte[] dressId, AuctionRecord info) { byte[] txInfo = Helper.Serialize(info); var key = "buy".AsByteArray().Concat(dressId); Storage.Put(Storage.CurrentContext, key, txInfo); }
public static bool SetAssetInfo(byte[] assetid, AssetInfo assetInfo) { StorageMap assentInfoMap = Storage.CurrentContext.CreateMap("assentInfoMap"); byte[] assetInfoBytes = Helper.Serialize(assetInfo); assentInfoMap.Put(assetid, assetInfoBytes); return(true); }
/** * 使用txid充值 */ public static bool rechargeToken(byte[] owner, byte[] txid) { if (owner.Length != 20) { Runtime.Log("Owner error."); return(false); } //2018/6/5 cwt 修补漏洞 byte[] keytxid = new byte[] { 0x11 }.Concat(txid); byte[] keytowner = new byte[] { 0x11 }.Concat(owner); byte[] txinfo = Storage.Get(Storage.CurrentContext, keytxid); if (txinfo.Length > 0) { // 已经处理过了 return(false); } // 查询交易记录 object[] args = new object[1] { txid }; byte[] sgasHash = Storage.Get(Storage.CurrentContext, "sgas"); deleDyncall dyncall = (deleDyncall)sgasHash.ToDelegate(); object[] res = (object[])dyncall("getTxInfo", args); if (res.Length > 0) { byte[] from = (byte[])res[0]; byte[] to = (byte[])res[1]; BigInteger value = (BigInteger)res[2]; if (from == owner) { if (to == ExecutionEngine.ExecutingScriptHash) { // 标记为处理 Storage.Put(Storage.CurrentContext, keytxid, value); BigInteger nMoney = 0; UserInfo userInfo = getUserInfo(owner); nMoney = userInfo.balance; nMoney += value; _addTotal(value); userInfo.balance = nMoney; // 记账 Storage.Put(Storage.CurrentContext, keytowner, Helper.Serialize(userInfo)); return(true); } } } return(false); }
public static bool transfer(byte[] from, byte[] to, BigInteger value) { if (value <= 0) { return(false); } if (from == to) { return(true); } //获得当前块的高度 var height = Blockchain.GetHeight(); //为了保护每个有交易的区块高度都有系统费的值 多了1.x个gas var curMoney = getCurMoney(height); CoinPoolInfo coinPoolInfo = getCoinPoolInfo(); if (curMoney == 0) { curMoney = getCurMoney(coinPoolInfo.lastblock); var bytes_CurHeight = ((BigInteger)height).AsByteArray().Concat(quadZero).Range(0, 4); var key_CurHeight = new byte[] { 0x12 }.Concat(bytes_CurHeight); Storage.Put(Storage.CurrentContext, key_CurHeight, curMoney); //这个地方可以不更新coinpoolinfo的值 不更新没有影响 updateCoinPoolInfo(coinPoolInfo, height); } //付款方 if (from.Length > 0) { var keyFrom = new byte[] { 0x11 }.Concat(from); Info fromInfo = getInfo(from); var from_value = fromInfo.balance; if (from_value < value) { return(false); } fromInfo = updateCanClaim(height, fromInfo, from_value, value); fromInfo.balance = from_value - value; Storage.Put(Storage.CurrentContext, keyFrom, Helper.Serialize(fromInfo)); } //收款方 if (to.Length > 0) { var keyTo = new byte[] { 0x11 }.Concat(to); Info toInfo = getInfo(to); var to_value = toInfo.balance; toInfo = updateCanClaim(height, toInfo, to_value, value); toInfo.balance = to_value + value; Storage.Put(Storage.CurrentContext, keyTo, Helper.Serialize(toInfo)); } //notify Transferred(from, to, value); return(true); }
/*向债仓锁定数字资产*/ public static bool Lock(byte[] addr, BigInteger value) { if (addr.Length != 20) return false; if (value == 0) return false; byte[] key = addr.Concat(ConvertN(0)); byte[] cdp = Storage.Get(Storage.CurrentContext, key); if (cdp.Length == 0) return false; byte[] to = Storage.Get(Storage.CurrentContext, STORAGE_ACCOUNT); if (to.Length == 0) return false; object[] arg = new object[3]; arg[0] = addr; arg[1] = to; arg[2] = value; if (!(bool)SDTContract("transfer", arg)) return false; var txid = ((Transaction)ExecutionEngine.ScriptContainer).Hash; //object[] obj = new object[1]; //obj[0] = txid; //TransferInfo transferInfo = (TransferInfo)SDTContract("getTXInfo", obj); /*校验交易信息*/ //if (transferInfo.from != addr || transferInfo.to != to || value != transferInfo.value) return false; byte[] used = Storage.Get(Storage.CurrentContext, txid); /*判断txid是否已被使用*/ if (used.Length != 0) return false; CDPTransferInfo cdpInfo = (CDPTransferInfo)Helper.Deserialize(cdp); cdpInfo.locked = cdpInfo.locked + value; BigInteger currLock = cdpInfo.locked; Storage.Put(Storage.CurrentContext, key, Helper.Serialize(cdpInfo)); //记录交易详细数据 CDPTransferDetail detail = new CDPTransferDetail(); detail.from = addr; detail.cdpTxid = cdpInfo.txid; detail.type = (int)ConfigTranType.TRANSACTION_TYPE_LOCK; detail.operated = value; detail.hasLocked = currLock; detail.hasDrawed = cdpInfo.hasDrawed; detail.txid = txid; Storage.Put(Storage.CurrentContext, txid, Helper.Serialize(detail)); /*记录txid 已被使用*/ Storage.Put(Storage.CurrentContext, txid, addr); return true; }