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 ///