diff --git a/src/Neo.SmartContract.Framework/Native/Policy.cs b/src/Neo.SmartContract.Framework/Native/Policy.cs
index ddc6c0a8d..7d0e504af 100644
--- a/src/Neo.SmartContract.Framework/Native/Policy.cs
+++ b/src/Neo.SmartContract.Framework/Native/Policy.cs
@@ -12,6 +12,7 @@
#pragma warning disable CS0626
using Neo.SmartContract.Framework.Attributes;
+using Neo.SmartContract.Framework;
namespace Neo.SmartContract.Framework.Native
{
@@ -26,5 +27,14 @@ public class Policy
public static extern bool IsBlocked(UInt160 account);
public static extern uint GetAttributeFee(TransactionAttributeType attributeType);
public static extern void SetAttributeFee(TransactionAttributeType attributeType, uint value);
+ public static extern void SetFeePerByte(long value);
+ public static extern void SetExecFeeFactor(uint value);
+ public static extern void SetStoragePrice(uint value);
+ public static extern bool BlockAccount(UInt160 account);
+ public static extern bool UnblockAccount(UInt160 account);
+ public static extern uint GetMaxValidUntilBlockIncrement();
+ public static extern void SetMaxValidUntilBlockIncrement(uint value);
+ public static extern uint GetMaxTraceableBlocks();
+ public static extern void SetMaxTraceableBlocks(uint value);
}
}
diff --git a/src/Neo.SmartContract.Framework/Native/RoleManagement.cs b/src/Neo.SmartContract.Framework/Native/RoleManagement.cs
index 72d3a63fc..b369ff82c 100644
--- a/src/Neo.SmartContract.Framework/Native/RoleManagement.cs
+++ b/src/Neo.SmartContract.Framework/Native/RoleManagement.cs
@@ -12,6 +12,7 @@
#pragma warning disable CS0626
using Neo.SmartContract.Framework.Attributes;
+using Neo.SmartContract.Framework;
namespace Neo.SmartContract.Framework.Native
{
@@ -21,5 +22,6 @@ public class RoleManagement
[ContractHash]
public static extern UInt160 Hash { get; }
public static extern ECPoint[] GetDesignatedByRole(Role role, uint index);
+ public static extern void DesignateAsRole(Role role, ECPoint[] nodes);
}
}
diff --git a/src/Neo.SmartContract.Framework/Native/TransactionAttribute.cs b/src/Neo.SmartContract.Framework/Native/TransactionAttribute.cs
new file mode 100644
index 000000000..de683335d
--- /dev/null
+++ b/src/Neo.SmartContract.Framework/Native/TransactionAttribute.cs
@@ -0,0 +1,111 @@
+// Copyright (C) 2015-2025 The Neo Project.
+//
+// TransactionAttribute.cs file belongs to the neo project and is free
+// software distributed under the MIT software license, see the
+// accompanying file LICENSE in the main directory of the
+// repository or http://www.opensource.org/licenses/mit-license.php
+// for more details.
+//
+// Redistribution and use in source and binary forms with or without
+// modifications are permitted.
+
+using Neo.SmartContract.Framework;
+
+namespace Neo.SmartContract.Framework.Native
+{
+ ///
+ /// Base type for transaction attributes exposed inside smart contracts.
+ ///
+ public abstract class TransactionAttribute
+ {
+ ///
+ /// The attribute type.
+ ///
+ public TransactionAttributeType Type { get; set; }
+ }
+
+ ///
+ /// Marks a transaction as high priority.
+ ///
+ public sealed class HighPriority : TransactionAttribute
+ {
+ public HighPriority()
+ {
+ Type = TransactionAttributeType.HighPriority;
+ }
+ }
+
+ ///
+ /// Declares that a transaction represents an oracle response.
+ ///
+ public sealed class OracleResponse : TransactionAttribute
+ {
+ public OracleResponse()
+ {
+ Type = TransactionAttributeType.OracleResponse;
+ }
+
+ ///
+ /// The oracle request identifier.
+ ///
+ public ulong Id { get; set; }
+
+ ///
+ /// Oracle execution result code.
+ ///
+ public OracleResponseCode Code { get; set; }
+
+ ///
+ /// Payload returned by the oracle.
+ ///
+ public ByteString Result { get; set; } = null!;
+ }
+
+ ///
+ /// Prevents a transaction from being accepted before a certain block height.
+ ///
+ public sealed class NotValidBefore : TransactionAttribute
+ {
+ public NotValidBefore()
+ {
+ Type = TransactionAttributeType.NotValidBefore;
+ }
+
+ ///
+ /// Minimum block height at which the transaction becomes valid.
+ ///
+ public uint Height { get; set; }
+ }
+
+ ///
+ /// Declares a mutual exclusion relationship between transactions.
+ ///
+ public sealed class Conflicts : TransactionAttribute
+ {
+ public Conflicts()
+ {
+ Type = TransactionAttributeType.Conflicts;
+ }
+
+ ///
+ /// Hash of the conflicting transaction.
+ ///
+ public UInt256 Hash { get; set; } = null!;
+ }
+
+ ///
+ /// Indicates that the transaction is assisted by the notary service.
+ ///
+ public sealed class NotaryAssisted : TransactionAttribute
+ {
+ public NotaryAssisted()
+ {
+ Type = TransactionAttributeType.NotaryAssisted;
+ }
+
+ ///
+ /// Number of keys that are expected to participate in the assisted signing flow.
+ ///
+ public byte NKeys { get; set; }
+ }
+}
diff --git a/src/Neo.SmartContract.Testing/Native/Policy.cs b/src/Neo.SmartContract.Testing/Native/Policy.cs
index 8d4ca8b21..823ced34c 100644
--- a/src/Neo.SmartContract.Testing/Native/Policy.cs
+++ b/src/Neo.SmartContract.Testing/Native/Policy.cs
@@ -57,6 +57,18 @@ public abstract class Policy(SmartContractInitialize initialize) : SmartContract
[DisplayName("isBlocked")]
public abstract bool IsBlocked(UInt160 account);
+ ///
+ /// Safe method
+ ///
+ [DisplayName("getMaxValidUntilBlockIncrement")]
+ public abstract uint GetMaxValidUntilBlockIncrement();
+
+ ///
+ /// Safe method
+ ///
+ [DisplayName("getMaxTraceableBlocks")]
+ public abstract uint GetMaxTraceableBlocks();
+
#endregion
#region Unsafe methods
diff --git a/tests/Neo.SmartContract.Framework.TestContracts/Contract_Native.cs b/tests/Neo.SmartContract.Framework.TestContracts/Contract_Native.cs
index 461316b1e..2b7e842c7 100644
--- a/tests/Neo.SmartContract.Framework.TestContracts/Contract_Native.cs
+++ b/tests/Neo.SmartContract.Framework.TestContracts/Contract_Native.cs
@@ -84,5 +84,17 @@ public static bool Policy_IsBlocked(UInt160 account)
{
return Policy.IsBlocked(account);
}
+
+ [DisplayName("Policy_GetMaxValidUntilBlockIncrement")]
+ public static uint Policy_GetMaxValidUntilBlockIncrement()
+ {
+ return Policy.GetMaxValidUntilBlockIncrement();
+ }
+
+ [DisplayName("Policy_GetMaxTraceableBlocks")]
+ public static uint Policy_GetMaxTraceableBlocks()
+ {
+ return Policy.GetMaxTraceableBlocks();
+ }
}
}
diff --git a/tests/Neo.SmartContract.Framework.UnitTests/Services/NativeTest.cs b/tests/Neo.SmartContract.Framework.UnitTests/Services/NativeTest.cs
index 46c5d4a33..1a6c67aef 100644
--- a/tests/Neo.SmartContract.Framework.UnitTests/Services/NativeTest.cs
+++ b/tests/Neo.SmartContract.Framework.UnitTests/Services/NativeTest.cs
@@ -10,12 +10,14 @@
// modifications are permitted.
using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Neo;
using Neo.Cryptography.ECC;
using Neo.Network.P2P.Payloads;
using Neo.SmartContract.Testing;
using Neo.SmartContract.Testing.Extensions;
using Neo.VM.Types;
using System.Linq;
+using System.Numerics;
namespace Neo.SmartContract.Framework.UnitTests.Services
{
@@ -56,6 +58,10 @@ public void Test_Policy()
{
Assert.AreEqual(1000L, Contract.Policy_GetFeePerByte());
Assert.IsFalse(Contract.Policy_IsBlocked(Alice.Account));
+ var maxValidUntilBlockIncrement = Engine.Native.Policy.GetMaxValidUntilBlockIncrement();
+ var maxTraceableBlocks = Engine.Native.Policy.GetMaxTraceableBlocks();
+ Assert.AreEqual((BigInteger)maxValidUntilBlockIncrement, Contract.Policy_GetMaxValidUntilBlockIncrement()!.Value);
+ Assert.AreEqual((BigInteger)maxTraceableBlocks, Contract.Policy_GetMaxTraceableBlocks()!.Value);
}
}
}
diff --git a/tests/Neo.SmartContract.Framework.UnitTests/TestingArtifacts/Contract_Native.cs b/tests/Neo.SmartContract.Framework.UnitTests/TestingArtifacts/Contract_Native.cs
index b7198ce9b..dbb92f4c3 100644
--- a/tests/Neo.SmartContract.Framework.UnitTests/TestingArtifacts/Contract_Native.cs
+++ b/tests/Neo.SmartContract.Framework.UnitTests/TestingArtifacts/Contract_Native.cs
@@ -11,12 +11,12 @@ public abstract class Contract_Native(Neo.SmartContract.Testing.SmartContractIni
{
#region Compiled data
- public static Neo.SmartContract.Manifest.ContractManifest Manifest => Neo.SmartContract.Manifest.ContractManifest.Parse(@"{""name"":""Contract_Native"",""groups"":[],""features"":{},""supportedstandards"":[],""abi"":{""methods"":[{""name"":""NEO_Decimals"",""parameters"":[],""returntype"":""Integer"",""offset"":0,""safe"":false},{""name"":""NEO_Transfer"",""parameters"":[{""name"":""from"",""type"":""Hash160""},{""name"":""to"",""type"":""Hash160""},{""name"":""amount"",""type"":""Integer""}],""returntype"":""Boolean"",""offset"":4,""safe"":false},{""name"":""NEO_BalanceOf"",""parameters"":[{""name"":""account"",""type"":""Hash160""}],""returntype"":""Integer"",""offset"":15,""safe"":false},{""name"":""NEO_GetAccountState"",""parameters"":[{""name"":""account"",""type"":""Hash160""}],""returntype"":""Any"",""offset"":23,""safe"":false},{""name"":""NEO_GetGasPerBlock"",""parameters"":[],""returntype"":""Integer"",""offset"":31,""safe"":false},{""name"":""NEO_UnclaimedGas"",""parameters"":[{""name"":""account"",""type"":""Hash160""},{""name"":""end"",""type"":""Integer""}],""returntype"":""Integer"",""offset"":35,""safe"":false},{""name"":""NEO_RegisterCandidate"",""parameters"":[{""name"":""pubkey"",""type"":""PublicKey""}],""returntype"":""Boolean"",""offset"":44,""safe"":false},{""name"":""NEO_GetCandidates"",""parameters"":[],""returntype"":""Array"",""offset"":52,""safe"":false},{""name"":""GAS_Decimals"",""parameters"":[],""returntype"":""Integer"",""offset"":56,""safe"":false},{""name"":""Policy_GetFeePerByte"",""parameters"":[],""returntype"":""Integer"",""offset"":60,""safe"":false},{""name"":""Policy_IsBlocked"",""parameters"":[{""name"":""account"",""type"":""Hash160""}],""returntype"":""Boolean"",""offset"":64,""safe"":false}],""events"":[]},""permissions"":[{""contract"":""0xcc5e4edd9f5f8dba8bb65734541df7a1c081c67b"",""methods"":[""getFeePerByte"",""isBlocked""]},{""contract"":""0xd2a4cff31913016155e38e474a2c06d08be276cf"",""methods"":[""decimals""]},{""contract"":""0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5"",""methods"":[""balanceOf"",""decimals"",""getAccountState"",""getCandidates"",""getGasPerBlock"",""registerCandidate"",""transfer"",""unclaimedGas""]}],""trusts"":[],""extra"":{""Version"":""3.8.1"",""nef"":{""optimization"":""All""}}}");
+ public static Neo.SmartContract.Manifest.ContractManifest Manifest => Neo.SmartContract.Manifest.ContractManifest.Parse(@"{""name"":""Contract_Native"",""groups"":[],""features"":{},""supportedstandards"":[],""abi"":{""methods"":[{""name"":""NEO_Decimals"",""parameters"":[],""returntype"":""Integer"",""offset"":0,""safe"":false},{""name"":""NEO_Transfer"",""parameters"":[{""name"":""from"",""type"":""Hash160""},{""name"":""to"",""type"":""Hash160""},{""name"":""amount"",""type"":""Integer""}],""returntype"":""Boolean"",""offset"":4,""safe"":false},{""name"":""NEO_BalanceOf"",""parameters"":[{""name"":""account"",""type"":""Hash160""}],""returntype"":""Integer"",""offset"":15,""safe"":false},{""name"":""NEO_GetAccountState"",""parameters"":[{""name"":""account"",""type"":""Hash160""}],""returntype"":""Any"",""offset"":23,""safe"":false},{""name"":""NEO_GetGasPerBlock"",""parameters"":[],""returntype"":""Integer"",""offset"":31,""safe"":false},{""name"":""NEO_UnclaimedGas"",""parameters"":[{""name"":""account"",""type"":""Hash160""},{""name"":""end"",""type"":""Integer""}],""returntype"":""Integer"",""offset"":35,""safe"":false},{""name"":""NEO_RegisterCandidate"",""parameters"":[{""name"":""pubkey"",""type"":""PublicKey""}],""returntype"":""Boolean"",""offset"":44,""safe"":false},{""name"":""NEO_GetCandidates"",""parameters"":[],""returntype"":""Array"",""offset"":52,""safe"":false},{""name"":""GAS_Decimals"",""parameters"":[],""returntype"":""Integer"",""offset"":56,""safe"":false},{""name"":""Policy_GetFeePerByte"",""parameters"":[],""returntype"":""Integer"",""offset"":60,""safe"":false},{""name"":""Policy_IsBlocked"",""parameters"":[{""name"":""account"",""type"":""Hash160""}],""returntype"":""Boolean"",""offset"":64,""safe"":false},{""name"":""Policy_GetMaxValidUntilBlockIncrement"",""parameters"":[],""returntype"":""Integer"",""offset"":72,""safe"":false},{""name"":""Policy_GetMaxTraceableBlocks"",""parameters"":[],""returntype"":""Integer"",""offset"":76,""safe"":false}],""events"":[]},""permissions"":[{""contract"":""0xcc5e4edd9f5f8dba8bb65734541df7a1c081c67b"",""methods"":[""getFeePerByte"",""getMaxTraceableBlocks"",""getMaxValidUntilBlockIncrement"",""isBlocked""]},{""contract"":""0xd2a4cff31913016155e38e474a2c06d08be276cf"",""methods"":[""decimals""]},{""contract"":""0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5"",""methods"":[""balanceOf"",""decimals"",""getAccountState"",""getCandidates"",""getGasPerBlock"",""registerCandidate"",""transfer"",""unclaimedGas""]}],""trusts"":[],""extra"":{""Version"":""3.8.1"",""nef"":{""optimization"":""All""}}}");
///
/// Optimization: "All"
///
- public static Neo.SmartContract.NefFile Nef => Convert.FromBase64String(@"TkVGM1Rlc3RpbmdFbmdpbmUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv1Y+pAvCg9TQ4FxI6jBbPyoHNA7whkZWNpbWFscwAAAQ/1Y+pAvCg9TQ4FxI6jBbPyoHNA7wh0cmFuc2ZlcgQAAQ/1Y+pAvCg9TQ4FxI6jBbPyoHNA7wliYWxhbmNlT2YBAAEP9WPqQLwoPU0OBcSOowWz8qBzQO8PZ2V0QWNjb3VudFN0YXRlAQABD/Vj6kC8KD1NDgXEjqMFs/Kgc0DvDmdldEdhc1BlckJsb2NrAAABD/Vj6kC8KD1NDgXEjqMFs/Kgc0DvDHVuY2xhaW1lZEdhcwIAAQ/1Y+pAvCg9TQ4FxI6jBbPyoHNA7xFyZWdpc3RlckNhbmRpZGF0ZQEAAQ/1Y+pAvCg9TQ4FxI6jBbPyoHNA7w1nZXRDYW5kaWRhdGVzAAABD8924ovQBixKR47jVWEBExnzz6TSCGRlY2ltYWxzAAABD3vGgcCh9x1UNFe2i7qNX5/dTl7MDWdldEZlZVBlckJ5dGUAAAEPe8aBwKH3HVQ0V7aLuo1fn91OXswJaXNCbG9ja2VkAQABDwAASDcAAEBXAAMLenl4NwEAQFcAAXg3AgBAVwABeDcDAEA3BABAVwACeXg3BQBAVwABeDcGAEA3BwBANwgAQDcJAEBXAAF4NwoAQL+gUWg=").AsSerializable();
+ public static Neo.SmartContract.NefFile Nef => Convert.FromBase64String(@"TkVGM1Rlc3RpbmdFbmdpbmUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA31Y+pAvCg9TQ4FxI6jBbPyoHNA7whkZWNpbWFscwAAAQ/1Y+pAvCg9TQ4FxI6jBbPyoHNA7wh0cmFuc2ZlcgQAAQ/1Y+pAvCg9TQ4FxI6jBbPyoHNA7wliYWxhbmNlT2YBAAEP9WPqQLwoPU0OBcSOowWz8qBzQO8PZ2V0QWNjb3VudFN0YXRlAQABD/Vj6kC8KD1NDgXEjqMFs/Kgc0DvDmdldEdhc1BlckJsb2NrAAABD/Vj6kC8KD1NDgXEjqMFs/Kgc0DvDHVuY2xhaW1lZEdhcwIAAQ/1Y+pAvCg9TQ4FxI6jBbPyoHNA7xFyZWdpc3RlckNhbmRpZGF0ZQEAAQ/1Y+pAvCg9TQ4FxI6jBbPyoHNA7w1nZXRDYW5kaWRhdGVzAAABD8924ovQBixKR47jVWEBExnzz6TSCGRlY2ltYWxzAAABD3vGgcCh9x1UNFe2i7qNX5/dTl7MDWdldEZlZVBlckJ5dGUAAAEPe8aBwKH3HVQ0V7aLuo1fn91OXswJaXNCbG9ja2VkAQABD3vGgcCh9x1UNFe2i7qNX5/dTl7MHmdldE1heFZhbGlkVW50aWxCbG9ja0luY3JlbWVudAAAAQ97xoHAofcdVDRXtou6jV+f3U5ezBVnZXRNYXhUcmFjZWFibGVCbG9ja3MAAAEPAABQNwAAQFcAAwt6eXg3AQBAVwABeDcCAEBXAAF4NwMAQDcEAEBXAAJ5eDcFAEBXAAF4NwYAQDcHAEA3CABANwkAQFcAAXg3CgBANwsAQDcMAEA2ACxb").AsSerializable();
#endregion
@@ -136,6 +136,26 @@ public abstract class Contract_Native(Neo.SmartContract.Testing.SmartContractIni
///
public abstract BigInteger? Policy_GetFeePerByte();
+ ///
+ /// Unsafe method
+ ///
+ ///
+ /// Script: NwwAQA==
+ /// CALLT 0C00 [32768 datoshi]
+ /// RET [0 datoshi]
+ ///
+ public abstract BigInteger? Policy_GetMaxTraceableBlocks();
+
+ ///
+ /// Unsafe method
+ ///
+ ///
+ /// Script: NwsAQA==
+ /// CALLT 0B00 [32768 datoshi]
+ /// RET [0 datoshi]
+ ///
+ public abstract BigInteger? Policy_GetMaxValidUntilBlockIncrement();
+
///
/// Unsafe method
///