From b7cc047485a973604d024270585cac16b4ec8741 Mon Sep 17 00:00:00 2001 From: Erik Zhang Date: Tue, 20 Dec 2016 00:04:10 +0800 Subject: [PATCH] rename fields; upgrade to AntShares.VM 1.2.1; --- src/AntShares/Consensus/ConsensusContext.cs | 2 +- src/AntShares/Core/Block.cs | 2 +- src/AntShares/Core/BlockBase.cs | 18 +- src/AntShares/Core/Blockchain.cs | 2 +- src/AntShares/Core/CoinReference.cs | 5 + src/AntShares/Core/Header.cs | 2 +- src/AntShares/Core/ISignable.cs | 2 +- src/AntShares/Core/Order.cs | 2 +- src/AntShares/Core/Transaction.cs | 7 +- src/AntShares/Core/TransactionAttribute.cs | 5 + src/AntShares/Core/TransactionOutput.cs | 5 + .../Network/Payloads/ConsensusPayload.cs | 2 +- .../Network/Payloads/MerkleBlockPayload.cs | 2 +- src/AntShares/Network/RemoteNode.cs | 10 +- src/AntShares/VM/InterfaceEngine.cs | 363 +++++++----------- src/AntShares/project.json | 6 +- 16 files changed, 187 insertions(+), 248 deletions(-) diff --git a/src/AntShares/Consensus/ConsensusContext.cs b/src/AntShares/Consensus/ConsensusContext.cs index 3bea02ea59..3a679d6886 100644 --- a/src/AntShares/Consensus/ConsensusContext.cs +++ b/src/AntShares/Consensus/ConsensusContext.cs @@ -64,7 +64,7 @@ public Block MakeHeader() MerkleRoot = MerkleTree.ComputeRoot(TransactionHashes), Timestamp = Timestamp, Height = Height, - Nonce = Nonce, + ConsensusData = Nonce, NextMiner = NextMiner, Transactions = new Transaction[0] }; diff --git a/src/AntShares/Core/Block.cs b/src/AntShares/Core/Block.cs index 4e393c2e95..7485cc057d 100644 --- a/src/AntShares/Core/Block.cs +++ b/src/AntShares/Core/Block.cs @@ -35,7 +35,7 @@ public Header Header MerkleRoot = MerkleRoot, Timestamp = Timestamp, Height = Height, - Nonce = Nonce, + ConsensusData = ConsensusData, NextMiner = NextMiner, Script = Script }; diff --git a/src/AntShares/Core/BlockBase.cs b/src/AntShares/Core/BlockBase.cs index a8aaaa3953..0f3e96903a 100644 --- a/src/AntShares/Core/BlockBase.cs +++ b/src/AntShares/Core/BlockBase.cs @@ -30,10 +30,7 @@ public abstract class BlockBase : IApiInterface, ISignable /// 区块高度 /// public uint Height; - /// - /// 随机数 - /// - public ulong Nonce; + public ulong ConsensusData; /// /// 下一个区块的记账合约的散列值 /// @@ -85,11 +82,11 @@ void ISignable.DeserializeUnsigned(BinaryReader reader) MerkleRoot = reader.ReadSerializable(); Timestamp = reader.ReadUInt32(); Height = reader.ReadUInt32(); - Nonce = reader.ReadUInt64(); + ConsensusData = reader.ReadUInt64(); NextMiner = reader.ReadSerializable(); } - byte[] ISignableObject.GetMessage() + byte[] IScriptContainer.GetMessage() { return this.GetHashData(); } @@ -116,10 +113,15 @@ void ISignable.SerializeUnsigned(BinaryWriter writer) writer.Write(MerkleRoot); writer.Write(Timestamp); writer.Write(Height); - writer.Write(Nonce); + writer.Write(ConsensusData); writer.Write(NextMiner); } + byte[] IApiInterface.ToArray() + { + return this.ToArray(); + } + public virtual JObject ToJson() { JObject json = new JObject(); @@ -130,7 +132,7 @@ public virtual JObject ToJson() json["merkleroot"] = MerkleRoot.ToString(); json["time"] = Timestamp; json["height"] = Height; - json["nonce"] = Nonce.ToString("x16"); + json["nonce"] = ConsensusData.ToString("x16"); json["nextminer"] = Wallet.ToAddress(NextMiner); json["script"] = Script.ToJson(); return json; diff --git a/src/AntShares/Core/Blockchain.cs b/src/AntShares/Core/Blockchain.cs index 390ccb8141..5f6b0175f3 100644 --- a/src/AntShares/Core/Blockchain.cs +++ b/src/AntShares/Core/Blockchain.cs @@ -89,7 +89,7 @@ public abstract class Blockchain : IDisposable, IScriptTable PrevBlock = UInt256.Zero, Timestamp = (new DateTime(2016, 7, 15, 15, 8, 21, DateTimeKind.Utc)).ToTimestamp(), Height = 0, - Nonce = 2083236893, //向比特币致敬 + ConsensusData = 2083236893, //向比特币致敬 NextMiner = GetMinerAddress(StandbyMiners), Script = new Witness { diff --git a/src/AntShares/Core/CoinReference.cs b/src/AntShares/Core/CoinReference.cs index 5d2146a53a..dc503c7920 100644 --- a/src/AntShares/Core/CoinReference.cs +++ b/src/AntShares/Core/CoinReference.cs @@ -68,6 +68,11 @@ void ISerializable.Serialize(BinaryWriter writer) writer.Write(PrevIndex); } + byte[] IApiInterface.ToArray() + { + return this.ToArray(); + } + /// /// 将交易输入转变为json对象 /// diff --git a/src/AntShares/Core/Header.cs b/src/AntShares/Core/Header.cs index b0eac29994..e8da788422 100644 --- a/src/AntShares/Core/Header.cs +++ b/src/AntShares/Core/Header.cs @@ -5,7 +5,7 @@ namespace AntShares.Core { - public class Header : BlockBase, IApiInterface, IEquatable
+ public class Header : BlockBase, IEquatable
{ public override int Size => base.Size + 1; diff --git a/src/AntShares/Core/ISignable.cs b/src/AntShares/Core/ISignable.cs index 5224947dc9..1cb8e535ee 100644 --- a/src/AntShares/Core/ISignable.cs +++ b/src/AntShares/Core/ISignable.cs @@ -7,7 +7,7 @@ namespace AntShares.Core /// /// 为需要签名的数据提供一个接口 /// - public interface ISignable : ISerializable, ISignableObject + public interface ISignable : ISerializable, IScriptContainer { /// /// 用于验证该对象的脚本列表 diff --git a/src/AntShares/Core/Order.cs b/src/AntShares/Core/Order.cs index c619b0c10b..870d422788 100644 --- a/src/AntShares/Core/Order.cs +++ b/src/AntShares/Core/Order.cs @@ -87,7 +87,7 @@ private void DeserializeUnsignedInternal(BinaryReader reader, UInt256 asset_id, throw new FormatException(); } - byte[] ISignableObject.GetMessage() + byte[] IScriptContainer.GetMessage() { return this.GetHashData(); } diff --git a/src/AntShares/Core/Transaction.cs b/src/AntShares/Core/Transaction.cs index 31be40d46e..d8b1d9c5a3 100644 --- a/src/AntShares/Core/Transaction.cs +++ b/src/AntShares/Core/Transaction.cs @@ -202,7 +202,7 @@ public override int GetHashCode() return Hash.GetHashCode(); } - byte[] ISignableObject.GetMessage() + byte[] IScriptContainer.GetMessage() { return this.GetHashData(); } @@ -285,6 +285,11 @@ void ISignable.SerializeUnsigned(BinaryWriter writer) writer.Write(Outputs); } + byte[] IApiInterface.ToArray() + { + return this.ToArray(); + } + /// /// 变成json对象 /// diff --git a/src/AntShares/Core/TransactionAttribute.cs b/src/AntShares/Core/TransactionAttribute.cs index a7ebcbd141..2193865583 100644 --- a/src/AntShares/Core/TransactionAttribute.cs +++ b/src/AntShares/Core/TransactionAttribute.cs @@ -66,6 +66,11 @@ void ISerializable.Serialize(BinaryWriter writer) writer.Write(Data); } + byte[] IApiInterface.ToArray() + { + return this.ToArray(); + } + /// /// 变成json对象 /// diff --git a/src/AntShares/Core/TransactionOutput.cs b/src/AntShares/Core/TransactionOutput.cs index b38d7dd4a5..5ad108612f 100644 --- a/src/AntShares/Core/TransactionOutput.cs +++ b/src/AntShares/Core/TransactionOutput.cs @@ -42,6 +42,11 @@ void ISerializable.Serialize(BinaryWriter writer) writer.Write(ScriptHash); } + byte[] IApiInterface.ToArray() + { + return this.ToArray(); + } + /// /// 将交易输出转变为json对象 /// diff --git a/src/AntShares/Network/Payloads/ConsensusPayload.cs b/src/AntShares/Network/Payloads/ConsensusPayload.cs index cefa26037f..363ff78b2e 100644 --- a/src/AntShares/Network/Payloads/ConsensusPayload.cs +++ b/src/AntShares/Network/Payloads/ConsensusPayload.cs @@ -66,7 +66,7 @@ void ISignable.DeserializeUnsigned(BinaryReader reader) Data = reader.ReadVarBytes(); } - byte[] ISignableObject.GetMessage() + byte[] IScriptContainer.GetMessage() { return this.GetHashData(); } diff --git a/src/AntShares/Network/Payloads/MerkleBlockPayload.cs b/src/AntShares/Network/Payloads/MerkleBlockPayload.cs index 1ce3c47aa5..2ed7b44d00 100644 --- a/src/AntShares/Network/Payloads/MerkleBlockPayload.cs +++ b/src/AntShares/Network/Payloads/MerkleBlockPayload.cs @@ -35,7 +35,7 @@ public static MerkleBlockPayload Create(Block block, BitArray flags) MerkleRoot = block.MerkleRoot, Timestamp = block.Timestamp, Height = block.Height, - Nonce = block.Nonce, + ConsensusData = block.ConsensusData, NextMiner = block.NextMiner, Script = block.Script, TxCount = block.Transactions.Length, diff --git a/src/AntShares/Network/RemoteNode.cs b/src/AntShares/Network/RemoteNode.cs index 501f52d3a6..012c4533e4 100644 --- a/src/AntShares/Network/RemoteNode.cs +++ b/src/AntShares/Network/RemoteNode.cs @@ -333,18 +333,18 @@ private void OnMessageReceived(Message message) if (message.Payload.Length <= 1024 * 1024) OnInventoryReceived(Transaction.DeserializeFrom(message.Payload)); break; + case "verack": + case "version": + Disconnect(true); + break; case "alert": case "merkleblock": case "notfound": case "ping": case "pong": case "reject": - //暂时忽略 - break; - case "verack": - case "version": default: - Disconnect(true); + //暂时忽略 break; } } diff --git a/src/AntShares/VM/InterfaceEngine.cs b/src/AntShares/VM/InterfaceEngine.cs index fddc0fe7d7..9803e02c3c 100644 --- a/src/AntShares/VM/InterfaceEngine.cs +++ b/src/AntShares/VM/InterfaceEngine.cs @@ -1,7 +1,5 @@ using AntShares.Core; using System; -using System.Collections.Generic; -using System.Linq; using System.Numerics; namespace AntShares.VM @@ -14,8 +12,8 @@ public bool Invoke(string method, ScriptEngine engine) { switch (method) { - case "System.now": - return SystemNow(engine); + //case "System.now": + // return SystemNow(engine); case "System.currentTx": return SystemCurrentTx(engine); case "System.currentScriptHash": @@ -116,379 +114,298 @@ private bool ChainHeight(ScriptEngine engine) private bool ChainGetHeader(ScriptEngine engine) { - if (engine.EvaluationStack.Count < 1) return false; - StackItem x = engine.EvaluationStack.Pop(); - byte[][] data = x.GetBytesArray(); - List
r = new List
(); - foreach (byte[] d in data) + byte[] data = (byte[])engine.EvaluationStack.Pop(); + Header header; + switch (data.Length) { - switch (d.Length) - { - case sizeof(uint): - uint height = BitConverter.ToUInt32(d, 0); - if (Blockchain.Default != null) - r.Add(Blockchain.Default.GetHeader(height)); - else if (height == 0) - r.Add(Blockchain.GenesisBlock.Header); - else - r.Add(null); - break; - case 32: - UInt256 hash = new UInt256(d); - if (Blockchain.Default != null) - r.Add(Blockchain.Default.GetHeader(hash)); - else if (hash == Blockchain.GenesisBlock.Hash) - r.Add(Blockchain.GenesisBlock.Header); - else - r.Add(null); - break; - default: - return false; - } + case sizeof(uint): + uint height = BitConverter.ToUInt32(data, 0); + if (Blockchain.Default != null) + header = Blockchain.Default.GetHeader(height); + else if (height == 0) + header = Blockchain.GenesisBlock.Header; + else + header = null; + break; + case 32: + UInt256 hash = new UInt256(data); + if (Blockchain.Default != null) + header = Blockchain.Default.GetHeader(hash); + else if (hash == Blockchain.GenesisBlock.Hash) + header = Blockchain.GenesisBlock.Header; + else + header = null; + break; + default: + return false; } - engine.EvaluationStack.Push(new StackItem(r.ToArray())); + engine.EvaluationStack.Push(new StackItem(header)); return true; } private bool ChainGetBlock(ScriptEngine engine) { - if (engine.EvaluationStack.Count < 1) return false; - StackItem x = engine.EvaluationStack.Pop(); - byte[][] data = x.GetBytesArray(); - List r = new List(); - foreach (byte[] d in data) + byte[] data = (byte[])engine.EvaluationStack.Pop(); + Block block; + switch (data.Length) { - switch (d.Length) - { - case sizeof(uint): - uint height = BitConverter.ToUInt32(d, 0); - if (Blockchain.Default != null) - r.Add(Blockchain.Default.GetBlock(height)); - else if (height == 0) - r.Add(Blockchain.GenesisBlock); - else - r.Add(null); - break; - case 32: - UInt256 hash = new UInt256(d); - if (Blockchain.Default != null) - r.Add(Blockchain.Default.GetBlock(hash)); - else if (hash == Blockchain.GenesisBlock.Hash) - r.Add(Blockchain.GenesisBlock); - else - r.Add(null); - break; - default: - return false; - } + case sizeof(uint): + uint height = BitConverter.ToUInt32(data, 0); + if (Blockchain.Default != null) + block = Blockchain.Default.GetBlock(height); + else if (height == 0) + block = Blockchain.GenesisBlock; + else + block = null; + break; + case 32: + UInt256 hash = new UInt256(data); + if (Blockchain.Default != null) + block = Blockchain.Default.GetBlock(hash); + else if (hash == Blockchain.GenesisBlock.Hash) + block = Blockchain.GenesisBlock; + else + block = null; + break; + default: + return false; } - engine.EvaluationStack.Push(new StackItem(r.ToArray())); + engine.EvaluationStack.Push(new StackItem(block)); return true; } private bool ChainGetTx(ScriptEngine engine) { - if (engine.EvaluationStack.Count < 1) return false; - StackItem x = engine.EvaluationStack.Pop(); - Transaction[] r = x.GetBytesArray().Select(p => Blockchain.Default?.GetTransaction(new UInt256(p))).ToArray(); - engine.EvaluationStack.Push(new StackItem(r)); + byte[] hash = (byte[])engine.EvaluationStack.Pop(); + Transaction tx = Blockchain.Default?.GetTransaction(new UInt256(hash)); + engine.EvaluationStack.Push(new StackItem(tx)); return true; } private bool HeaderHash(ScriptEngine engine) { - if (engine.AltStack.Count < 1) return false; - StackItem x = engine.AltStack.Peek(); - BlockBase[] headers = x.GetArray(); - if (headers.Any(p => p == null)) return false; - byte[][] r = headers.Select(p => p.Hash.ToArray()).ToArray(); - engine.EvaluationStack.Push(new StackItem(r)); + BlockBase header = engine.EvaluationStack.Pop().GetInterface(); + if (header == null) return false; + engine.EvaluationStack.Push(header.Hash.ToArray()); return true; } private bool HeaderVersion(ScriptEngine engine) { - if (engine.AltStack.Count < 1) return false; - StackItem x = engine.AltStack.Peek(); - BlockBase[] headers = x.GetArray(); - if (headers.Any(p => p == null)) return false; - uint[] r = headers.Select(p => p.Version).ToArray(); - engine.EvaluationStack.Push(r); + BlockBase header = engine.EvaluationStack.Pop().GetInterface(); + if (header == null) return false; + engine.EvaluationStack.Push(header.Version); return true; } private bool HeaderPrevHash(ScriptEngine engine) { - if (engine.AltStack.Count < 1) return false; - StackItem x = engine.AltStack.Peek(); - BlockBase[] headers = x.GetArray(); - if (headers.Any(p => p == null)) return false; - byte[][] r = headers.Select(p => p.PrevBlock.ToArray()).ToArray(); - engine.EvaluationStack.Push(new StackItem(r)); + BlockBase header = engine.EvaluationStack.Pop().GetInterface(); + if (header == null) return false; + engine.EvaluationStack.Push(header.PrevBlock.ToArray()); return true; } private bool HeaderMerkleRoot(ScriptEngine engine) { - if (engine.AltStack.Count < 1) return false; - StackItem x = engine.AltStack.Peek(); - BlockBase[] headers = x.GetArray(); - if (headers.Any(p => p == null)) return false; - byte[][] r = headers.Select(p => p.MerkleRoot.ToArray()).ToArray(); - engine.EvaluationStack.Push(new StackItem(r)); + BlockBase header = engine.EvaluationStack.Pop().GetInterface(); + if (header == null) return false; + engine.EvaluationStack.Push(header.MerkleRoot.ToArray()); return true; } private bool HeaderTimestamp(ScriptEngine engine) { - if (engine.AltStack.Count < 1) return false; - StackItem x = engine.AltStack.Peek(); - BlockBase[] headers = x.GetArray(); - if (headers.Any(p => p == null)) return false; - uint[] r = headers.Select(p => p.Timestamp).ToArray(); - engine.EvaluationStack.Push(r); + BlockBase header = engine.EvaluationStack.Pop().GetInterface(); + if (header == null) return false; + engine.EvaluationStack.Push(header.Timestamp); return true; } private bool HeaderNonce(ScriptEngine engine) { - if (engine.AltStack.Count < 1) return false; - StackItem x = engine.AltStack.Peek(); - BlockBase[] headers = x.GetArray(); - if (headers.Any(p => p == null)) return false; - ulong[] r = headers.Select(p => p.Nonce).ToArray(); - engine.EvaluationStack.Push(r); + BlockBase header = engine.EvaluationStack.Pop().GetInterface(); + if (header == null) return false; + engine.EvaluationStack.Push(header.ConsensusData); return true; } private bool HeaderNextMiner(ScriptEngine engine) { - if (engine.AltStack.Count < 1) return false; - StackItem x = engine.AltStack.Peek(); - BlockBase[] headers = x.GetArray(); - if (headers.Any(p => p == null)) return false; - byte[][] r = headers.Select(p => p.NextMiner.ToArray()).ToArray(); - engine.EvaluationStack.Push(new StackItem(r)); + BlockBase header = engine.EvaluationStack.Pop().GetInterface(); + if (header == null) return false; + engine.EvaluationStack.Push(header.NextMiner.ToArray()); return true; } private bool BlockTxCount(ScriptEngine engine) { - if (engine.AltStack.Count < 1) return false; - StackItem x = engine.AltStack.Peek(); - Block[] blocks = x.GetArray(); - if (blocks.Any(p => p == null)) return false; - int[] r = blocks.Select(p => p.Transactions.Length).ToArray(); - engine.EvaluationStack.Push(r); + Block block = engine.EvaluationStack.Pop().GetInterface(); + if (block == null) return false; + engine.EvaluationStack.Push(block.Transactions.Length); return true; } private bool BlockTx(ScriptEngine engine) { - if (engine.AltStack.Count < 1) return false; - Block block = engine.AltStack.Peek().GetInterface(); + Block block = engine.EvaluationStack.Pop().GetInterface(); if (block == null) return false; - engine.EvaluationStack.Push(new StackItem(block.Transactions)); + for (int i = block.Transactions.Length - 1; i >= 0; i--) + engine.EvaluationStack.Push(new StackItem(block.Transactions[i])); + engine.EvaluationStack.Push(block.Transactions.Length); return true; } private bool BlockGetTx(ScriptEngine engine) { - if (engine.EvaluationStack.Count < 1 || engine.AltStack.Count < 1) return false; - StackItem block_item = engine.AltStack.Peek(); - Block[] blocks = block_item.GetArray(); - if (blocks.Any(p => p == null)) return false; - StackItem index_item = engine.EvaluationStack.Pop(); - BigInteger[] indexes = index_item.GetIntArray(); - if (blocks.Length != 1 && indexes.Length != 1 && blocks.Length != indexes.Length) - return false; - if (blocks.Length == 1) - blocks = Enumerable.Repeat(blocks[0], indexes.Length).ToArray(); - else if (indexes.Length == 1) - indexes = Enumerable.Repeat(indexes[0], blocks.Length).ToArray(); - Transaction[] tx = blocks.Zip(indexes, (b, i) => i >= b.Transactions.Length ? null : b.Transactions[(int)i]).ToArray(); + int index = (int)(BigInteger)engine.EvaluationStack.Pop(); + Block block = engine.EvaluationStack.Pop().GetInterface(); + if (block == null) return false; + if (index < 0 || index >= block.Transactions.Length) return false; + Transaction tx = block.Transactions[index]; engine.EvaluationStack.Push(new StackItem(tx)); return true; } private bool TxHash(ScriptEngine engine) { - if (engine.AltStack.Count < 1) return false; - StackItem x = engine.AltStack.Peek(); - Transaction[] tx = x.GetArray(); - if (tx.Any(p => p == null)) return false; - byte[][] r = tx.Select(p => p.Hash.ToArray()).ToArray(); - engine.EvaluationStack.Push(new StackItem(r)); + Transaction tx = engine.EvaluationStack.Pop().GetInterface(); + if (tx == null) return false; + engine.EvaluationStack.Push(tx.Hash.ToArray()); return true; } private bool TxType(ScriptEngine engine) { - if (engine.AltStack.Count < 1) return false; - StackItem x = engine.AltStack.Peek(); - Transaction[] tx = x.GetArray(); - if (tx.Any(p => p == null)) return false; - byte[][] r = tx.Select(p => new[] { (byte)p.Type }).ToArray(); - engine.EvaluationStack.Push(r); + Transaction tx = engine.EvaluationStack.Pop().GetInterface(); + if (tx == null) return false; + engine.EvaluationStack.Push((int)tx.Type); return true; } private bool AssetType(ScriptEngine engine) { - if (engine.AltStack.Count < 1) return false; - StackItem x = engine.AltStack.Peek(); - RegisterTransaction[] tx = x.GetArray(); - if (tx.Any(p => p == null)) return false; - byte[][] r = tx.Select(p => new[] { (byte)p.AssetType }).ToArray(); - engine.EvaluationStack.Push(r); + RegisterTransaction asset = engine.EvaluationStack.Pop().GetInterface(); + if (asset == null) return false; + engine.EvaluationStack.Push((int)asset.AssetType); return true; } private bool AssetAmount(ScriptEngine engine) { - if (engine.AltStack.Count < 1) return false; - StackItem x = engine.AltStack.Peek(); - RegisterTransaction[] tx = x.GetArray(); - if (tx.Any(p => p == null)) return false; - long[] r = tx.Select(p => p.Amount.GetData()).ToArray(); - engine.EvaluationStack.Push(r); + RegisterTransaction asset = engine.EvaluationStack.Pop().GetInterface(); + if (asset == null) return false; + engine.EvaluationStack.Push(asset.Amount.GetData()); return true; } private bool AssetIssuer(ScriptEngine engine) { - if (engine.AltStack.Count < 1) return false; - StackItem x = engine.AltStack.Peek(); - RegisterTransaction[] tx = x.GetArray(); - if (tx.Any(p => p == null)) return false; - byte[][] r = tx.Select(p => p.Issuer.EncodePoint(true)).ToArray(); - engine.EvaluationStack.Push(new StackItem(r)); + RegisterTransaction asset = engine.EvaluationStack.Pop().GetInterface(); + if (asset == null) return false; + engine.EvaluationStack.Push(asset.Issuer.EncodePoint(true)); return true; } private bool AssetAdmin(ScriptEngine engine) { - if (engine.AltStack.Count < 1) return false; - StackItem x = engine.AltStack.Peek(); - RegisterTransaction[] tx = x.GetArray(); - if (tx.Any(p => p == null)) return false; - byte[][] r = tx.Select(p => p.Admin.ToArray()).ToArray(); - engine.EvaluationStack.Push(new StackItem(r)); + RegisterTransaction asset = engine.EvaluationStack.Pop().GetInterface(); + if (asset == null) return false; + engine.EvaluationStack.Push(asset.Admin.ToArray()); return true; } private bool EnrollPubkey(ScriptEngine engine) { - if (engine.AltStack.Count < 1) return false; - StackItem x = engine.AltStack.Peek(); - EnrollmentTransaction[] tx = x.GetArray(); - if (tx.Any(p => p == null)) return false; - byte[][] r = tx.Select(p => p.PublicKey.EncodePoint(true)).ToArray(); - engine.EvaluationStack.Push(new StackItem(r)); + EnrollmentTransaction tx = engine.EvaluationStack.Pop().GetInterface(); + if (tx == null) return false; + engine.EvaluationStack.Push(tx.PublicKey.EncodePoint(true)); return true; } private bool TxAttributes(ScriptEngine engine) { - if (engine.AltStack.Count < 1) return false; - Transaction tx = engine.AltStack.Pop().GetInterface(); + Transaction tx = engine.EvaluationStack.Pop().GetInterface(); if (tx == null) return false; - engine.EvaluationStack.Push(new StackItem(tx.Attributes)); + for (int i = tx.Attributes.Length - 1; i >= 0; i--) + engine.EvaluationStack.Push(new StackItem(tx.Attributes[i])); + engine.EvaluationStack.Push(tx.Attributes.Length); return true; } private bool TxInputs(ScriptEngine engine) { - if (engine.AltStack.Count < 1) return false; - Transaction tx = engine.AltStack.Pop().GetInterface(); + Transaction tx = engine.EvaluationStack.Pop().GetInterface(); if (tx == null) return false; - engine.EvaluationStack.Push(new StackItem(tx.Inputs)); + for (int i = tx.Inputs.Length - 1; i >= 0; i--) + engine.EvaluationStack.Push(new StackItem(tx.Inputs[i])); + engine.EvaluationStack.Push(tx.Inputs.Length); return true; } private bool TxOutputs(ScriptEngine engine) { - if (engine.AltStack.Count < 1) return false; - Transaction tx = engine.AltStack.Pop().GetInterface(); + Transaction tx = engine.EvaluationStack.Pop().GetInterface(); if (tx == null) return false; - engine.EvaluationStack.Push(new StackItem(tx.Outputs)); + for (int i = tx.Outputs.Length - 1; i >= 0; i--) + engine.EvaluationStack.Push(new StackItem(tx.Outputs[i])); + engine.EvaluationStack.Push(tx.Outputs.Length); return true; } private bool AttrUsage(ScriptEngine engine) { - if (engine.AltStack.Count < 1) return false; - StackItem x = engine.AltStack.Peek(); - TransactionAttribute[] attr = x.GetArray(); - if (attr.Any(p => p == null)) return false; - byte[][] r = attr.Select(p => new[] { (byte)p.Usage }).ToArray(); - engine.EvaluationStack.Push(r); + TransactionAttribute attr = engine.EvaluationStack.Pop().GetInterface(); + if (attr == null) return false; + engine.EvaluationStack.Push((int)attr.Usage); return true; } private bool AttrData(ScriptEngine engine) { - if (engine.AltStack.Count < 1) return false; - StackItem x = engine.AltStack.Peek(); - TransactionAttribute[] attr = x.GetArray(); - if (attr.Any(p => p == null)) return false; - byte[][] r = attr.Select(p => p.Data).ToArray(); - engine.EvaluationStack.Push(r); + TransactionAttribute attr = engine.EvaluationStack.Pop().GetInterface(); + if (attr == null) return false; + engine.EvaluationStack.Push(attr.Data); return true; } private bool TxInHash(ScriptEngine engine) { - if (engine.AltStack.Count < 1) return false; - StackItem x = engine.AltStack.Peek(); - CoinReference[] inputs = x.GetArray(); - if (inputs.Any(p => p == null)) return false; - byte[][] r = inputs.Select(p => p.PrevHash.ToArray()).ToArray(); - engine.EvaluationStack.Push(new StackItem(r)); + CoinReference input = engine.EvaluationStack.Pop().GetInterface(); + if (input == null) return false; + engine.EvaluationStack.Push(input.PrevHash.ToArray()); return true; } private bool TxInIndex(ScriptEngine engine) { - if (engine.AltStack.Count < 1) return false; - StackItem x = engine.AltStack.Peek(); - CoinReference[] inputs = x.GetArray(); - if (inputs.Any(p => p == null)) return false; - uint[] r = inputs.Select(p => (uint)p.PrevIndex).ToArray(); - engine.EvaluationStack.Push(r); + CoinReference input = engine.EvaluationStack.Pop().GetInterface(); + if (input == null) return false; + engine.EvaluationStack.Push((int)input.PrevIndex); return true; } private bool TxOutAsset(ScriptEngine engine) { - if (engine.AltStack.Count < 1) return false; - StackItem x = engine.AltStack.Peek(); - TransactionOutput[] outputs = x.GetArray(); - if (outputs.Any(p => p == null)) return false; - byte[][] r = outputs.Select(p => p.AssetId.ToArray()).ToArray(); - engine.EvaluationStack.Push(new StackItem(r)); + TransactionOutput output = engine.EvaluationStack.Pop().GetInterface(); + if (output == null) return false; + engine.EvaluationStack.Push(output.AssetId.ToArray()); return true; } private bool TxOutValue(ScriptEngine engine) { - if (engine.AltStack.Count < 1) return false; - StackItem x = engine.AltStack.Peek(); - TransactionOutput[] outputs = x.GetArray(); - if (outputs.Any(p => p == null)) return false; - long[] r = outputs.Select(p => p.Value.GetData()).ToArray(); - engine.EvaluationStack.Push(r); + TransactionOutput output = engine.EvaluationStack.Pop().GetInterface(); + if (output == null) return false; + engine.EvaluationStack.Push(output.Value.GetData()); return true; } private bool TxOutScriptHash(ScriptEngine engine) { - if (engine.AltStack.Count < 1) return false; - StackItem x = engine.AltStack.Peek(); - TransactionOutput[] outputs = x.GetArray(); - if (outputs.Any(p => p == null)) return false; - byte[][] r = outputs.Select(p => p.ScriptHash.ToArray()).ToArray(); - engine.EvaluationStack.Push(new StackItem(r)); + TransactionOutput output = engine.EvaluationStack.Pop().GetInterface(); + if (output == null) return false; + engine.EvaluationStack.Push(output.ScriptHash.ToArray()); return true; } } diff --git a/src/AntShares/project.json b/src/AntShares/project.json index d64d9330a0..db52051d49 100644 --- a/src/AntShares/project.json +++ b/src/AntShares/project.json @@ -2,7 +2,7 @@ "authors": [ "The Antshares team" ], "copyright": "2015-2016 The Antshares team", "title": "AntShares", - "version": "1.3.3.2", + "version": "1.3.4", "buildOptions": { "allowUnsafe": true, "copyToOutput": { @@ -27,8 +27,8 @@ }, "dependencies": { - "AntShares.Compiler": "1.1.0.2", - "AntShares.VM": "1.1.0.2", + "AntShares.Compiler": "1.2.1", + "AntShares.VM": "1.2.1", "Microsoft.AspNetCore.Server.Kestrel": "1.0.1", "Microsoft.AspNetCore.Server.Kestrel.Https": "1.0.1", "Microsoft.EntityFrameworkCore.Sqlite": "1.0.0",