diff --git a/src/AntShares/AntShares.csproj b/src/AntShares/AntShares.csproj index a82f2a9612..1aa5c29e8b 100644 --- a/src/AntShares/AntShares.csproj +++ b/src/AntShares/AntShares.csproj @@ -3,7 +3,7 @@ 2015-2017 The Antshares team AntShares - 1.6.1 + 1.6.2 The Antshares team netstandard1.6;net461 true diff --git a/src/AntShares/Core/Blockchain.cs b/src/AntShares/Core/Blockchain.cs index 5c9a908b4a..f67b639efe 100644 --- a/src/AntShares/Core/Blockchain.cs +++ b/src/AntShares/Core/Blockchain.cs @@ -386,6 +386,8 @@ byte[] IScriptTable.GetScript(byte[] script_hash) return GetContract(new UInt160(script_hash)).Code.Script; } + public abstract StorageItem GetStorageItem(StorageKey key); + /// /// 根据指定的区块高度,返回对应区块及之前所有区块中包含的系统费用的总量 /// diff --git a/src/AntShares/Core/TransactionType.cs b/src/AntShares/Core/TransactionType.cs index 49a32bccaa..4c6eea4941 100644 --- a/src/AntShares/Core/TransactionType.cs +++ b/src/AntShares/Core/TransactionType.cs @@ -30,10 +30,6 @@ public enum TransactionType : byte /// ContractTransaction = 0x80, /// - /// 委托交易 - /// - AgencyTransaction = 0xb0, - /// /// Publish scripts to the blockchain for being invoked later. /// PublishTransaction = 0xd0, diff --git a/src/AntShares/IO/Caching/DataCache.cs b/src/AntShares/IO/Caching/DataCache.cs index 9d5323d2ac..5262157c02 100644 --- a/src/AntShares/IO/Caching/DataCache.cs +++ b/src/AntShares/IO/Caching/DataCache.cs @@ -8,7 +8,7 @@ public abstract class DataCache where TKey : IEquatable, ISerializable where TValue : class, ISerializable, new() { - protected class Trackable + protected internal class Trackable { public TKey Key; public TValue Item; @@ -73,7 +73,7 @@ public void DeleteWhere(Func predicate) trackable.State = TrackState.Deleted; } - protected IEnumerable GetChangeSet() + protected internal IEnumerable GetChangeSet() { return dictionary.Values.Where(p => p.State != TrackState.None); } diff --git a/src/AntShares/Implementations/Blockchains/LevelDB/LevelDBBlockchain.cs b/src/AntShares/Implementations/Blockchains/LevelDB/LevelDBBlockchain.cs index df5a7234c4..6944abac2f 100644 --- a/src/AntShares/Implementations/Blockchains/LevelDB/LevelDBBlockchain.cs +++ b/src/AntShares/Implementations/Blockchains/LevelDB/LevelDBBlockchain.cs @@ -2,6 +2,7 @@ using AntShares.Cryptography; using AntShares.Cryptography.ECC; using AntShares.IO; +using AntShares.IO.Caching; using AntShares.SmartContract; using System; using System.Collections.Generic; @@ -274,6 +275,11 @@ public override UInt256 GetNextBlockHash(UInt256 hash) } } + public override StorageItem GetStorageItem(StorageKey key) + { + return db.TryGet(ReadOptions.Default, DataEntryPrefix.ST_Storage, key); + } + public override long GetSysFeeAmount(UInt256 hash) { Slice value; @@ -547,8 +553,14 @@ private void Persist(Block block) spentcoins.Commit(batch); validators.Commit(batch); assets.Commit(batch); + HashSet contracts_deleted = new HashSet(contracts.GetChangeSet().Where(p => p.State == TrackState.Deleted).Select(p => p.Key)); contracts.Commit(batch); + if (contracts_deleted.Count > 0) + storages.DeleteWhere((k, v) => contracts_deleted.Contains(k.ScriptHash)); storages.Commit(batch); + foreach (UInt160 script_hash in contracts_deleted) + foreach (Slice key in db.Find(ReadOptions.Default, SliceBuilder.Begin(DataEntryPrefix.ST_Storage).Add(script_hash), (k, v) => k)) + batch.Delete(key); batch.Put(SliceBuilder.Begin(DataEntryPrefix.SYS_CurrentBlock), SliceBuilder.Begin().Add(block.Hash).Add(block.Index)); db.Write(WriteOptions.Default, batch); current_block_height = block.Index; diff --git a/src/AntShares/Network/RPC/RpcServer.cs b/src/AntShares/Network/RPC/RpcServer.cs index a8466e744d..b2578524de 100644 --- a/src/AntShares/Network/RPC/RpcServer.cs +++ b/src/AntShares/Network/RPC/RpcServer.cs @@ -1,6 +1,7 @@ using AntShares.Core; using AntShares.IO; using AntShares.IO.Json; +using AntShares.Wallets; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; @@ -140,6 +141,22 @@ protected virtual JObject Process(string method, JArray _params) Block block = _params[0].AsString().HexToBytes().AsSerializable(); return LocalNode.Relay(block); } + case "validateaddress": + { + JObject json = new JObject(); + UInt160 scriptHash; + try + { + scriptHash = Wallet.ToScriptHash(_params[0].AsString()); + } + catch + { + scriptHash = null; + } + json["address"] = _params[0]; + json["isvalid"] = scriptHash != null; + return json; + } default: throw new RpcException(-32601, "Method not found"); } diff --git a/src/AntShares/SmartContract/StateMachine.cs b/src/AntShares/SmartContract/StateMachine.cs index 79f899d625..bec2ef7a29 100644 --- a/src/AntShares/SmartContract/StateMachine.cs +++ b/src/AntShares/SmartContract/StateMachine.cs @@ -78,6 +78,15 @@ protected override bool Blockchain_GetAccount(ExecutionEngine engine) return true; } + protected override bool Blockchain_GetAsset(ExecutionEngine engine) + { + UInt256 hash = new UInt256(engine.EvaluationStack.Pop().GetByteArray()); + AssetState asset = assets.TryGet(hash); + if (asset == null) return false; + engine.EvaluationStack.Push(StackItem.FromInterface(asset)); + return true; + } + private bool Account_SetVotes(ExecutionEngine engine) { AccountState account = engine.EvaluationStack.Pop().GetInterface();