diff --git a/src/neo/Network/P2P/Payloads/Conditions/AndCondition.cs b/src/neo/Network/P2P/Payloads/Conditions/AndCondition.cs
index d141443eac..a2a6045d83 100644
--- a/src/neo/Network/P2P/Payloads/Conditions/AndCondition.cs
+++ b/src/neo/Network/P2P/Payloads/Conditions/AndCondition.cs
@@ -11,6 +11,8 @@
using Neo.IO;
using Neo.IO.Json;
using Neo.SmartContract;
+using Neo.VM;
+using Neo.VM.Types;
using System;
using System.IO;
using System.Linq;
@@ -58,5 +60,12 @@ public override JObject ToJson()
json["expressions"] = Expressions.Select(p => p.ToJson()).ToArray();
return json;
}
+
+ public override StackItem ToStackItem(ReferenceCounter referenceCounter)
+ {
+ var result = (VM.Types.Array)base.ToStackItem(referenceCounter);
+ result.Add(new VM.Types.Array(referenceCounter, Expressions.Select(p => p.ToStackItem(referenceCounter))));
+ return result;
+ }
}
}
diff --git a/src/neo/Network/P2P/Payloads/Conditions/BooleanCondition.cs b/src/neo/Network/P2P/Payloads/Conditions/BooleanCondition.cs
index 3ae6c336e6..5339a50109 100644
--- a/src/neo/Network/P2P/Payloads/Conditions/BooleanCondition.cs
+++ b/src/neo/Network/P2P/Payloads/Conditions/BooleanCondition.cs
@@ -10,6 +10,8 @@
using Neo.IO.Json;
using Neo.SmartContract;
+using Neo.VM;
+using Neo.VM.Types;
using System.IO;
namespace Neo.Network.P2P.Payloads.Conditions
@@ -50,5 +52,12 @@ public override JObject ToJson()
json["expression"] = Expression;
return json;
}
+
+ public override StackItem ToStackItem(ReferenceCounter referenceCounter)
+ {
+ var result = (Array)base.ToStackItem(referenceCounter);
+ result.Add(Expression);
+ return result;
+ }
}
}
diff --git a/src/neo/Network/P2P/Payloads/Conditions/CalledByContractCondition.cs b/src/neo/Network/P2P/Payloads/Conditions/CalledByContractCondition.cs
index 836aa40117..f190585091 100644
--- a/src/neo/Network/P2P/Payloads/Conditions/CalledByContractCondition.cs
+++ b/src/neo/Network/P2P/Payloads/Conditions/CalledByContractCondition.cs
@@ -11,6 +11,8 @@
using Neo.IO;
using Neo.IO.Json;
using Neo.SmartContract;
+using Neo.VM;
+using Neo.VM.Types;
using System.IO;
namespace Neo.Network.P2P.Payloads.Conditions
@@ -51,5 +53,12 @@ public override JObject ToJson()
json["hash"] = Hash.ToString();
return json;
}
+
+ public override StackItem ToStackItem(ReferenceCounter referenceCounter)
+ {
+ var result = (Array)base.ToStackItem(referenceCounter);
+ result.Add(Hash.ToArray());
+ return result;
+ }
}
}
diff --git a/src/neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs b/src/neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs
index a7e9754566..6a6e15d83a 100644
--- a/src/neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs
+++ b/src/neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs
@@ -13,6 +13,8 @@
using Neo.IO.Json;
using Neo.SmartContract;
using Neo.SmartContract.Native;
+using Neo.VM;
+using Neo.VM.Types;
using System.IO;
using System.Linq;
@@ -56,5 +58,12 @@ public override JObject ToJson()
json["group"] = Group.ToString();
return json;
}
+
+ public override StackItem ToStackItem(ReferenceCounter referenceCounter)
+ {
+ var result = (Array)base.ToStackItem(referenceCounter);
+ result.Add(Group.ToArray());
+ return result;
+ }
}
}
diff --git a/src/neo/Network/P2P/Payloads/Conditions/GroupCondition.cs b/src/neo/Network/P2P/Payloads/Conditions/GroupCondition.cs
index b94773fb9e..3b1d53242e 100644
--- a/src/neo/Network/P2P/Payloads/Conditions/GroupCondition.cs
+++ b/src/neo/Network/P2P/Payloads/Conditions/GroupCondition.cs
@@ -13,6 +13,8 @@
using Neo.IO.Json;
using Neo.SmartContract;
using Neo.SmartContract.Native;
+using Neo.VM;
+using Neo.VM.Types;
using System.IO;
using System.Linq;
@@ -56,5 +58,12 @@ public override JObject ToJson()
json["group"] = Group.ToString();
return json;
}
+
+ public override StackItem ToStackItem(ReferenceCounter referenceCounter)
+ {
+ var result = (Array)base.ToStackItem(referenceCounter);
+ result.Add(Group.ToArray());
+ return result;
+ }
}
}
diff --git a/src/neo/Network/P2P/Payloads/Conditions/NotCondition.cs b/src/neo/Network/P2P/Payloads/Conditions/NotCondition.cs
index d71c2c03d2..ade2e03b24 100644
--- a/src/neo/Network/P2P/Payloads/Conditions/NotCondition.cs
+++ b/src/neo/Network/P2P/Payloads/Conditions/NotCondition.cs
@@ -11,6 +11,8 @@
using Neo.IO;
using Neo.IO.Json;
using Neo.SmartContract;
+using Neo.VM;
+using Neo.VM.Types;
using System;
using System.IO;
@@ -56,5 +58,12 @@ public override JObject ToJson()
json["expression"] = Expression.ToJson();
return json;
}
+
+ public override StackItem ToStackItem(ReferenceCounter referenceCounter)
+ {
+ var result = (VM.Types.Array)base.ToStackItem(referenceCounter);
+ result.Add(Expression.ToStackItem(referenceCounter));
+ return result;
+ }
}
}
diff --git a/src/neo/Network/P2P/Payloads/Conditions/OrCondition.cs b/src/neo/Network/P2P/Payloads/Conditions/OrCondition.cs
index 7fb150a9b6..7c6b85d49f 100644
--- a/src/neo/Network/P2P/Payloads/Conditions/OrCondition.cs
+++ b/src/neo/Network/P2P/Payloads/Conditions/OrCondition.cs
@@ -11,6 +11,8 @@
using Neo.IO;
using Neo.IO.Json;
using Neo.SmartContract;
+using Neo.VM;
+using Neo.VM.Types;
using System;
using System.IO;
using System.Linq;
@@ -58,5 +60,12 @@ public override JObject ToJson()
json["expressions"] = Expressions.Select(p => p.ToJson()).ToArray();
return json;
}
+
+ public override StackItem ToStackItem(ReferenceCounter referenceCounter)
+ {
+ var result = (VM.Types.Array)base.ToStackItem(referenceCounter);
+ result.Add(new VM.Types.Array(referenceCounter, Expressions.Select(p => p.ToStackItem(referenceCounter))));
+ return result;
+ }
}
}
diff --git a/src/neo/Network/P2P/Payloads/Conditions/ScriptHashCondition.cs b/src/neo/Network/P2P/Payloads/Conditions/ScriptHashCondition.cs
index 6c43c3a10d..b5d26fb1e4 100644
--- a/src/neo/Network/P2P/Payloads/Conditions/ScriptHashCondition.cs
+++ b/src/neo/Network/P2P/Payloads/Conditions/ScriptHashCondition.cs
@@ -11,6 +11,8 @@
using Neo.IO;
using Neo.IO.Json;
using Neo.SmartContract;
+using Neo.VM;
+using Neo.VM.Types;
using System.IO;
namespace Neo.Network.P2P.Payloads.Conditions
@@ -51,5 +53,12 @@ public override JObject ToJson()
json["hash"] = Hash.ToString();
return json;
}
+
+ public override StackItem ToStackItem(ReferenceCounter referenceCounter)
+ {
+ var result = (Array)base.ToStackItem(referenceCounter);
+ result.Add(Hash.ToArray());
+ return result;
+ }
}
}
diff --git a/src/neo/Network/P2P/Payloads/Conditions/WitnessCondition.cs b/src/neo/Network/P2P/Payloads/Conditions/WitnessCondition.cs
index 324d081d0f..76285f0348 100644
--- a/src/neo/Network/P2P/Payloads/Conditions/WitnessCondition.cs
+++ b/src/neo/Network/P2P/Payloads/Conditions/WitnessCondition.cs
@@ -12,12 +12,14 @@
using Neo.IO.Caching;
using Neo.IO.Json;
using Neo.SmartContract;
+using Neo.VM;
+using Neo.VM.Types;
using System;
using System.IO;
namespace Neo.Network.P2P.Payloads.Conditions
{
- public abstract class WitnessCondition : ISerializable
+ public abstract class WitnessCondition : IInteroperable, ISerializable
{
private const int MaxSubitems = 16;
internal const int MaxNestingDepth = 2;
@@ -119,5 +121,15 @@ public virtual JObject ToJson()
["type"] = Type
};
}
+
+ void IInteroperable.FromStackItem(StackItem stackItem)
+ {
+ throw new NotSupportedException();
+ }
+
+ public virtual StackItem ToStackItem(ReferenceCounter referenceCounter)
+ {
+ return new VM.Types.Array(referenceCounter, new StackItem[] { (byte)Type });
+ }
}
}
diff --git a/src/neo/Network/P2P/Payloads/Signer.cs b/src/neo/Network/P2P/Payloads/Signer.cs
index d9a0d422b8..c5fd4e3288 100644
--- a/src/neo/Network/P2P/Payloads/Signer.cs
+++ b/src/neo/Network/P2P/Payloads/Signer.cs
@@ -12,6 +12,8 @@
using Neo.IO;
using Neo.IO.Json;
using Neo.Network.P2P.Payloads.Conditions;
+using Neo.SmartContract;
+using Neo.VM;
using System;
using System.Collections.Generic;
using System.IO;
@@ -22,7 +24,7 @@ namespace Neo.Network.P2P.Payloads
///
/// Represents a signer of a .
///
- public class Signer : ISerializable
+ public class Signer : IInteroperable, ISerializable
{
// This limits maximum number of AllowedContracts or AllowedGroups here
private const int MaxSubitems = 16;
@@ -176,5 +178,23 @@ public JObject ToJson()
json["rules"] = Rules.Select(p => p.ToJson()).ToArray();
return json;
}
+
+ void IInteroperable.FromStackItem(VM.Types.StackItem stackItem)
+ {
+ throw new NotSupportedException();
+ }
+
+ VM.Types.StackItem IInteroperable.ToStackItem(ReferenceCounter referenceCounter)
+ {
+ return new VM.Types.Array(referenceCounter, new VM.Types.StackItem[]
+ {
+ this.ToArray(),
+ Account.ToArray(),
+ (byte)Scopes,
+ new VM.Types.Array(AllowedContracts.Select(u => new VM.Types.ByteString(u.ToArray()))),
+ new VM.Types.Array(AllowedGroups.Select(u => new VM.Types.ByteString(u.ToArray()))),
+ new VM.Types.Array(Rules.Select(u => u.ToStackItem(referenceCounter)))
+ });
+ }
}
}
diff --git a/src/neo/Network/P2P/Payloads/WitnessRule.cs b/src/neo/Network/P2P/Payloads/WitnessRule.cs
index acd40d5700..6436edc11a 100644
--- a/src/neo/Network/P2P/Payloads/WitnessRule.cs
+++ b/src/neo/Network/P2P/Payloads/WitnessRule.cs
@@ -11,6 +11,9 @@
using Neo.IO;
using Neo.IO.Json;
using Neo.Network.P2P.Payloads.Conditions;
+using Neo.SmartContract;
+using Neo.VM;
+using Neo.VM.Types;
using System;
using System.IO;
@@ -19,7 +22,7 @@ namespace Neo.Network.P2P.Payloads
///
/// The rule used to describe the scope of the witness.
///
- public class WitnessRule : ISerializable
+ public class WitnessRule : IInteroperable, ISerializable
{
///
/// Indicates the action to be taken if the current context meets with the rule.
@@ -73,5 +76,19 @@ public JObject ToJson()
["condition"] = Condition.ToJson()
};
}
+
+ void IInteroperable.FromStackItem(StackItem stackItem)
+ {
+ throw new NotSupportedException();
+ }
+
+ public StackItem ToStackItem(ReferenceCounter referenceCounter)
+ {
+ return new VM.Types.Array(referenceCounter, new StackItem[]
+ {
+ (byte)Action,
+ Condition.ToStackItem(referenceCounter)
+ });
+ }
}
}
diff --git a/src/neo/SmartContract/ApplicationEngine.Crypto.cs b/src/neo/SmartContract/ApplicationEngine.Crypto.cs
index f4d26d6046..e2eba2fd15 100644
--- a/src/neo/SmartContract/ApplicationEngine.Crypto.cs
+++ b/src/neo/SmartContract/ApplicationEngine.Crypto.cs
@@ -65,7 +65,7 @@ protected internal bool CheckMultisig(byte[][] pubkeys, byte[][] signatures)
byte[] message = ScriptContainer.GetSignData(ProtocolSettings.Network);
int m = signatures.Length, n = pubkeys.Length;
if (n == 0 || m == 0 || m > n) throw new ArgumentException();
- AddGas(CheckSigPrice * n * exec_fee_factor);
+ AddGas(CheckSigPrice * n * ExecFeeFactor);
try
{
for (int i = 0, j = 0; i < m && j < n;)
diff --git a/src/neo/SmartContract/ApplicationEngine.Runtime.cs b/src/neo/SmartContract/ApplicationEngine.Runtime.cs
index 877343bdd5..61bfa1a18b 100644
--- a/src/neo/SmartContract/ApplicationEngine.Runtime.cs
+++ b/src/neo/SmartContract/ApplicationEngine.Runtime.cs
@@ -46,6 +46,12 @@ partial class ApplicationEngine
///
public static readonly InteropDescriptor System_Runtime_GetNetwork = Register("System.Runtime.GetNetwork", nameof(GetNetwork), 1 << 3, CallFlags.None);
+ ///
+ /// The of System.Runtime.GetAddressVersion.
+ /// Gets the address version of the current network.
+ ///
+ public static readonly InteropDescriptor System_Runtime_GetAddressVersion = Register("System.Runtime.GetAddressVersion", nameof(GetAddressVersion), 1 << 3, CallFlags.None);
+
///
/// The of System.Runtime.GetTrigger.
/// Gets the trigger of the execution.
@@ -150,6 +156,16 @@ internal protected uint GetNetwork()
return ProtocolSettings.Network;
}
+ ///
+ /// The implementation of System.Runtime.GetAddressVersion.
+ /// Gets the address version of the current network.
+ ///
+ /// The address version of the current network.
+ internal protected byte GetAddressVersion()
+ {
+ return ProtocolSettings.AddressVersion;
+ }
+
///
/// The implementation of System.Runtime.GetTime.
/// Gets the timestamp of the current block.
diff --git a/src/neo/SmartContract/ApplicationEngine.cs b/src/neo/SmartContract/ApplicationEngine.cs
index 79c48c1a44..cd07184f02 100644
--- a/src/neo/SmartContract/ApplicationEngine.cs
+++ b/src/neo/SmartContract/ApplicationEngine.cs
@@ -58,7 +58,7 @@ public partial class ApplicationEngine : ExecutionEngine
private List disposables;
private readonly Dictionary invocationCounter = new();
private readonly Dictionary contractTasks = new();
- private readonly uint exec_fee_factor;
+ internal readonly uint ExecFeeFactor;
internal readonly uint StoragePrice;
private byte[] nonceData;
@@ -153,7 +153,7 @@ protected unsafe ApplicationEngine(TriggerType trigger, IVerifiable container, D
this.ProtocolSettings = settings;
this.gas_amount = gas;
this.Diagnostic = diagnostic;
- this.exec_fee_factor = snapshot is null || persistingBlock?.Index == 0 ? PolicyContract.DefaultExecFeeFactor : NativeContract.Policy.GetExecFeeFactor(Snapshot);
+ this.ExecFeeFactor = snapshot is null || persistingBlock?.Index == 0 ? PolicyContract.DefaultExecFeeFactor : NativeContract.Policy.GetExecFeeFactor(Snapshot);
this.StoragePrice = snapshot is null || persistingBlock?.Index == 0 ? PolicyContract.DefaultStoragePrice : NativeContract.Policy.GetStoragePrice(Snapshot);
this.nonceData = container is Transaction tx ? tx.Hash.ToArray()[..16] : new byte[16];
if (persistingBlock is not null)
@@ -479,7 +479,7 @@ protected override void OnSysCall(uint method)
protected virtual void OnSysCall(InteropDescriptor descriptor)
{
ValidateCallFlags(descriptor.RequiredCallFlags);
- AddGas(descriptor.FixedPrice * exec_fee_factor);
+ AddGas(descriptor.FixedPrice * ExecFeeFactor);
object[] parameters = new object[descriptor.Parameters.Count];
for (int i = 0; i < parameters.Length; i++)
@@ -493,7 +493,7 @@ protected virtual void OnSysCall(InteropDescriptor descriptor)
protected override void PreExecuteInstruction()
{
if (CurrentContext.InstructionPointer < CurrentContext.Script.Length)
- AddGas(exec_fee_factor * OpCodePrices[CurrentContext.CurrentInstruction.OpCode]);
+ AddGas(ExecFeeFactor * OpCodePrices[CurrentContext.CurrentInstruction.OpCode]);
}
private static Block CreateDummyBlock(DataCache snapshot, ProtocolSettings settings)
diff --git a/src/neo/SmartContract/Native/LedgerContract.cs b/src/neo/SmartContract/Native/LedgerContract.cs
index c3900709d6..6c3a7c8655 100644
--- a/src/neo/SmartContract/Native/LedgerContract.cs
+++ b/src/neo/SmartContract/Native/LedgerContract.cs
@@ -242,6 +242,12 @@ private Transaction GetTransactionForContract(ApplicationEngine engine, UInt256
return state.Transaction;
}
+ [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)]
+ private Signer[] GetTransactionSigners(DataCache snapshot, UInt256 hash)
+ {
+ return GetTransactionState(snapshot, hash)?.Transaction.Signers;
+ }
+
[ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)]
private VMState GetTransactionVMState(ApplicationEngine engine, UInt256 hash)
{
diff --git a/src/neo/SmartContract/Native/NativeContract.cs b/src/neo/SmartContract/Native/NativeContract.cs
index b19e5fe349..846eda81eb 100644
--- a/src/neo/SmartContract/Native/NativeContract.cs
+++ b/src/neo/SmartContract/Native/NativeContract.cs
@@ -198,7 +198,7 @@ internal async void Invoke(ApplicationEngine engine, byte version)
ExecutionContextState state = context.GetState();
if (!state.CallFlags.HasFlag(method.RequiredCallFlags))
throw new InvalidOperationException($"Cannot call this method with the flag {state.CallFlags}.");
- engine.AddGas(method.CpuFee * Policy.GetExecFeeFactor(engine.Snapshot) + method.StorageFee * Policy.GetStoragePrice(engine.Snapshot));
+ engine.AddGas(method.CpuFee * engine.ExecFeeFactor + method.StorageFee * engine.StoragePrice);
List