public void TestStorageList() { _ = new DC(null); var parent = new TestParent("Parent", isStoring: false); var storageList = new StorageList <TestChild>(); assert(storageList, "", ""); var child0 = new TestChild("Child0", parent, isStoring: false); storageList.Add(child0); assert(storageList, @"", @"Key: noKey, Text: Child0, Parent: noKey, Parent;"); var child1 = new TestChild("Child1", parent, isStoring: false); storageList.Add(child1); assert(storageList, @"", @"Key: noKey, Text: Child0, Parent: noKey, Parent; Key: noKey, Text: Child1, Parent: noKey, Parent;"); parent.Store(); assert(storageList, @"", @"Key: noKey, Text: Child0, Parent: 0, Parent; Key: noKey, Text: Child1, Parent: 0, Parent;"); child0.Store(); assert(storageList, @"Key: 0, Text: Child0, Parent: 0, Parent;", @"Key: 0, Text: Child0, Parent: 0, Parent; Key: noKey, Text: Child1, Parent: 0, Parent;"); child1.Store(); assert(storageList, @"Key: 0, Text: Child0, Parent: 0, Parent; Key: 1, Text: Child1, Parent: 0, Parent;", @"Key: 0, Text: Child0, Parent: 0, Parent; Key: 1, Text: Child1, Parent: 0, Parent;"); child0.Release(); assert(storageList, @"Key: 1, Text: Child1, Parent: 0, Parent;", @"Key: noKey, Text: Child0, Parent: 0, Parent; Key: 1, Text: Child1, Parent: 0, Parent;"); }
// migrates the full stake from one address to other public void Migrate(Address from, Address to) { Runtime.Expect(Runtime.IsWitness(from), "invalid witness"); Runtime.Expect(to.IsUser, "destination must be user address"); var targetStake = _stakes.Get <Address, EnergyAction>(to); Runtime.Expect(targetStake.totalAmount == 0, "Tried to migrate to an account that's already staking"); //migrate stake var sourceStake = _stakes.Get <Address, EnergyAction>(from); _stakes.Set(to, sourceStake); _stakes.Remove(from); //migrate master claim var masterAccountThreshold = GetMasterThreshold(); if (sourceStake.totalAmount >= masterAccountThreshold) { var count = _mastersList.Count(); var index = -1; Timestamp claimDate = Runtime.Time; for (int i = 0; i < count; i++) { var master = _mastersList.Get <EnergyMaster>(i); if (master.address == from) { index = i; claimDate = master.claimDate; break; } } Runtime.Expect(index >= 0, "Expected this address to be a master"); _mastersList.RemoveAt <EnergyMaster>(index); _mastersList.Add(new EnergyMaster() { address = to, claimDate = claimDate }); } //migrate voting power var votingLogbook = _voteHistory.Get <Address, StorageList>(from); votingLogbook.Add(to); votingLogbook.Remove(from); }
public void SaveGuide(int groupId) { if (!AlreadyGuide.Contains(groupId)) { AlreadyGuide.Add(groupId); } }
private void CreateOTC(Address from, string baseSymbol, string quoteSymbol, BigInteger amount, BigInteger price) { var uid = Runtime.GenerateUID(); var count = _otcBook.Count(); ExchangeOrder lockUpOrder; for (int i = 0; i < count; i++) { lockUpOrder = _otcBook.Get <ExchangeOrder>(i); if (lockUpOrder.Creator == from) { throw new Exception("Already have an offer created"); return; } } var baseBalance = Runtime.GetBalance(baseSymbol, from); Runtime.Expect(baseBalance >= amount, "invalid seller amount"); Runtime.TransferTokens(baseSymbol, from, this.Address, price); var order = new ExchangeOrder(uid, Runtime.Time, from, this.Address, amount, baseSymbol, price, quoteSymbol, ExchangeOrderSide.Sell, ExchangeOrderType.OTC); _otcBook.Add <ExchangeOrder>(order); }
private Hash SettleSwapToExternal(string destinationPlatform, Hash sourceHash, Func <Address, IToken, BigInteger, Hash> generator) { var oracleReader = Nexus.CreateOracleReader(); var swap = oracleReader.ReadTransaction(DomainSettings.PlatformName, DomainSettings.RootChainName, sourceHash); var transfers = swap.Transfers.Where(x => x.destinationAddress.IsInterop).ToArray(); // TODO not support yet if (transfers.Length != 1) { logger.Warning($"Not implemented: Swap support for multiple transfers in a single transaction"); return(Hash.Null); } var transfer = transfers[0]; var token = Nexus.GetTokenInfo(Nexus.RootStorage, transfer.Symbol); var destHash = generator(transfer.destinationAddress, token, transfer.Value); if (destHash != Hash.Null) { var pendingList = new StorageList(PendingTag, this.Storage); var settle = new PendingSettle() { sourceHash = sourceHash, destinationHash = destHash, settleHash = Hash.Null, time = DateTime.UtcNow, status = SwapStatus.Settle }; pendingList.Add <PendingSettle>(settle); } return(destHash); }
/// <summary> /// Setup a new lender /// </summary> /// <param name="from">Address from which KCAL will be lent</param> /// <param name="to">Address that will receive the profits from the lending (can be the same as the first address)</param> public void StartLend(Address from, Address to) { var maxLenderCount = Runtime.GetGovernanceValue(MaxLenderCountTag); Runtime.Expect(_lenderList.Count() < maxLenderCount, "too many lenders already"); Runtime.Expect(Runtime.IsWitness(from), "invalid witness"); Runtime.Expect(to.IsUser, "invalid destination address"); Runtime.Expect(!IsLender(from), "already lending at source address"); Runtime.Expect(!IsLender(to), "already lending at destination address"); var balance = Runtime.GetBalance(DomainSettings.FuelTokenSymbol, from); Runtime.Expect(balance > 0, "not enough gas for lending"); Runtime.Expect(Runtime.TransferTokens(DomainSettings.FuelTokenSymbol, from, this.Address, balance), "gas transfer failed"); var lender = new GasLender() { paymentAddress = to, balance = balance }; _lenderList.Add <Address>(from); _lenderMap.Set <Address, GasLender>(from, lender); Runtime.Notify(EventKind.AddressLink, from, Runtime.Chain.Address); Runtime.Notify(EventKind.TokenEscrow, from, new TokenEventData() { symbol = DomainSettings.FuelTokenSymbol, value = balance, chainAddress = Runtime.Chain.Address }); }
public bool DeployContractScript(StorageContext storage, Address contractOwner, string name, Address contractAddress, byte[] script, ContractInterface abi) { var scriptKey = GetContractKey(contractAddress, "script"); if (storage.Has(scriptKey)) { return(false); } storage.Put(scriptKey, script); var ownerBytes = contractOwner.ToByteArray(); var ownerKey = GetContractKey(contractAddress, "owner"); storage.Put(ownerKey, ownerBytes); var abiBytes = abi.ToByteArray(); var abiKey = GetContractKey(contractAddress, "abi"); storage.Put(abiKey, abiBytes); var nameBytes = Encoding.ASCII.GetBytes(name); var nameKey = GetContractKey(contractAddress, "name"); storage.Put(nameKey, nameBytes); var contractList = new StorageList(GetContractListKey(), storage); contractList.Add <Address>(contractAddress); return(true); }
public void TestStorageListWithNestedMap() { var context = new MemoryStorageContext(); var map = new StorageMap("map".AsByteArray(), context); Assert.IsTrue(map.Count() == 0); map.Set(1, "hello"); map.Set(3, "world"); var count = map.Count(); Assert.IsTrue(count == 2); var list = new StorageList("list".AsByteArray(), context); Assert.IsTrue(list.Count() == 0); list.Add(map); count = list.Count(); Assert.IsTrue(count == 1); var another = list.Get <StorageMap>(0); count = another.Count(); Assert.IsTrue(count == 2); }
public void AddValidator(Address from) { Runtime.Expect(from.IsUser, "must be user address"); Runtime.Expect(IsWitness(from), "witness failed"); var count = _validatorList.Count(); if (count > 0) { var max = Runtime.GetGovernanceValue(ActiveValidatorCountTag); Runtime.Expect(count < max, "no open validators spots"); var pollName = ConsensusContract.SystemPoll + ValidatorPollTag; var hasConsensus = (bool)Runtime.CallContext("consensus", "HasRank", pollName, from, max); Runtime.Expect(hasConsensus, "no consensus for electing this address"); } var requiredStake = EnergyContract.MasterAccountThreshold; var stakedAmount = (BigInteger)Runtime.CallContext("energy", "GetStake", from); Runtime.Expect(stakedAmount >= requiredStake, "not enough stake"); _validatorList.Add(from); var entry = new ValidatorEntry() { address = from, election = Runtime.Time, }; _validatorMap.Set(from, entry); Runtime.Notify(EventKind.ValidatorAdd, Runtime.Chain.Address, from); }
public void AddValidator(Address from) { Runtime.Expect(IsWitness(from), "witness failed"); var count = _validatorList.Count(); var max = GetMaxValidators(); Runtime.Expect(count < max, "no open validators spots"); var requiredStake = GetRequiredStake(); var stakedAmount = (BigInteger)Runtime.CallContext("energy", "GetStake", from); Runtime.Expect(stakedAmount >= requiredStake, "not enough stake"); _validatorList.Add(from); var entry = new ValidatorEntry() { address = from, joinDate = Runtime.Time, lastActivity = Runtime.Time, slashes = 0 }; _validatorMap.Set(from, entry); Runtime.Notify(EventKind.ValidatorAdd, Runtime.Chain.Address, from); }
private void CreateOTC(Address from, string baseSymbol, string quoteSymbol, BigInteger amount, BigInteger price) { var uid = Runtime.GenerateUID(); var order = new ExchangeOrder(uid, Runtime.Time, from, this.Address, amount, baseSymbol, price, quoteSymbol, ExchangeOrderSide.Sell, ExchangeOrderType.OTC); _otcBook.Add <ExchangeOrder>(order); }
public Hash CreateSale(Address from, string name, SaleFlags flags, Timestamp startDate, Timestamp endDate, string sellSymbol, string receiveSymbol, BigInteger price, BigInteger globalSoftCap, BigInteger globalHardCap, BigInteger userSoftCap, BigInteger userHardCap) { Runtime.Expect(Runtime.IsWitness(from), "invalid witness"); Runtime.Expect(Runtime.TokenExists(sellSymbol), "token must exist: " + sellSymbol); var token = Runtime.GetToken(sellSymbol); Runtime.Expect(token.IsFungible(), "token must be fungible: " + sellSymbol); Runtime.Expect(token.IsTransferable(), "token must be transferable: " + sellSymbol); Runtime.Expect(price >= 1, "invalid price"); Runtime.Expect(globalSoftCap >= 0, "invalid softcap"); Runtime.Expect(globalHardCap > 0, "invalid hard cap"); Runtime.Expect(globalHardCap >= globalSoftCap, "hard cap must be larger or equal to soft capt"); Runtime.Expect(userSoftCap >= 0, "invalid user soft cap"); Runtime.Expect(userHardCap >= userSoftCap, "invalid user hard cap"); Runtime.Expect(receiveSymbol != sellSymbol, "invalid receive token symbol: " + receiveSymbol); // TODO remove this later when Cosmic Swaps 2.0 are released Runtime.Expect(receiveSymbol == DomainSettings.StakingTokenSymbol, "invalid receive token symbol: " + receiveSymbol); Runtime.TransferTokens(sellSymbol, from, this.Address, globalHardCap); var sale = new SaleInfo() { Creator = from, Name = name, Flags = flags, StartDate = startDate, EndDate = endDate, SellSymbol = sellSymbol, ReceiveSymbol = receiveSymbol, Price = price, GlobalSoftCap = globalSoftCap, GlobalHardCap = globalHardCap, UserSoftCap = userSoftCap, UserHardCap = userHardCap, }; var bytes = Serialization.Serialize(sale); var hash = Hash.FromBytes(bytes); _saleList.Add(hash); _saleMap.Set(hash, sale); _saleSupply.Set <Hash, BigInteger>(hash, 0); Runtime.Notify(EventKind.Crowdsale, from, new SaleEventData() { kind = SaleEventKind.Creation, saleHash = hash }); return(hash); }
/// <summary> /// Adds a storage to the manager /// </summary> /// <param name="storage"></param> static public void AddStorage(StorageBase storage) { if (storage == null) { return; } storage.Process(); StorageList.Add(storage); }
public void AddFriend(Address target, Address friend) { Runtime.Expect(IsWitness(target), "invalid witness"); Runtime.Expect(friend != Address.Null, "friend address must not be null"); Runtime.Expect(friend != target, "friend must be different from target address"); _friends.Add(friend); Runtime.Notify(EventKind.AddressAdd, target, friend); }
public void Stake(Address from, BigInteger stakeAmount) { Runtime.Expect(StakeToFuel(stakeAmount) >= 1, "invalid amount"); Runtime.Expect(IsWitness(from), "witness failed"); var stakeBalances = Runtime.Chain.GetTokenBalances(Nexus.StakingTokenSymbol); var balance = stakeBalances.Get(this.Storage, from); var currentStake = _stakes.Get <Address, EnergyAction>(from); var newStake = stakeAmount + currentStake.totalAmount; Runtime.Expect(balance >= stakeAmount, "not enough balance"); Runtime.Expect(stakeBalances.Subtract(this.Storage, from, stakeAmount), "balance subtract failed"); Runtime.Expect(stakeBalances.Add(this.Storage, Runtime.Chain.Address, stakeAmount), "balance add failed"); var entry = new EnergyAction() { unclaimedPartials = stakeAmount + GetLastAction(from).unclaimedPartials, totalAmount = newStake, timestamp = this.Runtime.Time, }; _stakes.Set(from, entry); var logEntry = new VotingLogEntry() { timestamp = this.Runtime.Time, amount = stakeAmount }; var votingLogbook = _voteHistory.Get <Address, StorageList>(from); votingLogbook.Add(logEntry); if (Runtime.Nexus.GenesisAddress != from && newStake >= MasterAccountThreshold && !IsMaster(from)) { var nextClaim = GetMasterClaimDate(2); _mastersList.Add(new EnergyMaster() { address = from, claimDate = nextClaim }); Runtime.Notify(EventKind.MasterPromote, from, nextClaim); } Runtime.Notify(EventKind.TokenStake, from, new TokenEventData() { chainAddress = Runtime.Chain.Address, symbol = Nexus.StakingTokenSymbol, value = newStake }); }
public void TestStorageMapWithNestedList() { var context = new MemoryStorageContext(); var list = new StorageList("list".AsByteArray(), context); Assert.IsTrue(list.Count() == 0); var map = new StorageMap("map".AsByteArray(), context); Assert.IsTrue(map.Count() == 0); int key = 123; map.Set(key, list); list.Add("hello"); list.Add("world"); var count = list.Count(); Assert.IsTrue(count == 2); count = map.Count(); Assert.IsTrue(count == 1); int otherKey = 21; var other = map.Get <int, StorageList>(otherKey); Assert.IsTrue(other.Count() == 0); var another = map.Get <int, StorageList>(key); count = another.Count(); Assert.IsTrue(count == 2); // note: here we remove from one list and count the other, should be same since both are references to same storage list another.RemoveAt(0); count = list.Count(); Assert.IsTrue(count == 1); }
public void TestStorageList() { var context = new MemoryStorageContext(); var list = new StorageList("test".AsByteArray(), context); Assert.IsTrue(list.Count() == 0); list.Add("hello"); list.Add("world"); Assert.IsTrue(list.Count() == 2); list.RemoveAt(0); Assert.IsTrue(list.Count() == 1); var temp = list.Get <string>(0); Assert.IsTrue(temp == "world"); list.Replace <string>(0, "hello"); temp = list.Get <string>(0); Assert.IsTrue(temp == "hello"); }
private Hash SettleSwapToExternal(Hash sourceHash, string destPlatform) { var swap = OracleReader.ReadTransaction(DomainSettings.PlatformName, DomainSettings.RootChainName, sourceHash); var transfers = swap.Transfers.Where(x => x.destinationAddress.IsInterop).ToArray(); // TODO not support yet if (transfers.Length != 1) { Logger.Warning($"Not implemented: Swap support for multiple transfers in a single transaction"); return(Hash.Null); } var transfer = transfers[0]; var token = Nexus.GetTokenInfo(Nexus.RootStorage, transfer.Symbol); lock (StateModificationLock) { var destHash = GetSettleHash(DomainSettings.PlatformName, sourceHash); Logger.Debug("settleHash in settleswap: " + destHash); if (destHash != Hash.Null) { return(destHash); } if (!_swappers.ContainsKey(destPlatform)) { return(Hash.Null); // just in case, should never happen } var chainSwapper = _swappers[destPlatform]; destHash = chainSwapper.SettleSwap(sourceHash, transfer.destinationAddress, token, transfer.Value); // if the asset transfer was sucessfull, we prepare a fee settlement on the mainnet if (destHash != Hash.Null) { var pendingList = new StorageList(PendingTag, this.Storage); var settle = new PendingFee() { sourceHash = sourceHash, destinationHash = destHash, settleHash = Hash.Null, time = DateTime.UtcNow, status = SwapStatus.Settle }; pendingList.Add <PendingFee>(settle); } return(destHash); } }
public void CreateExchange(Address from, string id, string name) { Runtime.Expect(Runtime.IsWitness(from), "invalid witness"); Runtime.Expect(ValidationUtils.IsValidIdentifier(id), "invalid id"); var exchange = new ExchangeProvider() { address = from, id = id, name = name, }; _exchanges.Add <ExchangeProvider>(exchange); }
/// <summary> /// Setup a new lender /// </summary> /// <param name="from">Address from which KCAL will be lent</param> /// <param name="to">Address that will receive the profits from the lending (can be the same as the first address)</param> public void StartLend(Address from, Address to) { var maxLenderCount = Runtime.GetGovernanceValue(MaxLenderCountTag); Runtime.Expect(_lenderList.Count() < maxLenderCount, "too many lenders already"); Runtime.Expect(IsWitness(from), "invalid witness"); Runtime.Expect(to.IsUser, "invalid destination address"); Runtime.Expect(!IsLender(from), "already lending at source address"); Runtime.Expect(!IsLender(to), "already lending at destination address"); _lenderList.Add <Address>(from); _lenderMap.Set <Address, Address>(from, to); Runtime.Notify(EventKind.AddressLink, from, Runtime.Chain.Address); }
public async void RefreshAsync() { while (true) { try { using (var httpClient = new HttpClient()) { FoodClient foodClient = new FoodClient(httpClient); Task <ICollection <Food> > allFoodTask = foodClient.GetAllFoodAsync(); FoodList.Clear(); foreach (var item in await allFoodTask) { FoodList.Add(item); } CategoryClient categoryClient = new CategoryClient(httpClient); Task <ICollection <Category> > allCategoryTask = categoryClient.GetAllCategoryAsync(); CategoryList.Clear(); foreach (var item in await allCategoryTask) { CategoryList.Add(item); } StorageClient storageClient = new StorageClient(httpClient); Task <ICollection <Storage> > allStorageTask = storageClient.GetAllStorageAsync(); StorageList.Clear(); foreach (var item in await allStorageTask) { StorageList.Add(item); } SlotClient slotClient = new SlotClient(httpClient); Task <ICollection <Slot> > allSlotTask = slotClient.GetAllSlotAsync(); SlotList.Clear(); foreach (var item in await allSlotTask) { SlotList.Add(item); } } return; } catch { Thread.Sleep(500); } } }
public void SendMessage(Address from, Address to, byte[] content) { Runtime.Expect(IsWitness(from), "invalid witness"); Runtime.Expect(content.Length >= MIN_MESSAGE_LENGTH, "message too small"); Runtime.Expect(content.Length <= MAX_MESSAGE_LENGTH, "message too large"); var msg = new AddressMessage() { from = from, timestamp = Runtime.Block.Timestamp, content = content }; _messages.Add <AddressMessage>(msg); }
public void RegisterApp(Address owner, string name) { Runtime.Expect(IsWitness(owner), "invalid witness"); var chain = this.Runtime.Nexus.CreateChain(this.Storage, owner, name, Runtime.Chain, Runtime.Block, new string[] { /*TODO*/ }); var app = new AppInfo() { id = name, title = name, url = "", description = "", icon = Hash.Null, }; _apps.Add(app); }
public void SendMessage(Address from, Address to, byte[] content) { Runtime.Expect(Runtime.IsWitness(from), "invalid witness"); Runtime.Expect(to.IsUser, "destination must be user address"); Runtime.Expect(content.Length >= MAX_MESSAGE_LENGTH, "message too small"); Runtime.Expect(content.Length <= MIN_MESSAGE_LENGTH, "message too large"); var msg = new Mail() { from = from, timestamp = Runtime.Time, content = content }; _messages.Add <Mail>(msg); }
private bool DeployContractScript(StorageContext storage, Address contractAddress, byte[] script) { var key = GetContractDeploymentKey(contractAddress); if (storage.Has(key)) { return(false); } storage.Put(key, script); var contractList = new StorageList(GetContractListKey(), storage); contractList.Add <Address>(contractAddress); return(true); }
public ScrollDataFixed <T> Init(ScrollDataView scroll_, Func <RectTransform, T> PrepareT_, Action <T, bool> SwitchT_, string templateName_ = "entry") { _scroll = scroll_; elementPerLine = 1; PrepareT = PrepareT_; SwitchT = SwitchT_; template = (RectTransform)_scroll.content.Find(templateName_); template.gameObject.SetActive(false); defaultElementSize = template.sizeDelta; entry = new StorageList <Entry <T> >(64, 16, InitEntry); var e = PrepareT(template); entry.Add(new Entry <T>() { transform = template, item = e }); return(this); }
internal void AddToTracks(Track track) { #if DEBUG if (track == Track.NoTrack) { throw new Exception(); } if ((track.Key >= 0) && (Key < 0)) { throw new Exception(); } if (tracks.Contains(track)) { throw new Exception(); } #endif tracks.Add(track); onAddedToTracks(track); }
internal void AddToPlaylistTracks(PlaylistTrack playlistTrack) { #if DEBUG if (playlistTrack == PlaylistTrack.NoPlaylistTrack) { throw new Exception(); } if ((playlistTrack.Key >= 0) && (Key < 0)) { throw new Exception(); } if (playlistTracks.Contains(playlistTrack)) { throw new Exception(); } #endif playlistTracks.Add(playlistTrack); onAddedToPlaylistTracks(playlistTrack); }
public void SellToken(Address from, string baseSymbol, string quoteSymbol, BigInteger tokenID, BigInteger price, Timestamp endDate) { Runtime.Expect(IsWitness(from), "invalid witness"); Runtime.Expect(endDate > Runtime.Time, "invalid end date"); var maxAllowedDate = Runtime.Time + TimeSpan.FromDays(30); Runtime.Expect(endDate <= maxAllowedDate, "end date is too distant"); var quoteToken = Runtime.Nexus.FindTokenBySymbol(quoteSymbol); Runtime.Expect(quoteToken != null, "invalid quote token"); Runtime.Expect(quoteToken.Flags.HasFlag(TokenFlags.Fungible), "quote token must be fungible"); var baseToken = Runtime.Nexus.FindTokenBySymbol(baseSymbol); Runtime.Expect(baseToken != null, "invalid base token"); Runtime.Expect(!baseToken.Flags.HasFlag(TokenFlags.Fungible), "base token must be non-fungible"); var ownerships = Runtime.Chain.GetTokenOwnerships(baseToken); var owner = ownerships.GetOwner(this.Storage, tokenID); Runtime.Expect(owner == from, "invalid owner"); Runtime.Expect(baseToken.Transfer(this.Storage, ownerships, from, Runtime.Chain.Address, tokenID), "transfer failed"); var auction = new MarketAuction(from, Runtime.Time, endDate, baseSymbol, quoteSymbol, tokenID, price); var auctionID = baseSymbol + "." + tokenID; _auctionMap.Set(auctionID, auction); _auctionIDs.Add(auctionID); var nft = this.Runtime.Nexus.GetNFT(baseToken, tokenID); nft.CurrentChain = Runtime.Chain.Address; nft.CurrentOwner = Runtime.Chain.Address; Runtime.Notify(EventKind.AuctionCreated, from, new MarketEventData() { ID = tokenID, BaseSymbol = baseSymbol, QuoteSymbol = quoteSymbol, Price = price }); }
public void SellToken(Address from, string baseSymbol, string quoteSymbol, BigInteger tokenID, BigInteger price, Timestamp endDate) { Runtime.Expect(IsWitness(from), "invalid witness"); Runtime.Expect(endDate > Runtime.Time, "invalid end date"); var maxAllowedDate = Runtime.Time + TimeSpan.FromDays(30); Runtime.Expect(endDate <= maxAllowedDate, "end date is too distant"); Runtime.Expect(Runtime.Nexus.TokenExists(quoteSymbol), "invalid quote token"); var quoteToken = Runtime.Nexus.GetTokenInfo(quoteSymbol); Runtime.Expect(quoteToken.Flags.HasFlag(TokenFlags.Fungible), "quote token must be fungible"); Runtime.Expect(Runtime.Nexus.TokenExists(baseSymbol), "invalid base token"); var baseToken = Runtime.Nexus.GetTokenInfo(baseSymbol); Runtime.Expect(!baseToken.Flags.HasFlag(TokenFlags.Fungible), "base token must be non-fungible"); var ownerships = new OwnershipSheet(baseSymbol); var owner = ownerships.GetOwner(this.Storage, tokenID); Runtime.Expect(owner == from, "invalid owner"); Runtime.Expect(Runtime.Nexus.TransferToken(Runtime, baseToken.Symbol, from, Runtime.Chain.Address, tokenID), "transfer failed"); var auction = new MarketAuction(from, Runtime.Time, endDate, baseSymbol, quoteSymbol, tokenID, price); var auctionID = baseSymbol + "." + tokenID; _auctionMap.Set(auctionID, auction); _auctionIDs.Add(auctionID); Runtime.Notify(EventKind.OrderCreated, from, new MarketEventData() { ID = tokenID, BaseSymbol = baseSymbol, QuoteSymbol = quoteSymbol, Price = price }); Runtime.Notify(EventKind.TokenSend, from, new TokenEventData() { chainAddress = this.Runtime.Chain.Address, symbol = auction.BaseSymbol, value = tokenID }); }