diff --git a/Converter/Converter.csproj b/Converter/Converter.csproj
index 844453f..e86e0f1 100644
--- a/Converter/Converter.csproj
+++ b/Converter/Converter.csproj
@@ -2,13 +2,13 @@
Exe
- net5.0
+ net7.0
-
+
diff --git a/Fura/Cache/Cache.cs b/Fura/Cache/Cache.cs
index b397220..0ee85ed 100644
--- a/Fura/Cache/Cache.cs
+++ b/Fura/Cache/Cache.cs
@@ -34,12 +34,14 @@ public static DBCache Ins
}
public CacheAddress cacheAddress { get; }
public CacheAddressAsset cacheAddressAsset { get; }
+ public CacheMarket cacheMarket { get; }
public CacheAsset cacheAsset { get; }
public CacheCandidate cacheCandidate { get; }
public CacheContract cacheContract { get; }
public CacheNep11TransferNotification cacheNep11TransferNotification { get; }
public CacheScVoteCall cacheScVoteCall { get; }
public CacheTransferNotification cacheTransferNotification;
+ public CacheMatketNotification cacheMatketNotification;
public CacheVote cacheVote { get; }
public CacheScCall cacheScCall { get; }
public CacheExecution cacheExecution { get; }
@@ -57,6 +59,9 @@ public DBCache()
cacheAddressAsset = new CacheAddressAsset();
caches.Add(cacheAddressAsset);
+ cacheMarket = new CacheMarket();
+ caches.Add(cacheMarket);
+
cacheAsset = new CacheAsset();
caches.Add(cacheAsset);
@@ -75,6 +80,9 @@ public DBCache()
cacheTransferNotification = new CacheTransferNotification();
caches.Add(cacheTransferNotification);
+ cacheMatketNotification = new CacheMatketNotification();
+ caches.Add(cacheMatketNotification);
+
cacheVote = new CacheVote();
caches.Add(cacheVote);
diff --git a/Fura/Cache/Cache_AddressAsset.cs b/Fura/Cache/Cache_AddressAsset.cs
index d12eba6..212de38 100644
--- a/Fura/Cache/Cache_AddressAsset.cs
+++ b/Fura/Cache/Cache_AddressAsset.cs
@@ -86,7 +86,7 @@ public void AddOrUpdate(UInt160 address, UInt160 asset, BigInteger balance, stri
}
else
{
- addressAssetModel.Balance = BsonDecimal128.Create(balance.ToString());
+ addressAssetModel.Balance = BsonDecimal128.Create(balance.ToString().WipeNumStrToFitDecimal128());
}
D_AddressAssetModel[(address, asset, tokenid)] = addressAssetModel;
}
diff --git a/Fura/Cache/Cache_Asset.cs b/Fura/Cache/Cache_Asset.cs
index 70fc92d..ed4ec89 100644
--- a/Fura/Cache/Cache_Asset.cs
+++ b/Fura/Cache/Cache_Asset.cs
@@ -85,7 +85,7 @@ public void AddOrUpdate(UInt160 contractHash, ulong firstTransferTime, string to
assetModel.TokenName = tokenName;
assetModel.Decimals = decimals;
assetModel.Symbol = symbol;
- assetModel.TotalSupply = BsonDecimal128.Create(totalSupply.ToString());
+ assetModel.TotalSupply = BsonDecimal128.Create(totalSupply.ToString().WipeNumStrToFitDecimal128());
}
D_AssetModel[contractHash] = assetModel;
}
diff --git a/Fura/Cache/Cache_Contract.cs b/Fura/Cache/Cache_Contract.cs
index 30dd00c..8a038e6 100644
--- a/Fura/Cache/Cache_Contract.cs
+++ b/Fura/Cache/Cache_Contract.cs
@@ -14,6 +14,7 @@ public class CacheContractParams
public UInt160 Hash;
public ulong Time;
public UInt256 Txid;
+ public bool IsDestroy;
}
public class CacheContract : IDBCache
@@ -33,9 +34,9 @@ public void Clear()
D_Contract = new ConcurrentDictionary();
}
- public void AddNeedUpdate(UInt160 contractHash, ulong createTime, UInt256 txid)
+ public void AddNeedUpdate(UInt160 contractHash, ulong createTime, UInt256 txid, bool isDestroy = false)
{
- D_Contract[contractHash] = new() { Hash = contractHash, Time = createTime, Txid = txid };
+ D_Contract[contractHash] = new() { Hash = contractHash, Time = createTime, Txid = txid , IsDestroy = isDestroy };
}
public List GetNeedUpdate()
@@ -48,7 +49,7 @@ public void Update(NeoSystem system, DataCache snapshot)
List list = GetNeedUpdate();
Parallel.For(0, list.Count, (i) =>
{
- AddOrUpdate(list[i].Hash, snapshot, list[i].Time, list[i].Txid);
+ AddOrUpdate(list[i].Hash, snapshot, list[i].Time, list[i].Txid, list[i].IsDestroy);
});
}
@@ -64,24 +65,21 @@ public ContractModel Get(UInt160 contractHash)
}
}
- public void AddOrUpdate(UInt160 contractHash, DataCache snapshot, ulong createTime, UInt256 txid)
+ public void AddOrUpdate(UInt160 contractHash, DataCache snapshot, ulong createTime, UInt256 txid, bool isDestroy)
{
ContractModel contractModel = Get(contractHash);
- if (contractModel is null)
+
+ if (isDestroy)
{
- StorageKey key = new KeyBuilder(Neo.SmartContract.Native.NativeContract.ContractManagement.Id, 8).Add(contractHash);
- ContractState contract = snapshot.TryGet(key)?.GetInteroperable();
- contractModel = new(contractHash, contract.Manifest.Name, contract.Id, contract.UpdateCounter, contract.Nef.ToJson(), contract.Manifest.ToJson(), createTime, txid);
+ contractModel = new ContractModel() { UpdateCounter = -1, CreateTime = createTime, Hash = contractHash, _ID = -999, CreateTxid = txid, Manifest = "", Name = "", Nef = ""};
}
else
{
- if (contractModel.CreateTime == createTime)
- return;
StorageKey key = new KeyBuilder(Neo.SmartContract.Native.NativeContract.ContractManagement.Id, 8).Add(contractHash);
ContractState contract = snapshot.TryGet(key)?.GetInteroperable();
- if (contractModel.UpdateCounter == contract.UpdateCounter)
+ if (contractModel is not null && (contract is null || contractModel.CreateTxid == txid || contractModel.UpdateCounter == contract.UpdateCounter))
return;
- contractModel = new(contractHash, contract.Manifest.Name, contract.Id, contract.UpdateCounter, contract.Nef.ToJson(), contract.Manifest.ToJson(), createTime, txid);
+ contractModel = new(contractHash, contract.Manifest.Name, contract.Id, (short)contract.UpdateCounter, contract.Nef.ToJson(), contract.Manifest.ToJson(), createTime, txid);
}
D_ContractModel[contractHash] = contractModel;
}
diff --git a/Fura/Cache/Cache_GasMintBurn.cs b/Fura/Cache/Cache_GasMintBurn.cs
index bacde1a..5a9ade0 100644
--- a/Fura/Cache/Cache_GasMintBurn.cs
+++ b/Fura/Cache/Cache_GasMintBurn.cs
@@ -31,11 +31,24 @@ public void Clear()
public void Save(Transaction tran)
{
- if(GasMintBurnParams.BlockIndex > 0 || GasMintBurnParams.BurnAmount > 0 || GasMintBurnParams.MintAmount > 0)
+ BigInteger totalBurnAmount = 0;
+ BigInteger totalMintAmount = 0;
+ if(GasMintBurnParams.BlockIndex > 0)
{
- GasMintBurnModel gasMintBurnModel = new GasMintBurnModel() { BurnAmount = BsonDecimal128.Create(GasMintBurnParams.BurnAmount.ToString()), MintAmount = BsonDecimal128.Create(GasMintBurnParams.MintAmount.ToString()), BlockIndex = GasMintBurnParams.BlockIndex };
- tran.SaveAsync(gasMintBurnModel).Wait();
+ //获取上一个块的total来计算本块的数据
+ GasMintBurnModel gasMintBurnModel_Pre = GasMintBurnModel.Get(GasMintBurnParams.BlockIndex - 1);
+ totalBurnAmount = BigInteger.Parse(gasMintBurnModel_Pre.TotalBurnAmount.ToString());
+ totalMintAmount = BigInteger.Parse(gasMintBurnModel_Pre.TotalMintAmount.ToString());
}
+ GasMintBurnModel gasMintBurnModel = new GasMintBurnModel()
+ {
+ BurnAmount = BsonDecimal128.Create(GasMintBurnParams.BurnAmount.ToString().WipeNumStrToFitDecimal128()),
+ TotalBurnAmount = BsonDecimal128.Create((totalBurnAmount + GasMintBurnParams.BurnAmount).ToString().WipeNumStrToFitDecimal128()),
+ MintAmount = BsonDecimal128.Create(GasMintBurnParams.MintAmount.ToString().WipeNumStrToFitDecimal128()),
+ TotalMintAmount = BsonDecimal128.Create((totalMintAmount + GasMintBurnParams.MintAmount).ToString().WipeNumStrToFitDecimal128()),
+ BlockIndex = GasMintBurnParams.BlockIndex
+ };
+ tran.SaveAsync(gasMintBurnModel).Wait();
}
public void Add(uint blockIndex, BigInteger burnAmount, BigInteger mintAmount)
diff --git a/Fura/Cache/Cache_Market.cs b/Fura/Cache/Cache_Market.cs
new file mode 100644
index 0000000..10929f5
--- /dev/null
+++ b/Fura/Cache/Cache_Market.cs
@@ -0,0 +1,173 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using MongoDB.Entities;
+using Neo.Persistence;
+using Neo.Plugins.Models;
+using System.Numerics;
+using System.Threading.Tasks;
+
+namespace Neo.Plugins.Cache
+{
+ public class CacheMarketParams
+ {
+ public int NotificationIndex;
+ public bool SimpleUpdate;
+ public UInt160 Owner;
+ public UInt160 Asset;
+ public string TokenId;
+ public BigInteger Amount;
+ public UInt160 Market;
+ public uint AuctionType;
+ public UInt160 Auctor;
+ public UInt160 AuctionAsset;
+ public BigInteger AuctionAmount;
+ public ulong Deadline;
+ public UInt160 Bidder;
+ public BigInteger BidAmount;
+ public BigInteger Timestamp;
+ }
+
+ public class CacheMarket : IDBCache
+ {
+ private ConcurrentDictionary<(UInt160, UInt160, string), CacheMarketParams> D_Market;
+
+ private ConcurrentDictionary<(UInt160, UInt160, string), MarketModel> D_MarketModel;
+
+ public void AddNeedUpdate(int notificationIndex, bool simpleUpdate, UInt160 asset, UInt160 owner, string tokenid, BigInteger timestamp)
+ {
+ lock (D_Market)
+ {
+ if (!D_Market.ContainsKey((asset, owner, tokenid)) || notificationIndex > D_Market[(asset, owner, tokenid)].NotificationIndex )
+ {
+ D_Market[(asset, owner, tokenid)] = new()
+ {
+ NotificationIndex = notificationIndex,
+ SimpleUpdate = simpleUpdate,
+ Asset = asset,
+ TokenId = tokenid,
+ Owner = owner,
+ Timestamp = timestamp
+ };
+ }
+ }
+
+ }
+
+ public void AddNeedUpdate(int notificationIndex, bool simpleUpdate, UInt160 asset, UInt160 owner, string tokenid, UInt160 market, BigInteger auctionType, UInt160 auctor, UInt160 auctionAsset, BigInteger auctionAmount, BigInteger deadline, UInt160 bidder, BigInteger bidAmount, BigInteger timestamp)
+ {
+ lock (D_Market)
+ {
+ if (!D_Market.ContainsKey((asset, owner, tokenid)) || notificationIndex > D_Market[(asset, owner, tokenid)].NotificationIndex)
+ {
+ D_Market[(asset, owner, tokenid)] = new()
+ {
+ SimpleUpdate = simpleUpdate,
+ Asset = asset,
+ TokenId = tokenid,
+ Owner = owner,
+ Market = market,
+ AuctionType = (uint)auctionType,
+ Auctor = auctor,
+ AuctionAsset = auctionAsset,
+ AuctionAmount = auctionAmount,
+ Deadline = (ulong)deadline,
+ Bidder = bidder,
+ BidAmount = bidAmount,
+ Timestamp = timestamp,
+ NotificationIndex = notificationIndex
+ };
+ }
+ }
+ }
+
+ public List GetNeedUpdate()
+ {
+ return D_Market.Values.ToList();
+ }
+
+ public void Update(NeoSystem system, DataCache snapshot)
+ {
+ List list = GetNeedUpdate();
+ Parallel.For(0, list.Count, (i) =>
+ {
+ list[i].Amount = Neo.Plugins.VM.Helper.GetNep11BalanceOf(system, snapshot, list[i].Asset, list[i].TokenId, list[i].Owner);
+ AddOrUpdate(list[i]);
+ });
+ }
+
+ public MarketModel Get(UInt160 owner, UInt160 asset, string tokenid)
+ {
+ if (D_MarketModel.ContainsKey((owner, asset, tokenid)))
+ {
+ return D_MarketModel[(owner, asset, tokenid)];
+ }
+ else
+ {
+ return MarketModel.Get(owner, asset, tokenid);
+ }
+ }
+
+ public void AddOrUpdate(CacheMarketParams cacheMarketParams)
+ {
+ if (cacheMarketParams.Owner == null || cacheMarketParams.Asset == null)
+ return;
+ MarketModel marketModel = Get(cacheMarketParams.Owner, cacheMarketParams.Asset, cacheMarketParams.TokenId);
+ if (marketModel is null)
+ {
+ marketModel = new MarketModel()
+ {
+ Asset = cacheMarketParams.Asset,
+ TokenId = cacheMarketParams.TokenId,
+ Owner = cacheMarketParams.Owner,
+ Amount = MongoDB.Bson.BsonDecimal128.Create(cacheMarketParams.Amount.ToString().WipeNumStrToFitDecimal128()),
+ Market = cacheMarketParams.Market,
+ AuctionType = cacheMarketParams.AuctionType,
+ AuctionAmount = MongoDB.Bson.BsonDecimal128.Create(cacheMarketParams.AuctionAmount.ToString().WipeNumStrToFitDecimal128()),
+ AuctionAsset = cacheMarketParams.AuctionAsset,
+ Auctor = cacheMarketParams.Auctor,
+ BidAmount = MongoDB.Bson.BsonDecimal128.Create(cacheMarketParams.BidAmount.ToString().WipeNumStrToFitDecimal128()),
+ Bidder = cacheMarketParams.Bidder,
+ Deadline = cacheMarketParams.Deadline,
+ Timestamp = (ulong)cacheMarketParams.Timestamp
+ };
+ }
+ else if(cacheMarketParams.SimpleUpdate)
+ {
+ marketModel.Timestamp = (ulong)cacheMarketParams.Timestamp;
+ marketModel.Amount = MongoDB.Bson.BsonDecimal128.Create(cacheMarketParams.Amount.ToString().WipeNumStrToFitDecimal128());
+ }
+ else
+ {
+ marketModel.Asset = cacheMarketParams.Asset;
+ marketModel.TokenId = cacheMarketParams.TokenId;
+ marketModel.Owner = cacheMarketParams.Owner;
+ marketModel.Amount = MongoDB.Bson.BsonDecimal128.Create(cacheMarketParams.Amount.ToString().WipeNumStrToFitDecimal128());
+ marketModel.Market = cacheMarketParams.Market;
+ marketModel.AuctionType = cacheMarketParams.AuctionType;
+ marketModel.AuctionAmount = MongoDB.Bson.BsonDecimal128.Create(cacheMarketParams.AuctionAmount.ToString().WipeNumStrToFitDecimal128());
+ marketModel.AuctionAsset = cacheMarketParams.AuctionAsset;
+ marketModel.Auctor = cacheMarketParams.Auctor;
+ marketModel.BidAmount = MongoDB.Bson.BsonDecimal128.Create(cacheMarketParams.BidAmount.ToString().WipeNumStrToFitDecimal128());
+ marketModel.Bidder = cacheMarketParams.Bidder;
+ marketModel.Deadline = cacheMarketParams.Deadline;
+ marketModel.Timestamp = (ulong)cacheMarketParams.Timestamp;
+ }
+ D_MarketModel[((marketModel.Owner, marketModel.Asset, marketModel.TokenId))] = marketModel;
+ }
+
+ public void Clear()
+ {
+ D_Market = new ConcurrentDictionary<(UInt160, UInt160, string), CacheMarketParams>();
+ D_MarketModel = new ConcurrentDictionary<(UInt160, UInt160, string), MarketModel>();
+ }
+
+ public void Save(Transaction tran)
+ {
+ if (D_MarketModel.Values.Count > 0)
+ tran.SaveAsync(D_MarketModel.Values).Wait();
+ }
+ }
+}
+
diff --git a/Fura/Cache/Cache_MarketNotification.cs b/Fura/Cache/Cache_MarketNotification.cs
new file mode 100644
index 0000000..09a8768
--- /dev/null
+++ b/Fura/Cache/Cache_MarketNotification.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using Neo.Plugins.Models;
+using System.Numerics;
+using MongoDB.Entities;
+using System.Collections.Concurrent;
+using Neo.Persistence;
+
+namespace Neo.Plugins.Cache
+{
+ public class CacheMatketNotification : IDBCache
+ {
+ private ConcurrentBag L_MarketNotificationModel;
+
+ public CacheMatketNotification()
+ {
+ L_MarketNotificationModel = new ConcurrentBag();
+ }
+
+ public void Clear()
+ {
+ L_MarketNotificationModel = new ConcurrentBag();
+ }
+
+ public void Add(UInt256 txid, UInt256 blockHash, UInt160 market, BigInteger nonce, UInt160 user, UInt160 asset, string tokenId, string eventName, string extendData, ulong timestamp)
+ {
+ MarketNotificationModel marketNotificationModel = new(txid, blockHash, nonce, user, market, asset, tokenId, eventName, extendData, timestamp);
+ L_MarketNotificationModel.Add(marketNotificationModel);
+ }
+
+ public void Update(NeoSystem system, DataCache snapshot)
+ {
+ }
+
+ public void Save(Transaction tran)
+ {
+ if (L_MarketNotificationModel.Count > 0)
+ tran.SaveAsync(L_MarketNotificationModel).Wait();
+ }
+ }
+}
diff --git a/Fura/Cache/Cache_Nep11Properties.cs b/Fura/Cache/Cache_Nep11Properties.cs
index acb14d1..545b4e8 100644
--- a/Fura/Cache/Cache_Nep11Properties.cs
+++ b/Fura/Cache/Cache_Nep11Properties.cs
@@ -3,9 +3,11 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
+using Akka.Configuration.Hocon;
using MongoDB.Entities;
using Neo.Persistence;
using Neo.Plugins.Models;
+using System.Numerics;
namespace Neo.Plugins.Cache
{
@@ -20,21 +22,33 @@ public class CacheNep11Properties : IDBCache
private ConcurrentDictionary<(UInt160, string), CacheNep11PropertiesParams> D_Nep11Properties;
private ConcurrentDictionary<(UInt160, string), Nep11PropertiesModel> D_Nep11PropertiesModel;
+ private ConcurrentDictionary<(UInt160, string), NNSPropertiesModel> D_NNSPropertiesModel;
+
+ private ConcurrentDictionary<(UInt160, string), IlexPropertiesModel> D_IlexPropertiesModel;
+
+ private ConcurrentDictionary<(UInt160, string), MetaPropertiesModel> D_MetaPropertiesModel;
+
public CacheNep11Properties()
{
D_Nep11Properties = new ConcurrentDictionary<(UInt160, string), CacheNep11PropertiesParams>();
D_Nep11PropertiesModel = new ConcurrentDictionary<(UInt160, string), Nep11PropertiesModel>();
+ D_NNSPropertiesModel = new ConcurrentDictionary<(UInt160, string), NNSPropertiesModel>();
+ D_IlexPropertiesModel = new ConcurrentDictionary<(UInt160, string), IlexPropertiesModel>();
+ D_MetaPropertiesModel = new ConcurrentDictionary<(UInt160, string), MetaPropertiesModel>();
}
public void Clear()
{
D_Nep11Properties = new ConcurrentDictionary<(UInt160, string), CacheNep11PropertiesParams>();
D_Nep11PropertiesModel = new ConcurrentDictionary<(UInt160, string), Nep11PropertiesModel>();
+ D_NNSPropertiesModel = new ConcurrentDictionary<(UInt160, string), NNSPropertiesModel>();
+ D_IlexPropertiesModel = new ConcurrentDictionary<(UInt160, string), IlexPropertiesModel>();
+ D_MetaPropertiesModel = new ConcurrentDictionary<(UInt160, string), MetaPropertiesModel>();
}
- public void AddNeedUpdate( UInt160 asset, string tokenid)
+ public void AddNeedUpdate(UInt160 asset, string tokenid)
{
- D_Nep11Properties[(asset, tokenid)] = new() {Asset = asset, Tokenid = tokenid };
+ D_Nep11Properties[(asset, tokenid)] = new() { Asset = asset, Tokenid = tokenid };
}
public List GetNeedUpdate()
@@ -49,7 +63,8 @@ public void Update(NeoSystem system, DataCache snapshot)
{
//从vm中获取properties
var properties = Neo.Plugins.VM.Helper.GetNep11Properties(system, snapshot, list[i].Asset, list[i].Tokenid);
- AddOrUpdate(list[i].Asset, list[i].Tokenid, properties);
+ var isSelfControl = Neo.Plugins.VM.Helper.IsSelfControl(system, snapshot, list[i].Asset);
+ AddOrUpdate(list[i].Asset, list[i].Tokenid, properties, isSelfControl);
});
}
@@ -65,7 +80,60 @@ public Nep11PropertiesModel Get(UInt160 asset, string tokenid)
}
}
- public void AddOrUpdate(UInt160 asset, string tokenid, string properties)
+ public IlexPropertiesModel GetIlex(UInt160 asset, string tokenid)
+ {
+ if (D_IlexPropertiesModel.ContainsKey((asset, tokenid)))
+ {
+ return D_IlexPropertiesModel[(asset, tokenid)];
+ }
+ else
+ {
+ return IlexPropertiesModel.Get(asset, tokenid);
+ }
+ }
+
+ public MetaPropertiesModel GetMeta(UInt160 asset, string tokenid)
+ {
+ if (D_MetaPropertiesModel.ContainsKey((asset, tokenid)))
+ {
+ return D_MetaPropertiesModel[(asset, tokenid)];
+ }
+ else
+ {
+ return MetaPropertiesModel.Get(asset, tokenid);
+ }
+ }
+
+ public NNSPropertiesModel GetNNS(UInt160 asset, string tokenid)
+ {
+ if (D_NNSPropertiesModel.ContainsKey((asset, tokenid)))
+ {
+ return D_NNSPropertiesModel[(asset, tokenid)];
+ }
+ else
+ {
+ return NNSPropertiesModel.Get(asset, tokenid);
+ }
+ }
+
+ public void AddOrUpdate(UInt160 asset, string tokenid, string properties, BigInteger selfControl)
+ {
+ AddOrUpdateNep11(asset, tokenid, properties);
+ if (Settings.Default.IlexContractHashes.Contains(asset.ToString()) || selfControl == 1)
+ {
+ AddOrUpdateIlex(asset, tokenid, properties);
+ }
+ if (Settings.Default.MetaContractHashes.Contains(asset.ToString()) || selfControl == 2)
+ {
+ AddOrUpdateMeta(asset, tokenid, properties);
+ }
+ if (Settings.Default.NNS == asset.ToString())
+ {
+ AddOrUpdateNNS(asset, tokenid, properties);
+ }
+ }
+
+ private void AddOrUpdateNep11(UInt160 asset, string tokenid, string properties)
{
Nep11PropertiesModel nep11PropertiesModel = Get(asset, tokenid);
if (nep11PropertiesModel is null)
@@ -79,10 +147,58 @@ public void AddOrUpdate(UInt160 asset, string tokenid, string properties)
D_Nep11PropertiesModel[(asset, tokenid)] = nep11PropertiesModel;
}
+ private void AddOrUpdateIlex(UInt160 asset, string tokenid, string properties)
+ {
+ IlexPropertiesModel ilexPropertiesModel = GetIlex(asset, tokenid);
+ if (ilexPropertiesModel is null)
+ {
+ ilexPropertiesModel = new(asset, tokenid, properties);
+ }
+ else
+ {
+ ilexPropertiesModel.UpdateProperties(properties);
+ }
+ D_IlexPropertiesModel[(asset, tokenid)] = ilexPropertiesModel;
+ }
+
+ private void AddOrUpdateMeta(UInt160 asset, string tokenid, string properties)
+ {
+ MetaPropertiesModel metaPropertiesModel = GetMeta(asset, tokenid);
+ if (metaPropertiesModel is null)
+ {
+ metaPropertiesModel = new(asset, tokenid, properties);
+ }
+ else
+ {
+ metaPropertiesModel.UpdateProperties(properties);
+ }
+ D_MetaPropertiesModel[(asset, tokenid)] = metaPropertiesModel;
+ }
+
+ private void AddOrUpdateNNS(UInt160 asset, string tokenid, string properties)
+ {
+ NNSPropertiesModel nnsPropertiesModel = GetNNS(asset, tokenid);
+ if (nnsPropertiesModel is null)
+ {
+ nnsPropertiesModel = new(asset, tokenid, properties);
+ }
+ else
+ {
+ nnsPropertiesModel.Properties = properties;
+ }
+ D_NNSPropertiesModel[(asset, tokenid)] = nnsPropertiesModel;
+ }
+
public void Save(Transaction tran)
{
if (D_Nep11PropertiesModel.Values.Count > 0)
tran.SaveAsync(D_Nep11PropertiesModel.Values).Wait();
+ if (D_IlexPropertiesModel.Values.Count > 0)
+ tran.SaveAsync(D_IlexPropertiesModel.Values).Wait();
+ if (D_MetaPropertiesModel.Values.Count > 0)
+ tran.SaveAsync(D_MetaPropertiesModel.Values).Wait();
+ if (D_NNSPropertiesModel.Values.Count > 0)
+ tran.SaveAsync(D_NNSPropertiesModel.Values).Wait();
}
}
}
diff --git a/Fura/DB/MongoClient.cs b/Fura/DB/MongoClient.cs
index 6746716..bff6522 100644
--- a/Fura/DB/MongoClient.cs
+++ b/Fura/DB/MongoClient.cs
@@ -35,7 +35,7 @@ public static async Task InitDB(string dbName, string url)
public static async Task InitCollectionAndIndex()
{
- var assembly = Assembly.Load(File.ReadAllBytes("Plugins/Fura.dll"));
+ var assembly = Assembly.Load(File.ReadAllBytes("Plugins/Fura/Fura.dll"));
foreach (Type type in assembly.ExportedTypes)
{
diff --git a/Fura/Fura.cs b/Fura/Fura.cs
index c620ee5..48ec0bd 100644
--- a/Fura/Fura.cs
+++ b/Fura/Fura.cs
@@ -13,15 +13,29 @@
using System.Threading.Tasks;
using System.IO;
using System.Reflection;
+using Neo.Plugins.Notification;
namespace Neo.Plugins
{
- public class Fura : Plugin, IPersistencePlugin
+ public class Fura : Plugin
{
public override string Name => "Fura";
public override string Description => "Analyze the data and store it in MongoDB";
+ public Fura()
+ {
+ Blockchain.Committing += OnCommitting;
+ Blockchain.Committed += OnCommitted;
+ }
+
+
+ public override void Dispose()
+ {
+ Blockchain.Committing -= OnCommitting;
+ Blockchain.Committed -= OnCommitted;
+ }
+
protected override void Configure()
{
Settings.Load(GetConfiguration());
@@ -42,8 +56,9 @@ protected override void OnSystemLoaded(NeoSystem system)
MongoClient.InitBasicData(system).Wait();
}
- void IPersistencePlugin.OnPersist(NeoSystem system, Block block, DataCache snapshot, IReadOnlyList applicationExecutedList)
+ void OnCommitting(NeoSystem system, Block block, DataCache snapshot, IReadOnlyList applicationExecutedList)
{
+ Loger.Common(string.Format("OnPersist------ {0} 高度的数据正在录入-- 总计有{1}比交易", block.Index, applicationExecutedList.Count));
bool loop = true;
uint errLoopTimes = 0;
while (loop)
@@ -68,9 +83,18 @@ void IPersistencePlugin.OnPersist(NeoSystem system, Block block, DataCache snaps
{
Parallel.For(0, applicationExecutedList.Count, (i) =>
{
- ExecApplicationExecuted(applicationExecutedList[i], system, block, snapshot);
+ try
+ {
+ ExecApplicationExecuted(applicationExecutedList[i], system, block, snapshot);
+ }
+ catch (Exception e)
+ {
+ DebugModel debugModel = new(e.Message);
+ debugModel.SaveAsync().Wait();
+ }
});
}
+ Loger.Common(String.Format("application exec done"));
//标记此块已经结束
RecordPersistModel recordPersistModel = RecordPersistModel.Get(block.Index);
recordPersistModel.State = EnumRecordState.Confirm.ToString();
@@ -88,12 +112,13 @@ void IPersistencePlugin.OnPersist(NeoSystem system, Block block, DataCache snaps
errLoopTimes++;
DebugModel debugModel = new(string.Format("{0}---ExecApplicationExecuted----block: {1}, loopTimes:{2}, error: {3}", Settings.Default.PName, block.Index, errLoopTimes, e));
debugModel.SaveAsync().Wait();
- if (errLoopTimes < 100)
+ if (errLoopTimes < 30)
{
System.Threading.Thread.Sleep(Settings.Default.SleepTime * 100);
}
else
{
+ loop = false;
throw;
}
}
@@ -109,8 +134,9 @@ void IPersistencePlugin.OnPersist(NeoSystem system, Block block, DataCache snaps
}
}
- void IPersistencePlugin.OnCommit(NeoSystem system, Block block, DataCache snapshot)
+ void OnCommitted(NeoSystem system, Block block)
{
+ Loger.Common(string.Format("OnCommit------ {0} 高度的数据正在录入", block.Index));
bool loop = true;
uint errLoopTimes = 0;
while (loop)
@@ -128,7 +154,7 @@ void IPersistencePlugin.OnCommit(NeoSystem system, Block block, DataCache snapsh
{
try
{
- ExecBlock(transaction, system, block, snapshot);
+ ExecBlock(transaction, system, block);
var time1 = (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000;
Loger.Common(string.Format("OnCommit------ {0} 高度的数据录入耗时 {1} ms", block.Index, time1 - time0));
loop = false;
@@ -248,7 +274,7 @@ void ExecApplicationExecuted(Blockchain.ApplicationExecuted applicationExecuted,
if(executionModel.VmState == "HALT")
{
//通过解析script得到调用了哪些合约哪些方法,从而处理一些特殊数据
- list_ScCall = VM.Helper.Script2ScCallModels(applicationExecuted.Transaction.Script, applicationExecuted.Transaction.Hash, applicationExecuted.Transaction.Sender, applicationExecuted.VMState.ToString());
+ list_ScCall = VM.Helper.Script2ScCallModels(applicationExecuted.Transaction.Script.ToArray(), applicationExecuted.Transaction.Hash, applicationExecuted.Transaction.Sender, applicationExecuted.VMState.ToString());
}
}
else
@@ -270,14 +296,14 @@ void ExecApplicationExecuted(Blockchain.ApplicationExecuted applicationExecuted,
var notificationModel = new NotificationModel(executionModel.Txid, i, executionModel.BlockHash, executionModel.Timestamp, n.ScriptHash, n.EventName, executionModel.VmState, n.State);
notificationModels.Add(notificationModel);
}
- if (notificationModels.Count > 0)
+ if (notificationModels.Count > 0 && notificationModels.Count < 1500)
{
DBCache.Ins.cacheNotification.Add(notificationModels);
NotificationMgr.Ins.Filter(notificationModels, system, block, snapshot);
}
}
- void ExecBlock(MongoDB.Entities.Transaction transaction, NeoSystem system, Block block, DataCache snapshot)
+ void ExecBlock(MongoDB.Entities.Transaction transaction, NeoSystem system, Block block)
{
//如果这个高度的block数据能在数据库中查到,证明已经录入过了(防止重启重录)
BlockModel blockModel = BlockModel.Get(block.Hash);
@@ -318,21 +344,24 @@ void ExecBlock(MongoDB.Entities.Transaction transaction, NeoSystem system, Block
candidateModel_old = candidateModel_old.Select(c => { c.IsCommittee = false; return c; }).ToList();
transaction.SaveAsync(candidateModel_old).Wait();
}
- //更新新的一批次
- ECPoint[] committees = Neo.SmartContract.Native.NeoToken.NEO.GetCommittee(snapshot);
- CandidateModel[] candidateModels_new = committees.Select(c =>
+ using(var snapshot = system.GetSnapshot())
{
- var hash = Contract.CreateSignatureContract(c).ScriptHash;
- var candidateModel = CandidateModel.Get(hash);
- if (candidateModel is null)
+ //更新新的一批次
+ ECPoint[] committees = Neo.SmartContract.Native.NeoToken.NEO.GetCommittee(snapshot);
+ CandidateModel[] candidateModels_new = committees.Select(c =>
{
- var votes = Neo.Plugins.VM.Helper.GetCandidateVotes(c, system, snapshot);
- candidateModel = new CandidateModel(hash, false, votes.ToString(), true);
- }
- candidateModel.IsCommittee = true;
- return candidateModel;
- }).ToArray();
- transaction.SaveAsync(candidateModels_new).Wait();
+ var hash = Contract.CreateSignatureContract(c).ScriptHash;
+ var candidateModel = CandidateModel.Get(hash);
+ if (candidateModel is null)
+ {
+ var votes = Neo.Plugins.VM.Helper.GetCandidateVotes(c, system, snapshot);
+ candidateModel = new CandidateModel(hash, false, votes.ToString(), true);
+ }
+ candidateModel.IsCommittee = true;
+ return candidateModel;
+ }).ToArray();
+ transaction.SaveAsync(candidateModels_new).Wait();
+ }
}
//将此块的record标记为完成
diff --git a/Fura/Fura.csproj b/Fura/Fura.csproj
index 9433b05..d8434c2 100644
--- a/Fura/Fura.csproj
+++ b/Fura/Fura.csproj
@@ -1,11 +1,11 @@
- net5.0
+ net7.0
Neo.Plugins
-
+
@@ -14,21 +14,15 @@
+
-
+
-
+
-
-
-
-
-
-
-
PreserveNewest
@@ -37,4 +31,7 @@
+
+
+
diff --git a/Fura/Fura/config.json b/Fura/Fura/config.json
index d1bb5a6..7e82269 100644
--- a/Fura/Fura/config.json
+++ b/Fura/Fura/config.json
@@ -8,6 +8,12 @@
"Log": false,
"SleepTime": 10,
"WaitTime": 120,
- "ConnectionString": ""
+ "ConnectionString": "",
+ "MarketContractIds": [ 0, 0 ],
+ "Nep11ContractIds": [],
+ "Nep17ContractIds": [],
+ "IlexContractHashes": [],
+ "MetaContractHashes": [],
+ "NNS": ""
}
}
diff --git a/Fura/Helper.cs b/Fura/Helper.cs
new file mode 100644
index 0000000..9cb9416
--- /dev/null
+++ b/Fura/Helper.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Numerics;
+using MongoDB.Bson;
+
+namespace Neo.Plugins
+{
+ public static class Helper
+ {
+ public static string WipeNumStrToFitDecimal128(this string str)
+ {
+ if(BigInteger.TryParse(str, out BigInteger bigint))
+ {
+ var maxLength = 34;
+ if (str.Length > maxLength)
+ {
+ var t = bigint / (BigInteger)Math.Pow(10, str.Length - maxLength);
+ t = t * (BigInteger)Math.Pow(10, str.Length - maxLength);
+ str = t.ToString();
+ }
+ }
+ return str;
+ }
+ }
+}
+
diff --git a/Fura/Models/AddressAssetModel.cs b/Fura/Models/AddressAssetModel.cs
index 16e7cf0..9a2b650 100644
--- a/Fura/Models/AddressAssetModel.cs
+++ b/Fura/Models/AddressAssetModel.cs
@@ -52,6 +52,8 @@ public async static Task InitCollectionAndIndex()
await DB.Index().Key(a => a.Balance, KeyType.Ascending).Key(a => a.Asset, KeyType.Ascending).Option(o => { o.Name = "_balance_asset_"; }).CreateAsync();
await DB.Index().Key(a => a.Balance, KeyType.Ascending).Key(a => a.Address, KeyType.Ascending).Option(o => { o.Name = "_balance_address_"; }).CreateAsync();
await DB.Index().Key(a => a.Address, KeyType.Ascending).Option(o => { o.Name = "_address_"; }).CreateAsync();
+ await DB.Index().Key(a => a.Balance, KeyType.Ascending).Option(o => { o.Name = "_balance_"; }).CreateAsync();
+ await DB.Index().Key(a => a.Asset, KeyType.Ascending).Option(o => { o.Name = "_asset_"; }).CreateAsync();
}
}
}
diff --git a/Fura/Models/AssetModel.cs b/Fura/Models/AssetModel.cs
index eb6c034..e06e8e0 100644
--- a/Fura/Models/AssetModel.cs
+++ b/Fura/Models/AssetModel.cs
@@ -53,7 +53,7 @@ public AssetModel(UInt160 hash,ulong firstTransferTime, string tokenName, byte d
TokenName = tokenName;
Decimals = decimals;
Symbol = symbol;
- TotalSupply = BsonDecimal128.Create(totalSupply.ToString());
+ TotalSupply = BsonDecimal128.Create(totalSupply.ToString().WipeNumStrToFitDecimal128());
Type = enumAssetType.ToString();
}
diff --git a/Fura/Models/ContractModel.cs b/Fura/Models/ContractModel.cs
index 4dbca53..e59fc38 100644
--- a/Fura/Models/ContractModel.cs
+++ b/Fura/Models/ContractModel.cs
@@ -3,7 +3,7 @@
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Driver;
using MongoDB.Entities;
-using Neo.IO.Json;
+using Neo.Json;
using Neo.Plugins.Attribute;
namespace Neo.Plugins.Models
@@ -19,7 +19,7 @@ public class ContractModel : Entity
public int _ID { get; set; }
[BsonElement("updatecounter")]
- public ushort UpdateCounter { get; set; }
+ public short UpdateCounter { get; set; }
[BsonElement("nef")]
public BsonString Nef { get; set; }
@@ -39,7 +39,7 @@ public class ContractModel : Entity
public ContractModel() { }
- public ContractModel(UInt160 hash,string name, int id, ushort updateCounter, JObject nef,JObject manifest, ulong createTime, UInt256 txid)
+ public ContractModel(UInt160 hash,string name, int id, short updateCounter, JObject nef,JObject manifest, ulong createTime, UInt256 txid)
{
Hash = hash;
Name = name;
@@ -53,7 +53,7 @@ public ContractModel(UInt160 hash,string name, int id, ushort updateCounter, JOb
public static ContractModel Get(UInt160 hash)
{
- ContractModel contractModel = DB.Find().Match(c => c.Hash == hash).ExecuteFirstAsync().Result;
+ ContractModel contractModel = DB.Find().Match(c => c.Hash == hash).Sort(c => c.CreateTime, Order.Descending).ExecuteFirstAsync().Result;
return contractModel;
}
@@ -61,7 +61,8 @@ public async static Task InitCollectionAndIndex()
{
await DB.CreateCollection(new CreateCollectionOptions());
await DB.Index().Key(a => a.Hash, KeyType.Ascending).Option(o => { o.Name = "_hash_"; }).CreateAsync();
- await DB.Index().Key(a => a.Hash, KeyType.Ascending).Key(a => a.UpdateCounter, KeyType.Ascending).Option(o => { o.Name = "_hash_updatecounter_unique_"; o.Unique = true; }).CreateAsync();
+ await DB.Index().Key(a => a.CreateTime, KeyType.Descending).Option(o => { o.Name = "_createtime_"; }).CreateAsync();
+ await DB.Index().Key(a => a.Hash, KeyType.Ascending).Key(a => a.UpdateCounter, KeyType.Ascending).Key(a => a.CreateTxid, KeyType.Ascending).Option(o => { o.Name = "_hash_updatecounter_createtxid_unique_"; o.Unique = true; }).CreateAsync();
}
}
}
diff --git a/Fura/Models/ExecutionModel.cs b/Fura/Models/ExecutionModel.cs
index 041fbc1..628ddd6 100644
--- a/Fura/Models/ExecutionModel.cs
+++ b/Fura/Models/ExecutionModel.cs
@@ -48,7 +48,24 @@ public ExecutionModel(UInt256 txid, UInt256 blockHash, ulong timestamp, string t
Exception = exception;
GasConsumed = gasconsumed;
Timestamp = timestamp;
- Stacks = stack.Select(p => p.ToJson().ToString()).ToArray();
+ if(stack.Length < 500)
+ {
+ Stacks = stack.Select(p =>
+ {
+ try
+ {
+ return p.ToJson().ToString();
+ }
+ catch
+ {
+ return "";
+ }
+ }).ToArray();
+ }
+ else
+ {
+ Stacks = new string[] { };
+ }
}
public static ExecutionModel Get(UInt256 txid,UInt256 blockHash, string trigger)
diff --git a/Fura/Models/GasMintBurnModel.cs b/Fura/Models/GasMintBurnModel.cs
index 2b63bdf..5abc477 100644
--- a/Fura/Models/GasMintBurnModel.cs
+++ b/Fura/Models/GasMintBurnModel.cs
@@ -13,9 +13,15 @@ public class GasMintBurnModel : Entity
[BsonElement("burnAmount")]
public BsonDecimal128 BurnAmount { get; set; }
+ [BsonElement("totalBurnAmount")]
+ public BsonDecimal128 TotalBurnAmount { get; set; }
+
[BsonElement("mintAmount")]
public BsonDecimal128 MintAmount { get; set; }
+ [BsonElement("totalMintAmount")]
+ public BsonDecimal128 TotalMintAmount { get; set; }
+
[BsonElement("blockIndex")]
public uint BlockIndex { get; set; }
@@ -23,6 +29,12 @@ public GasMintBurnModel()
{
}
+ public static GasMintBurnModel Get(uint BlockIndex)
+ {
+ GasMintBurnModel gasMintBurnModel = DB.Find().Match(g => g.BlockIndex == BlockIndex).ExecuteFirstAsync().Result;
+ return gasMintBurnModel;
+ }
+
public async static Task InitCollectionAndIndex()
{
await DB.CreateCollection(new CreateCollectionOptions());
diff --git a/Fura/Models/HeaderModel.cs b/Fura/Models/HeaderModel.cs
index 0255aa5..26b14db 100644
--- a/Fura/Models/HeaderModel.cs
+++ b/Fura/Models/HeaderModel.cs
@@ -79,8 +79,8 @@ public class WitnessModel
public WitnessModel(Witness witness)
{
- Invocation_B64String = Convert.ToBase64String(witness.InvocationScript);
- Verification_B64String = Convert.ToBase64String(witness.VerificationScript);
+ Invocation_B64String = Convert.ToBase64String(witness.InvocationScript.ToArray());
+ Verification_B64String = Convert.ToBase64String(witness.VerificationScript.ToArray());
}
public static WitnessModel[] ToModels(Witness[] witnesses)
diff --git a/Fura/Models/IlexPropertiesModel.cs b/Fura/Models/IlexPropertiesModel.cs
new file mode 100644
index 0000000..bd432bd
--- /dev/null
+++ b/Fura/Models/IlexPropertiesModel.cs
@@ -0,0 +1,71 @@
+using System;
+using System.Threading.Tasks;
+using MongoDB.Bson.Serialization.Attributes;
+using MongoDB.Driver;
+using MongoDB.Entities;
+using Neo.Network.P2P.Payloads;
+using Neo.Plugins.Attribute;
+using static System.Net.Mime.MediaTypeNames;
+
+namespace Neo.Plugins.Models
+{
+ [Collection("SelfControlNep11Properties")]
+ public class IlexPropertiesModel : Entity
+ {
+ [UInt160AsString]
+ [BsonElement("asset")]
+ public UInt160 Asset { get; set; }
+
+ [BsonElement("tokenid")]
+ public string TokenId { get; set; }
+
+ [BsonElement("properties")]
+ public string Properties { get; set; }
+
+ [BsonElement("name")]
+ public string Name { get; set; }
+
+ [BsonElement("tokenURI")]
+ public string TokenURI { get; set; }
+
+ public IlexPropertiesModel() { }
+
+ public IlexPropertiesModel(UInt160 asset, string tokenid, string properties)
+ {
+ Asset = asset;
+ TokenId = tokenid;
+ Properties = properties;
+ try
+ {
+ Json.JObject jObject = (Json.JObject)Json.JObject.Parse(properties);
+ Name = jObject["name"].GetString();
+ TokenURI = jObject["tokenURI"].GetString();
+ }
+ catch
+ {
+
+ }
+ }
+
+ public void UpdateProperties(string properties)
+ {
+ Properties = Properties;
+ try
+ {
+ Json.JObject jObject = (Json.JObject)Json.JObject.Parse(properties);
+ Name = jObject["name"].GetString();
+ TokenURI = jObject["tokenURI"].GetString();
+ }
+ catch
+ {
+
+ }
+ }
+
+ public static IlexPropertiesModel Get(UInt160 asset, string tokenid)
+ {
+ IlexPropertiesModel model = DB.Find().Match(a => a.Asset == asset && a.TokenId == tokenid).ExecuteFirstAsync().Result;
+ return model;
+ }
+ }
+}
diff --git a/Fura/Models/MarketModel.cs b/Fura/Models/MarketModel.cs
new file mode 100644
index 0000000..97f4029
--- /dev/null
+++ b/Fura/Models/MarketModel.cs
@@ -0,0 +1,302 @@
+using MongoDB.Bson;
+using MongoDB.Bson.Serialization.Attributes;
+using MongoDB.Driver;
+using MongoDB.Entities;
+using Neo.Plugins.Attribute;
+using System.Numerics;
+using System.Threading.Tasks;
+
+namespace Neo.Plugins.Models
+{
+ [Collection("Market")]
+ public class MarketModel : Entity
+ {
+ [UInt160AsString]
+ [BsonElement("asset")]
+ public UInt160 Asset { get; set; }
+
+ [BsonElement("tokenid")]
+ public string TokenId { get; set; }
+
+ [BsonElement("amount")]
+ public BsonDecimal128 Amount { get; set; }
+
+ [UInt160AsString]
+ [BsonElement("owner")]
+ public UInt160 Owner { get; set; }
+
+ [UInt160AsString]
+ [BsonElement("market")]
+ public UInt160 Market { get; set; }
+
+ [BsonElement("auctionType")]
+ public uint AuctionType { get; set; }
+
+ [UInt160AsString]
+ [BsonElement("auctor")]
+ public UInt160 Auctor { get; set; }
+
+ [UInt160AsString]
+ [BsonElement("auctionAsset")]
+ public UInt160 AuctionAsset { get; set; }
+
+ [BsonElement("auctionAmount")]
+ public BsonDecimal128 AuctionAmount { get; set; }
+
+ [BsonElement("deadline")]
+ public ulong Deadline { get; set; }
+
+ [UInt160AsString]
+ [BsonElement("bidder")]
+ public UInt160 Bidder { get; set; }
+
+ [BsonElement("bidAmount")]
+ public BsonDecimal128 BidAmount { get; set; }
+
+ [BsonElement("timestamp")]
+ public ulong Timestamp;
+
+ public static MarketModel Get(UInt160 owner, UInt160 asset, string tokenid)
+ {
+ MarketModel marketModel = DB.Find().Match(a => a.Owner == owner && a.Asset == asset && a.TokenId == tokenid).ExecuteFirstAsync().Result;
+ return marketModel;
+ }
+
+ public static void Delete(UInt160 owner, UInt160 asset, string tokenid)
+ {
+ }
+
+ public async static Task InitCollectionAndIndex()
+ {
+ await DB.CreateCollection(new CreateCollectionOptions());
+
+ await DB.Index()
+ .Key(a => a.TokenId, KeyType.Ascending)
+ .Key(a => a.Amount, KeyType.Ascending)
+ .Key(a => a.AuctionType, KeyType.Ascending)
+ .Key(a => a.Asset, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Key(a => a.Deadline, KeyType.Ascending)
+ .Option(o => { o.Name = "_tokenid_amount_auctionType_asset_market_deadline_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.Asset, KeyType.Ascending)
+ .Key(a => a.TokenId, KeyType.Ascending)
+ .Key(a => a.Amount, KeyType.Ascending)
+ .Option(o => { o.Name = "_asset_tokenid_amount_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.Asset, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Key(a => a.Amount, KeyType.Ascending)
+ .Key(a => a.Owner, KeyType.Ascending)
+ .Option(o => { o.Name = "_asset_market_amount_owner_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.Asset, KeyType.Ascending)
+ .Key(a => a.Owner, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Option(o => { o.Name = "_asset_market_owner_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.Asset, KeyType.Ascending)
+ .Key(a => a.AuctionType, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Option(o => { o.Name = "_asset_market_auctionType_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.Asset, KeyType.Ascending)
+ .Key(a => a.Amount, KeyType.Ascending)
+ .Key(a => a.TokenId, KeyType.Ascending)
+ .Option(o => { o.Name = "_asset_amount_tokenid_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.AuctionAsset, KeyType.Ascending)
+ .Key(a => a.AuctionType, KeyType.Ascending)
+ .Key(a => a.Deadline, KeyType.Ascending)
+ .Key(a => a.Asset, KeyType.Ascending)
+ .Key(a => a.Amount, KeyType.Ascending)
+ .Key(a => a.TokenId, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Key(a => a.Owner, KeyType.Ascending)
+ .Option(o => { o.Name = "_auctionAsset_amount_auctionType_deadline_asset_tokenid_market_owner_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.Amount, KeyType.Ascending)
+ .Key(a => a.AuctionType, KeyType.Ascending)
+ .Key(a => a.Deadline, KeyType.Ascending)
+ .Key(a => a.Asset, KeyType.Ascending)
+ .Key(a => a.TokenId, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Key(a => a.Owner, KeyType.Ascending)
+ .Option(o => { o.Name = "_auctionType_deadline_asset_amount_tokenid_market_owner_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.Asset, KeyType.Ascending)
+ .Key(a => a.AuctionAsset, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Key(a => a.Amount, KeyType.Ascending)
+ .Option(o => { o.Name = "_asset_auctionAsset_market_amount_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.AuctionAsset, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Key(a => a.Amount, KeyType.Ascending)
+ .Option(o => { o.Name = "_auctionAsset_market_amount_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.Asset, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Key(a => a.Amount, KeyType.Ascending)
+ .Option(o => { o.Name = "_market_asset_amount_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.Asset, KeyType.Ascending)
+ .Key(a => a.AuctionAsset, KeyType.Ascending)
+ .Key(a => a.Amount, KeyType.Ascending)
+ .Key(a => a.Auctor, KeyType.Ascending)
+ .Key(a => a.AuctionType, KeyType.Ascending)
+ .Key(a => a.Deadline, KeyType.Ascending)
+ .Key(a => a.Owner, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Option(o => { o.Name = "_asset_auctionAsset_amount_auctor_auctionType_deadline_owner_market_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.AuctionAsset, KeyType.Ascending)
+ .Key(a => a.Amount, KeyType.Ascending)
+ .Key(a => a.Auctor, KeyType.Ascending)
+ .Key(a => a.AuctionType, KeyType.Ascending)
+ .Key(a => a.Deadline, KeyType.Ascending)
+ .Key(a => a.Owner, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Option(o => { o.Name = "_auctionAsset_amount_auctor_auctionType_deadline_owner_market_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.Amount, KeyType.Ascending)
+ .Key(a => a.Auctor, KeyType.Ascending)
+ .Key(a => a.Deadline, KeyType.Ascending)
+ .Key(a => a.AuctionType, KeyType.Ascending)
+ .Key(a => a.Owner, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Option(o => { o.Name = "_amount_auctor_auctionType_deadline_owner_market_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.Asset, KeyType.Ascending)
+ .Key(a => a.AuctionAsset, KeyType.Ascending)
+ .Key(a => a.Deadline, KeyType.Ascending)
+ .Key(a => a.Owner, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Key(a => a.Amount, KeyType.Ascending)
+ .Option(o => { o.Name = "_asset_auctionAsset_deadline_owner_market_amount_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.AuctionAsset, KeyType.Ascending)
+ .Key(a => a.Deadline, KeyType.Ascending)
+ .Key(a => a.Owner, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Key(a => a.Amount, KeyType.Ascending)
+ .Option(o => { o.Name = "_auctionAsset_deadline_owner_market_amount_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.Owner, KeyType.Ascending)
+ .Key(a => a.Deadline, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Key(a => a.Amount, KeyType.Ascending)
+ .Option(o => { o.Name = "_deadline_owner_market_amount_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.Owner, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Key(a => a.Amount, KeyType.Ascending)
+ .Option(o => { o.Name = "_owner_market_amount_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.Asset, KeyType.Ascending)
+ .Key(a => a.AuctionAsset, KeyType.Ascending)
+ .Key(a => a.Auctor, KeyType.Ascending)
+ .Key(a => a.BidAmount, KeyType.Ascending)
+ .Key(a => a.Amount, KeyType.Ascending)
+ .Key(a => a.Deadline, KeyType.Ascending)
+ .Key(a => a.Owner, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Option(o => { o.Name = "_asset_auctionAsset_auctor_bidAmount_amount_deadline_owner_market_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.AuctionAsset, KeyType.Ascending)
+ .Key(a => a.Auctor, KeyType.Ascending)
+ .Key(a => a.BidAmount, KeyType.Ascending)
+ .Key(a => a.Amount, KeyType.Ascending)
+ .Key(a => a.Deadline, KeyType.Ascending)
+ .Key(a => a.Owner, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Option(o => { o.Name = "_auctionAsset_auctor_bidAmount__amount_deadline_owner_market_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.Auctor, KeyType.Ascending)
+ .Key(a => a.BidAmount, KeyType.Ascending)
+ .Key(a => a.Amount, KeyType.Ascending)
+ .Key(a => a.Deadline, KeyType.Ascending)
+ .Key(a => a.Owner, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Option(o => { o.Name = "_auctor_bidAmount_amount_deadline_owner_market_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.Asset, KeyType.Ascending)
+ .Key(a => a.AuctionAsset, KeyType.Ascending)
+ .Key(a => a.Bidder, KeyType.Ascending)
+ .Key(a => a.BidAmount, KeyType.Ascending)
+ .Key(a => a.Amount, KeyType.Ascending)
+ .Key(a => a.Deadline, KeyType.Ascending)
+ .Key(a => a.Owner, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Option(o => { o.Name = "_asset_auctionAsset_bidder_bidAmount_amount_deadline_owner_market_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.AuctionAsset, KeyType.Ascending)
+ .Key(a => a.Bidder, KeyType.Ascending)
+ .Key(a => a.BidAmount, KeyType.Ascending)
+ .Key(a => a.Amount, KeyType.Ascending)
+ .Key(a => a.Deadline, KeyType.Ascending)
+ .Key(a => a.Owner, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Option(o => { o.Name = "_auctionAsset_bidder_bidAmount_amount_deadline_owner_market_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.Bidder, KeyType.Ascending)
+ .Key(a => a.BidAmount, KeyType.Ascending)
+ .Key(a => a.Amount, KeyType.Ascending)
+ .Key(a => a.Deadline, KeyType.Ascending)
+ .Key(a => a.Owner, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Option(o => { o.Name = "_bidder_bidAmount_amount_deadline_owner_market_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.Asset, KeyType.Ascending)
+ .Key(a => a.AuctionAsset, KeyType.Ascending)
+ .Key(a => a.Deadline, KeyType.Ascending)
+ .Key(a => a.Auctor, KeyType.Ascending)
+ .Key(a => a.Owner, KeyType.Ascending)
+ .Key(a => a.Amount, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Option(o => { o.Name = "_asset_auctionAsset_deadline_auctor_owner_amount_market_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.AuctionAsset, KeyType.Ascending)
+ .Key(a => a.Deadline, KeyType.Ascending)
+ .Key(a => a.Auctor, KeyType.Ascending)
+ .Key(a => a.Owner, KeyType.Ascending)
+ .Key(a => a.Amount, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Option(o => { o.Name = "_auctionAsset_deadline_auctor_owner_amount_market_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.Deadline, KeyType.Ascending)
+ .Key(a => a.Auctor, KeyType.Ascending)
+ .Key(a => a.Owner, KeyType.Ascending)
+ .Key(a => a.Amount, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Option(o => { o.Name = "_deadline_auctor_owner_amount_market_"; }).CreateAsync();
+
+ }
+ }
+}
diff --git a/Fura/Models/MetaPropertiesModel.cs b/Fura/Models/MetaPropertiesModel.cs
new file mode 100644
index 0000000..e994d8f
--- /dev/null
+++ b/Fura/Models/MetaPropertiesModel.cs
@@ -0,0 +1,91 @@
+using System;
+using System.Threading.Tasks;
+using MongoDB.Bson.Serialization.Attributes;
+using MongoDB.Driver;
+using MongoDB.Entities;
+using Neo.Network.P2P.Payloads;
+using Neo.Plugins.Attribute;
+
+namespace Neo.Plugins.Models
+{
+ [Collection("SelfControlNep11Properties")]
+ public class MetaPropertiesModel : Entity
+ {
+ [UInt160AsString]
+ [BsonElement("asset")]
+ public UInt160 Asset { get; set; }
+
+ [BsonElement("tokenid")]
+ public string TokenId { get; set; }
+
+ [BsonElement("properties")]
+ public string Properties { get; set; }
+
+ [BsonElement("name")]
+ public string Name { get; set; }
+
+ [BsonElement("image")]
+ public string Image { get; set; }
+
+ [BsonElement("series")]
+ public string Series { get; set; }
+
+ [BsonElement("supply")]
+ public string Supply { get; set; }
+
+ [BsonElement("thumbnail")]
+ public string Thumbnail { get; set; }
+
+ public MetaPropertiesModel() { }
+
+ public MetaPropertiesModel(UInt160 asset, string tokenid, string properties)
+ {
+ Asset = asset;
+ TokenId = tokenid;
+ Properties = properties;
+ try
+ {
+ Json.JObject jObject = (Json.JObject)Json.JObject.Parse(properties);
+ Name = jObject["name"].GetString();
+ Image = jObject["image"].GetString();
+ Series = jObject["series"].GetString();
+ Supply = jObject["supply"].GetString();
+ Thumbnail = jObject["thumbnail"].GetString();
+ }
+ catch
+ {
+
+ }
+ }
+
+ public void UpdateProperties(string properties)
+ {
+ Properties = Properties;
+ try
+ {
+ Json.JObject jObject = (Json.JObject)Json.JObject.Parse(properties);
+ Name = jObject["name"].GetString();
+ Image = jObject["image"].GetString();
+ Series = jObject["series"].GetString();
+ Supply = jObject["supply"].GetString();
+ Thumbnail = jObject["thumbnail"].GetString();
+ }
+ catch
+ {
+
+ }
+ }
+
+ public static MetaPropertiesModel Get(UInt160 asset, string tokenid)
+ {
+ MetaPropertiesModel model = DB.Find().Match(a => a.Asset == asset && a.TokenId == tokenid).ExecuteFirstAsync().Result;
+ return model;
+ }
+
+ public async static Task InitCollectionAndIndex()
+ {
+ await DB.CreateCollection(new CreateCollectionOptions());
+ await DB.Index().Key(a => a.Asset, KeyType.Ascending).Key(a => a.TokenId, KeyType.Ascending).Option(o => { o.Name = "_asset_tokenid_unique_"; o.Unique = true; }).CreateAsync();
+ }
+ }
+}
diff --git a/Fura/Models/NNSPropertiesModel.cs b/Fura/Models/NNSPropertiesModel.cs
new file mode 100644
index 0000000..82d3cc6
--- /dev/null
+++ b/Fura/Models/NNSPropertiesModel.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Threading.Tasks;
+using MongoDB.Bson.Serialization.Attributes;
+using MongoDB.Driver;
+using MongoDB.Entities;
+using Neo.Network.P2P.Payloads;
+using Neo.Plugins.Attribute;
+
+namespace Neo.Plugins.Models
+{
+ [Collection("SelfControlNep11Properties")]
+ public class NNSPropertiesModel : Entity
+ {
+ [UInt160AsString]
+ [BsonElement("asset")]
+ public UInt160 Asset { get; set; }
+
+ [BsonElement("tokenid")]
+ public string TokenId { get; set; }
+
+ [BsonElement("properties")]
+ public string Properties { get; set; }
+
+ public NNSPropertiesModel() { }
+
+ public NNSPropertiesModel(UInt160 asset, string tokenid, string properties)
+ {
+ Asset = asset;
+ TokenId = tokenid;
+ Properties = properties;
+ }
+
+ public static NNSPropertiesModel Get(UInt160 asset, string tokenid)
+ {
+ NNSPropertiesModel nnsPropertiesModel = DB.Find().Match(a => a.Asset == asset && a.TokenId == tokenid).ExecuteFirstAsync().Result;
+ return nnsPropertiesModel;
+ }
+ }
+}
diff --git a/Fura/Models/Notification/MarketNotificationModel.cs b/Fura/Models/Notification/MarketNotificationModel.cs
new file mode 100644
index 0000000..08c63ca
--- /dev/null
+++ b/Fura/Models/Notification/MarketNotificationModel.cs
@@ -0,0 +1,150 @@
+using System.Numerics;
+using System.Threading.Tasks;
+using MongoDB.Bson;
+using MongoDB.Bson.Serialization.Attributes;
+using MongoDB.Driver;
+using MongoDB.Entities;
+using Neo.Plugins.Attribute;
+
+namespace Neo.Plugins.Models
+{
+ [Collection("MarketNotification")]
+ public class MarketNotificationModel : Entity
+ {
+ [BsonElement("nonce")]
+ public ulong Nonce { get; set; }
+
+ [UInt256AsString]
+ [BsonElement("txid")]
+ public UInt256 Txid { get; set; }
+
+ [UInt256AsString]
+ [BsonElement("blockhash")]
+ public UInt256 BlockHash { get; set; }
+
+ [UInt160AsString]
+ [BsonElement("user")]
+ public UInt160 User { get; set; }
+
+ [UInt160AsString]
+ [BsonElement("market")]
+ public UInt160 Market { get; set; }
+
+ [UInt160AsString]
+ [BsonElement("asset")]
+ public UInt160 Asset { get; set; }
+
+ [BsonElement("tokenid")]
+ public string TokenId { get; set; }
+
+ [BsonElement("eventname")]
+ public string EventName { get; set; }
+
+ [BsonElement("extendData")]
+ public string ExtendData { get; set; }
+
+ [BsonElement("timestamp")]
+ public ulong Timestamp { get; set; }
+
+ public MarketNotificationModel(UInt256 txid, UInt256 blockhash, BigInteger nonce, UInt160 user, UInt160 market, UInt160 asset, string tokenId, string eventName, string extendData, ulong timestamp)
+ {
+ Nonce = (ulong)nonce;
+ Txid = txid;
+ BlockHash = blockhash;
+ User = user;
+ Market = market;
+ Asset = asset;
+ TokenId = tokenId;
+ EventName = eventName;
+ ExtendData = extendData;
+ Timestamp = timestamp;
+ }
+
+ public async static Task InitCollectionAndIndex()
+ {
+ await DB.CreateCollection(new CreateCollectionOptions());
+
+ await DB.Index()
+ .Key(a => a.Nonce, KeyType.Ascending)
+ .Key(a => a.Asset, KeyType.Ascending)
+ .Key(a => a.TokenId, KeyType.Ascending)
+ .Key(a => a.EventName, KeyType.Ascending)
+ .Key(a => a.Timestamp, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Option(o => { o.Name = "_nonce_asset_tokenid_eventname_timestamp_market_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.Nonce, KeyType.Ascending)
+ .Key(a => a.Asset, KeyType.Ascending)
+ .Key(a => a.EventName, KeyType.Ascending)
+ .Key(a => a.Timestamp, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Option(o => { o.Name = "_nonce_asset_eventname_timestamp_market_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.Nonce, KeyType.Ascending)
+ .Key(a => a.Asset, KeyType.Ascending)
+ .Key(a => a.EventName, KeyType.Ascending)
+ .Key(a => a.Timestamp, KeyType.Ascending)
+ .Key(a => a.User, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Option(o => { o.Name = "_nonce_asset_eventname_timestamp_user_market_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.Nonce, KeyType.Ascending)
+ .Key(a => a.Asset, KeyType.Ascending)
+ .Key(a => a.User, KeyType.Ascending)
+ .Key(a => a.EventName, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Option(o => { o.Name = "_nonce_asset_user_eventname_market_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.Nonce, KeyType.Ascending)
+ .Key(a => a.Asset, KeyType.Ascending)
+ .Key(a => a.User, KeyType.Ascending)
+ .Key(a => a.EventName, KeyType.Ascending)
+ .Key(a => a.TokenId, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Option(o => { o.Name = "_nonce_asset_user_eventname_tokenid_market_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.EventName, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Key(a => a.Asset, KeyType.Ascending)
+ .Option(o => { o.Name = "_eventname_market_asset_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.Asset, KeyType.Ascending)
+ .Key(a => a.TokenId, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Key(a => a.EventName, KeyType.Ascending)
+ .Option(o => { o.Name = "_asset_tokenid_market_eventname_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.Market, KeyType.Ascending)
+ .Key(a => a.Timestamp, KeyType.Ascending)
+ .Option(o => { o.Name = "_market_timestamp_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.User, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Key(a => a.Timestamp, KeyType.Ascending)
+ .Option(o => { o.Name = "_user_market_timestamp_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.EventName, KeyType.Ascending)
+ .Key(a => a.Asset, KeyType.Ascending)
+ .Key(a => a.Timestamp, KeyType.Ascending)
+ .Key(a => a.TokenId, KeyType.Ascending)
+ .Option(o => { o.Name = "_eventname_asset_tokenid_timestamp_"; }).CreateAsync();
+
+ await DB.Index()
+ .Key(a => a.EventName, KeyType.Ascending)
+ .Key(a => a.Asset, KeyType.Ascending)
+ .Key(a => a.TokenId, KeyType.Ascending)
+ .Key(a => a.Timestamp, KeyType.Ascending)
+ .Key(a => a.Market, KeyType.Ascending)
+ .Option(o => { o.Name = "_eventname_asset_tokenid_market_timestamp_"; }).CreateAsync();
+ }
+ }
+}
diff --git a/Fura/Models/Notification/Nep11TransferNotificationModel.cs b/Fura/Models/Notification/Nep11TransferNotificationModel.cs
index 13f3966..673c398 100644
--- a/Fura/Models/Notification/Nep11TransferNotificationModel.cs
+++ b/Fura/Models/Notification/Nep11TransferNotificationModel.cs
@@ -56,9 +56,9 @@ public Nep11TransferNotificationModel(UInt256 txid, UInt256 blockHash, ulong tim
TokenId = tokenId;
From = from;
To = to;
- Value = BsonDecimal128.Create(value.ToString());
- FromBalanceOf = BsonDecimal128.Create(fromBalanceOf.ToString());
- ToBalanceOf = BsonDecimal128.Create(toBalanceOf.ToString());
+ Value = BsonDecimal128.Create(value.ToString().WipeNumStrToFitDecimal128());
+ FromBalanceOf = BsonDecimal128.Create(fromBalanceOf.ToString().WipeNumStrToFitDecimal128());
+ ToBalanceOf = BsonDecimal128.Create(toBalanceOf.ToString().WipeNumStrToFitDecimal128());
Timestamp = timestamp;
}
diff --git a/Fura/Models/Notification/TransferNotificationModel.cs b/Fura/Models/Notification/TransferNotificationModel.cs
index 819511d..75fc4d8 100644
--- a/Fura/Models/Notification/TransferNotificationModel.cs
+++ b/Fura/Models/Notification/TransferNotificationModel.cs
@@ -52,9 +52,9 @@ public TransferNotificationModel(UInt256 txid, UInt256 blockHash, ulong timestam
AssetHash = assetHash;
From = from;
To = to;
- Value = BsonDecimal128.Create(value.ToString());
- FromBalanceOf = BsonDecimal128.Create(fromBalanceOf.ToString());
- ToBalanceOf = BsonDecimal128.Create(toBalanceOf.ToString());
+ Value = BsonDecimal128.Create(value.ToString().WipeNumStrToFitDecimal128());
+ FromBalanceOf = BsonDecimal128.Create(fromBalanceOf.ToString().WipeNumStrToFitDecimal128());
+ ToBalanceOf = BsonDecimal128.Create(toBalanceOf.ToString().WipeNumStrToFitDecimal128());
Timestamp = timestamp;
}
diff --git a/Fura/Models/ScCall/CandidateModel.cs b/Fura/Models/ScCall/CandidateModel.cs
index 52ff7cd..aa7888b 100644
--- a/Fura/Models/ScCall/CandidateModel.cs
+++ b/Fura/Models/ScCall/CandidateModel.cs
@@ -30,7 +30,7 @@ public CandidateModel(UInt160 candidate, bool state, string votesOfCandidate, bo
{
Candidate = candidate;
State = state;
- VotesOfCandidate = BsonDecimal128.Create(votesOfCandidate);
+ VotesOfCandidate = BsonDecimal128.Create(votesOfCandidate.WipeNumStrToFitDecimal128());
IsCommittee = isCommittee;
}
diff --git a/Fura/Models/ScCall/VoteModel.cs b/Fura/Models/ScCall/VoteModel.cs
index ab04a9e..8c7245f 100644
--- a/Fura/Models/ScCall/VoteModel.cs
+++ b/Fura/Models/ScCall/VoteModel.cs
@@ -50,7 +50,7 @@ public VoteModel(UInt256 lastVoteTxid, uint blockNumber, UInt160 voter, UInt160
Voter = voter;
Candidate = candidate;
CandidatePubKey = candidatePubKey;
- BalanceOfVoter = BsonDecimal128.Create(balanceOfVoter);
+ BalanceOfVoter = BsonDecimal128.Create(balanceOfVoter.WipeNumStrToFitDecimal128());
LastTransferTxid = lastTransferTxid;
}
diff --git a/Fura/Models/TransactionModel.cs b/Fura/Models/TransactionModel.cs
index 00d6529..8d1a586 100644
--- a/Fura/Models/TransactionModel.cs
+++ b/Fura/Models/TransactionModel.cs
@@ -74,7 +74,7 @@ public TransactionModel(Neo.Network.P2P.Payloads.Transaction transaction,UInt256
ValidUntilBlock = transaction.ValidUntilBlock;
Signers = SignerModel.ToModels(transaction.Signers);
Attributes = TransactionAttributeModel.ToModels(transaction.Attributes);
- Script = transaction.Script;
+ Script = transaction.Script.ToArray();
Witnesses = WitnessModel.ToModels(transaction.Witnesses);
BlockHash = blockHash;
BlockTime = blockTime;
diff --git a/Fura/Notification/NotificationMgr.Deploy.cs b/Fura/Notification/NotificationMgr.Deploy.cs
new file mode 100644
index 0000000..2b2d5d4
--- /dev/null
+++ b/Fura/Notification/NotificationMgr.Deploy.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Linq;
+using Neo.Network.P2P.Payloads;
+using Neo.Persistence;
+using Neo.Plugins.Cache;
+using Neo.Plugins.Models;
+using Neo.SmartContract.Native;
+
+namespace Neo.Plugins.Notification
+{
+ public partial class NotificationMgr
+ {
+ private bool ExecuteDeployNotification(NotificationModel notificationModel, NeoSystem system, Block block, DataCache snapshot)
+ {
+ if (notificationModel.ContractHash == NativeContract.ContractManagement.Hash)
+ {
+ UInt160 contractHash = null;
+ bool succ = UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[0].Value).Reverse().ToArray().ToHexString(), out contractHash);
+ if (!succ) return false;
+ DBCache.Ins.cacheContract.AddNeedUpdate(contractHash, block.Timestamp, notificationModel.Txid);
+ //如果合约还是asset,也一并更新了
+ EnumAssetType assetType = GetAssetType(snapshot, contractHash);
+ if (assetType is EnumAssetType.NEP11 || assetType is EnumAssetType.NEP17)
+ {
+ DBCache.Ins.cacheAsset.AddNeedUpdate(contractHash, block.Timestamp, assetType);
+ }
+ }
+ return true;
+ }
+
+ }
+}
+
diff --git a/Fura/Notification/NotificationMgr.Destroy.cs b/Fura/Notification/NotificationMgr.Destroy.cs
new file mode 100644
index 0000000..e36cd78
--- /dev/null
+++ b/Fura/Notification/NotificationMgr.Destroy.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Linq;
+using Neo.Network.P2P.Payloads;
+using Neo.Persistence;
+using Neo.Plugins.Cache;
+using Neo.Plugins.Models;
+using Neo.SmartContract.Native;
+
+namespace Neo.Plugins.Notification
+{
+ public partial class NotificationMgr
+ {
+ private bool ExecuteDestroyNotification(NotificationModel notificationModel, NeoSystem system, Block block, DataCache snapshot)
+ {
+ if (notificationModel.ContractHash == NativeContract.ContractManagement.Hash)
+ {
+ UInt160 contractHash = null;
+ bool succ = UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[0].Value).Reverse().ToArray().ToHexString(), out contractHash);
+ if (!succ) return false;
+ DBCache.Ins.cacheContract.AddNeedUpdate(contractHash, block.Timestamp, notificationModel.Txid, true);
+ }
+ return true;
+ }
+ }
+}
+
diff --git a/Fura/Notification/NotificationMgr.Market.AddAsset.cs b/Fura/Notification/NotificationMgr.Market.AddAsset.cs
new file mode 100644
index 0000000..f59a436
--- /dev/null
+++ b/Fura/Notification/NotificationMgr.Market.AddAsset.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Linq;
+using Neo.Network.P2P.Payloads;
+using Neo.Persistence;
+using Neo.Plugins.Cache;
+using Neo.Plugins.Models;
+using Neo.SmartContract.Native;
+using System.Numerics;
+using Neo.Json;
+
+namespace Neo.Plugins.Notification
+{
+ public partial class NotificationMgr
+ {
+ private bool ExecuteAddAssetNotification(NotificationModel notificationModel, NeoSystem system, Block block, DataCache snapshot)
+ {
+ ContractModel contractModel = DBCache.Ins.cacheContract.Get(notificationModel.ContractHash);
+ if (Settings.Default.MarketContractIds.Contains(contractModel._ID))
+ {
+ UInt160 asset = null;
+ BigInteger _feeRate = 0;
+ BigInteger _rewardRate = 0;
+ UInt160 _rewardReceiveAddress = null;
+ bool succ = true;
+ //asset
+ if (notificationModel.State.Values[0].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[0].Value).Reverse().ToArray().ToHexString(), out asset);
+ }
+ //_feeRate
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[1].Value, out _feeRate);
+ //_rewardRate
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[2].Value, out _rewardRate);
+ //_rewardReceiveAddress
+ if (notificationModel.State.Values[3].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[3].Value).Reverse().ToArray().ToHexString(), out _rewardReceiveAddress);
+ }
+
+ JObject json = new JObject();
+ json["feeRate"] = _feeRate.ToString();
+ json["rewardRate"] = _rewardRate.ToString();
+ json["rewardReceiveAddress"] = _rewardReceiveAddress.ToString();
+ DBCache.Ins.cacheMatketNotification.Add(notificationModel.Txid, notificationModel.BlockHash, notificationModel.ContractHash, 0, null, asset, "", "AddAsset", json.ToString(), notificationModel.Timestamp);
+ }
+ return true;
+ }
+ }
+}
+
diff --git a/Fura/Notification/NotificationMgr.Market.Auction.cs b/Fura/Notification/NotificationMgr.Market.Auction.cs
new file mode 100644
index 0000000..f9cd1db
--- /dev/null
+++ b/Fura/Notification/NotificationMgr.Market.Auction.cs
@@ -0,0 +1,74 @@
+using System;
+using System.Linq;
+using Neo.Network.P2P.Payloads;
+using Neo.Persistence;
+using Neo.Plugins.Cache;
+using Neo.Plugins.Models;
+using Neo.SmartContract.Native;
+using System.Numerics;
+using Neo.Json;
+
+namespace Neo.Plugins.Notification
+{
+ public partial class NotificationMgr
+ {
+ private bool ExecuteAuctionNotification(NotificationModel notificationModel, NeoSystem system, Block block, DataCache snapshot)
+ {
+ ContractModel contractModel= DBCache.Ins.cacheContract.Get(notificationModel.ContractHash);
+ if (Settings.Default.MarketContractIds.Contains(contractModel._ID))
+ {
+ BigInteger nonce = 0;
+ UInt160 user = null;
+ UInt160 asset = null;
+ string tokenId = "";
+ BigInteger auctionType = 0;
+ UInt160 auctionAsset = null;
+ BigInteger auctionAmount = 0;
+ BigInteger deadline = 0;
+ bool succ = true;
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[0].Value, out nonce);
+ //user
+ if (notificationModel.State.Values[1].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[1].Value).Reverse().ToArray().ToHexString(), out user);
+ }
+ //asset
+ if (notificationModel.State.Values[2].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[2].Value).Reverse().ToArray().ToHexString(), out asset);
+ }
+ //tokenid
+ if (notificationModel.State.Values[3].Type == "Integer") //需要转换一下
+ {
+ tokenId = Convert.ToBase64String(BigInteger.Parse(notificationModel.State.Values[3].Value).ToByteArray());
+ }
+ else
+ {
+ tokenId = notificationModel.State.Values[3].Value;
+ }
+ //type
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[4].Value, out auctionType);
+ //auctionAsset
+ if (notificationModel.State.Values[5].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[5].Value).Reverse().ToArray().ToHexString(), out auctionAsset);
+ }
+ //auctionAmount
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[6].Value, out auctionAmount);
+ //deadline
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[7].Value, out deadline);
+
+ //暴露出通知的时候,nft的所有者已经变成了market了。
+ DBCache.Ins.cacheMarket.AddNeedUpdate(notificationModel.Index, false, asset, notificationModel.ContractHash, tokenId, notificationModel.ContractHash, auctionType, user, auctionAsset, auctionAmount, deadline, null, 0, block.Timestamp);
+ JObject json = new JObject();
+ json["auctionType"] = auctionType.ToString();
+ json["auctionAsset"] = auctionAsset?.ToString();
+ json["auctionAmount"] = auctionAmount.ToString();
+ json["deadline"] = deadline.ToString();
+ DBCache.Ins.cacheMatketNotification.Add(notificationModel.Txid, notificationModel.BlockHash, notificationModel.ContractHash, nonce, user, asset, tokenId, "Auction", json.ToString(), notificationModel.Timestamp);
+ }
+ return true;
+ }
+ }
+}
+
diff --git a/Fura/Notification/NotificationMgr.Market.Bid.cs b/Fura/Notification/NotificationMgr.Market.Bid.cs
new file mode 100644
index 0000000..2972619
--- /dev/null
+++ b/Fura/Notification/NotificationMgr.Market.Bid.cs
@@ -0,0 +1,67 @@
+using System;
+using System.Linq;
+using Neo.Network.P2P.Payloads;
+using Neo.Persistence;
+using Neo.Plugins.Cache;
+using Neo.Plugins.Models;
+using Neo.SmartContract.Native;
+using System.Numerics;
+using Neo.Json;
+
+namespace Neo.Plugins.Notification
+{
+ public partial class NotificationMgr
+ {
+ private bool ExecuteBidNotification(NotificationModel notificationModel, NeoSystem system, Block block, DataCache snapshot)
+ {
+ ContractModel contractModel = DBCache.Ins.cacheContract.Get(notificationModel.ContractHash);
+ if (Settings.Default.MarketContractIds.Contains(contractModel._ID))
+ {
+ BigInteger nonce = 0;
+ UInt160 user = null;
+ UInt160 asset = null;
+ string tokenId = "";
+ UInt160 auctionAsset = null;
+ BigInteger bidAmount = 0;
+ bool succ = true;
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[0].Value, out nonce);
+ //user
+ if (notificationModel.State.Values[1].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[1].Value).Reverse().ToArray().ToHexString(), out user);
+ }
+ //asset
+ if (notificationModel.State.Values[2].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[2].Value).Reverse().ToArray().ToHexString(), out asset);
+ }
+ //tokenid
+ if (notificationModel.State.Values[3].Type == "Integer") //需要转换一下
+ {
+ tokenId = Convert.ToBase64String(BigInteger.Parse(notificationModel.State.Values[3].Value).ToByteArray());
+ }
+ else
+ {
+ tokenId = notificationModel.State.Values[3].Value;
+ }
+ //auctionAsset
+ if (notificationModel.State.Values[4].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[4].Value).Reverse().ToArray().ToHexString(), out auctionAsset);
+ }
+ //auctionAmount
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[5].Value, out bidAmount);
+
+ MarketModel marketModel = DBCache.Ins.cacheMarket.Get(notificationModel.ContractHash, asset, tokenId);
+ DBCache.Ins.cacheMarket.AddNeedUpdate(notificationModel.Index, false, asset, notificationModel.ContractHash, tokenId, notificationModel.ContractHash, marketModel.AuctionType, marketModel.Auctor, marketModel.AuctionAsset, BigInteger.Parse(marketModel.AuctionAmount.ToString()), marketModel.Deadline, user, bidAmount, block.Timestamp);
+
+ JObject json = new JObject();
+ json["auctionAsset"] = auctionAsset?.ToString();
+ json["bidAmount"] = bidAmount.ToString();
+ DBCache.Ins.cacheMatketNotification.Add(notificationModel.Txid, notificationModel.BlockHash, notificationModel.ContractHash, nonce, user, asset, tokenId, "Bid", json.ToString(), notificationModel.Timestamp);
+ }
+ return true;
+ }
+ }
+}
+
diff --git a/Fura/Notification/NotificationMgr.Market.Cancel.cs b/Fura/Notification/NotificationMgr.Market.Cancel.cs
new file mode 100644
index 0000000..03f0676
--- /dev/null
+++ b/Fura/Notification/NotificationMgr.Market.Cancel.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Linq;
+using Neo.Network.P2P.Payloads;
+using Neo.Persistence;
+using Neo.Plugins.Cache;
+using Neo.Plugins.Models;
+using Neo.SmartContract.Native;
+using System.Numerics;
+using Neo.Json;
+
+namespace Neo.Plugins.Notification
+{
+ public partial class NotificationMgr
+ {
+ private bool ExecuteCancelNotification(NotificationModel notificationModel, NeoSystem system, Block block, DataCache snapshot)
+ {
+ ContractModel contractModel = DBCache.Ins.cacheContract.Get(notificationModel.ContractHash);
+ if (Settings.Default.MarketContractIds.Contains(contractModel._ID))
+ {
+ BigInteger nonce = 0;
+ UInt160 user = null;
+ UInt160 asset = null;
+ string tokenId = "";
+ bool succ = true;
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[0].Value, out nonce);
+ //user
+ if (notificationModel.State.Values[1].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[1].Value).Reverse().ToArray().ToHexString(), out user);
+ }
+ //asset
+ if (notificationModel.State.Values[2].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[2].Value).Reverse().ToArray().ToHexString(), out asset);
+ }
+ //tokenid
+ if (notificationModel.State.Values[3].Type == "Integer") //需要转换一下
+ {
+ tokenId = Convert.ToBase64String(BigInteger.Parse(notificationModel.State.Values[3].Value).ToByteArray());
+ }
+ else
+ {
+ tokenId = notificationModel.State.Values[3].Value;
+ }
+ //暴露出通知的时候,nft的所有者已经变成了原先的用户了。
+ MarketModel marketModel = DBCache.Ins.cacheMarket.Get(notificationModel.ContractHash, asset, tokenId);
+ DBCache.Ins.cacheMarket.AddNeedUpdate(notificationModel.Index, false, asset, notificationModel.ContractHash, tokenId, null, 0, null, null, 0, 0, null, 0, block.Timestamp);
+
+ DBCache.Ins.cacheMatketNotification.Add(notificationModel.Txid, notificationModel.BlockHash, notificationModel.ContractHash, nonce, user, asset, tokenId, "Cancel", "{}", notificationModel.Timestamp);
+ }
+ return true;
+ }
+ }
+}
+
diff --git a/Fura/Notification/NotificationMgr.Market.CancelOffer.cs b/Fura/Notification/NotificationMgr.Market.CancelOffer.cs
new file mode 100644
index 0000000..b4c6238
--- /dev/null
+++ b/Fura/Notification/NotificationMgr.Market.CancelOffer.cs
@@ -0,0 +1,70 @@
+using System;
+using System.Linq;
+using Neo.Network.P2P.Payloads;
+using Neo.Persistence;
+using Neo.Plugins.Cache;
+using Neo.Plugins.Models;
+using Neo.SmartContract.Native;
+using System.Numerics;
+using Neo.Json;
+
+namespace Neo.Plugins.Notification
+{
+ public partial class NotificationMgr
+ {
+ private bool ExecuteCancelOfferNotification(NotificationModel notificationModel, NeoSystem system, Block block, DataCache snapshot)
+ {
+ ContractModel contractModel = DBCache.Ins.cacheContract.Get(notificationModel.ContractHash);
+ if (Settings.Default.MarketContractIds.Contains(contractModel._ID))
+ {
+ //(nonce, 用户 ,求购使用的nep17资产,nep17数额,求购的nft的hash,求购的nfttokenid,求购截止日期)
+ BigInteger nonce = 0;
+ UInt160 user = null;
+ UInt160 offerAsset = null;
+ BigInteger offerAmount = 0;
+ UInt160 asset = null;
+ string tokenId = "";
+ BigInteger endTimestamp = 0;
+ bool succ = true;
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[0].Value, out nonce);
+ //user
+ if (notificationModel.State.Values[1].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[1].Value).Reverse().ToArray().ToHexString(), out user);
+ }
+ //offerAsset
+ if (notificationModel.State.Values[2].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[2].Value).Reverse().ToArray().ToHexString(), out offerAsset);
+ }
+ //offerAmount
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[3].Value, out offerAmount);
+ //asset
+ if (notificationModel.State.Values[4].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[4].Value).Reverse().ToArray().ToHexString(), out asset);
+ }
+ //tokenid
+ if (notificationModel.State.Values[5].Type == "Integer") //需要转换一下
+ {
+ tokenId = Convert.ToBase64String(BigInteger.Parse(notificationModel.State.Values[5].Value).ToByteArray());
+ }
+ else
+ {
+ tokenId = notificationModel.State.Values[5].Value;
+ }
+ //endtimestamp
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[6].Value, out endTimestamp);
+
+
+ JObject json = new JObject();
+ json["offerAsset"] = offerAsset?.ToString();
+ json["offerAmount"] = offerAmount.ToString();
+ json["deadline"] = endTimestamp.ToString();
+ DBCache.Ins.cacheMatketNotification.Add(notificationModel.Txid, notificationModel.BlockHash, notificationModel.ContractHash, nonce, user, asset, tokenId, "CancelOffer", json.ToString(), notificationModel.Timestamp);
+ }
+ return true;
+ }
+ }
+}
+
diff --git a/Fura/Notification/NotificationMgr.Market.CancelOfferCollection.cs b/Fura/Notification/NotificationMgr.Market.CancelOfferCollection.cs
new file mode 100644
index 0000000..5d11c40
--- /dev/null
+++ b/Fura/Notification/NotificationMgr.Market.CancelOfferCollection.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Linq;
+using Neo.Network.P2P.Payloads;
+using Neo.Persistence;
+using Neo.Plugins.Cache;
+using Neo.Plugins.Models;
+using Neo.SmartContract.Native;
+using System.Numerics;
+using Neo.Json;
+
+namespace Neo.Plugins.Notification
+{
+ public partial class NotificationMgr
+ {
+ private bool ExecuteCancelOfferCollectionNotification(NotificationModel notificationModel, NeoSystem system, Block block, DataCache snapshot)
+ {
+ ContractModel contractModel = DBCache.Ins.cacheContract.Get(notificationModel.ContractHash);
+ if (Settings.Default.MarketContractIds.Contains(contractModel._ID))
+ {
+ //(nonce, 用户 ,求购使用的nep17资产,nep17数额,求购的nft的hash,求购的nfttokenid,求购截止日期)
+ BigInteger nonce = 0;
+ UInt160 user = null;
+ UInt160 offerAsset = null;
+ BigInteger offerAmount = 0;
+ UInt160 asset = null;
+ BigInteger count = 0;
+ BigInteger endTimestamp = 0;
+ bool succ = true;
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[0].Value, out nonce);
+ //user
+ if (notificationModel.State.Values[1].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[1].Value).Reverse().ToArray().ToHexString(), out user);
+ }
+ //offerAsset
+ if (notificationModel.State.Values[2].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[2].Value).Reverse().ToArray().ToHexString(), out offerAsset);
+ }
+ //offerAmount
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[3].Value, out offerAmount);
+ //asset
+ if (notificationModel.State.Values[4].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[4].Value).Reverse().ToArray().ToHexString(), out asset);
+ }
+ //count
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[5].Value, out count);
+ //endtimestamp
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[6].Value, out endTimestamp);
+
+
+ JObject json = new JObject();
+ json["count"] = count.ToString();
+ json["offerAsset"] = offerAsset?.ToString();
+ json["offerAmount"] = offerAmount.ToString();
+ json["deadline"] = endTimestamp.ToString();
+ DBCache.Ins.cacheMatketNotification.Add(notificationModel.Txid, notificationModel.BlockHash, notificationModel.ContractHash, nonce, user, asset, "", "CancelOfferCollection", json.ToString(), notificationModel.Timestamp);
+ }
+ return true;
+ }
+ }
+}
+
diff --git a/Fura/Notification/NotificationMgr.Market.Claim.cs b/Fura/Notification/NotificationMgr.Market.Claim.cs
new file mode 100644
index 0000000..de21d9f
--- /dev/null
+++ b/Fura/Notification/NotificationMgr.Market.Claim.cs
@@ -0,0 +1,69 @@
+using System;
+using System.Linq;
+using Neo.Network.P2P.Payloads;
+using Neo.Persistence;
+using Neo.Plugins.Cache;
+using Neo.Plugins.Models;
+using Neo.SmartContract.Native;
+using System.Numerics;
+using Neo.Json;
+
+namespace Neo.Plugins.Notification
+{
+ public partial class NotificationMgr
+ {
+ private bool ExecuteClaimNotification(NotificationModel notificationModel, NeoSystem system, Block block, DataCache snapshot)
+ {
+ ContractModel contractModel = DBCache.Ins.cacheContract.Get(notificationModel.ContractHash);
+ if (Settings.Default.MarketContractIds.Contains(contractModel._ID))
+ {
+ BigInteger nonce = 0;
+ UInt160 user = null;
+ UInt160 asset = null;
+ string tokenId = "";
+ BigInteger auctionType = 0;
+ UInt160 auctionAsset = null;
+ BigInteger bidAmount = 0;
+ bool succ = true;
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[0].Value, out nonce);
+ if (notificationModel.State.Values[1].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[1].Value).Reverse().ToArray().ToHexString(), out user);
+ }
+ //asset
+ if (notificationModel.State.Values[2].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[2].Value).Reverse().ToArray().ToHexString(), out asset);
+ }
+ //tokenid
+ if (notificationModel.State.Values[3].Type == "Integer") //需要转换一下
+ {
+ tokenId = Convert.ToBase64String(BigInteger.Parse(notificationModel.State.Values[3].Value).ToByteArray());
+ }
+ else
+ {
+ tokenId = notificationModel.State.Values[3].Value;
+ }
+ //type
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[4].Value, out auctionType);
+ //auctionAsset
+ if (notificationModel.State.Values[5].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[5].Value).Reverse().ToArray().ToHexString(), out auctionAsset);
+ }
+ //auctionAmount
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[6].Value, out bidAmount);
+
+ MarketModel marketModel = DBCache.Ins.cacheMarket.Get(notificationModel.ContractHash, asset, tokenId);
+ DBCache.Ins.cacheMarket.AddNeedUpdate(notificationModel.Index, false, asset, notificationModel.ContractHash, tokenId, null, 0, null, null, 0, 0, null, 0, block.Timestamp);
+
+ JObject json = new JObject();
+ json["auctionType"] = auctionType.ToString();
+ json["auctionAsset"] = auctionAsset?.ToString();
+ json["bidAmount"] = bidAmount.ToString();
+ DBCache.Ins.cacheMatketNotification.Add(notificationModel.Txid, notificationModel.BlockHash, notificationModel.ContractHash, nonce, user, asset, tokenId, "Claim", json.ToString(), notificationModel.Timestamp);
+ }
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Fura/Notification/NotificationMgr.Market.CompleteOffer.cs b/Fura/Notification/NotificationMgr.Market.CompleteOffer.cs
new file mode 100644
index 0000000..46272a0
--- /dev/null
+++ b/Fura/Notification/NotificationMgr.Market.CompleteOffer.cs
@@ -0,0 +1,77 @@
+using System;
+using System.Linq;
+using Neo.Network.P2P.Payloads;
+using Neo.Persistence;
+using Neo.Plugins.Cache;
+using Neo.Plugins.Models;
+using Neo.SmartContract.Native;
+using System.Numerics;
+using Neo.Json;
+
+namespace Neo.Plugins.Notification
+{
+ public partial class NotificationMgr
+ {
+ private bool ExecuteCompleteOfferNotification(NotificationModel notificationModel, NeoSystem system, Block block, DataCache snapshot)
+ {
+ ContractModel contractModel = DBCache.Ins.cacheContract.Get(notificationModel.ContractHash);
+ if (Settings.Default.MarketContractIds.Contains(contractModel._ID))
+ {
+ //(nonce, 用户 ,求购使用的nep17资产,nep17数额,求购的nft的hash,求购的nfttokenid,求购截止日期)
+ BigInteger nonce = 0;
+ UInt160 offerer = null;
+ UInt160 user = null;
+ UInt160 offerAsset = null;
+ BigInteger offerAmount = 0;
+ UInt160 asset = null;
+ string tokenId = "";
+ BigInteger endTimestamp = 0;
+ bool succ = true;
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[0].Value, out nonce);
+ //user
+ if (notificationModel.State.Values[1].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[1].Value).Reverse().ToArray().ToHexString(), out user);
+ }
+ //offerer
+ if (notificationModel.State.Values[2].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[2].Value).Reverse().ToArray().ToHexString(), out offerer);
+ }
+ //offerAsset
+ if (notificationModel.State.Values[3].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[3].Value).Reverse().ToArray().ToHexString(), out offerAsset);
+ }
+ //offerAmount
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[4].Value, out offerAmount);
+ //asset
+ if (notificationModel.State.Values[5].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[5].Value).Reverse().ToArray().ToHexString(), out asset);
+ }
+ //tokenid
+ if (notificationModel.State.Values[6].Type == "Integer") //需要转换一下
+ {
+ tokenId = Convert.ToBase64String(BigInteger.Parse(notificationModel.State.Values[6].Value).ToByteArray());
+ }
+ else
+ {
+ tokenId = notificationModel.State.Values[6].Value;
+ }
+ //endtimestamp
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[7].Value, out endTimestamp);
+
+
+ JObject json = new JObject();
+ json["offerer"] = offerer?.ToString();
+ json["offerAsset"] = offerAsset?.ToString();
+ json["offerAmount"] = offerAmount.ToString();
+ json["deadline"] = endTimestamp.ToString();
+ DBCache.Ins.cacheMatketNotification.Add(notificationModel.Txid, notificationModel.BlockHash, notificationModel.ContractHash, nonce, user, asset, tokenId, "CompleteOffer", json.ToString(), notificationModel.Timestamp);
+ }
+ return true;
+ }
+ }
+}
+
diff --git a/Fura/Notification/NotificationMgr.Market.CompleteOfferCollection.cs b/Fura/Notification/NotificationMgr.Market.CompleteOfferCollection.cs
new file mode 100644
index 0000000..09823c1
--- /dev/null
+++ b/Fura/Notification/NotificationMgr.Market.CompleteOfferCollection.cs
@@ -0,0 +1,81 @@
+using System;
+using System.Linq;
+using Neo.Network.P2P.Payloads;
+using Neo.Persistence;
+using Neo.Plugins.Cache;
+using Neo.Plugins.Models;
+using Neo.SmartContract.Native;
+using System.Numerics;
+using Neo.Json;
+
+namespace Neo.Plugins.Notification
+{
+ public partial class NotificationMgr
+ {
+ private bool ExecuteCompleteOfferCollectionNotification(NotificationModel notificationModel, NeoSystem system, Block block, DataCache snapshot)
+ {
+ ContractModel contractModel = DBCache.Ins.cacheContract.Get(notificationModel.ContractHash);
+ if (Settings.Default.MarketContractIds.Contains(contractModel._ID))
+ {
+ //(nonce, 用户 ,求购使用的nep17资产,nep17数额,求购的nft的hash,求购的nfttokenid,求购截止日期)
+ BigInteger nonce = 0;
+ UInt160 offerer = null;
+ UInt160 user = null;
+ UInt160 offerAsset = null;
+ BigInteger offerAmount = 0;
+ UInt160 asset = null;
+ string tokenId = "";
+ BigInteger endTimestamp = 0;
+ BigInteger count = 0;
+ bool succ = true;
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[0].Value, out nonce);
+ //user
+ if (notificationModel.State.Values[1].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[1].Value).Reverse().ToArray().ToHexString(), out user);
+ }
+ //offerer
+ if (notificationModel.State.Values[2].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[2].Value).Reverse().ToArray().ToHexString(), out offerer);
+ }
+ //offerAsset
+ if (notificationModel.State.Values[3].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[3].Value).Reverse().ToArray().ToHexString(), out offerAsset);
+ }
+ //offerAmount
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[4].Value, out offerAmount);
+ //asset
+ if (notificationModel.State.Values[5].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[5].Value).Reverse().ToArray().ToHexString(), out asset);
+ }
+ //tokenid
+ if (notificationModel.State.Values[6].Type == "Integer") //需要转换一下
+ {
+ tokenId = Convert.ToBase64String(BigInteger.Parse(notificationModel.State.Values[6].Value).ToByteArray());
+ }
+ else
+ {
+ tokenId = notificationModel.State.Values[6].Value;
+ }
+ //count
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[7].Value, out count);
+ //endtimestamp
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[8].Value, out endTimestamp);
+
+
+ JObject json = new JObject();
+ json["offerer"] = offerer?.ToString();
+ json["offerAsset"] = offerAsset?.ToString();
+ json["offerAmount"] = offerAmount.ToString();
+ json["count"] = count.ToString();
+ json["deadline"] = endTimestamp.ToString();
+ DBCache.Ins.cacheMatketNotification.Add(notificationModel.Txid, notificationModel.BlockHash, notificationModel.ContractHash, nonce, user, asset, tokenId, "CompleteOfferCollection", json.ToString(), notificationModel.Timestamp);
+ }
+ return true;
+ }
+ }
+}
+
diff --git a/Fura/Notification/NotificationMgr.Market.Offer.cs b/Fura/Notification/NotificationMgr.Market.Offer.cs
new file mode 100644
index 0000000..a6a6cf3
--- /dev/null
+++ b/Fura/Notification/NotificationMgr.Market.Offer.cs
@@ -0,0 +1,76 @@
+using System;
+using System.Linq;
+using Neo.Network.P2P.Payloads;
+using Neo.Persistence;
+using Neo.Plugins.Cache;
+using Neo.Plugins.Models;
+using Neo.SmartContract.Native;
+using System.Numerics;
+using Neo.Json;
+
+namespace Neo.Plugins.Notification
+{
+ public partial class NotificationMgr
+ {
+ private bool ExecuteOfferNotification(NotificationModel notificationModel, NeoSystem system, Block block, DataCache snapshot)
+ {
+ ContractModel contractModel = DBCache.Ins.cacheContract.Get(notificationModel.ContractHash);
+ if (Settings.Default.MarketContractIds.Contains(contractModel._ID))
+ {
+ //(nonce, 用户 ,求购使用的nep17资产,nep17数额,求购的nft的hash,求购的nfttokenid,求购截止日期)
+ BigInteger nonce = 0;
+ UInt160 user = null;
+ UInt160 originOwner = null;
+ UInt160 offerAsset = null;
+ BigInteger offerAmount = 0;
+ UInt160 asset = null;
+ string tokenId = "";
+ BigInteger endTimestamp = 0;
+ bool succ = true;
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[0].Value, out nonce);
+ //user
+ if (notificationModel.State.Values[1].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[1].Value).Reverse().ToArray().ToHexString(), out user);
+ }
+ //offerAsset
+ if (notificationModel.State.Values[2].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[2].Value).Reverse().ToArray().ToHexString(), out offerAsset);
+ }
+ //offerAmount
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[3].Value, out offerAmount);
+ //asset
+ if (notificationModel.State.Values[4].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[4].Value).Reverse().ToArray().ToHexString(), out asset);
+ }
+ //tokenid
+ if (notificationModel.State.Values[5].Type == "Integer") //需要转换一下
+ {
+ tokenId = Convert.ToBase64String(BigInteger.Parse(notificationModel.State.Values[5].Value).ToByteArray());
+ }
+ else
+ {
+ tokenId = notificationModel.State.Values[5].Value;
+ }
+ //endtimestamp
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[6].Value, out endTimestamp);
+ //originOwner
+ if (notificationModel.State.Values[7].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[7].Value).Reverse().ToArray().ToHexString(), out originOwner);
+ }
+
+ JObject json = new JObject();
+ json["originOwner"] = originOwner?.ToString();
+ json["offerAsset"] = offerAsset?.ToString();
+ json["offerAmount"] = offerAmount.ToString();
+ json["deadline"] = endTimestamp.ToString();
+ DBCache.Ins.cacheMatketNotification.Add(notificationModel.Txid, notificationModel.BlockHash, notificationModel.ContractHash, nonce, user, asset, tokenId, "Offer", json.ToString(), notificationModel.Timestamp);
+ }
+ return true;
+ }
+ }
+}
+
diff --git a/Fura/Notification/NotificationMgr.Market.OfferCollection.cs b/Fura/Notification/NotificationMgr.Market.OfferCollection.cs
new file mode 100644
index 0000000..577b3b7
--- /dev/null
+++ b/Fura/Notification/NotificationMgr.Market.OfferCollection.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Linq;
+using Neo.Network.P2P.Payloads;
+using Neo.Persistence;
+using Neo.Plugins.Cache;
+using Neo.Plugins.Models;
+using Neo.SmartContract.Native;
+using System.Numerics;
+using Neo.Json;
+
+namespace Neo.Plugins.Notification
+{
+ public partial class NotificationMgr
+ {
+ private bool ExecuteOfferCollectionNotification(NotificationModel notificationModel, NeoSystem system, Block block, DataCache snapshot)
+ {
+ ContractModel contractModel = DBCache.Ins.cacheContract.Get(notificationModel.ContractHash);
+ if (Settings.Default.MarketContractIds.Contains(contractModel._ID))
+ {
+ //(nonce, 用户 ,求购使用的nep17资产,nep17数额,求购的nft的hash,求购的nfttokenid,求购截止日期)
+ BigInteger nonce = 0;
+ UInt160 user = null;
+ UInt160 offerAsset = null;
+ BigInteger offerAmount = 0;
+ BigInteger count = 0;
+ UInt160 asset = null;
+ BigInteger endTimestamp = 0;
+ bool succ = true;
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[0].Value, out nonce);
+ //user
+ if (notificationModel.State.Values[1].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[1].Value).Reverse().ToArray().ToHexString(), out user);
+ }
+ //offerAsset
+ if (notificationModel.State.Values[2].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[2].Value).Reverse().ToArray().ToHexString(), out offerAsset);
+ }
+ //offerAmount
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[3].Value, out offerAmount);
+ //asset
+ if (notificationModel.State.Values[4].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[4].Value).Reverse().ToArray().ToHexString(), out asset);
+ }
+ //endtimestamp
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[5].Value, out count);
+ //endtimestamp
+ succ = succ && BigInteger.TryParse(notificationModel.State.Values[6].Value, out endTimestamp);
+
+ JObject json = new JObject();
+ json["count"] = count.ToString();
+ json["offerAsset"] = offerAsset?.ToString();
+ json["offerAmount"] = offerAmount.ToString();
+ json["deadline"] = endTimestamp.ToString();
+ DBCache.Ins.cacheMatketNotification.Add(notificationModel.Txid, notificationModel.BlockHash, notificationModel.ContractHash, nonce, user, asset, "", "OfferCollection", json.ToString(), notificationModel.Timestamp);
+ }
+ return true;
+ }
+ }
+}
+
diff --git a/Fura/Notification/NotificationMgr.Market.RemoveAsset.cs b/Fura/Notification/NotificationMgr.Market.RemoveAsset.cs
new file mode 100644
index 0000000..b50bac3
--- /dev/null
+++ b/Fura/Notification/NotificationMgr.Market.RemoveAsset.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Linq;
+using Neo.Network.P2P.Payloads;
+using Neo.Persistence;
+using Neo.Plugins.Cache;
+using Neo.Plugins.Models;
+
+
+namespace Neo.Plugins.Notification
+{
+ public partial class NotificationMgr
+ {
+ private bool ExecuteRemoveAssetNotification(NotificationModel notificationModel, NeoSystem system, Block block, DataCache snapshot)
+ {
+ ContractModel contractModel = DBCache.Ins.cacheContract.Get(notificationModel.ContractHash);
+ if (Settings.Default.MarketContractIds.Contains(contractModel._ID))
+ {
+ UInt160 asset = null;
+ bool succ = true;
+ //asset
+ if (notificationModel.State.Values[0].Value is not null)
+ {
+ succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[0].Value).Reverse().ToArray().ToHexString(), out asset);
+ }
+
+ DBCache.Ins.cacheMatketNotification.Add(notificationModel.Txid, notificationModel.BlockHash, notificationModel.ContractHash, 0, null, asset, "", "RemoveAsset", "{}", notificationModel.Timestamp);
+ }
+ return true;
+ }
+ }
+}
+
diff --git a/Fura/Notification/NotificationMgr.NNS.Renew.cs b/Fura/Notification/NotificationMgr.NNS.Renew.cs
new file mode 100644
index 0000000..2eb9889
--- /dev/null
+++ b/Fura/Notification/NotificationMgr.NNS.Renew.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Linq;
+using System.Numerics;
+using Neo.Network.P2P.Payloads;
+using Neo.Persistence;
+using Neo.Plugins.Cache;
+using Neo.Plugins.Models;
+
+namespace Neo.Plugins.Notification
+{
+ public partial class NotificationMgr
+ {
+ private bool ExecuteRenewNotification(NotificationModel notificationModel, NeoSystem system, Block block, DataCache snapshot)
+ {
+ if (UInt160.Parse(Settings.Default.NNS) == notificationModel.ContractHash)
+ {
+ bool succ = true;
+ string tokenId = "";
+ if (notificationModel.State.Values[0].Type == "Integer") //需要转换一下
+ {
+ tokenId = Convert.ToBase64String(BigInteger.Parse(notificationModel.State.Values[0].Value).ToByteArray());
+ }
+ else
+ {
+ tokenId = notificationModel.State.Values[0].Value;
+ }
+
+ if (!succ)
+ {
+ return succ;
+ }
+ DBCache.Ins.cacheNep11Properties.AddNeedUpdate(notificationModel.ContractHash, tokenId);
+ }
+ return true;
+ }
+ }
+}
+
diff --git a/Fura/Notification/NotificationMgr.NNS.SetAdmin.cs b/Fura/Notification/NotificationMgr.NNS.SetAdmin.cs
new file mode 100644
index 0000000..dcd4c79
--- /dev/null
+++ b/Fura/Notification/NotificationMgr.NNS.SetAdmin.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Linq;
+using System.Numerics;
+using Neo.Network.P2P.Payloads;
+using Neo.Persistence;
+using Neo.Plugins.Cache;
+using Neo.Plugins.Models;
+
+namespace Neo.Plugins.Notification
+{
+ public partial class NotificationMgr
+ {
+ private bool ExecuteSetAdminNotification(NotificationModel notificationModel, NeoSystem system, Block block, DataCache snapshot)
+ {
+ if (UInt160.Parse(Settings.Default.NNS) == notificationModel.ContractHash)
+ {
+ bool succ = true;
+ string tokenId = "";
+ if (notificationModel.State.Values[0].Type == "Integer") //需要转换一下
+ {
+ tokenId = Convert.ToBase64String(BigInteger.Parse(notificationModel.State.Values[0].Value).ToByteArray());
+ }
+ else
+ {
+ tokenId = notificationModel.State.Values[0].Value;
+ }
+
+ if (!succ)
+ {
+ return succ;
+ }
+ DBCache.Ins.cacheNep11Properties.AddNeedUpdate(notificationModel.ContractHash, tokenId);
+ }
+ return true;
+ }
+ }
+}
+
diff --git a/Fura/NotificationMgr.cs b/Fura/Notification/NotificationMgr.Transfer.cs
similarity index 50%
rename from Fura/NotificationMgr.cs
rename to Fura/Notification/NotificationMgr.Transfer.cs
index c1c9a94..fbc6719 100644
--- a/Fura/NotificationMgr.cs
+++ b/Fura/Notification/NotificationMgr.Transfer.cs
@@ -1,81 +1,17 @@
using System;
-using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
-using System.Threading.Tasks;
-using MongoDB.Bson;
-using Neo.Cryptography;
using Neo.Network.P2P.Payloads;
using Neo.Persistence;
using Neo.Plugins.Cache;
using Neo.Plugins.Models;
-using Neo.SmartContract;
using Neo.SmartContract.Native;
-namespace Neo.Plugins
+namespace Neo.Plugins.Notification
{
- public class NotificationMgr
+ public partial class NotificationMgr
{
- Dictionary> dic_filter = new Dictionary>();
-
- private static NotificationMgr ins;
-
- private static Dictionary dic_AssetType = new Dictionary();
-
- private static object lockObj = new object();
-
- public static NotificationMgr Ins
- {
- get
- {
- if (ins is null)
- {
- lock (lockObj)
- {
- if (ins is null)
- ins = new NotificationMgr();
- }
- }
- return ins;
- }
-
- }
-
- public NotificationMgr()
- {
- Register("Transfer", ExecuteTransferNotification);
- Register("Deploy", ExecuteDeployNotification);
- Register("Update", ExecuteUpdateNotification);
- }
-
- public void Register(string eventName, Func entity)
- {
- dic_filter.Add(GetKey(eventName), entity);
- }
-
- public UInt256 GetKey(string eventName)
- {
- return new UInt256((UTF8Encoding.UTF8.GetBytes(eventName)).Sha256());
- }
-
- public void Filter(List notificationModels, NeoSystem system, Block block, DataCache snapshot)
- {
- Parallel.For(0, notificationModels.Count, (i) =>
- {
- var notificationModel = notificationModels[i];
- if (notificationModel.Vmstate != "HALT")
- {
- return;
- }
- var key = GetKey(notificationModel.EventName);
- if (dic_filter.ContainsKey(key))
- {
- dic_filter[key](notificationModel, system, block, snapshot);
- }
- });
- }
-
private bool ExecuteTransferNotification(NotificationModel notificationModel, NeoSystem system, Block block, DataCache snapshot)
{
if (notificationModel.State.Values.Count() == 3)
@@ -113,21 +49,21 @@ private void UpdateVoteModelByTransfer(UInt256 txid, UInt160 voter, NeoSystem sy
private void ExecuteGasSepical(NotificationModel notificationModel, NeoSystem system, Block block, DataCache snapshot)
{
- if(notificationModel.State.Values[1].Value is null)//gas 销毁
+ if (notificationModel.State.Values[1].Value is null)//gas 销毁
{
BigInteger value = 0;
BigInteger.TryParse(notificationModel.State.Values[2].Value, out value);
- DBCache.Ins.cacheGasMintBurn.Add(block.Index,value, 0);
+ DBCache.Ins.cacheGasMintBurn.Add(block.Index, value, 0);
}
if (notificationModel.State.Values[0].Value is null)//gas 增发
{
BigInteger value = 0;
BigInteger.TryParse(notificationModel.State.Values[2].Value, out value);
- DBCache.Ins.cacheGasMintBurn.Add(block.Index,0, value);
+ DBCache.Ins.cacheGasMintBurn.Add(block.Index, 0, value);
}
}
- private (UInt160,UInt160) ExecuteNep17TransferNotification(NotificationModel notificationModel, NeoSystem system, Block block, DataCache snapshot)
+ private (UInt160, UInt160) ExecuteNep17TransferNotification(NotificationModel notificationModel, NeoSystem system, Block block, DataCache snapshot)
{
EnumAssetType assetType = GetAssetType(snapshot, notificationModel.ContractHash);
if (assetType != EnumAssetType.NEP17)
@@ -142,11 +78,12 @@ private void ExecuteGasSepical(NotificationModel notificationModel, NeoSystem sy
bool succ = true;
if (notificationModel.State.Values[0].Value is not null)
{
- succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[0].Value).Reverse().ToArray().ToHexString(), out from);
+ succ = succ && TryParseBase64ToScriptHash(notificationModel.State.Values[0].Value, out from);
+
}
if (notificationModel.State.Values[1].Value is not null)
{
- succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[1].Value).Reverse().ToArray().ToHexString(), out to);
+ succ = succ && TryParseBase64ToScriptHash(notificationModel.State.Values[1].Value, out to);
}
succ = succ && BigInteger.TryParse(notificationModel.State.Values[2].Value, out value);
if (!succ)
@@ -160,7 +97,7 @@ private void ExecuteGasSepical(NotificationModel notificationModel, NeoSystem sy
DBCache.Ins.cacheAddress.AddNeedUpdate(from, block.Timestamp);
DBCache.Ins.cacheAddress.AddNeedUpdate(to, block.Timestamp);
- if (from == UInt160.Zero || from is null) //如果from为0x0,意味着发行代币,这个时候需要更新资产的总量
+ if (from == UInt160.Zero || from is null || to is null || to == UInt160.Zero) //如果from为0x0,意味着发行代币,这个时候需要更新资产的总量
{
DBCache.Ins.cacheAsset.AddNeedUpdate(notificationModel.ContractHash, block.Timestamp, EnumAssetType.NEP17);
}
@@ -171,7 +108,7 @@ private void ExecuteNep11TransferNotification(NotificationModel notificationMode
{
EnumAssetType assetType = GetAssetType(snapshot, notificationModel.ContractHash);
if (assetType != EnumAssetType.NEP11)
- return ;
+ return;
UInt256 txid = notificationModel.Txid;
UInt256 blockHash = notificationModel.BlockHash;
ulong timestamp = notificationModel.Timestamp;
@@ -182,11 +119,11 @@ private void ExecuteNep11TransferNotification(NotificationModel notificationMode
bool succ = true;
if (notificationModel.State.Values[0].Value is not null)
{
- succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[0].Value).Reverse().ToArray().ToHexString(), out from);
+ succ = succ && TryParseBase64ToScriptHash(notificationModel.State.Values[0].Value, out from);
}
if (notificationModel.State.Values[1].Value is not null)
{
- succ = succ && UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[1].Value).Reverse().ToArray().ToHexString(), out to);
+ succ = succ && TryParseBase64ToScriptHash(notificationModel.State.Values[1].Value, out to);
}
succ = succ && BigInteger.TryParse(notificationModel.State.Values[2].Value, out value);
string tokenId = "";
@@ -212,79 +149,27 @@ private void ExecuteNep11TransferNotification(NotificationModel notificationMode
DBCache.Ins.cacheAddressAsset.AddNeedUpdate(from, notificationModel.ContractHash, tokenId);
DBCache.Ins.cacheAddressAsset.AddNeedUpdate(to, notificationModel.ContractHash, tokenId);
+ DBCache.Ins.cacheMarket.AddNeedUpdate(notificationModel.Index, true, notificationModel.ContractHash, from, tokenId, block.Timestamp);
+ DBCache.Ins.cacheMarket.AddNeedUpdate(notificationModel.Index, true, notificationModel.ContractHash, to, tokenId, block.Timestamp);
+
DBCache.Ins.cacheAddress.Add(block.Timestamp, from, to);
DBCache.Ins.cacheNep11Properties.AddNeedUpdate(notificationModel.ContractHash, tokenId);
- if (from == UInt160.Zero || from is null) //如果from为0x0,意味着发行代币,这个时候需要更新资产的总量
+ if (from == UInt160.Zero || from is null || to is null || to == UInt160.Zero) //如果from为0x0,意味着发行代币,这个时候需要更新资产的总量
{
DBCache.Ins.cacheAsset.AddNeedUpdate(notificationModel.ContractHash, block.Timestamp, EnumAssetType.NEP11);
}
}
- private bool ExecuteDeployNotification(NotificationModel notificationModel, NeoSystem system, Block block, DataCache snapshot)
+ private bool TryParseBase64ToScriptHash(string base64String, out UInt160 addr)
{
- if(notificationModel.ContractHash == NativeContract.ContractManagement.Hash)
+ bool _succ = true;
+ _succ = UInt160.TryParse(Convert.FromBase64String(base64String).Reverse().ToArray().ToHexString(), out addr);
+ if (!_succ)
{
- UInt160 contractHash = null;
- bool succ = UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[0].Value).Reverse().ToArray().ToHexString(), out contractHash);
- if (!succ) return false;
- DBCache.Ins.cacheContract.AddNeedUpdate(contractHash, block.Timestamp, notificationModel.Txid);
- //如果合约还是asset,也一并更新了
- EnumAssetType assetType = GetAssetType(snapshot, contractHash);
- if (assetType is EnumAssetType.NEP11 || assetType is EnumAssetType.NEP17)
- {
- DBCache.Ins.cacheAsset.AddNeedUpdate(contractHash, block.Timestamp, assetType);
- }
+ _succ = UInt160.TryParse(Encoding.UTF8.GetString(Convert.FromBase64String(base64String)), out addr);
}
- return true;
- }
-
- private bool ExecuteUpdateNotification(NotificationModel notificationModel, NeoSystem system, Block block, DataCache snapshot)
- {
- if (notificationModel.ContractHash == NativeContract.ContractManagement.Hash)
- {
- UInt160 contractHash = null;
- bool succ = UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[0].Value).Reverse().ToArray().ToHexString(), out contractHash);
- if (!succ) return false;
- DBCache.Ins.cacheContract.AddNeedUpdate(contractHash, block.Timestamp, notificationModel.Txid);
- //如果合约还是asset,也一并更新了
- EnumAssetType assetType = GetAssetType(snapshot, contractHash);
- if (assetType is EnumAssetType.NEP11 || assetType is EnumAssetType.NEP17)
- {
- DBCache.Ins.cacheAsset.AddNeedUpdate(contractHash, block.Timestamp, assetType);
- }
- }
- return true;
- }
-
- private EnumAssetType GetAssetType(DataCache snapshot, UInt160 hash)
- {
- if (dic_AssetType.ContainsKey(hash))
- return dic_AssetType[hash];
- StorageKey key = new KeyBuilder(Neo.SmartContract.Native.NativeContract.ContractManagement.Id, 8).Add(hash);
- ContractState contract = snapshot.TryGet(key)?.GetInteroperable();
- EnumAssetType assetType;
- if (contract is null)
- {
- assetType = EnumAssetType.Unknown;
- }
- else if (contract.Manifest.SupportedStandards.Contains("NEP-17"))
- {
- assetType = EnumAssetType.NEP17;
- }
- else if (contract.Manifest.SupportedStandards.Contains("NEP-11"))
- {
- assetType = EnumAssetType.NEP11;
- }
- else
- {
- assetType = EnumAssetType.Unknown;
- }
- lock (dic_AssetType)
- {
- if (!dic_AssetType.ContainsKey(hash))
- dic_AssetType.Add(hash, assetType);
- }
- return assetType;
+ return _succ;
}
}
}
+
diff --git a/Fura/Notification/NotificationMgr.Update.cs b/Fura/Notification/NotificationMgr.Update.cs
new file mode 100644
index 0000000..7d187cc
--- /dev/null
+++ b/Fura/Notification/NotificationMgr.Update.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Linq;
+using Neo.Network.P2P.Payloads;
+using Neo.Persistence;
+using Neo.Plugins.Cache;
+using Neo.Plugins.Models;
+using Neo.SmartContract.Native;
+
+namespace Neo.Plugins.Notification
+{
+ public partial class NotificationMgr
+ {
+ private bool ExecuteUpdateNotification(NotificationModel notificationModel, NeoSystem system, Block block, DataCache snapshot)
+ {
+ if (notificationModel.ContractHash == NativeContract.ContractManagement.Hash)
+ {
+ UInt160 contractHash = null;
+ bool succ = UInt160.TryParse(Convert.FromBase64String(notificationModel.State.Values[0].Value).Reverse().ToArray().ToHexString(), out contractHash);
+ if (!succ) return false;
+ DBCache.Ins.cacheContract.AddNeedUpdate(contractHash, block.Timestamp, notificationModel.Txid);
+ //如果合约还是asset,也一并更新了
+ EnumAssetType assetType = GetAssetType(snapshot, contractHash);
+ if (assetType is EnumAssetType.NEP11 || assetType is EnumAssetType.NEP17)
+ {
+ DBCache.Ins.cacheAsset.AddNeedUpdate(contractHash, block.Timestamp, assetType);
+ }
+ }
+ return true;
+ }
+ }
+}
+
diff --git a/Fura/Notification/NotificationMgr.cs b/Fura/Notification/NotificationMgr.cs
new file mode 100644
index 0000000..c12c202
--- /dev/null
+++ b/Fura/Notification/NotificationMgr.cs
@@ -0,0 +1,120 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Numerics;
+using System.Text;
+using System.Threading.Tasks;
+using MongoDB.Bson;
+using Neo.Cryptography;
+using Neo.Network.P2P.Payloads;
+using Neo.Persistence;
+using Neo.Plugins.Cache;
+using Neo.Plugins.Models;
+using Neo.SmartContract;
+using Neo.SmartContract.Native;
+
+namespace Neo.Plugins.Notification
+{
+ public partial class NotificationMgr
+ {
+ Dictionary> dic_filter = new Dictionary>();
+
+ private static NotificationMgr ins;
+
+ private static object lockObj = new object();
+
+ public static NotificationMgr Ins
+ {
+ get
+ {
+ if (ins is null)
+ {
+ lock (lockObj)
+ {
+ if (ins is null)
+ ins = new NotificationMgr();
+ }
+ }
+ return ins;
+ }
+
+ }
+
+ public NotificationMgr()
+ {
+ Register("Transfer", ExecuteTransferNotification);
+ Register("Deploy", ExecuteDeployNotification);
+ Register("Update", ExecuteUpdateNotification);
+ Register("Destroy", ExecuteDestroyNotification);
+
+ Register("Auction", ExecuteAuctionNotification);
+ Register("Bid", ExecuteBidNotification);
+ Register("Cancel", ExecuteCancelNotification);
+ Register("Claim", ExecuteClaimNotification);
+ Register("AddAsset", ExecuteAddAssetNotification);
+ Register("RemoveAsset", ExecuteRemoveAssetNotification);
+ Register("Offer", ExecuteOfferNotification);
+ Register("CancelOffer", ExecuteCancelOfferNotification);
+ Register("CompleteOffer", ExecuteCompleteOfferNotification);
+ Register("OfferCollection", ExecuteOfferCollectionNotification);
+ Register("CancelOfferCollection", ExecuteCancelOfferCollectionNotification);
+ Register("CompleteOfferCollection", ExecuteCompleteOfferCollectionNotification);
+
+
+
+ Register("SetAdmin", ExecuteSetAdminNotification);
+ Register("Renew", ExecuteRenewNotification);
+ }
+
+ public void Register(string eventName, Func entity)
+ {
+ dic_filter.Add(GetKey(eventName), entity);
+ }
+
+ public UInt256 GetKey(string eventName)
+ {
+ return new UInt256((UTF8Encoding.UTF8.GetBytes(eventName)).Sha256());
+ }
+
+ public void Filter(List notificationModels, NeoSystem system, Block block, DataCache snapshot)
+ {
+ Parallel.For(0, notificationModels.Count, (i) =>
+ {
+ var notificationModel = notificationModels[i];
+ if (notificationModel.Vmstate != "HALT")
+ {
+ return;
+ }
+ var key = GetKey(notificationModel.EventName);
+ if (dic_filter.ContainsKey(key))
+ {
+ dic_filter[key](notificationModel, system, block, snapshot);
+ }
+ });
+ }
+
+ private EnumAssetType GetAssetType(DataCache snapshot, UInt160 hash)
+ {
+ StorageKey key = new KeyBuilder(Neo.SmartContract.Native.NativeContract.ContractManagement.Id, 8).Add(hash);
+ ContractState contract = snapshot.TryGet(key)?.GetInteroperable();
+ EnumAssetType assetType;
+ if (contract is null)
+ {
+ assetType = EnumAssetType.Unknown;
+ }
+ else if (contract.Manifest.SupportedStandards.Contains("NEP-17") || Settings.Default.Nep17ContractIds.Contains(contract.Id))
+ {
+ assetType = EnumAssetType.NEP17;
+ }
+ else if (contract.Manifest.SupportedStandards.Contains("NEP-11") || Settings.Default.Nep11ContractIds.Contains(contract.Id))
+ {
+ assetType = EnumAssetType.NEP11;
+ }
+ else
+ {
+ assetType = EnumAssetType.Unknown;
+ }
+ return assetType;
+ }
+ }
+}
diff --git a/Fura/Settings.cs b/Fura/Settings.cs
index 3c02ddc..f765932 100644
--- a/Fura/Settings.cs
+++ b/Fura/Settings.cs
@@ -1,5 +1,7 @@
using System;
+using System.Collections.Generic;
using Microsoft.Extensions.Configuration;
+using System.Linq;
namespace Neo.Plugins
{
@@ -17,9 +19,21 @@ internal class Settings
public static Settings Default { get; private set; }
- public int SleepTime { get; set; }
+ public int SleepTime { get; }
- public int WaitTime { get; set; }
+ public int WaitTime { get;}
+
+ public IReadOnlyList MarketContractIds { get; }
+
+ public IReadOnlyList Nep11ContractIds { get; }
+
+ public IReadOnlyList Nep17ContractIds { get; }
+
+ public IReadOnlyList IlexContractHashes { get; }
+
+ public IReadOnlyList MetaContractHashes { get; }
+
+ public string NNS { get; }
private Settings(IConfigurationSection section)
{
@@ -27,13 +41,30 @@ private Settings(IConfigurationSection section)
this.Host = section.GetValue("Host", "127.0.0.1");
this.Port = section.GetValue("Port", 27017);
this.User = section.GetValue("User", "admin");
- this.Password = section.GetValue("Password","admin");
+ this.Password = section.GetValue("Password", "admin");
this.ConnectionString = section.GetValue("ConnectionString", "");
this.Log = section.GetValue("Log", true);
Console.WriteLine(Environment.CurrentDirectory);
this.PName = section.GetValue("PName", Environment.CurrentDirectory);
this.SleepTime = section.GetValue("SleepTime", 10);
this.WaitTime = section.GetValue("WaitTime", 900);
+ this.MarketContractIds = section.GetSection("MarketContractIds").Exists()
+ ? section.GetSection("MarketContractIds").GetChildren().Select(p => int.Parse(p.Value)).ToArray()
+ : new[] { 0 };
+ this.Nep11ContractIds = section.GetSection("Nep11ContractIds").Exists()
+ ? section.GetSection("Nep11ContractIds").GetChildren().Select(p => int.Parse(p.Value)).ToArray()
+ : new[] { 0 };
+ this.Nep17ContractIds = section.GetSection("Nep17ContractIds").Exists()
+ ? section.GetSection("Nep17ContractIds").GetChildren().Select(p => int.Parse(p.Value)).ToArray()
+ : new[] { 0 };
+ this.IlexContractHashes = section.GetSection("IlexContractHashes").Exists()
+ ? section.GetSection("IlexContractHashes").GetChildren().Select(p => p.Value).ToArray()
+ : new string[] { };
+ this.MetaContractHashes = section.GetSection("MetaContractHashes").Exists()
+ ? section.GetSection("MetaContractHashes").GetChildren().Select(p => p.Value).ToArray()
+ : new string[] { };
+ this.NNS = section.GetValue("NNS", "");
+
}
public static void Load(IConfigurationSection section)
diff --git a/Fura/VM/Helper.cs b/Fura/VM/Helper.cs
index 8f9c0a1..0451109 100644
--- a/Fura/VM/Helper.cs
+++ b/Fura/VM/Helper.cs
@@ -39,7 +39,7 @@ public static class Helper
public static List Script2ScCallModels(byte[] script, UInt256 txid, UInt160 sender, string vmstate)
{
List scCalls = new List();
- List instructions = Script2Instruction(script).ToArray().Reverse().ToList(); ;
+ List instructions = Script2Instruction(txid, script).ToArray().Reverse().ToList();
for (var index = 0; index < instructions.Count; index++)
{
var instruction = instructions[index];
@@ -64,7 +64,15 @@ public static List Script2ScCallModels(byte[] script, UInt256 txid,
string[] hexParams = new string[paramsCount];
for (var i = 0; i < paramsCount; i++)
{
- hexParams[i] = instructions[++index].Operand.Span.ToHexString();
+ ++index;
+ if (instructions[index].OpCode >= OpCode.PUSH0 && instructions[index].OpCode <= OpCode.PUSH16)
+ {
+ hexParams[i] = (Convert.ToInt16(instructions[index].OpCode) - 16).ToString("X2");
+ }
+ else
+ {
+ hexParams[i] = instructions[index].Operand.Span.ToHexString();
+ }
}
scCalls.Add(new(vmstate, txid, sender, UInt160.Parse(contractHash), method, callFlags.ToString(), hexParams));
}
@@ -72,16 +80,25 @@ public static List Script2ScCallModels(byte[] script, UInt256 txid,
return scCalls;
}
- public static List Script2Instruction(byte[] script)
+ public static List Script2Instruction(UInt256 txid, byte[] script)
{
- List instructions = new List();
- Script s = new Script(script,true);
- for (int ip = 0; ip < s.Length; ip += s.GetInstruction(ip).Size)
+ try
+ {
+ List instructions = new List();
+ Script s = new Script(script, true);
+ for (int ip = 0; ip < s.Length; ip += s.GetInstruction(ip).Size)
+ {
+ var instruction = s.GetInstruction(ip);
+ instructions.Add(instruction);
+ }
+ return instructions;
+ }
+ catch
{
- var instruction = s.GetInstruction(ip);
- instructions.Add(instruction);
+ DebugModel debugModel = new(string.Format("Script2Instruction----txid: {0}", txid));
+ debugModel.SaveAsync().Wait();
}
- return instructions;
+ return new List();
}
public static CallFlags Opcode2CallFlags(OpCode opCode)
@@ -155,7 +172,7 @@ public static BigInteger GetNeoBalanceOf(UInt160 user, NeoSystem system, DataCac
script = sb.ToArray();
}
- using (ApplicationEngine engine = ApplicationEngine.Run(script, snapshot, settings: system.Settings))
+ using (ApplicationEngine engine = ApplicationEngine.Run(script, snapshot, settings: system.Settings, gas: 50000000))
{
if (engine.State.HasFlag(VMState.FAULT))
{
@@ -219,7 +236,7 @@ public static (string, byte, BigInteger) GetAssetInfo(NeoSystem system, DataCach
script = sb.ToArray();
}
(string, byte, BigInteger) t = new("", 0, 0);
- using (ApplicationEngine engine = ApplicationEngine.Run(script, snapshot, settings: system.Settings))
+ using (ApplicationEngine engine = ApplicationEngine.Run(script, snapshot, settings: system.Settings, gas: 50000000))
{
if (engine.State.HasFlag(VMState.FAULT))
{
@@ -229,7 +246,15 @@ public static (string, byte, BigInteger) GetAssetInfo(NeoSystem system, DataCach
t.Item2 = (byte)engine.ResultStack.Pop().GetInteger();
t.Item1 = engine.ResultStack.Pop().GetString();
}
- t.Item3 = GetAssetTotalSupply(system, snapshot, asset);
+ try
+ {
+ t.Item3 = GetAssetTotalSupply(system, snapshot, asset);
+
+ }
+ catch
+ {
+ t.Item3 = 0;
+ }
return t;
}
@@ -242,7 +267,7 @@ public static BigInteger GetAssetTotalSupply(NeoSystem system, DataCache snapsho
script = sb.ToArray();
}
BigInteger totalSupply = 0;
- using (ApplicationEngine engine = ApplicationEngine.Run(script, snapshot, settings: system.Settings))
+ using (ApplicationEngine engine = ApplicationEngine.Run(script, snapshot, settings: system.Settings, gas: 50000000))
{
if (engine.State.HasFlag(VMState.FAULT))
{
@@ -255,6 +280,32 @@ public static BigInteger GetAssetTotalSupply(NeoSystem system, DataCache snapsho
}
+ public static BigInteger IsSelfControl(NeoSystem system, DataCache snapshot, UInt160 asset)
+ {
+ try
+ {
+ byte[] script;
+ using (ScriptBuilder sb = new ScriptBuilder())
+ {
+ sb.EmitDynamicCall(asset, "selfControl");
+ script = sb.ToArray();
+ }
+ using (ApplicationEngine engine = ApplicationEngine.Run(script, snapshot, settings: system.Settings, gas: 50000000))
+ {
+ if (engine.State.HasFlag(VMState.FAULT))
+ {
+ Console.WriteLine("Error:GetNep11Info,VMState.FAULT" + asset.ToString()); //后面需要去掉,返回null
+ return 0;
+ }
+ return engine.ResultStack.Pop().GetInteger();
+ }
+ }
+ catch
+ {
+ return 0;
+ }
+ }
+
public static string GetNep11Properties(NeoSystem system, DataCache snapshot, UInt160 asset, string TokenId)
{
byte[] script;
@@ -272,14 +323,13 @@ public static string GetNep11Properties(NeoSystem system, DataCache snapshot, UI
script = sb.ToArray();
}
var properties = "";
- using (ApplicationEngine engine = ApplicationEngine.Run(script, snapshot, settings: system.Settings))
+ using (ApplicationEngine engine = ApplicationEngine.Run(script, snapshot, settings: system.Settings, gas: 50000000))
{
if (engine.State.HasFlag(VMState.HALT))
{
properties = engine.ResultStack.Pop().ToJson().ToString();
}
}
-
if (!string.IsNullOrEmpty(properties))
{
try
@@ -407,69 +457,92 @@ public static BigInteger GetNep11BalanceOf(NeoSystem system, DataCache snapshot,
byte[] script;
BigInteger decimals = 0;
BigInteger balanceOf = 0;
- //先获取decimals来确定是不是可以分割的nft,如果是可以分割的nft,那么balanceOf(usr,tokenid),反为balanceOf(usr)
- using (ScriptBuilder sb = new ScriptBuilder())
- {
- sb.EmitDynamicCall(asset, "decimals");
- script = sb.ToArray();
- }
-
- using (ApplicationEngine engine = ApplicationEngine.Run(script, snapshot, settings: system.Settings))
- {
- if (engine.State.HasFlag(VMState.HALT))
- {
- decimals = engine.ResultStack.Pop().GetInteger();
- }
- }
- //如果精度是0,那么tokenid一定只有一个地址拥有。查询ownerOf看是不是属于addr,是就返回1,不是就返回0
- if (decimals == 0)
+ try
{
- //如果是有精度的就查询balanceof
+ //先获取decimals来确定是不是可以分割的nft,如果是可以分割的nft,那么balanceOf(usr,tokenid),反为balanceOf(usr)
using (ScriptBuilder sb = new ScriptBuilder())
{
- try
- {
- sb.EmitDynamicCall(asset, "ownerOf", Convert.FromBase64String(TokenId));
-
- }
- catch
- {
- sb.EmitDynamicCall(asset, "ownerOf", TokenId);
- }
+ sb.EmitDynamicCall(asset, "decimals");
script = sb.ToArray();
}
- using (ApplicationEngine engine = ApplicationEngine.Run(script, snapshot, settings: system.Settings))
+
+ using (ApplicationEngine engine = ApplicationEngine.Run(script, snapshot, settings: system.Settings, gas: 50000000))
{
if (engine.State.HasFlag(VMState.HALT))
{
- var owner = new UInt160(engine.ResultStack.Pop().GetSpan().ToArray());
- balanceOf = owner == addr ? 1 : 0;
+ var stackitem = engine.ResultStack.Pop();
+ if (!stackitem.IsNull)
+ {
+ decimals = stackitem.GetInteger();
+ }
}
}
- }
- else
- {
- //如果是有精度的就查询balanceof
- using (ScriptBuilder sb = new ScriptBuilder())
+ //如果精度是0,那么tokenid一定只有一个地址拥有。查询ownerOf看是不是属于addr,是就返回1,不是就返回0
+ if (decimals == 0)
{
- try
+ //如果是有精度的就查询balanceof
+ using (ScriptBuilder sb = new ScriptBuilder())
{
- sb.EmitDynamicCall(asset, "balanceOf", addr == null ? UInt160.Parse("0x1100000000000000000220000000000000000011") : addr, Convert.FromBase64String(TokenId));
+ try
+ {
+ sb.EmitDynamicCall(asset, "ownerOf", Convert.FromBase64String(TokenId));
+
+ }
+ catch
+ {
+ sb.EmitDynamicCall(asset, "ownerOf", TokenId);
+ }
+ script = sb.ToArray();
}
- catch
+ using (ApplicationEngine engine = ApplicationEngine.Run(script, snapshot, settings: system.Settings, gas: 50000000))
{
- sb.EmitDynamicCall(asset, "balanceOf", addr == null ? UInt160.Parse("0x1100000000000000000220000000000000000011") : addr, TokenId);
+ if (engine.State.HasFlag(VMState.HALT))
+ {
+ var stackitem = engine.ResultStack.Pop();
+ if (!stackitem.IsNull)
+ {
+ var bts = stackitem.GetSpan().ToArray();
+ var owner_1 = new UInt160(bts);
+ UInt160 owner_2 = null;
+ UInt160.TryParse(UTF8Encoding.UTF8.GetString(bts), out owner_2);
+ balanceOf = owner_1 == addr || owner_2 == addr ? 1 : 0;
+ }
+ }
}
- script = sb.ToArray();
}
- using (ApplicationEngine engine = ApplicationEngine.Run(script, snapshot, settings: system.Settings))
+ else
{
- if (engine.State.HasFlag(VMState.HALT))
+ //如果是有精度的就查询balanceof
+ using (ScriptBuilder sb = new ScriptBuilder())
{
- balanceOf = engine.ResultStack.Pop().GetInteger();
+ try
+ {
+ sb.EmitDynamicCall(asset, "balanceOf", addr == null ? UInt160.Parse("0x1100000000000000000220000000000000000011") : addr, Convert.FromBase64String(TokenId));
+ }
+ catch
+ {
+ sb.EmitDynamicCall(asset, "balanceOf", addr == null ? UInt160.Parse("0x1100000000000000000220000000000000000011") : addr, TokenId);
+ }
+ script = sb.ToArray();
+ }
+ using (ApplicationEngine engine = ApplicationEngine.Run(script, snapshot, settings: system.Settings, gas: 50000000))
+ {
+ if (engine.State.HasFlag(VMState.HALT))
+ {
+ var stackitem = engine.ResultStack.Pop();
+ if (!stackitem.IsNull)
+ {
+ balanceOf = stackitem.GetInteger();
+ }
+ }
}
}
}
+ catch(Exception e)
+ {
+ Loger.Warning(string.Format("Commit:{0}", e.Message));
+ }
+
return balanceOf;
}
@@ -487,7 +560,7 @@ public static BigInteger[] GetNep17BalanceOf(NeoSystem system, DataCache snapsho
}
BigInteger[] balanceOfs = new BigInteger[addrs.Length];
- using (ApplicationEngine engine = ApplicationEngine.Run(script, snapshot, settings: system.Settings))
+ using (ApplicationEngine engine = ApplicationEngine.Run(script, snapshot, settings: system.Settings, gas: 50000000 * addrs.Length))
{
if (engine.State.HasFlag(VMState.HALT))
{
diff --git a/UnitFuraTest/FuraTest.cs b/UnitFuraTest/FuraTest.cs
index 6038ea3..bae5a39 100644
--- a/UnitFuraTest/FuraTest.cs
+++ b/UnitFuraTest/FuraTest.cs
@@ -12,6 +12,8 @@
using System.Collections.Generic;
using System.Text.Json;
using System.IO;
+using Neo.VM;
+using Neo.Cryptography;
namespace UnitFuraTest
{
@@ -26,11 +28,44 @@ public void Init()
[TestMethod]
public void TestScript2Executions()
{
- var base64String = "7b226e616d65223a2247686f73744d61726b65742054657374204e4654222c226465736372697074696f6e223a224e6f74207265616c6c7920666f722073616c652c206e6f74206f726967696e616c20617274776f726b222c22696d616765223a22697066733a2f2f516d66527161414b6d53544153457a6f724234367145706236514a65656f784b6f3653566b4a7953363443767344222c22746f6b656e555249223a22222c2261747472696275746573223a5b7b2274797065223a22417274697374222c2276616c7565223a22556e6b6e6f776e222c22646973706c6179223a22227d2c7b2274797065223a224f726967696e616c222c2276616c7565223a224e6f7065222c22646973706c6179223a22227d2c7b2274797065223a22546573746e65742046756e222c2276616c7565223a22596573222c22646973706c6179223a22227d5d2c2270726f70657274696573223a7b226861735f6c6f636b6564223a747275652c2263726561746f72223a224e4c5a334b785864393838527633373473343231396877704d567175487841725944222c22726f79616c74696573223a323030302c2274797065223a317d7Q==";
- //var base64String = "DCEC13y+vWO9KxAxFwg0SF0rjAJoq/n2N89uNwqrDwi+WHsMFIU5Il4pKR6Kf5xyOLaNS67/1PekEsAfDAR2b3RlDBT1Y+pAvCg9TQ4FxI6jBbPyoHNA70FifVtS";
- var script = Convert.FromBase64String(base64String);
- var str = Encoding.UTF8.GetString(script);
- var scCalls = Neo.Plugins.VM.Helper.Script2ScCallModels(script, UInt256.Zero, UInt160.Zero, "");
+ var aa = new UInt256((UTF8Encoding.UTF8.GetBytes("Auction")).Sha256());
+ var ba = new UInt256((UTF8Encoding.UTF8.GetBytes("relaunch")).Sha256());
+
+ UInt160 asset = UInt160.Parse("0xd74d35311c2a20ba78cd12056d3017da5bd352a6");
+ string TokenId = "1LDil6dnxse4WiGC+2nk/gi0mnazuu0aMGI9hYsilHs=";
+ byte[] script;
+ using (ScriptBuilder sb = new ScriptBuilder())
+ {
+ try
+ {
+ sb.EmitDynamicCall(asset, "properties", Convert.FromBase64String(TokenId));
+
+ }
+ catch
+ {
+ sb.EmitDynamicCall(asset, "properties", TokenId);
+ }
+ script = sb.ToArray();
+ }
+ var a = script.ToHexString();
+
+ //var base64String = "7b226e616d65223a2247686f73744d61726b65742054657374204e4654222c226465736372697074696f6e223a224e6f74207265616c6c7920666f722073616c652c206e6f74206f726967696e616c20617274776f726b222c22696d616765223a22697066733a2f2f516d66527161414b6d53544153457a6f724234367145706236514a65656f784b6f3653566b4a7953363443767344222c22746f6b656e555249223a22222c2261747472696275746573223a5b7b2274797065223a22417274697374222c2276616c7565223a22556e6b6e6f776e222c22646973706c6179223a22227d2c7b2274797065223a224f726967696e616c222c2276616c7565223a224e6f7065222c22646973706c6179223a22227d2c7b2274797065223a22546573746e65742046756e222c2276616c7565223a22596573222c22646973706c6179223a22227d5d2c2270726f70657274696573223a7b226861735f6c6f636b6564223a747275652c2263726561746f72223a224e4c5a334b785864393838527633373473343231396877704d567175487841725944222c22726f79616c74696573223a323030302c2274797065223a317d7Q==";
+ ////var base64String = "DCEC13y+vWO9KxAxFwg0SF0rjAJoq/n2N89uNwqrDwi+WHsMFIU5Il4pKR6Kf5xyOLaNS67/1PekEsAfDAR2b3RlDBT1Y+pAvCg9TQ4FxI6jBbPyoHNA70FifVtS";
+ //var script = Convert.FromBase64String(base64String);
+ //var str = Encoding.UTF8.GetString(script);
+ //var scCalls = Neo.Plugins.VM.Helper.Script2ScCallModels(script, UInt256.Zero, UInt160.Zero, "");
+ }
+
+ [TestMethod]
+ public void TestConvert()
+ {
+ //var a = (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000;
+ //UInt160 from;
+ //bool succ = UInt160.TryParse(Convert.FromBase64String("krOcd6pg8ptXwXPO2Rfxf9Mhpus=").Reverse().ToArray().ToHexString(), out from);
+ //succ = UInt160.TryParse("d79888e16f9186e873b18a2bc80fd3ecf2ba74b3", out from);
+
+ string properties = "{\"name\":\"CryptoFallen #6-19\",\"description\":\"CryptoFallen #6-19 \\\"Neo3 Series\\\" Follow @1Bigbagheera on twitter for updates!\",\"image\":\"ipfs://QmXZF4Pu1txhKo938X43RqrVJZ98p9QZyKnNGQ3ZR5Q3y3\",\"tokenURI\":\"\",\"attributes\":[{\"type\":\"Author\",\"value\":\"1Bigbagheera\",\"display\":\"\"},{\"type\":\"Date\",\"value\":\"8/25/21\",\"display\":\"\"},{\"type\":\"Series\",\"value\":\"Neo3\",\"display\":\"\"}],\"properties\":{\"has_locked\":false,\"creator\":\"NMV6PXumvk74JHkrrgynh932dQKd2p9vGF\",\"royalties\":1000,\"type\":2}}";
+ Neo.Json.JObject jObject = (Neo.Json.JObject)Neo.Json.JObject.Parse(properties);
}
public static string TryParseByteString(string str)
@@ -111,15 +146,6 @@ public static string GetValue(JsonElement element)
return value;
}
- [TestMethod]
- public void TestConvert()
- {
- var a = (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000;
- UInt160 from;
- bool succ = UInt160.TryParse(Convert.FromBase64String("krOcd6pg8ptXwXPO2Rfxf9Mhpus=").Reverse().ToArray().ToHexString(), out from);
- succ = UInt160.TryParse("d79888e16f9186e873b18a2bc80fd3ecf2ba74b3", out from);
- }
-
[TestMethod]
public void TestECPointParse()
{
diff --git a/UnitFuraTest/UnitFuraTest.csproj b/UnitFuraTest/UnitFuraTest.csproj
index 0dc3d85..b819de0 100644
--- a/UnitFuraTest/UnitFuraTest.csproj
+++ b/UnitFuraTest/UnitFuraTest.csproj
@@ -1,7 +1,7 @@
- net5.0
+ net7.0
false