diff --git a/src/AntShares/Core/Block.cs b/src/AntShares/Core/Block.cs index 7485cc057d..8eac9ef940 100644 --- a/src/AntShares/Core/Block.cs +++ b/src/AntShares/Core/Block.cs @@ -49,7 +49,7 @@ public Header Header /// InventoryType IInventory.InventoryType => InventoryType.Block; - public override int Size => base.Size + Transactions.Length.GetVarSize() + Transactions.Sum(p => p.Size); + public override int Size => base.Size + Transactions.GetVarSize(); public static Fixed8 CalculateNetFee(IEnumerable transactions) { diff --git a/src/AntShares/Core/ClaimTransaction.cs b/src/AntShares/Core/ClaimTransaction.cs index 74938650e4..74c96b168f 100644 --- a/src/AntShares/Core/ClaimTransaction.cs +++ b/src/AntShares/Core/ClaimTransaction.cs @@ -18,7 +18,7 @@ public class ClaimTransaction : Transaction /// public CoinReference[] Claims; - public override int Size => base.Size + Claims.Length.GetVarSize() + Claims.Sum(p => p.Size); + public override int Size => base.Size + Claims.GetVarSize(); public ClaimTransaction() : base(TransactionType.ClaimTransaction) diff --git a/src/AntShares/Wallets/ContractParameterType.cs b/src/AntShares/Core/ContractParameterType.cs similarity index 94% rename from src/AntShares/Wallets/ContractParameterType.cs rename to src/AntShares/Core/ContractParameterType.cs index 8e37b7060a..5b9bd6fb0b 100644 --- a/src/AntShares/Wallets/ContractParameterType.cs +++ b/src/AntShares/Core/ContractParameterType.cs @@ -1,4 +1,4 @@ -namespace AntShares.Wallets +namespace AntShares.Core { /// /// 表示智能合约的参数类型 diff --git a/src/AntShares/Core/PublishTransaction.cs b/src/AntShares/Core/PublishTransaction.cs index 5407e876eb..b90767a1e6 100644 --- a/src/AntShares/Core/PublishTransaction.cs +++ b/src/AntShares/Core/PublishTransaction.cs @@ -1,6 +1,5 @@ using AntShares.IO; using AntShares.IO.Json; -using System; using System.IO; using System.Linq; @@ -8,11 +7,18 @@ namespace AntShares.Core { public class PublishTransaction : Transaction { - public byte[][] Contracts; + public byte[] Script; + public ContractParameterType[] ParameterList; + public ContractParameterType ReturnType; + public string Name; + public byte CodeVersion; + public string Author; + public string Email; + public string Description; - public override int Size => base.Size + Contracts.Length.GetVarSize() + Contracts.Sum(p => p.Length.GetVarSize() + p.Length); + public override int Size => base.Size + Script.GetVarSize() + ParameterList.GetVarSize() + sizeof(ContractParameterType) + Name.GetVarSize() + sizeof(byte) + Author.GetVarSize() + Email.GetVarSize() + Description.GetVarSize(); - public override Fixed8 SystemFee => Fixed8.FromDecimal(500 * Contracts.Length); + public override Fixed8 SystemFee => Fixed8.FromDecimal(500); public PublishTransaction() : base(TransactionType.PublishTransaction) @@ -21,23 +27,40 @@ public PublishTransaction() protected override void DeserializeExclusiveData(BinaryReader reader) { - Contracts = new byte[reader.ReadByte()][]; - if (Contracts.Length == 0) throw new FormatException(); - for (int i = 0; i < Contracts.Length; i++) - Contracts[i] = reader.ReadVarBytes(); + Script = reader.ReadVarBytes(65536); + ParameterList = reader.ReadVarBytes(252).Select(p => (ContractParameterType)p).ToArray(); + ReturnType = (ContractParameterType)reader.ReadByte(); + Name = reader.ReadVarString(252); + CodeVersion = reader.ReadByte(); + Author = reader.ReadVarString(252); + Email = reader.ReadVarString(252); + Description = reader.ReadVarString(65536); } protected override void SerializeExclusiveData(BinaryWriter writer) { - writer.Write((byte)Contracts.Length); - for (int i = 0; i < Contracts.Length; i++) - writer.WriteVarBytes(Contracts[i]); + writer.WriteVarBytes(Script); + writer.WriteVarBytes(ParameterList.Cast().ToArray()); + writer.Write((byte)ReturnType); + writer.WriteVarString(Name); + writer.Write(CodeVersion); + writer.WriteVarString(Author); + writer.WriteVarString(Email); + writer.WriteVarString(Description); } public override JObject ToJson() { JObject json = base.ToJson(); - json["contracts"] = new JArray(Contracts.Select(p => new JString(p.ToHexString()))); + json["contract"] = new JObject(); + json["contract"]["script"] = Script.ToHexString(); + json["contract"]["parameters"] = new JArray(ParameterList.Select(p => (JObject)p)); + json["contract"]["returntype"] = ReturnType; + json["contract"]["name"] = Name; + json["contract"]["version"] = CodeVersion; + json["contract"]["author"] = Author; + json["contract"]["email"] = Email; + json["contract"]["description"] = Description; return json; } } diff --git a/src/AntShares/Core/RegisterTransaction.cs b/src/AntShares/Core/RegisterTransaction.cs index 6ddb6e8a49..c271d07ec0 100644 --- a/src/AntShares/Core/RegisterTransaction.cs +++ b/src/AntShares/Core/RegisterTransaction.cs @@ -7,7 +7,6 @@ using System.Globalization; using System.IO; using System.Linq; -using System.Text; namespace AntShares.Core { @@ -39,21 +38,8 @@ public class RegisterTransaction : Transaction /// 资产管理员的合约散列值 /// public UInt160 Admin; - public string CertUrl; - public override int Size - { - get - { - int size = base.Size; - size += sizeof(AssetType) + Encoding.UTF8.GetByteCount(Name).GetVarSize() + Encoding.UTF8.GetByteCount(Name) + Amount.Size + sizeof(byte) + Issuer.Size + Admin.Size; - if (Version > 0) - { - size += sizeof(byte) + Encoding.UTF8.GetByteCount(CertUrl); - } - return size; - } - } + public override int Size => base.Size + sizeof(AssetType) + Name.GetVarSize() + Amount.Size + sizeof(byte) + Issuer.Size + Admin.Size; /// /// 系统费用 @@ -89,10 +75,6 @@ protected override void DeserializeExclusiveData(BinaryReader reader) Precision = reader.ReadByte(); Issuer = ECPoint.DeserializeFrom(reader, ECCurve.Secp256r1); Admin = reader.ReadSerializable(); - if (Version > 0) - { - CertUrl = reader.ReadVarString(252); - } } private Dictionary _names; @@ -165,10 +147,6 @@ protected override void SerializeExclusiveData(BinaryWriter writer) writer.Write(Precision); writer.Write(Issuer); writer.Write(Admin); - if (Version > 0) - { - writer.WriteVarString(CertUrl); - } } /// @@ -194,10 +172,6 @@ public override JObject ToJson() json["asset"]["low"] = Amount.GetData() & 0xffffffff; json["asset"]["issuer"] = Issuer.ToString(); json["asset"]["admin"] = Wallet.ToAddress(Admin); - if (Version > 0) - { - json["asset"]["cert"] = CertUrl; - } return json; } diff --git a/src/AntShares/Core/Transaction.cs b/src/AntShares/Core/Transaction.cs index 7457f01340..2c115ce1ed 100644 --- a/src/AntShares/Core/Transaction.cs +++ b/src/AntShares/Core/Transaction.cs @@ -91,7 +91,7 @@ public IReadOnlyDictionary References } } - public virtual int Size => sizeof(TransactionType) + sizeof(byte) + Attributes.Length.GetVarSize() + Attributes.Sum(p => p.Size) + Inputs.Length.GetVarSize() + Inputs.Sum(p => p.Size) + Outputs.Length.GetVarSize() + Outputs.Sum(p => p.Size) + Scripts.Length.GetVarSize() + Scripts.Sum(p => p.Size); + public virtual int Size => sizeof(TransactionType) + sizeof(byte) + Attributes.GetVarSize() + Inputs.GetVarSize() + Outputs.GetVarSize() + Scripts.GetVarSize(); /// /// 系统费用 diff --git a/src/AntShares/Core/TransactionAttribute.cs b/src/AntShares/Core/TransactionAttribute.cs index 2193865583..53267f66ec 100644 --- a/src/AntShares/Core/TransactionAttribute.cs +++ b/src/AntShares/Core/TransactionAttribute.cs @@ -32,7 +32,7 @@ public int Size else if (Usage == TransactionAttributeUsage.DescriptionUrl) return sizeof(TransactionAttributeUsage) + sizeof(byte) + Data.Length; else - return sizeof(TransactionAttributeUsage) + Data.Length.GetVarSize() + Data.Length; + return sizeof(TransactionAttributeUsage) + Data.GetVarSize(); } } diff --git a/src/AntShares/Core/Witness.cs b/src/AntShares/Core/Witness.cs index 0bbfb2e108..342a8958d6 100644 --- a/src/AntShares/Core/Witness.cs +++ b/src/AntShares/Core/Witness.cs @@ -12,7 +12,7 @@ public class Witness : ISerializable public byte[] StackScript; public byte[] RedeemScript; - public int Size => StackScript.Length.GetVarSize() + StackScript.Length + RedeemScript.Length.GetVarSize() + RedeemScript.Length; + public int Size => StackScript.GetVarSize() + RedeemScript.GetVarSize(); void ISerializable.Deserialize(BinaryReader reader) { diff --git a/src/AntShares/IO/Helper.cs b/src/AntShares/IO/Helper.cs index 0a28c4949f..f551c99885 100644 --- a/src/AntShares/IO/Helper.cs +++ b/src/AntShares/IO/Helper.cs @@ -2,6 +2,7 @@ using System.IO; using System.Linq; using System.Reflection; +using System.Runtime.InteropServices; using System.Text; namespace AntShares.IO @@ -30,7 +31,7 @@ public static ISerializable AsSerializable(this byte[] value, Type type) return serializable; } - internal static int GetVarSize(this int value) + internal static int GetVarSize(int value) { if (value < 0xFD) return sizeof(byte); @@ -40,6 +41,41 @@ internal static int GetVarSize(this int value) return sizeof(byte) + sizeof(uint); } + internal static int GetVarSize(this T[] value) + { + int value_size; + Type t = typeof(T); + if (typeof(ISerializable).IsAssignableFrom(t)) + { + value_size = value.OfType().Sum(p => p.Size); + } + else if (t.GetTypeInfo().IsEnum) + { + int element_size; + Type u = t.GetTypeInfo().GetEnumUnderlyingType(); + if (u == typeof(sbyte) || u == typeof(byte)) + element_size = 1; + else if (u == typeof(short) || u == typeof(ushort)) + element_size = 2; + else if (u == typeof(int) || u == typeof(uint)) + element_size = 4; + else //if (u == typeof(long) || u == typeof(ulong)) + element_size = 8; + value_size = value.Length * element_size; + } + else + { + value_size = value.Length * Marshal.SizeOf(); + } + return GetVarSize(value.Length) + value_size; + } + + internal static int GetVarSize(this string value) + { + int size = Encoding.UTF8.GetByteCount(value); + return GetVarSize(size) + size; + } + internal static string ReadFixedString(this BinaryReader reader, int length) { byte[] data = reader.ReadBytes(length); diff --git a/src/AntShares/Implementations/Blockchains/LevelDB/LevelDBBlockchain.cs b/src/AntShares/Implementations/Blockchains/LevelDB/LevelDBBlockchain.cs index dfc3647e5d..513245582c 100644 --- a/src/AntShares/Implementations/Blockchains/LevelDB/LevelDBBlockchain.cs +++ b/src/AntShares/Implementations/Blockchains/LevelDB/LevelDBBlockchain.cs @@ -223,7 +223,7 @@ public override byte[] GetContract(UInt160 hash) Slice value; if (!db.TryGet(ReadOptions.Default, SliceBuilder.Begin(DataEntryPrefix.DATA_Contract).Add(hash), out value)) return null; - return value.ToArray(); + return value.ToArray().Skip(32).ToArray(); } public override IEnumerable GetEnrollments(IEnumerable others) @@ -510,9 +510,9 @@ private void Persist(Block block) } break; case TransactionType.PublishTransaction: - foreach (byte[] script in ((PublishTransaction)tx).Contracts) { - batch.Put(SliceBuilder.Begin(DataEntryPrefix.DATA_Contract).Add(script.ToScriptHash()), script); + PublishTransaction publish_tx = (PublishTransaction)tx; + batch.Put(SliceBuilder.Begin(DataEntryPrefix.DATA_Contract).Add(publish_tx.Script.ToScriptHash()), SliceBuilder.Begin().Add(tx.Hash).Add(publish_tx.Script)); } break; } diff --git a/src/AntShares/Network/Payloads/AddrPayload.cs b/src/AntShares/Network/Payloads/AddrPayload.cs index b0102272d3..e22567ed95 100644 --- a/src/AntShares/Network/Payloads/AddrPayload.cs +++ b/src/AntShares/Network/Payloads/AddrPayload.cs @@ -1,6 +1,5 @@ using AntShares.IO; using System.IO; -using System.Linq; namespace AntShares.Network.Payloads { @@ -8,7 +7,7 @@ internal class AddrPayload : ISerializable { public NetworkAddressWithTime[] AddressList; - public int Size => AddressList.Length.GetVarSize() + AddressList.Sum(p => p.Size); + public int Size => AddressList.GetVarSize(); public static AddrPayload Create(params NetworkAddressWithTime[] addresses) { diff --git a/src/AntShares/Network/Payloads/ConsensusPayload.cs b/src/AntShares/Network/Payloads/ConsensusPayload.cs index 55814237a2..acf1de540e 100644 --- a/src/AntShares/Network/Payloads/ConsensusPayload.cs +++ b/src/AntShares/Network/Payloads/ConsensusPayload.cs @@ -47,7 +47,7 @@ Witness[] ISignable.Scripts } } - public int Size => sizeof(uint) + PrevHash.Size + sizeof(uint) + sizeof(ushort) + sizeof(uint) + Data.Length.GetVarSize() + Data.Length + 1 + Script.Size; + public int Size => sizeof(uint) + PrevHash.Size + sizeof(uint) + sizeof(ushort) + sizeof(uint) + Data.GetVarSize() + 1 + Script.Size; void ISerializable.Deserialize(BinaryReader reader) { diff --git a/src/AntShares/Network/Payloads/FilterAddPayload.cs b/src/AntShares/Network/Payloads/FilterAddPayload.cs index ca8ab3892e..920bcfc8bc 100644 --- a/src/AntShares/Network/Payloads/FilterAddPayload.cs +++ b/src/AntShares/Network/Payloads/FilterAddPayload.cs @@ -7,7 +7,7 @@ internal class FilterAddPayload : ISerializable { public byte[] Data; - public int Size => Data.Length.GetVarSize() + Data.Length; + public int Size => Data.GetVarSize(); void ISerializable.Deserialize(BinaryReader reader) { diff --git a/src/AntShares/Network/Payloads/FilterLoadPayload.cs b/src/AntShares/Network/Payloads/FilterLoadPayload.cs index 38e4cc7cbf..9f340f1353 100644 --- a/src/AntShares/Network/Payloads/FilterLoadPayload.cs +++ b/src/AntShares/Network/Payloads/FilterLoadPayload.cs @@ -11,7 +11,7 @@ internal class FilterLoadPayload : ISerializable public byte K; public uint Tweak; - public int Size => Filter.Length.GetVarSize() + Filter.Length + sizeof(byte) + sizeof(uint); + public int Size => Filter.GetVarSize() + sizeof(byte) + sizeof(uint); public static FilterLoadPayload Create(BloomFilter filter) { diff --git a/src/AntShares/Network/Payloads/GetBlocksPayload.cs b/src/AntShares/Network/Payloads/GetBlocksPayload.cs index 3357288b89..c28db10fbb 100644 --- a/src/AntShares/Network/Payloads/GetBlocksPayload.cs +++ b/src/AntShares/Network/Payloads/GetBlocksPayload.cs @@ -1,6 +1,5 @@ using AntShares.IO; using System.IO; -using System.Linq; namespace AntShares.Network.Payloads { @@ -9,7 +8,7 @@ internal class GetBlocksPayload : ISerializable public UInt256[] HashStart; public UInt256 HashStop; - public int Size => HashStart.Length.GetVarSize() + HashStart.Sum(p => p.Size) + HashStop.Size; + public int Size => HashStart.GetVarSize() + HashStop.Size; public static GetBlocksPayload Create(UInt256 hash_start, UInt256 hash_stop = null) { diff --git a/src/AntShares/Network/Payloads/HeadersPayload.cs b/src/AntShares/Network/Payloads/HeadersPayload.cs index 4f317c966f..bc281a6b7d 100644 --- a/src/AntShares/Network/Payloads/HeadersPayload.cs +++ b/src/AntShares/Network/Payloads/HeadersPayload.cs @@ -10,7 +10,7 @@ internal class HeadersPayload : ISerializable { public Header[] Headers; - public int Size => Headers.Length.GetVarSize() + Headers.Sum(p => p.Size); + public int Size => Headers.GetVarSize(); public static HeadersPayload Create(IEnumerable
headers) { diff --git a/src/AntShares/Network/Payloads/InvPayload.cs b/src/AntShares/Network/Payloads/InvPayload.cs index 6dfb7fb5aa..0f882f8901 100644 --- a/src/AntShares/Network/Payloads/InvPayload.cs +++ b/src/AntShares/Network/Payloads/InvPayload.cs @@ -1,7 +1,6 @@ using AntShares.IO; using System; using System.IO; -using System.Linq; namespace AntShares.Network.Payloads { @@ -10,7 +9,7 @@ internal class InvPayload : ISerializable public InventoryType Type; public UInt256[] Hashes; - public int Size => sizeof(InventoryType) + Hashes.Length.GetVarSize() + Hashes.Sum(p => p.Size); + public int Size => sizeof(InventoryType) + Hashes.GetVarSize(); public static InvPayload Create(InventoryType type, params UInt256[] hashes) { diff --git a/src/AntShares/Network/Payloads/MerkleBlockPayload.cs b/src/AntShares/Network/Payloads/MerkleBlockPayload.cs index 2ed7b44d00..2d6912da99 100644 --- a/src/AntShares/Network/Payloads/MerkleBlockPayload.cs +++ b/src/AntShares/Network/Payloads/MerkleBlockPayload.cs @@ -13,7 +13,7 @@ internal class MerkleBlockPayload : BlockBase public UInt256[] Hashes; public byte[] Flags; - public override int Size => base.Size + sizeof(int) + Hashes.Length.GetVarSize() + Hashes.Sum(p => p.Size) + Flags.Length.GetVarSize() + Flags.Length; + public override int Size => base.Size + sizeof(int) + Hashes.GetVarSize() + Flags.GetVarSize(); public static MerkleBlockPayload Create(Block block, BitArray flags) { diff --git a/src/AntShares/Network/Payloads/VersionPayload.cs b/src/AntShares/Network/Payloads/VersionPayload.cs index ab9b5c8961..cd14d4fb98 100644 --- a/src/AntShares/Network/Payloads/VersionPayload.cs +++ b/src/AntShares/Network/Payloads/VersionPayload.cs @@ -2,7 +2,6 @@ using AntShares.IO; using System; using System.IO; -using System.Text; namespace AntShares.Network.Payloads { @@ -17,7 +16,7 @@ internal class VersionPayload : ISerializable public uint StartHeight; public bool Relay; - public int Size => sizeof(uint) + sizeof(ulong) + sizeof(uint) + sizeof(ushort) + sizeof(uint) + Encoding.UTF8.GetByteCount(UserAgent).GetVarSize() + Encoding.UTF8.GetByteCount(UserAgent) + sizeof(uint) + sizeof(bool); + public int Size => sizeof(uint) + sizeof(ulong) + sizeof(uint) + sizeof(ushort) + sizeof(uint) + UserAgent.GetVarSize() + sizeof(uint) + sizeof(bool); public static VersionPayload Create(int port, uint nonce, string userAgent) { diff --git a/src/AntShares/Wallets/Contract.cs b/src/AntShares/Wallets/Contract.cs index 0b6efd7789..a24245e7ec 100644 --- a/src/AntShares/Wallets/Contract.cs +++ b/src/AntShares/Wallets/Contract.cs @@ -69,7 +69,7 @@ public UInt160 ScriptHash } } - public int Size => PublicKeyHash.Size + ParameterList.Length.GetVarSize() + ParameterList.Length + RedeemScript.Length.GetVarSize() + RedeemScript.Length; + public int Size => PublicKeyHash.Size + ParameterList.GetVarSize() + RedeemScript.GetVarSize(); public ContractType Type { diff --git a/src/AntShares/project.json b/src/AntShares/project.json index d2e422748e..bbb0d2af01 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.6", + "version": "1.4.0", "buildOptions": { "allowUnsafe": true, "copyToOutput": {